]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-141174: Improve `ForwardRef` test coverage (#141175)
authordr-carlos <77367421+dr-carlos@users.noreply.github.com>
Mon, 10 Nov 2025 14:53:40 +0000 (01:23 +1030)
committerGitHub <noreply@github.com>
Mon, 10 Nov 2025 14:53:40 +0000 (14:53 +0000)
* Test unsupported format in ForwardRef.evaluate()

* Test dict cell closure with multiple variables

* Test all options in ForwardRef repr

* Test ForwardRef being a final class

Lib/test/test_annotationlib.py

index f1d32ab50cf82b680932e83e07da23628c70bc5d..d196801eedee577e55bda2e125d5626a4397a51b 100644 (file)
@@ -74,6 +74,30 @@ class TestForwardRefFormat(unittest.TestCase):
         anno = get_annotations(inner, format=Format.FORWARDREF)
         self.assertEqual(anno["arg"], x)
 
+    def test_multiple_closure(self):
+        def inner(arg: x[y]):
+            pass
+
+        fwdref = get_annotations(inner, format=Format.FORWARDREF)["arg"]
+        self.assertIsInstance(fwdref, ForwardRef)
+        self.assertEqual(fwdref.__forward_arg__, "x[y]")
+        with self.assertRaises(NameError):
+            fwdref.evaluate()
+
+        y = str
+        fwdref = get_annotations(inner, format=Format.FORWARDREF)["arg"]
+        self.assertIsInstance(fwdref, ForwardRef)
+        extra_name, extra_val = next(iter(fwdref.__extra_names__.items()))
+        self.assertEqual(fwdref.__forward_arg__.replace(extra_name, extra_val.__name__), "x[str]")
+        with self.assertRaises(NameError):
+            fwdref.evaluate()
+
+        x = list
+        self.assertEqual(fwdref.evaluate(), x[y])
+
+        fwdref = get_annotations(inner, format=Format.FORWARDREF)["arg"]
+        self.assertEqual(fwdref, x[y])
+
     def test_function(self):
         def f(x: int, y: doesntexist):
             pass
@@ -1756,6 +1780,14 @@ class TestForwardRefClass(unittest.TestCase):
             repr(List[ForwardRef("int", module="mod")]),
             "typing.List[ForwardRef('int', module='mod')]",
         )
+        self.assertEqual(
+            repr(List[ForwardRef("int", module="mod", is_class=True)]),
+            "typing.List[ForwardRef('int', module='mod', is_class=True)]",
+        )
+        self.assertEqual(
+            repr(List[ForwardRef("int", owner="class")]),
+            "typing.List[ForwardRef('int', owner='class')]",
+        )
 
     def test_forward_recursion_actually(self):
         def namespace1():
@@ -1861,6 +1893,19 @@ class TestForwardRefClass(unittest.TestCase):
             support.EqualToForwardRef('"a" + 1'),
         )
 
+    def test_evaluate_notimplemented_format(self):
+        class C:
+            x: alias
+
+        fwdref = get_annotations(C, format=Format.FORWARDREF)["x"]
+
+        with self.assertRaises(NotImplementedError):
+            fwdref.evaluate(format=Format.VALUE_WITH_FAKE_GLOBALS)
+
+        with self.assertRaises(NotImplementedError):
+            # Some other unsupported value
+            fwdref.evaluate(format=7)
+
     def test_evaluate_with_type_params(self):
         class Gen[T]:
             alias = int
@@ -1994,6 +2039,11 @@ class TestForwardRefClass(unittest.TestCase):
         with self.assertRaises(SyntaxError):
             fr.evaluate()
 
+    def test_fwdref_final_class(self):
+        with self.assertRaises(TypeError):
+            class C(ForwardRef):
+                pass
+
 
 class TestAnnotationLib(unittest.TestCase):
     def test__all__(self):