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

Skip to content

Commit 24ea8d3

Browse files
committed
Fix SF bug #505315: Make free and cell vars show up consistently in locals().
PyFrame_FastToLocals() and PyFrame_LocalsToFast() had a return if f_nlocals was 0. I think this was a holdover from the pre 2.1 days when regular locals were the only kind of local variables. The change makes it possible to use a free variable in eval or exec if it the variable is also used elsewhere in the same block, which is what the documentation says.
1 parent d9a1050 commit 24ea8d3

1 file changed

Lines changed: 7 additions & 6 deletions

File tree

Objects/frameobject.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,6 @@ PyFrame_FastToLocals(PyFrameObject *f)
416416
return;
417417
}
418418
}
419-
if (f->f_nlocals == 0)
420-
return;
421419
map = f->f_code->co_varnames;
422420
if (!PyDict_Check(locals) || !PyTuple_Check(map))
423421
return;
@@ -426,7 +424,8 @@ PyFrame_FastToLocals(PyFrameObject *f)
426424
j = PyTuple_Size(map);
427425
if (j > f->f_nlocals)
428426
j = f->f_nlocals;
429-
map_to_dict(map, j, locals, fast, 0);
427+
if (f->f_nlocals)
428+
map_to_dict(map, j, locals, fast, 0);
430429
if (f->f_ncells || f->f_nfreevars) {
431430
if (!(PyTuple_Check(f->f_code->co_cellvars)
432431
&& PyTuple_Check(f->f_code->co_freevars))) {
@@ -455,7 +454,7 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
455454
return;
456455
locals = f->f_locals;
457456
map = f->f_code->co_varnames;
458-
if (locals == NULL || f->f_code->co_nlocals == 0)
457+
if (locals == NULL)
459458
return;
460459
if (!PyDict_Check(locals) || !PyTuple_Check(map))
461460
return;
@@ -464,7 +463,8 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
464463
j = PyTuple_Size(map);
465464
if (j > f->f_nlocals)
466465
j = f->f_nlocals;
467-
dict_to_map(f->f_code->co_varnames, j, locals, fast, 0, clear);
466+
if (f->f_nlocals)
467+
dict_to_map(f->f_code->co_varnames, j, locals, fast, 0, clear);
468468
if (f->f_ncells || f->f_nfreevars) {
469469
if (!(PyTuple_Check(f->f_code->co_cellvars)
470470
&& PyTuple_Check(f->f_code->co_freevars)))
@@ -474,7 +474,8 @@ PyFrame_LocalsToFast(PyFrameObject *f, int clear)
474474
locals, fast + f->f_nlocals, 1, clear);
475475
dict_to_map(f->f_code->co_freevars,
476476
PyTuple_GET_SIZE(f->f_code->co_freevars),
477-
locals, fast + f->f_nlocals + f->f_ncells, 1, clear);
477+
locals, fast + f->f_nlocals + f->f_ncells, 1,
478+
clear);
478479
}
479480
PyErr_Restore(error_type, error_value, error_traceback);
480481
}

0 commit comments

Comments
 (0)