Kaydet (Commit) ce7ef599 authored tarafından Jeremy Hylton's avatar Jeremy Hylton

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
üst e241e29f
...@@ -3808,6 +3808,7 @@ dict_keys_inorder(PyObject *dict, int offset) ...@@ -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) ...@@ -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) ...@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment