summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/test_typing.py66
-rw-r--r--Lib/test/typinganndata/ann_module695.py50
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)
+ )