Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 46c7a4f

Browse files
committed
fix u_fasthidden in nested case
1 parent ca636a5 commit 46c7a4f

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed

Lib/test/test_listcomps.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,23 @@ def test_nested(self):
249249
outputs = {"y": [[0, 1], [0, 1, 4]]}
250250
self._check_in_scopes(code, outputs)
251251

252+
def test_nested_2(self):
253+
code = """
254+
l = [1, 2, 3]
255+
x = 3
256+
y = [x for [x ** x for x in range(x)][x - 1] in l]
257+
"""
258+
outputs = {"y": [3, 3, 3]}
259+
self._check_in_scopes(code, outputs)
260+
261+
def test_nested_3(self):
262+
code = """
263+
l = [(1, 2), (3, 4), (5, 6)]
264+
y = [x for (x, [x ** x for x in range(x)][x - 1]) in l]
265+
"""
266+
outputs = {"y": [1, 3, 5]}
267+
self._check_in_scopes(code, outputs)
268+
252269
def test_nameerror(self):
253270
code = """
254271
[x for x in [1]]

Python/compile.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4990,6 +4990,7 @@ compiler_async_comprehension_generator(struct compiler *c, location loc,
49904990
typedef struct {
49914991
PyObject *pushed_locals;
49924992
PyObject *temp_symbols;
4993+
PyObject *fast_hidden;
49934994
} inlined_comprehension_state;
49944995

49954996
static int
@@ -5011,8 +5012,20 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
50115012
if (symbol & DEF_LOCAL && ~symbol & DEF_NONLOCAL) {
50125013
if (c->u->u_ste->ste_type != FunctionBlock) {
50135014
// non-function scope: override this name to use fast locals
5014-
if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_True) < 0) {
5015-
return ERROR;
5015+
PyObject *orig = PyDict_GetItem(c->u->u_metadata.u_fasthidden, k);
5016+
if (orig != Py_True) {
5017+
if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_True) < 0) {
5018+
return ERROR;
5019+
}
5020+
if (state->fast_hidden == NULL) {
5021+
state->fast_hidden = PySet_New(NULL);
5022+
if (state->fast_hidden == NULL) {
5023+
return ERROR;
5024+
}
5025+
}
5026+
if (PySet_Add(state->fast_hidden, k) < 0) {
5027+
return ERROR;
5028+
}
50165029
}
50175030
}
50185031
long scope = (symbol >> SCOPE_OFFSET) & SCOPE_MASK;
@@ -5092,6 +5105,7 @@ pop_inlined_comprehension_state(struct compiler *c, location loc,
50925105
return ERROR;
50935106
}
50945107
}
5108+
Py_CLEAR(state.temp_symbols);
50955109
}
50965110
if (state.pushed_locals) {
50975111
// pop names we pushed to stack earlier
@@ -5108,16 +5122,21 @@ pop_inlined_comprehension_state(struct compiler *c, location loc,
51085122
}
51095123
ADDOP_NAME(c, loc, STORE_FAST_MAYBE_NULL, k, varnames);
51105124
}
5125+
Py_CLEAR(state.pushed_locals);
51115126
}
5112-
pos = 0;
5113-
while (PyDict_Next(c->u->u_metadata.u_fasthidden, &pos, &k, &v)) {
5114-
if (v == Py_True) {
5127+
if (state.fast_hidden) {
5128+
while (PySet_Size(state.fast_hidden) > 0) {
5129+
PyObject *k = PySet_Pop(state.fast_hidden);
5130+
if (k == NULL) {
5131+
return ERROR;
5132+
}
51155133
// we set to False instead of clearing, so we can track which names
51165134
// were temporarily fast-locals and should use CO_FAST_HIDDEN
51175135
if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_False)) {
51185136
return ERROR;
51195137
}
51205138
}
5139+
Py_CLEAR(state.fast_hidden);
51215140
}
51225141
return SUCCESS;
51235142
}
@@ -5214,8 +5233,6 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
52145233
if (pop_inlined_comprehension_state(c, loc, inline_state)) {
52155234
goto error;
52165235
}
5217-
Py_XDECREF(inline_state.pushed_locals);
5218-
Py_XDECREF(inline_state.temp_symbols);
52195236
return SUCCESS;
52205237
}
52215238

@@ -5265,6 +5282,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type,
52655282
Py_XDECREF(entry);
52665283
Py_XDECREF(inline_state.pushed_locals);
52675284
Py_XDECREF(inline_state.temp_symbols);
5285+
Py_XDECREF(inline_state.fast_hidden);
52685286
return ERROR;
52695287
}
52705288

0 commit comments

Comments
 (0)