@@ -1605,7 +1605,10 @@ def func1(*args: *Ts): pass
16051605 self .assertEqual (gth (func1 ), {'args' : Unpack [Ts ]})
16061606
16071607 def func2 (* args : * tuple [int , str ]): pass
1608- self .assertEqual (gth (func2 ), {'args' : Unpack [tuple [int , str ]]})
1608+ hint = gth (func2 )['args' ]
1609+ self .assertIsInstance (hint , types .GenericAlias )
1610+ self .assertEqual (hint .__args__ [0 ], int )
1611+ self .assertIs (hint .__unpacked__ , True )
16091612
16101613 class CustomVariadic (Generic [* Ts ]): pass
16111614
@@ -1620,7 +1623,10 @@ def func1(*args: '*Ts'): pass
16201623 {'args' : Unpack [Ts ]})
16211624
16221625 def func2 (* args : '*tuple[int, str]' ): pass
1623- self .assertEqual (gth (func2 ), {'args' : Unpack [tuple [int , str ]]})
1626+ hint = gth (func2 )['args' ]
1627+ self .assertIsInstance (hint , types .GenericAlias )
1628+ self .assertEqual (hint .__args__ [0 ], int )
1629+ self .assertIs (hint .__unpacked__ , True )
16241630
16251631 class CustomVariadic (Generic [* Ts ]): pass
16261632
@@ -6303,31 +6309,6 @@ def foo(a: 'whatevers') -> {}:
63036309
63046310
63056311class InternalsTests (BaseTestCase ):
6306- def test_deprecation_for_no_type_params_passed_to__evaluate (self ):
6307- with self .assertWarnsRegex (
6308- DeprecationWarning ,
6309- (
6310- "Failing to pass a value to the 'type_params' parameter "
6311- "of 'typing._eval_type' is deprecated"
6312- )
6313- ) as cm :
6314- self .assertEqual (typing ._eval_type (list ["int" ], globals (), {}), list [int ])
6315-
6316- self .assertEqual (cm .filename , __file__ )
6317-
6318- f = ForwardRef ("int" )
6319-
6320- with self .assertWarnsRegex (
6321- DeprecationWarning ,
6322- (
6323- "Failing to pass a value to the 'type_params' parameter "
6324- "of 'typing.ForwardRef._evaluate' is deprecated"
6325- )
6326- ) as cm :
6327- self .assertIs (f ._evaluate (globals (), {}, recursive_guard = frozenset ()), int )
6328-
6329- self .assertEqual (cm .filename , __file__ )
6330-
63316312 def test_collect_parameters (self ):
63326313 typing = import_helper .import_fresh_module ("typing" )
63336314 with self .assertWarnsRegex (
@@ -7114,6 +7095,24 @@ def add_right(self, node: 'Node[T]' = None):
71147095 right_hints = get_type_hints (t .add_right , globals (), locals ())
71157096 self .assertEqual (right_hints ['node' ], Node [T ])
71167097
7098+ def test_get_type_hints_preserve_generic_alias_subclasses (self ):
7099+ # https://github.com/python/cpython/issues/130870
7100+ # A real world example of this is `collections.abc.Callable`. When parameterized,
7101+ # the result is a subclass of `types.GenericAlias`.
7102+ class MyAlias (types .GenericAlias ):
7103+ pass
7104+
7105+ class MyClass :
7106+ def __class_getitem__ (cls , args ):
7107+ return MyAlias (cls , args )
7108+
7109+ # Using a forward reference is important, otherwise it works as expected.
7110+ # `y` tests that the `GenericAlias` subclass is preserved when stripping `Annotated`.
7111+ def func (x : MyClass ['int' ], y : MyClass [Annotated [int , ...]]): ...
7112+
7113+ assert isinstance (get_type_hints (func )['x' ], MyAlias )
7114+ assert isinstance (get_type_hints (func )['y' ], MyAlias )
7115+
71177116
71187117class GetUtilitiesTestCase (TestCase ):
71197118 def test_get_origin (self ):
0 commit comments