Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Include/internal/pycore_magic_number.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,13 @@ Known values:
Python 3.14b1 3624 (Don't optimize LOAD_FAST when local is killed by DELETE_FAST)
Python 3.14b3 3625 (Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST)
Python 3.14rc2 3626 (Fix missing exception handlers in logical expression)
Python 3.14rc3 3627 (Fix miscompilation of some module-level annotations)
Python 3.15a0 3650 (Initial version)
Python 3.15a1 3651 (Simplify LOAD_CONST)
Python 3.15a1 3652 (Virtual iterators)
Python 3.15a1 3653 (Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST)
Python 3.15a1 3654 (Fix missing exception handlers in logical expression)
Python 3.15a1 3655 (Fix miscompilation of some module-level annotations)


Python 3.16 will start with 3700
Expand All @@ -297,7 +299,7 @@ PC/launcher.c must also be updated.

*/

#define PYC_MAGIC_NUMBER 3654
#define PYC_MAGIC_NUMBER 3655
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
(little-endian) and then appending b'\r\n'. */
#define PYC_MAGIC_NUMBER_TOKEN \
Expand Down
37 changes: 37 additions & 0 deletions Lib/test/test_type_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -835,3 +835,40 @@ def test_complex_comprehension_inlining_exec(self):
genexp = annos["unique_name_2"][0]
lamb = list(genexp)[0]
self.assertEqual(lamb(), 42)

# gh-138349
def test_module_level_annotation_plus_listcomp(self):
cases = [
"""
def report_error():
pass
try:
[0 for name_2 in unique_name_0 if (lambda: name_2)]
except:
pass
annotated_name: 0
""",
"""
class Generic:
pass
try:
[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)]
except:
pass
annotated_name: 0
""",
"""
class Generic:
pass
annotated_name: 0
try:
[0 for name_2 in [[0]] for unique_name_1 in unique_name_2 if (lambda: name_2)]
except:
pass
""",
]
for code in cases:
with self.subTest(code=code):
mod = build_module(code)
annos = mod.__annotations__
self.assertEqual(annos, {"annotated_name": 0})
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix crash in certain cases where a module contains both a module-level
annotation and a comprehension.
10 changes: 6 additions & 4 deletions Python/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -5492,10 +5492,12 @@ codegen_annassign(compiler *c, stmt_ty s)
RETURN_IF_ERROR(_PyCompile_AddDeferredAnnotation(
c, s, &conditional_annotation_index));
if (conditional_annotation_index != NULL) {
ADDOP_NAME(
c, loc,
SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS ? LOAD_DEREF : LOAD_NAME,
&_Py_ID(__conditional_annotations__), cellvars);
if (SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS) {
ADDOP_NAME(c, loc, LOAD_DEREF, &_Py_ID(__conditional_annotations__), cellvars);
}
else {
ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__conditional_annotations__), names);
}
ADDOP_LOAD_CONST_NEW(c, loc, conditional_annotation_index);
ADDOP_I(c, loc, SET_ADD, 1);
ADDOP(c, loc, POP_TOP);
Expand Down
Loading