Skip to content

Commit 1dd5f47

Browse files
[3.15] gh-143493: fix cleanup on errors in codegen_comprehension (GH-156374)
Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 0ca288a commit 1dd5f47

1 file changed

Lines changed: 42 additions & 29 deletions

File tree

Python/codegen.c

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4948,6 +4948,34 @@ pop_inlined_comprehension_state(compiler *c, location loc,
49484948
return SUCCESS;
49494949
}
49504950

4951+
static int
4952+
codegen_comprehension_init_container(compiler *c, location loc, int type,
4953+
int is_inlined)
4954+
{
4955+
int op;
4956+
switch (type) {
4957+
case COMP_LISTCOMP:
4958+
op = BUILD_LIST;
4959+
break;
4960+
case COMP_SETCOMP:
4961+
op = BUILD_SET;
4962+
break;
4963+
case COMP_DICTCOMP:
4964+
op = BUILD_MAP;
4965+
break;
4966+
default:
4967+
PyErr_Format(PyExc_SystemError,
4968+
"unknown comprehension type %d", type);
4969+
return ERROR;
4970+
}
4971+
4972+
ADDOP_I(c, loc, op, 0);
4973+
if (is_inlined) {
4974+
ADDOP_I(c, loc, SWAP, 2);
4975+
}
4976+
return SUCCESS;
4977+
}
4978+
49514979
static int
49524980
codegen_comprehension(compiler *c, expr_ty e, int type,
49534981
identifier name, asdl_comprehension_seq *generators, expr_ty elt,
@@ -4986,19 +5014,22 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
49865014
if (type == COMP_GENEXP) {
49875015
/* Insert GET_ITER before RETURN_GENERATOR.
49885016
https://docs.python.org/3/reference/expressions.html#generator-expressions */
4989-
RETURN_IF_ERROR(
4990-
_PyInstructionSequence_InsertInstruction(
5017+
if (_PyInstructionSequence_InsertInstruction(
49915018
INSTR_SEQUENCE(c), 0,
4992-
RESUME, RESUME_AT_GEN_EXPR_START, NO_LOCATION));
4993-
RETURN_IF_ERROR(
4994-
_PyInstructionSequence_InsertInstruction(
5019+
RESUME, RESUME_AT_GEN_EXPR_START, NO_LOCATION) < 0) {
5020+
goto error_in_scope;
5021+
}
5022+
if (_PyInstructionSequence_InsertInstruction(
49955023
INSTR_SEQUENCE(c), 1,
4996-
LOAD_FAST, 0, LOC(outermost->iter)));
4997-
RETURN_IF_ERROR(
4998-
_PyInstructionSequence_InsertInstruction(
5024+
LOAD_FAST, 0, LOC(outermost->iter)) < 0) {
5025+
goto error_in_scope;
5026+
}
5027+
if (_PyInstructionSequence_InsertInstruction(
49995028
INSTR_SEQUENCE(c), 2,
50005029
outermost->is_async ? GET_AITER : GET_ITER,
5001-
0, LOC(outermost->iter)));
5030+
0, LOC(outermost->iter)) < 0) {
5031+
goto error_in_scope;
5032+
}
50025033
iter_state = ITERATOR_ON_STACK;
50035034
}
50045035
else {
@@ -5008,27 +5039,9 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
50085039
Py_CLEAR(entry);
50095040

50105041
if (type != COMP_GENEXP) {
5011-
int op;
5012-
switch (type) {
5013-
case COMP_LISTCOMP:
5014-
op = BUILD_LIST;
5015-
break;
5016-
case COMP_SETCOMP:
5017-
op = BUILD_SET;
5018-
break;
5019-
case COMP_DICTCOMP:
5020-
op = BUILD_MAP;
5021-
break;
5022-
default:
5023-
PyErr_Format(PyExc_SystemError,
5024-
"unknown comprehension type %d", type);
5042+
if (codegen_comprehension_init_container(c, loc, type, is_inlined) < 0) {
50255043
goto error_in_scope;
50265044
}
5027-
5028-
ADDOP_I(c, loc, op, 0);
5029-
if (is_inlined) {
5030-
ADDOP_I(c, loc, SWAP, 2);
5031-
}
50325045
}
50335046
if (codegen_comprehension_generator(c, loc, generators, 0, 0,
50345047
elt, val, type, iter_state) < 0) {
@@ -5043,7 +5056,7 @@ codegen_comprehension(compiler *c, expr_ty e, int type,
50435056
}
50445057

50455058
if (type != COMP_GENEXP) {
5046-
ADDOP(c, LOC(e), RETURN_VALUE);
5059+
ADDOP_IN_SCOPE(c, LOC(e), RETURN_VALUE);
50475060
}
50485061
if (type == COMP_GENEXP) {
50495062
if (codegen_wrap_in_stopiteration_handler(c) < 0) {

0 commit comments

Comments
 (0)