Skip to content

Commit

Permalink
[3.12] gh-105164: Detect annotations inside match blocks (GH-105177) (#…
Browse files Browse the repository at this point in the history
…105313)

(cherry picked from commit 69d1245)

Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
  • Loading branch information
miss-islington and JelleZijlstra committed Jun 5, 2023
1 parent 3e7ddc2 commit 6d03541
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
111 changes: 111 additions & 0 deletions Lib/test/test_type_annotations.py
@@ -1,4 +1,6 @@
import textwrap
import unittest
from test.support import run_code

class TypeAnnotationTests(unittest.TestCase):

Expand Down Expand Up @@ -101,3 +103,112 @@ class D(metaclass=C):
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 = run_code(code)
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
""")
@@ -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.
10 changes: 10 additions & 0 deletions Python/compile.c
Expand Up @@ -1422,8 +1422,18 @@ 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 = false;
break;
}
if (res) {
break;
Expand Down

0 comments on commit 6d03541

Please sign in to comment.