Mercurial > cpython-lru_cache-weakref
diff Python/compile.c @ 17078:7e181eba6b9b legacy-trunk
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
| author | Jeremy Hylton <jeremy@alum.mit.edu> |
|---|---|
| date | Tue, 20 Mar 2001 00:25:43 +0000 |
| parents | 85d74f040712 |
| children | a488a63cb867 |
line wrap: on
line diff
--- a/Python/compile.c Mon Mar 19 20:42:11 2001 +0000 +++ b/Python/compile.c Tue Mar 20 00:25:43 2001 +0000 @@ -3808,6 +3808,7 @@ 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 @@ /* 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 @@ 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,
