summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-03-20 00:25:43 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-03-20 00:25:43 (GMT)
commitce7ef599d2df7c43f8228f22a77de4554039dc0f (patch)
tree448f981095e78aa66180a78910a2a9c1b9e13ce0 /Python
parente241e29f3d0c4a2e4c7beee018ae409beb4239de (diff)
downloadcpython-ce7ef599d2df7c43f8228f22a77de4554039dc0f.zip
cpython-ce7ef599d2df7c43f8228f22a77de4554039dc0f.tar.gz
cpython-ce7ef599d2df7c43f8228f22a77de4554039dc0f.tar.bz2
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
Diffstat (limited to 'Python')
-rw-r--r--Python/compile.c15
1 files 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,