gh-105164: Detect annotations inside match blocks (#105177)

This commit is contained in:
Jelle Zijlstra 2023-06-05 06:07:17 -07:00 committed by GitHub
parent 0689340366
commit 69d1245685
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 123 additions and 0 deletions

View File

@ -1,4 +1,6 @@
import textwrap
import unittest
from test.support import run_code
class TypeAnnotationTests(unittest.TestCase):
@ -101,3 +103,112 @@ 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 = 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
""")

View File

@ -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.

View File

@ -1398,8 +1398,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;