Skip to content

Commit e4574d1

Browse files
committed
Backport get_origin() and get_args()
The implementations come from CPython commit 427c84f13f77 with one small change – the get_origin's docstring mentions Annotated as it's also supported. get_origin() and get_args() introduced in [1] and modified in [2] to support Annotated. [1] python/cpython#13685 [2] python/cpython#18260
1 parent 8280de2 commit e4574d1

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

typing_extensions/src_py3/typing_extensions.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ def _check_methods_in_mro(C, *methods):
151151
HAVE_ANNOTATED = PEP_560 or SUBS_TREE
152152

153153
if PEP_560:
154-
__all__.append("get_type_hints")
154+
__all__.extend(["get_args", "get_origin", "get_type_hints"])
155155

156156
if HAVE_ANNOTATED:
157157
__all__.append("Annotated")
@@ -1992,3 +1992,52 @@ class Annotated(metaclass=AnnotatedMeta):
19921992
OptimizedList = Annotated[List[T], runtime.Optimize()]
19931993
OptimizedList[int] == Annotated[List[int], runtime.Optimize()]
19941994
"""
1995+
1996+
# Python 3.9.0+ has those
1997+
if hasattr(typing, 'get_origin'):
1998+
get_origin = typing.get_origin
1999+
get_args = typing.get_args
2000+
elif PEP_560:
2001+
from typing import _GenericAlias # noqa
2002+
2003+
def get_origin(tp):
2004+
"""Get the unsubscripted version of a type.
2005+
2006+
This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar
2007+
and Annotated. Return None for unsupported types. Examples::
2008+
2009+
get_origin(Literal[42]) is Literal
2010+
get_origin(int) is None
2011+
get_origin(ClassVar[int]) is ClassVar
2012+
get_origin(Generic) is Generic
2013+
get_origin(Generic[T]) is Generic
2014+
get_origin(Union[T, int]) is Union
2015+
get_origin(List[Tuple[T, T]][int]) == list
2016+
"""
2017+
if isinstance(tp, _AnnotatedAlias):
2018+
return Annotated
2019+
if isinstance(tp, _GenericAlias):
2020+
return tp.__origin__
2021+
if tp is Generic:
2022+
return Generic
2023+
return None
2024+
2025+
def get_args(tp):
2026+
"""Get type arguments with all substitutions performed.
2027+
2028+
For unions, basic simplifications used by Union constructor are performed.
2029+
Examples::
2030+
get_args(Dict[str, int]) == (str, int)
2031+
get_args(int) == ()
2032+
get_args(Union[int, Union[T, int], str][int]) == (int, str)
2033+
get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int])
2034+
get_args(Callable[[], T][int]) == ([], int)
2035+
"""
2036+
if isinstance(tp, _AnnotatedAlias):
2037+
return (tp.__origin__,) + tp.__metadata__
2038+
if isinstance(tp, _GenericAlias):
2039+
res = tp.__args__
2040+
if get_origin(tp) is collections.abc.Callable and res[0] is not Ellipsis:
2041+
res = (list(res[:-1]), res[-1])
2042+
return res
2043+
return ()

0 commit comments

Comments
 (0)