Skip to content

Commit 7a6fd4a

Browse files
gh-138349: Fix crash when combining module-level annotation and listcomp (#138363)
1 parent f5fa336 commit 7a6fd4a

File tree

4 files changed

+48
-5
lines changed

4 files changed

+48
-5
lines changed

Include/internal/pycore_magic_number.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,11 +279,13 @@ Known values:
279279
Python 3.14b1 3624 (Don't optimize LOAD_FAST when local is killed by DELETE_FAST)
280280
Python 3.14b3 3625 (Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST)
281281
Python 3.14rc2 3626 (Fix missing exception handlers in logical expression)
282+
Python 3.14rc3 3627 (Fix miscompilation of some module-level annotations)
282283
Python 3.15a0 3650 (Initial version)
283284
Python 3.15a1 3651 (Simplify LOAD_CONST)
284285
Python 3.15a1 3652 (Virtual iterators)
285286
Python 3.15a1 3653 (Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST)
286287
Python 3.15a1 3654 (Fix missing exception handlers in logical expression)
288+
Python 3.15a1 3655 (Fix miscompilation of some module-level annotations)
287289
288290
289291
Python 3.16 will start with 3700
@@ -297,7 +299,7 @@ PC/launcher.c must also be updated.
297299
298300
*/
299301

300-
#define PYC_MAGIC_NUMBER 3654
302+
#define PYC_MAGIC_NUMBER 3655
301303
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
302304
(little-endian) and then appending b'\r\n'. */
303305
#define PYC_MAGIC_NUMBER_TOKEN \

Lib/test/test_type_annotations.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,3 +835,40 @@ def test_complex_comprehension_inlining_exec(self):
835835
genexp = annos["unique_name_2"][0]
836836
lamb = list(genexp)[0]
837837
self.assertEqual(lamb(), 42)
838+
839+
# gh-138349
840+
def test_module_level_annotation_plus_listcomp(self):
841+
cases = [
842+
"""
843+
def report_error():
844+
pass
845+
try:
846+
[0 for name_2 in unique_name_0 if (lambda: name_2)]
847+
except:
848+
pass
849+
annotated_name: 0
850+
""",
851+
"""
852+
class Generic:
853+
pass
854+
try:
855+
[0 for name_2 in unique_name_0 if (0 for unique_name_1 in unique_name_2 for unique_name_3 in name_2)]
856+
except:
857+
pass
858+
annotated_name: 0
859+
""",
860+
"""
861+
class Generic:
862+
pass
863+
annotated_name: 0
864+
try:
865+
[0 for name_2 in [[0]] for unique_name_1 in unique_name_2 if (lambda: name_2)]
866+
except:
867+
pass
868+
""",
869+
]
870+
for code in cases:
871+
with self.subTest(code=code):
872+
mod = build_module(code)
873+
annos = mod.__annotations__
874+
self.assertEqual(annos, {"annotated_name": 0})
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash in certain cases where a module contains both a module-level
2+
annotation and a comprehension.

Python/codegen.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5477,10 +5477,12 @@ codegen_annassign(compiler *c, stmt_ty s)
54775477
RETURN_IF_ERROR(_PyCompile_AddDeferredAnnotation(
54785478
c, s, &conditional_annotation_index));
54795479
if (conditional_annotation_index != NULL) {
5480-
ADDOP_NAME(
5481-
c, loc,
5482-
SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS ? LOAD_DEREF : LOAD_NAME,
5483-
&_Py_ID(__conditional_annotations__), cellvars);
5480+
if (SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS) {
5481+
ADDOP_NAME(c, loc, LOAD_DEREF, &_Py_ID(__conditional_annotations__), cellvars);
5482+
}
5483+
else {
5484+
ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__conditional_annotations__), names);
5485+
}
54845486
ADDOP_LOAD_CONST_NEW(c, loc, conditional_annotation_index);
54855487
ADDOP_I(c, loc, SET_ADD, 1);
54865488
ADDOP(c, loc, POP_TOP);

0 commit comments

Comments
 (0)