mirror of https://github.com/python/cpython.git
Fixup handling of free variables in methods when the class scope also
has a binding for the name. The fix is in two places: - in symtable_update_free_vars, ignore a global stmt in a class scope - in symtable_load_symbols, add extra handling for names that are defined at class scope and free in a method Closes SF bug 407800
This commit is contained in:
parent
e241e29f3d
commit
ce7ef599d2
|
@ -3808,6 +3808,7 @@ dict_keys_inorder(PyObject *dict, int offset)
|
||||||
while (PyDict_Next(dict, &pos, &k, &v)) {
|
while (PyDict_Next(dict, &pos, &k, &v)) {
|
||||||
i = PyInt_AS_LONG(v);
|
i = PyInt_AS_LONG(v);
|
||||||
Py_INCREF(k);
|
Py_INCREF(k);
|
||||||
|
assert((i - offset) < size);
|
||||||
PyTuple_SET_ITEM(tuple, i - offset, k);
|
PyTuple_SET_ITEM(tuple, i - offset, k);
|
||||||
}
|
}
|
||||||
return tuple;
|
return tuple;
|
||||||
|
@ -4316,9 +4317,17 @@ symtable_load_symbols(struct compiling *c)
|
||||||
/* undo the original DEF_FREE */
|
/* undo the original DEF_FREE */
|
||||||
flags &= ~(DEF_FREE | DEF_FREE_CLASS);
|
flags &= ~(DEF_FREE | DEF_FREE_CLASS);
|
||||||
|
|
||||||
if ((flags & (DEF_FREE | DEF_FREE_CLASS))
|
/* Deal with names that need two actions:
|
||||||
&& (flags & (DEF_LOCAL | DEF_PARAM)))
|
1. Cell variables, which are also locals.
|
||||||
|
2. Free variables in methods that are also class
|
||||||
|
variables or declared global.
|
||||||
|
*/
|
||||||
|
if (flags & (DEF_FREE | DEF_FREE_CLASS)) {
|
||||||
|
if ((ste->ste_type == TYPE_CLASS
|
||||||
|
&& flags != DEF_FREE_CLASS)
|
||||||
|
|| (flags & (DEF_LOCAL | DEF_PARAM)))
|
||||||
symtable_resolve_free(c, name, &si);
|
symtable_resolve_free(c, name, &si);
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & DEF_STAR) {
|
if (flags & DEF_STAR) {
|
||||||
c->c_argcount--;
|
c->c_argcount--;
|
||||||
|
@ -4478,7 +4487,7 @@ symtable_update_free_vars(struct symtable *st)
|
||||||
with bindings for N between B and A, then N
|
with bindings for N between B and A, then N
|
||||||
is global in B.
|
is global in B.
|
||||||
*/
|
*/
|
||||||
if (v) {
|
if (v && (ste->ste_type != TYPE_CLASS)) {
|
||||||
int flags = PyInt_AS_LONG(v);
|
int flags = PyInt_AS_LONG(v);
|
||||||
if (flags & DEF_GLOBAL) {
|
if (flags & DEF_GLOBAL) {
|
||||||
symtable_undo_free(st, child->ste_id,
|
symtable_undo_free(st, child->ste_id,
|
||||||
|
|
Loading…
Reference in New Issue