Introspecting the typing module

New in version 1.1.

The introspection.typing submodule provides functions for the purpose of dissecting typing types. It is recommended to familiarize yourself with the typing module’s core concepts by reading PEP 0483 before working with its internals.

Note

Sometimes there are discrepancies between what is correct and what the typing module actually lets you do. For example, in python 3.9 most types accept an arbitrary number of type arguments:

>>> list[int, str]
list[int, str]

In cases like this, where the implementation is more lenient than the specification, the functions in this module will return what’s correct according to the specification. Like so:

>>> is_variadic_generic(list)
False

Other times, the implementation won’t let you do things that should be possible. For example, in python 3.6 it wasn’t possible to parameterize a typing.ClassVar more than once:

>>> ClassVar[T][int]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/typing.py", line 1404, in __getitem__
    .format(cls.__name__[1:]))
TypeError: ClassVar cannot be further subscripted

In such cases, this module will respect the limitations of the implementation:

>>> is_fully_parameterized_generic(ClassVar[T])
True

introspection.typing.is_type(type_, allow_forwardref=True)

Returns whether type_ is a type - i.e. something that is a valid type annotation.

Examples:

>>> is_type(int)
True
>>> is_type(None)
True
>>> is_type(typing.List)
True
>>> is_type(typing.List[str])
True
>>> is_type('Foo')  # this is a forward reference
True
>>> is_type(3)
False

New in version 1.2: The allow_forwardref parameter.

Parameters
  • type_ – The object to examine

  • allow_forwardref (bool, default: True) – Controls whether strings and ForwardRefs are considered types

Return type

bool

Returns

Whether the object is a class or type (or forward reference)

introspection.typing.is_typing_type(type_, raising=True)

Returns whether type_ is a type added by PEP 0484. This includes parameterized generics and all types defined in the typing module (but not custom subclasses thereof) except for typing.ForwardRef.

If type_ is not a type as defined by is_type() and raising is True, a TypeError is raised. (Otherwise, False is returned.)

Parameters
  • type_ – The object to examine

  • raising – Whether to throw a TypeError if type_ is not a type

Return type

bool

Returns

Whether the object is a typing type

Raises

TypeError – If type_ is not a type and raising is True

introspection.typing.is_generic(type_, raising=True)

Returns whether type_ is any kind of generic type, for example List, List[T] or even List[Tuple[T]]. This includes “special” types like Union, Tuple and Literal - anything that’s subscriptable is considered generic, except for typing.Generic itself.

If type_ is not a type as defined by is_type() and raising is True, a TypeError is raised. (Otherwise, False is returned.)

Parameters
  • type_ – The object to examine

  • raising – Whether to throw a TypeError if type_ is not a type

Returns

Whether the object is a generic type

Raises

TypeError – If type_ is not a type and raising is True

introspection.typing.is_variadic_generic(type_, raising=True)

Returns whether type_ is a generic type that accepts an arbitrary number of type arguments. (e.g. Union, Tuple, Literal, etc.)

If type_ is not a type as defined by is_type() and raising is True, a TypeError is raised. (Otherwise, False is returned.)

Parameters
  • type_ – The object to examine

  • raising – Whether to throw a TypeError if type_ is not a type

Returns

Whether the object is a variadic generic type

Raises

TypeError – If type_ is not a type and raising is True

introspection.typing.is_forwardref(type_, raising=True)

Returns whether type_ is a forward reference.

Examples:

>>> is_forwardref('List')
True
>>> is_forwardref(typing.ForwardRef('List'))
True
>>> is_forwardref(List)
False

New in version 1.2.

Parameters
  • type_ – The object to examine

  • raising (bool, default: True) – Whether to throw a TypeError if type_ is not a type

Returns

Whether the object is a class or type (or forward reference)

introspection.typing.is_generic_base_class(type_, raising=True)

Returns whether type_ is a generic base class, for example List (but not List[int] or List[T]).

If type_ is not a type as defined by is_type() and raising is True, a TypeError is raised. (Otherwise, False is returned.)

Parameters
  • type_ – The object to examine

  • raising – Whether to throw a TypeError on invalid input

Returns

Whether the object is a generic class with no type arguments

Raises

TypeError – If type_ is not a type and raising is True

introspection.typing.is_parameterized_generic(type_, raising=True)

Returns whether type_ is a generic type with some type arguments supplied, for example List[int] or List[T] (but not List) - in other words, a types.GenericAlias.

If type_ is not a type as defined by is_type() and raising is True, a TypeError is raised. (Otherwise, False is returned.)

Parameters
  • type_ – The object to examine

  • raising – Whether to throw a TypeError on invalid input

Returns

Whether the object is a generic type with type arguments

Raises

TypeError – If type_ is not a type and raising is True

introspection.typing.is_fully_parameterized_generic(type_, raising=True)

Returns whether type_ is a generic type with all type arguments supplied, for example List[int] (but not List[T] or List[Tuple[T]]).

Unlike is_parameterized_generic(), which will only ever return True for types.GenericAlias objects, this function returns True for any input that was once generic, but no longer accepts any more type parameters. For example:

>>> is_parameterized_generic(typing.ByteString)
False
>>> is_fully_parameterized_generic(typing.ByteString)
True

If type_ is not a type as defined by is_type() and raising is True, a TypeError is raised. (Otherwise, False is returned.)

Parameters
  • type_ – The object to examine

  • raising – Whether to throw a TypeError on invalid input

Returns

Whether the object is a generic type with type arguments

Raises
  • TypeError – If type_ is not a type and raising is True

  • ValueError – If type_ is not a type and raising is True

introspection.typing.get_generic_base_class(type_)

Given a parameterized generic type as input, returns the corresponding generic base class.

Example:

>>> get_generic_base_class(typing.List[int])
typing.List

Changed in version 1.5.1: Now throws ValueError instead of TypeError if the input is a type, but not generic.

Parameters

type_ – A parameterized generic type

Returns

The input type without its type arguments

introspection.typing.get_type_arguments(type_)

Given a parameterized generic type as input, returns a tuple of its type arguments.

Example:

>>> get_type_arguments(typing.List[int])
(<class 'int'>,)
>>> get_type_arguments(typing.Callable[[str], None])
([<class 'str'>], None)

Note that some generic types (like typing.Optional) won’t accept a tuple as input, so take care when you try to parameterize something with this function’s return value:

>>> get_type_arguments(typing.Optional[int])
(<class 'int'>,)
>>> typing.Optional[(int,)]
TypeError: typing.Optional requires a single type. Got (<class 'int'>,).

Changed in version 1.5.1: Now throws ValueError instead of TypeError if the input is a type, but not generic.

Parameters

type_ – A parameterized generic type

Returns

The input type’s type arguments

introspection.typing.get_type_parameters(type_)

Returns the TypeVars of a generic type.

If type_ is not a type, TypeError is raised. If type_ is a type, but not generic, a ValueError is raised. If type_ is a fully parameterized generic class (like typing.ByteString), an empty tuple is returned.

Examples:

>>> get_type_parameters(List)
(~T,)
>>> get_type_parameters(Generator)
(+T_co, -T_contra, +V_co)
>>> get_type_parameters(List[Tuple[T, int, T]])
(~T,)
>>> get_type_parameters(ByteString)
()

In most cases, the returned TypeVars correspond directly to the type parameters the type accepts. However, some special cases exist. Firstly, there are generics which accept any number of type arguments, like Tuple. Calling get_type_parameters on these will only return a single TypeVar:

>>> get_type_parameters(Union)
(+T_co,)
>>> get_type_parameters(Tuple)
(+T_co,)

Secondly, there are special generic types that the typing module internally doesn’t implement with TypeVars. Despite this, get_type_parameters still supports them:

>>> get_type_parameters(Optional)
(+T_co,)
>>> get_type_parameters(ClassVar)
(+T_co,)
>>> get_type_parameters(Callable)
(-A_contra, +R_co)

Changed in version 1.2: Now throws ValueError instead of TypeError if the input is a type, but not generic.

Raises
introspection.typing.get_type_name(type_)

Returns the name of a type.

Examples:

>>> get_type_name(list)
'list'
>>> get_type_name(typing.List)
'List'
Parameters

type_ – The type whose name to retrieve

Returns

The type’s name

Raises

TypeError – If type_ isn’t a type or is a parameterized generic type

introspection.typing.resolve_forward_refs(annotation, module=None, eval_=True, strict=True)

Resolves forward references in a type annotation.

Examples:

>>> resolve_forward_refs(List['int'])
typing.List[int]
>>> resolve_forward_refs('ellipsis')
<class 'ellipsis'>
Parameters
  • annotation – The annotation in which forward references should be resolved

  • module – The module in which forward references will be evaluated

  • eval_ – If True, references may contain arbitrary code that will be evaluated with eval. Otherwise, they must be identifiers and will be resolved with getattr.

  • strict – Whether to raise an exception if a forward reference can’t be resolved

Returns

A new annotation with no forward references

introspection.typing.annotation_to_string(annotation, implicit_typing=True)

Converts a type annotation to string. The result is valid python code.

Examples:

>>> annotation_to_string(int)
'int'
>>> annotation_to_string(None)
'None'
>>> annotation_to_string(typing.List[int])
'List[int]'
Parameters
  • annotation – A class or type annotation

  • implicit_typing – Whether to omit the “typing.” prefix from typing types’ names

Returns

A string that, when evaluated, returns annotation

introspection.typing.annotation_for_callable(callable_)

Given a callable object as input, returns a matching type annotation.

Examples:

>>> annotation_for_callable(len)
typing.Callable[[typing.Sized], int]

Note: How *args, **kwargs, and keyword-only parameters are handled is currently undefined.

New in version 1.5.

introspection.typing.to_python(type_, strict=False)

Given a typing type as input, returns the corresponding “regular” python class.

Examples:

>>> to_python(typing.List)
<class 'list'>
>>> to_python(typing.Iterable)
<class 'collections.abc.Iterable'>

Note that typing.Any and object are two distinct types:

>>> to_python(typing.Any)
typing.Any
>>> to_python(object)
<class 'object'>

Generics parameterized with typing.Any or other pointless constraints are converted to their regular python counterparts:

>>> to_python(typing.List[typing.Any])
<class 'list'>
>>> to_python(typing.Callable[..., typing.Any])
<class 'collections.abc.Callable'>
>>> to_python(typing.Type[object])
<class 'type'>

The function recurses on the type arguments of parameterized generics:

>>> to_python(typing.List[typing.Set], strict=False)
typing.List[set]

Forward references are handled, as well:

>>> to_python(typing.List['Set'], strict=False)
typing.List[set]
Parameters
  • type_ – The type to convert to a python class

  • strict – Whether to raise an exception if the input type has no python equivalent

Returns

The class corresponding to the input type

introspection.typing.to_typing(type_, strict=False)

Given a python class as input, returns the corresponding typing annotation.

Examples:

>>> to_typing(list)
typing.List
>>> to_typing(typing.List[tuple])
typing.List[typing.Tuple]
>>> to_typing(typing.List['tuple'])
typing.List[typing.Tuple]
Parameters
  • type_ – The class to convert to a typing annotation

  • strict – Whether to raise an exception if the input class has no typing equivalent

Returns

The corresponding annotation from the typing module