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:
Jeremy Hylton 2001-03-20 00:25:43 +00:00
parent e241e29f3d
commit ce7ef599d2
1 changed files with 12 additions and 3 deletions

View File

@ -3808,6 +3808,7 @@ dict_keys_inorder(PyObject *dict, int offset)
while (PyDict_Next(dict, &pos, &k, &v)) {
i = PyInt_AS_LONG(v);
Py_INCREF(k);
assert((i - offset) < size);
PyTuple_SET_ITEM(tuple, i - offset, k);
}
return tuple;
@ -4316,9 +4317,17 @@ symtable_load_symbols(struct compiling *c)
/* undo the original DEF_FREE */
flags &= ~(DEF_FREE | DEF_FREE_CLASS);
if ((flags & (DEF_FREE | DEF_FREE_CLASS))
&& (flags & (DEF_LOCAL | DEF_PARAM)))
/* Deal with names that need two actions:
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);
}
if (flags & DEF_STAR) {
c->c_argcount--;
@ -4478,7 +4487,7 @@ symtable_update_free_vars(struct symtable *st)
with bindings for N between B and A, then N
is global in B.
*/
if (v) {
if (v && (ste->ste_type != TYPE_CLASS)) {
int flags = PyInt_AS_LONG(v);
if (flags & DEF_GLOBAL) {
symtable_undo_free(st, child->ste_id,