a dictionary constructed by merging all the ``__annotations__`` along
``C.__mro__`` in reverse order.
+.. function:: get_origin(typ)
+.. function:: get_args(typ)
+
+ Provide basic introspection for generic types and special typing forms.
+
+ For a typing object of the form ``X[Y, Z, ...]`` these functions return
+ ``X`` and ``(Y, Z, ...)``. If ``X`` is a generic alias for a builtin or
+ :mod:`collections` class, it gets normalized to the original class.
+ For unsupported objects return ``None`` and ``()`` correspondingly.
+ Examples::
+
+ assert get_origin(Dict[str, int]) is dict
+ assert get_args(Dict[int, str]) == (int, str)
+
+ assert get_origin(Union[int, str]) is Union
+ assert get_args(Union[int, str]) == (int, str)
+
+ .. versionadded:: 3.8
+
.. decorator:: overload
The ``@overload`` decorator allows describing functions and methods
from typing import Generic, ClassVar, Final, final, Protocol
from typing import cast, runtime_checkable
from typing import get_type_hints
+from typing import get_origin, get_args
from typing import no_type_check, no_type_check_decorator
from typing import Type
from typing import NewType
self.assertEqual(gth(G), {'lst': ClassVar[List[T]]})
+class GetUtilitiesTestCase(TestCase):
+ def test_get_origin(self):
+ T = TypeVar('T')
+ class C(Generic[T]): pass
+ self.assertIs(get_origin(C[int]), C)
+ self.assertIs(get_origin(C[T]), C)
+ self.assertIs(get_origin(int), None)
+ self.assertIs(get_origin(ClassVar[int]), ClassVar)
+ self.assertIs(get_origin(Union[int, str]), Union)
+ self.assertIs(get_origin(Literal[42, 43]), Literal)
+ self.assertIs(get_origin(Final[List[int]]), Final)
+ self.assertIs(get_origin(Generic), Generic)
+ self.assertIs(get_origin(Generic[T]), Generic)
+ self.assertIs(get_origin(List[Tuple[T, T]][int]), list)
+
+ def test_get_args(self):
+ T = TypeVar('T')
+ class C(Generic[T]): pass
+ self.assertEqual(get_args(C[int]), (int,))
+ self.assertEqual(get_args(C[T]), (T,))
+ self.assertEqual(get_args(int), ())
+ self.assertEqual(get_args(ClassVar[int]), (int,))
+ self.assertEqual(get_args(Union[int, str]), (int, str))
+ self.assertEqual(get_args(Literal[42, 43]), (42, 43))
+ self.assertEqual(get_args(Final[List[int]]), (List[int],))
+ self.assertEqual(get_args(Union[int, Tuple[T, int]][str]),
+ (int, Tuple[str, int]))
+ self.assertEqual(get_args(typing.Dict[int, Tuple[T, T]][Optional[int]]),
+ (int, Tuple[Optional[int], Optional[int]]))
+ self.assertEqual(get_args(Callable[[], T][int]), ([], int,))
+ self.assertEqual(get_args(Union[int, Callable[[Tuple[T, ...]], str]]),
+ (int, Callable[[Tuple[T, ...]], str]))
+ self.assertEqual(get_args(Tuple[int, ...]), (int, ...))
+ self.assertEqual(get_args(Tuple[()]), ((),))
+
+
class CollectionsAbcTests(BaseTestCase):
def test_hashable(self):
'AnyStr',
'cast',
'final',
+ 'get_args',
+ 'get_origin',
'get_type_hints',
'NewType',
'no_type_check',
return hints
+def get_origin(tp):
+ """Get the unsubscripted version of a type.
+
+ This supports generic types, Callable, Tuple, Union, Literal, Final and ClassVar.
+ Return None for unsupported types. Examples::
+
+ get_origin(Literal[42]) is Literal
+ get_origin(int) is None
+ get_origin(ClassVar[int]) is ClassVar
+ get_origin(Generic) is Generic
+ get_origin(Generic[T]) is Generic
+ get_origin(Union[T, int]) is Union
+ get_origin(List[Tuple[T, T]][int]) == list
+ """
+ if isinstance(tp, _GenericAlias):
+ return tp.__origin__
+ if tp is Generic:
+ return Generic
+ return None
+
+
+def get_args(tp):
+ """Get type arguments with all substitutions performed.
+
+ For unions, basic simplifications used by Union constructor are performed.
+ Examples::
+ get_args(Dict[str, int]) == (str, int)
+ get_args(int) == ()
+ get_args(Union[int, Union[T, int], str][int]) == (int, str)
+ get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
+ get_args(Callable[[], T][int]) == ([], int)
+ """
+ if isinstance(tp, _GenericAlias):
+ res = tp.__args__
+ if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis:
+ res = (list(res[:-1]), res[-1])
+ return res
+ return ()
+
+
def no_type_check(arg):
"""Decorator to indicate that annotations are not type hints.