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,