From ce7ef599d2df7c43f8228f22a77de4554039dc0f Mon Sep 17 00:00:00 2001 From: Jeremy Hylton Date: Tue, 20 Mar 2001 00:25:43 +0000 Subject: 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 --- Python/compile.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Python/compile.c b/Python/compile.c index cec8669..07729b1 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -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, -- cgit v0.12