typing: Advanced Type Hints

We’ve learned about basic type-hints for primitives, but when you want to start type-hinting more complicated data types, the built-in options in Python 3.9 (the version used in Rhino 8) don’t cut it. This is where the typing package comes in.

It’s rarely imported on its own. Instead, individual members are imported from it to be used in type hints:

from typing import ...

Important

The following syntax does nothing but instruct the type checker that a variable is a specific type:

some_variable: SomeType

I will use this in Grasshopper Python script nodes to match the type checker to the type hint specified on the input parameter.

Warning

Type hinting in later versions of Python has changed to support easier syntax and to separate many of the type hints provided by typing to more relevant packages like collections.abc.

Parameterized Types

Many type hints provided in the typing pacakge can be parameterized. That means you can provide extra information about the data being typed. For example, if you have a list of integers, you can use List[int] to indicate that your list contains integers. This can be incredibly helpful for autocompletion and intellisense because, for example, the type checker will know that your iteration variable in a for loop is an int, which allows it to provide more specific feedback:

from typing import List

my_list: List[int] = [0, 1, 2, 3]
for n in my_list:
    # The type checker knows that n is of type int
    ...

Useful Imports

The following imports are incredibly useful to know from typing:

Special Typing Primitives and Forms

  • typing.Any: compatible with every type

  • typing.Union: one of multiple types

    • Parameterized as Union[Type1, Type2, etc.]`

  • typing.Optional: either the specified type or None

    • Optional[X] is equivalent to Union[X, None]

  • typing.Literal: value will be one of provided values

    • Literal[1, 2, "hello"] means the value will either be 1, 2, or "hello". This is most useful on function parameters or outputs.

    • I don’t know if we’ll use this in this class

Collections Type Hints

Note

Technically, tuple, list, set, frozenset, and dict can all be parameterized directly instead of having to use their typing counterpart shown below.

  • typing.List, parameterized as List[ItemType]

  • typing.Set, parameterized as Set[ItemType]

  • typing.FrozenSet, parameterized as FrozenSet[ItemType]

  • typing.Dict, parameterized as Dict[KeyType, ValueType]

  • typing.Tuple, parameterized as Tuple[Item1Type, Item2Type, etc.]

    • Because a tuple has a fixed size, you need to explicitly state the types of each item.

    • To specify an unknown-length tuple of homogeneous type, you can do Tuple[ItemType, ...] with the ellipses after the ItemType.

    • To specify an empty tuple, use Tuple[()]

  • typing.Collection, parameterized as Collection[ItemType]

  • typing.Container, parameterized as Container[ItemType]

    • Supports containment checks with in and not in

  • typing.Iterable, parameterized as Iterable[ItemType]

    • Supports iteration with a for loop

  • typing.Sequence, parameterized as Sequence[ItemType]

    • Supports subscripting with integers and reversed()