]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-105164: Detect annotations inside match blocks (GH-105177). (#105314)
authorJelle Zijlstra <jelle.zijlstra@gmail.com>
Mon, 5 Jun 2023 13:46:12 +0000 (06:46 -0700)
committerGitHub <noreply@github.com>
Mon, 5 Jun 2023 13:46:12 +0000 (13:46 +0000)
(cherry picked from commit 69d1245685cf95ddc678633e978a56673da64865)

Lib/test/test_type_annotations.py
Misc/NEWS.d/next/Core and Builtins/2023-05-31-19-35-22.gh-issue-105164.6Wajph.rst [new file with mode: 0644]
Python/compile.c

index 87f46c2ce8ce616ff00d07085b09dad36ba2190e..bf39fdfa95e124c3079aba1f16e0a8607d28d887 100644 (file)
@@ -1,3 +1,4 @@
+import textwrap
 import unittest
 
 class TypeAnnotationTests(unittest.TestCase):
@@ -101,3 +102,113 @@ class TypeAnnotationTests(unittest.TestCase):
         with self.assertRaises(AttributeError):
             del D.__annotations__
         self.assertEqual(D.__annotations__, {})
+
+
+class TestSetupAnnotations(unittest.TestCase):
+    def check(self, code: str):
+        code = textwrap.dedent(code)
+        for scope in ("module", "class"):
+            with self.subTest(scope=scope):
+                if scope == "class":
+                    code = f"class C:\n{textwrap.indent(code, '    ')}"
+                ns = {}
+                exec(code, ns)
+                if scope == "class":
+                    annotations = ns["C"].__annotations__
+                else:
+                    annotations = ns["__annotations__"]
+                self.assertEqual(annotations, {"x": int})
+
+    def test_top_level(self):
+        self.check("x: int = 1")
+
+    def test_blocks(self):
+        self.check("if True:\n    x: int = 1")
+        self.check("""
+            while True:
+                x: int = 1
+                break
+        """)
+        self.check("""
+            while False:
+                pass
+            else:
+                x: int = 1
+        """)
+        self.check("""
+            for i in range(1):
+                x: int = 1
+        """)
+        self.check("""
+            for i in range(1):
+                pass
+            else:
+                x: int = 1
+        """)
+
+    def test_try(self):
+        self.check("""
+            try:
+                x: int = 1
+            except:
+                pass
+        """)
+        self.check("""
+            try:
+                pass
+            except:
+                pass
+            else:
+                x: int = 1
+        """)
+        self.check("""
+            try:
+                pass
+            except:
+                pass
+            finally:
+                x: int = 1
+        """)
+        self.check("""
+            try:
+                1/0
+            except:
+                x: int = 1
+        """)
+
+    def test_try_star(self):
+        self.check("""
+            try:
+                x: int = 1
+            except* Exception:
+                pass
+        """)
+        self.check("""
+            try:
+                pass
+            except* Exception:
+                pass
+            else:
+                x: int = 1
+        """)
+        self.check("""
+            try:
+                pass
+            except* Exception:
+                pass
+            finally:
+                x: int = 1
+        """)
+        self.check("""
+            try:
+                1/0
+            except* Exception:
+                x: int = 1
+        """)
+
+    def test_match(self):
+        self.check("""
+            match 0:
+                case 0:
+                    x: int = 1
+        """)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-05-31-19-35-22.gh-issue-105164.6Wajph.rst b/Misc/NEWS.d/next/Core and Builtins/2023-05-31-19-35-22.gh-issue-105164.6Wajph.rst
new file mode 100644 (file)
index 0000000..7d3486c
--- /dev/null
@@ -0,0 +1,2 @@
+Ensure annotations are set up correctly if the only annotation in a block is
+within a :keyword:`match` block. Patch by Jelle Zijlstra.
index 1c712fba31573e2dba4f3bb8c60adf9b69e7aa1c..5f26da8608a47725b9d95b1674550b6f11e4d2a2 100644 (file)
@@ -1905,6 +1905,15 @@ find_ann(asdl_stmt_seq *stmts)
                   find_ann(st->v.TryStar.finalbody) ||
                   find_ann(st->v.TryStar.orelse);
             break;
+        case Match_kind:
+            for (j = 0; j < asdl_seq_LEN(st->v.Match.cases); j++) {
+                match_case_ty match_case = (match_case_ty)asdl_seq_GET(
+                    st->v.Match.cases, j);
+                if (find_ann(match_case->body)) {
+                    return true;
+                }
+            }
+            break;
         default:
             res = 0;
         }