SOLVED Python typing features

Are you planning to implement the new static typing features introduced in python 3.5 in future releases?
In some parts of the python documentation I can already see type information for input arguments written like Union[int, float, c4d.Vector] etc...

Right now I am creating my own stubs for pylance but it would be awesome, if you could add those 🙂

Hi @heilei, Pycharm already handles our dummy package nicely since Pycharm bases its inspection on the docstring.
Regarding support for type-hints as said this is not something we are aiming to do at the moment but we might in the future.

Major points against type-hints are that it clutters a lot of the code and duplicates information which means a waste of space, time, and resources. For example FieldInfo.Create


def Create(flags, thread, doc, currentThreadIndex, threadCount, inputs, callers):
    """
    Creates a :class:`c4d.modules.mograph.FieldInfo` while relaying potential allocation errors.

    :type flags: int
    :param flags: The channels to sample.

        .. include:: /consts/FIELDSAMPLE_FLAG.rst
            :start-line: 3

    :type thread: c4d.threading.BaseThread
    :param thread: The caller thread.
    :type doc: c4d.documents.BaseDocument
    :param doc: The document to sample.
    :type currentThreadIndex: int
    :param currentThreadIndex: The thread index that will sample those points.
    :type threadCount: int
    :param threadCount: The total thread count.
    :type inputs: Optional[c4d.modules.mograph.FieldInput]
    :param inputs: The full point list.
    :type callers: Optional[list(c4d.BaseList2D)]
    :param callers: An initializer list to build the stack, first item is base of stack.
    :rtype: `c4d.modules.mograph.FieldInfo`
    :return: The created FieldInfo
    """

Become

def Create(self, flags:int, thread: c4d.threading.BaseThread, doc: c4d.documents.BaseDocument, currentThreadIndex: int, threadCount: int, inputs: Optional[c4d.modules.mograph.FieldInput], callers: Optional[List(c4d.BaseList2D)]) -> c4d.modules.mograph.FieldInfo:
    """
    Creates a :class:`c4d.modules.mograph.FieldInfo` while relaying potential allocation errors.

    :type flags: int
    :param flags: The channels to sample.

        .. include:: /consts/FIELDSAMPLE_FLAG.rst
            :start-line: 3

    :type thread: c4d.threading.BaseThread
    :param thread: The caller thread.
    :type doc: c4d.documents.BaseDocument
    :param doc: The document to sample.
    :type currentThreadIndex: int
    :param currentThreadIndex: The thread index that will sample those points.
    :type threadCount: int
    :param threadCount: The total thread count.
    :type inputs: Optional[c4d.modules.mograph.FieldInput]
    :param inputs: The full point list.
    :type callers: Optional[list(c4d.BaseList2D)]
    :param callers: An initializer list to build the stack, first item is base of stack.
    :rtype: `c4d.modules.mograph.FieldInfo`
    :return: The created FieldInfo
    """

Which makes the code unreadable... A code signature that is 263 character longs... Such a shame.
But I get the fact that this dummy package purpose is for IDE so code readability may not be that important.

However, PyLance is supposed to support docstring type hinting in the future Type hinting through docstrings.

@beesperester said in Python typing features:

Would I be allowed to share my customized version of the dummy package?

While we do not encourage this, the fact that we do not support typehint is limiting its usage, so you can release it but it will be on you to maintain it.

Cheers,
Maxime.

Hi @beesperester sorry for the late reply,

There is no static typing feature in Python but only type hint to help some IDE that can't cope with Python dynamic language to offer some type hinting.

However, due to the current limitation of the type hitting (import order should be respected, you have to import them, etc...), the work it will require to add them and the most important this will clutter a lot signature and some signature will be more than 500 char long, which is unacceptable in my POV.

I don't know pylance, but normally any decent IDE should be able to provide you type hint and autocompletion based on type with the docstring available within the dummy package.

Cheers,
Maxime.

Hi @m_adam, thanks for taking time to answer my question. I have been using the dummy package before, but there are some limitations / shortcomings compared to the type checking functionality of mypy or pylance.

With the dummy package for example I am not getting the proper return type from BaseObject.GetName() which should be str but is None. Of course I can see that the return type is described as str in the docstring, but for the IDE it is still None and since it is a dummy package, the IDE can not infer the actual return type in python types or objects
Screenshot 2021-05-13 at 15.35.03.png

When using my customized version of the dummy package I can get the correct return type
Screenshot 2021-05-16 at 18.43.37.png

This is especially useful if I use something like GetChildren, because now pylance already knows about the type of objects in the returned list and I can easily browse the objects functions and can check in the IDE if my variables have the correct type
Screenshot 2021-05-16 at 18.52.57.png

Would I be allowed to share my customized version of the dummy package? It is based on the provided package but with added type hints and modified imports where possible and covers ca. 90% of the definitions.

For example the definition for c4d.Vector would look like this:

class Vector(object):
    x: float
    y: float
    z: float

    def __init__(self, x: Optional[Union[int, Vector, float]] = ..., y: Optional[Union[int, float]] = ..., z: Optional[Union[int, float]] = ...) -> None:
        """
        | Initializes a new :class:`Vector <c4d.Vector>`.
        | All arguments are optional so it is possible to create a new vector without any arguments. All components are simply `0`.
        | Otherwise *x* can be a :class:`Vector <c4d.Vector>` so all components of the passed vector will be copied to the new vector.
        | If only a number is passed, all components will be set to this.
        .. code-block:: python
        c4d.Vector()
        # => Vector(0,0,0)
        c4d.Vector(100)
        # => Vector(100,100,100)
        v = c4d.Vector(100,100,100)
        c4d.Vector(v)
        # => Vector(100,100,100)
        c4d.Vector(1,2,3)
        # => Vector(1,2,3)
        :type x: Union[int, float, c4d.Vector]
        :param x: If *x* is a number and is the only passed argument, set this to all components. If *x* is a vector, clone it. Otherwise set the X component.
        :type y: number
        :param y: Set the Y component.
        :type z: number
        :param z: Set the Z component.
        :rtype: c4d.Vector
        :return: A new vector.
        """
        ...

Cheers

A big thumbs-up for this! I've also started using Python typing in PyCharm, now that C4D API is finally based on Python 3. Having correct typing also in the dummy package would be really useful.

Hi @heilei, Pycharm already handles our dummy package nicely since Pycharm bases its inspection on the docstring.
Regarding support for type-hints as said this is not something we are aiming to do at the moment but we might in the future.

Major points against type-hints are that it clutters a lot of the code and duplicates information which means a waste of space, time, and resources. For example FieldInfo.Create


def Create(flags, thread, doc, currentThreadIndex, threadCount, inputs, callers):
    """
    Creates a :class:`c4d.modules.mograph.FieldInfo` while relaying potential allocation errors.

    :type flags: int
    :param flags: The channels to sample.

        .. include:: /consts/FIELDSAMPLE_FLAG.rst
            :start-line: 3

    :type thread: c4d.threading.BaseThread
    :param thread: The caller thread.
    :type doc: c4d.documents.BaseDocument
    :param doc: The document to sample.
    :type currentThreadIndex: int
    :param currentThreadIndex: The thread index that will sample those points.
    :type threadCount: int
    :param threadCount: The total thread count.
    :type inputs: Optional[c4d.modules.mograph.FieldInput]
    :param inputs: The full point list.
    :type callers: Optional[list(c4d.BaseList2D)]
    :param callers: An initializer list to build the stack, first item is base of stack.
    :rtype: `c4d.modules.mograph.FieldInfo`
    :return: The created FieldInfo
    """

Become

def Create(self, flags:int, thread: c4d.threading.BaseThread, doc: c4d.documents.BaseDocument, currentThreadIndex: int, threadCount: int, inputs: Optional[c4d.modules.mograph.FieldInput], callers: Optional[List(c4d.BaseList2D)]) -> c4d.modules.mograph.FieldInfo:
    """
    Creates a :class:`c4d.modules.mograph.FieldInfo` while relaying potential allocation errors.

    :type flags: int
    :param flags: The channels to sample.

        .. include:: /consts/FIELDSAMPLE_FLAG.rst
            :start-line: 3

    :type thread: c4d.threading.BaseThread
    :param thread: The caller thread.
    :type doc: c4d.documents.BaseDocument
    :param doc: The document to sample.
    :type currentThreadIndex: int
    :param currentThreadIndex: The thread index that will sample those points.
    :type threadCount: int
    :param threadCount: The total thread count.
    :type inputs: Optional[c4d.modules.mograph.FieldInput]
    :param inputs: The full point list.
    :type callers: Optional[list(c4d.BaseList2D)]
    :param callers: An initializer list to build the stack, first item is base of stack.
    :rtype: `c4d.modules.mograph.FieldInfo`
    :return: The created FieldInfo
    """

Which makes the code unreadable... A code signature that is 263 character longs... Such a shame.
But I get the fact that this dummy package purpose is for IDE so code readability may not be that important.

However, PyLance is supposed to support docstring type hinting in the future Type hinting through docstrings.

@beesperester said in Python typing features:

Would I be allowed to share my customized version of the dummy package?

While we do not encourage this, the fact that we do not support typehint is limiting its usage, so you can release it but it will be on you to maintain it.

Cheers,
Maxime.

@m_adam said in Python typing features:

[...]
@beesperester said in Python typing features:

Would I be allowed to share my customized version of the dummy package?

While we do not encourage this, the fact that we do not support typehint is limiting its usage, so you can release it but it will be on you to maintain it.

Cheers,
Maxime.

Thanks. For everyone interested in the extended definitions you can find them in my github repository here: https://github.com/cgbits/c4dstubs

Some of the definitions may not be 100% accurate because the docstrings have varying ways of defining the types / rtypes (list of float, tuple(int, float) etc.) and sometimes they omit the information if a parameter is optional. Over time I will improve the definitions while using them for my own plugin development purposes.

Cheers

Hello @beesperester,

thank you for sharing your repository, but without further questions or postings, we will consider this topic as solved by Wednesday and flag it accordingly.

Thank you for your understanding,
Ferdinand