diff options
Diffstat (limited to 'Lib/test')
| -rw-r--r-- | Lib/test/test_typing.py | 66 | ||||
| -rw-r--r-- | Lib/test/typinganndata/ann_module695.py | 50 |
2 files changed, 112 insertions, 4 deletions
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 1ab7d35..0b6cae2 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -4858,20 +4858,30 @@ class GenericTests(BaseTestCase): {'x': list[list[ForwardRef('X')]]} ) - def test_pep695_generic_with_future_annotations(self): + def test_pep695_generic_class_with_future_annotations(self): + original_globals = dict(ann_module695.__dict__) + hints_for_A = get_type_hints(ann_module695.A) A_type_params = ann_module695.A.__type_params__ self.assertIs(hints_for_A["x"], A_type_params[0]) self.assertEqual(hints_for_A["y"].__args__[0], Unpack[A_type_params[1]]) self.assertIs(hints_for_A["z"].__args__[0], A_type_params[2]) + # should not have changed as a result of the get_type_hints() calls! + self.assertEqual(ann_module695.__dict__, original_globals) + + def test_pep695_generic_class_with_future_annotations_and_local_shadowing(self): hints_for_B = get_type_hints(ann_module695.B) - self.assertEqual(hints_for_B.keys(), {"x", "y", "z"}) + self.assertEqual(hints_for_B, {"x": int, "y": str, "z": bytes}) + + def test_pep695_generic_class_with_future_annotations_name_clash_with_global_vars(self): + hints_for_C = get_type_hints(ann_module695.C) self.assertEqual( - set(hints_for_B.values()) ^ set(ann_module695.B.__type_params__), - set() + set(hints_for_C.values()), + set(ann_module695.C.__type_params__) ) + def test_pep_695_generic_function_with_future_annotations(self): hints_for_generic_function = get_type_hints(ann_module695.generic_function) func_t_params = ann_module695.generic_function.__type_params__ self.assertEqual( @@ -4882,6 +4892,54 @@ class GenericTests(BaseTestCase): self.assertIs(hints_for_generic_function["z"].__origin__, func_t_params[2]) self.assertIs(hints_for_generic_function["zz"].__origin__, func_t_params[2]) + def test_pep_695_generic_function_with_future_annotations_name_clash_with_global_vars(self): + self.assertEqual( + set(get_type_hints(ann_module695.generic_function_2).values()), + set(ann_module695.generic_function_2.__type_params__) + ) + + def test_pep_695_generic_method_with_future_annotations(self): + hints_for_generic_method = get_type_hints(ann_module695.D.generic_method) + params = { + param.__name__: param + for param in ann_module695.D.generic_method.__type_params__ + } + self.assertEqual( + hints_for_generic_method, + {"x": params["Foo"], "y": params["Bar"], "return": types.NoneType} + ) + + def test_pep_695_generic_method_with_future_annotations_name_clash_with_global_vars(self): + self.assertEqual( + set(get_type_hints(ann_module695.D.generic_method_2).values()), + set(ann_module695.D.generic_method_2.__type_params__) + ) + + def test_pep_695_generics_with_future_annotations_nested_in_function(self): + results = ann_module695.nested() + + self.assertEqual( + set(results.hints_for_E.values()), + set(results.E.__type_params__) + ) + self.assertEqual( + set(results.hints_for_E_meth.values()), + set(results.E.generic_method.__type_params__) + ) + self.assertNotEqual( + set(results.hints_for_E_meth.values()), + set(results.E.__type_params__) + ) + self.assertEqual( + set(results.hints_for_E_meth.values()).intersection(results.E.__type_params__), + set() + ) + + self.assertEqual( + set(results.hints_for_generic_func.values()), + set(results.generic_func.__type_params__) + ) + def test_extended_generic_rules_subclassing(self): class T1(Tuple[T, KT]): ... class T2(Tuple[T, ...]): ... diff --git a/Lib/test/typinganndata/ann_module695.py b/Lib/test/typinganndata/ann_module695.py index 2ede9fe..b6f3b06 100644 --- a/Lib/test/typinganndata/ann_module695.py +++ b/Lib/test/typinganndata/ann_module695.py @@ -17,6 +17,56 @@ class B[T, *Ts, **P]: z: P +Eggs = int +Spam = str + + +class C[Eggs, **Spam]: + x: Eggs + y: Spam + + def generic_function[T, *Ts, **P]( x: T, *y: *Ts, z: P.args, zz: P.kwargs ) -> None: ... + + +def generic_function_2[Eggs, **Spam](x: Eggs, y: Spam): pass + + +class D: + Foo = int + Bar = str + + def generic_method[Foo, **Bar]( + self, x: Foo, y: Bar + ) -> None: ... + + def generic_method_2[Eggs, **Spam](self, x: Eggs, y: Spam): pass + + +def nested(): + from types import SimpleNamespace + from typing import get_type_hints + + Eggs = bytes + Spam = memoryview + + + class E[Eggs, **Spam]: + x: Eggs + y: Spam + + def generic_method[Eggs, **Spam](self, x: Eggs, y: Spam): pass + + + def generic_function[Eggs, **Spam](x: Eggs, y: Spam): pass + + + return SimpleNamespace( + E=E, + hints_for_E=get_type_hints(E), + hints_for_E_meth=get_type_hints(E.generic_method), + generic_func=generic_function, + hints_for_generic_func=get_type_hints(generic_function) + ) |
