Skip to content
Prev Previous commit
Next Next commit
Add one more utility, make some things faster
  • Loading branch information
Ivan Levkivskyi
Ivan Levkivskyi committed Mar 9, 2017
commit b34b263f9373e8b5cadffe4ad3f11f46d30fe561
11 changes: 10 additions & 1 deletion typing_inspect/test_typing_inspect.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing_inspect import (
is_generic_type, is_callable_type, is_tuple_type, is_union_type,
is_typevar, is_classvar, get_origin, get_parameters, get_last_args, get_args,
get_generic_type, get_generic_bases,
get_generic_type, get_generic_bases, get_last_origin,
)
from unittest import TestCase, main
from typing import (
Expand Down Expand Up @@ -65,6 +65,15 @@ def test_classvar(self):


class GetUtilityTestCase(TestCase):

def test_last_origin(self):
T = TypeVar('T')
self.assertEqual(get_last_origin(int), None)
self.assertEqual(get_last_origin(ClassVar[int]), None)
self.assertEqual(get_last_origin(Generic[T]), Generic)
self.assertEqual(get_last_origin(Union[T, int][str]), Union[T, int])
self.assertEqual(get_last_origin(List[Tuple[T, T]][int]), List[Tuple[T, T]])

def test_origin(self):
T = TypeVar('T')
self.assertEqual(get_origin(int), None)
Expand Down
34 changes: 26 additions & 8 deletions typing_inspect/typing_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@

# NOTE: This module must support Python 2.7 in addition to Python 3.x

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a requirement for all typing modules?

And regardless: Why?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typing on PyPI supports 2.7 (which is supported until 2020).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah! didn’t know it was on PyPI


from typing import Callable, Union, Tuple, TypeVar, _gorg, ClassVar, Generic
from typing import (
Callable, CallableMeta, Union, _Union, TupleMeta, TypeVar,
_gorg, _ClassVar, GenericMeta,
)


def is_generic_type(tp):
Expand All @@ -29,8 +32,8 @@ def is_generic_type(tp):
is_generic_type(Sequence[Union[str, bytes]]) == True
"""

return (isinstance(tp, type(Generic)) and not
isinstance(tp, (type(Callable), type(Tuple))))
return (isinstance(tp, GenericMeta) and not
isinstance(tp, (CallableMeta, TupleMeta)))


def is_callable_type(tp):
Expand All @@ -53,7 +56,7 @@ class MyClass(Callable[[int], int]):
get_origin(tp) is Callable

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference exactly between this construct and is_callable_type? I think this could be explained more.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the latter excludes subclasses, I added this to the docstring.

"""

return type(tp) is type(Callable)
return type(tp) is CallableMeta


def is_tuple_type(tp):
Expand All @@ -75,7 +78,7 @@ class MyClass(Tuple[str, int]):
get_origin(tp) is Tuple
"""

return type(tp) is type(Tuple)
return type(tp) is TupleMeta


def is_union_type(tp):
Expand All @@ -87,7 +90,7 @@ def is_union_type(tp):
is_union_type(Union[T, int]) == True
"""

return type(tp) is type(Union)
return type(tp) is _Union


def is_typevar(tp):
Expand All @@ -110,7 +113,22 @@ def is_classvar(tp):
is_classvar(ClassVar[List[T]]) == True
"""

return type(tp) is type(ClassVar)
return type(tp) is _ClassVar


def get_last_origin(tp):
"""Get the last base of (multiply) subscripted type. Supports generic types,
Union, Callable, and Tuple. Returns None for unsupported types.
Examples::

get_last_origin(int) == None
get_last_origin(ClassVar[int]) == None
get_last_origin(Generic[T]) == Generic
get_last_origin(Union[T, int][str]) == Union[T, int]
get_last_origin(List[Tuple[T, T]][int]) == List[Tuple[T, T]]
"""

return getattr(tp, '__origin__', None)


def get_origin(tp):
Expand All @@ -125,7 +143,7 @@ def get_origin(tp):
get_origin(List[Tuple[T, T]][int]) == List
"""

if isinstance(tp, type(Generic)):
if isinstance(tp, GenericMeta):
return _gorg(tp)
if is_union_type(tp):
return Union
Expand Down