mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									e241e29f3d
								
							
						
					
					
						commit
						ce7ef599d2
					
				
					 1 changed files with 12 additions and 3 deletions
				
			
		|  | @ -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, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeremy Hylton
						Jeremy Hylton