Skip to content

Commit

Permalink
fix the test
Browse files Browse the repository at this point in the history
  • Loading branch information
carljm committed Sep 27, 2024
1 parent 84f2c62 commit 0b3d0c9
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
1 change: 0 additions & 1 deletion Lib/test/test_listcomps.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ def get_output(moddict, name):
def _f():
{code}
return locals()
import dis; dis.dis(_f) # TODO
_out = _f()
""").format(code=textwrap.indent(code, " "))
def get_output(moddict, name):
Expand Down
40 changes: 34 additions & 6 deletions Python/symtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ is_free_in_any_child(PySTEntryObject *entry, PyObject *key)
static int
inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
PyObject *scopes, PyObject *comp_free,
PyObject *inlined_cells)
PyObject *inlined_cells, PyObject *inlined_locals)
{
PyObject *k, *v;
Py_ssize_t pos = 0;
Expand Down Expand Up @@ -843,6 +843,11 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
return 0;
}
SET_SCOPE(scopes, k, scope);
if (scope == LOCAL) {
if (PySet_Add(inlined_locals, k) < 0) {
return 0;
}
}
}
else {
long flags = PyLong_AsLong(existing);
Expand Down Expand Up @@ -882,15 +887,20 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
*/

static int
analyze_cells(PyObject *scopes, PyObject *free, PyObject *inlined_cells)
analyze_cells(PyObject *scopes, PyObject *free, PyObject *inlined_cells, PyObject *inlined_locals)
{
PyObject *name, *v, *v_cell;
PyObject *name, *v, *v_cell, *v_free;
int success = 0;
Py_ssize_t pos = 0;

v_cell = PyLong_FromLong(CELL);
if (!v_cell)
return 0;
v_free = PyLong_FromLong(FREE);
if (!v_free) {
Py_DECREF(v_cell);
return 0;
}
while (PyDict_Next(scopes, &pos, &name, &v)) {
long scope = PyLong_AsLong(v);
if (scope == -1 && PyErr_Occurred()) {
Expand All @@ -911,6 +921,19 @@ analyze_cells(PyObject *scopes, PyObject *free, PyObject *inlined_cells)
continue;
}
}
/* If the name is defined by an inlined comprehension, it must be
* preserved as free in the outer scope. */
contains = PySet_Contains(inlined_locals, name);
if (contains < 0) {
goto error;
}
if (contains) {
if (PyDict_SetItem(scopes, name, v_free) < 0) {
goto error;
}
continue;
}

/* Replace LOCAL with CELL for this name, and remove
from free. It is safe to replace the value of name
in the dict, because it will not cause a resize.
Expand All @@ -923,6 +946,7 @@ analyze_cells(PyObject *scopes, PyObject *free, PyObject *inlined_cells)
success = 1;
error:
Py_DECREF(v_cell);
Py_DECREF(v_free);
return success;
}

Expand Down Expand Up @@ -1099,7 +1123,8 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
PySTEntryObject *class_entry)
{
PyObject *name, *v, *local = NULL, *scopes = NULL, *newbound = NULL;
PyObject *newglobal = NULL, *newfree = NULL, *inlined_cells = NULL;
PyObject *newglobal = NULL, *newfree = NULL;
PyObject *inlined_cells = NULL, *inlined_locals = NULL;
PyObject *temp;
int success = 0;
Py_ssize_t i, pos = 0;
Expand Down Expand Up @@ -1134,6 +1159,9 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
inlined_cells = PySet_New(NULL);
if (!inlined_cells)
goto error;
inlined_locals = PySet_New(NULL);
if (!inlined_locals)
goto error;

/* Class namespace has no effect on names visible in
nested functions, so populate the global and bound
Expand Down Expand Up @@ -1231,7 +1259,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
goto error;
}
if (inline_comp) {
if (!inline_comprehension(ste, entry, scopes, child_free, inlined_cells)) {
if (!inline_comprehension(ste, entry, scopes, child_free, inlined_cells, inlined_locals)) {
Py_DECREF(child_free);
goto error;
}
Expand Down Expand Up @@ -1259,7 +1287,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
}

/* Check if any local variables must be converted to cell variables */
if (_PyST_IsFunctionLike(ste) && !analyze_cells(scopes, newfree, inlined_cells))
if (_PyST_IsFunctionLike(ste) && !analyze_cells(scopes, newfree, inlined_cells, inlined_locals))
goto error;
else if (ste->ste_type == ClassBlock && !drop_class_free(ste, newfree))
goto error;
Expand Down

0 comments on commit 0b3d0c9

Please sign in to comment.