[Python-checkins] CVS: python/dist/src/Python compile.c,2.183,2.184
Jeremy Hylton
jhylton@users.sourceforge.net
Wed, 28 Feb 2001 22:09:36 -0800
Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv26299/Python
Modified Files:
compile.c
Log Message:
Fix core dump in example from Samuele Pedroni:
from __future__ import nested_scopes
x=7
def f():
x=1
def g():
global x
def i():
def h():
return x
return h()
return i()
return g()
print f()
print x
This kind of code didn't work correctly because x was treated as free
in i, leading to an attempt to load x in g to make a closure for i.
Solution is to make global decl apply to nested scopes unless their is
an assignment. Thus, x in h is global.
Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.183
retrieving revision 2.184
diff -C2 -r2.183 -r2.184
*** compile.c 2001/03/01 00:42:55 2.183
--- compile.c 2001/03/01 06:09:34 2.184
***************
*** 180,183 ****
--- 180,185 ----
}
+ /* XXX code objects need to participate in GC? */
+
PyTypeObject PyCode_Type = {
PyObject_HEAD_INIT(&PyType_Type)
***************
*** 2133,2138 ****
arg = com_lookup_arg(c->c_freevars, name);
if (arg == -1) {
! fprintf(stderr, "lookup %s in %s %d %d\n",
! PyObject_REPR(name), c->c_name, reftype, arg);
Py_FatalError("com_make_closure()");
}
--- 2135,2145 ----
arg = com_lookup_arg(c->c_freevars, name);
if (arg == -1) {
! fprintf(stderr, "lookup %s in %s %d %d\n"
! "freevars of %s: %s\n",
! PyObject_REPR(name),
! c->c_name,
! reftype, arg,
! PyString_AS_STRING(co->co_name),
! PyObject_REPR(co->co_freevars));
Py_FatalError("com_make_closure()");
}
***************
*** 4425,4430 ****
PyList_GET_ITEM(ste->ste_children, i);
while (PyDict_Next(child->ste_symbols, &pos, &name, &o)) {
! int v = PyInt_AS_LONG(o);
! if (!(is_free(v)))
continue; /* avoids indentation */
if (list == NULL) {
--- 4432,4437 ----
PyList_GET_ITEM(ste->ste_children, i);
while (PyDict_Next(child->ste_symbols, &pos, &name, &o)) {
! int flags = PyInt_AS_LONG(o);
! if (!(is_free(flags)))
continue; /* avoids indentation */
if (list == NULL) {
***************
*** 4439,4454 ****
}
}
- /*
- if (st->st_nested_scopes == 0
- && list && PyList_GET_SIZE(list) > 0) {
- fprintf(stderr, "function %s has children with "
- "the following free vars:\n%s\n",
- PyString_AS_STRING(ste->ste_name),
- PyObject_REPR(list));
- continue;
- }
- */
for (j = 0; list && j < PyList_GET_SIZE(list); j++) {
name = PyList_GET_ITEM(list, j);
if (ste->ste_nested) {
if (symtable_add_def_o(st, ste->ste_symbols,
--- 4446,4467 ----
}
}
for (j = 0; list && j < PyList_GET_SIZE(list); j++) {
+ PyObject *v;
name = PyList_GET_ITEM(list, j);
+ v = PyDict_GetItem(ste->ste_symbols, name);
+ /* If a name N is declared global in scope A and
+ referenced in scope B contained (perhaps
+ indirectly) in A and there are no scopes
+ with bindings for N between B and A, then N
+ is global in B.
+ */
+ if (v) {
+ int flags = PyInt_AS_LONG(v);
+ if (flags & DEF_GLOBAL) {
+ symtable_undo_free(st, child->ste_id,
+ name);
+ continue;
+ }
+ }
if (ste->ste_nested) {
if (symtable_add_def_o(st, ste->ste_symbols,
***************
*** 4482,4486 ****
int v;
PySymtableEntryObject *ste = st->st_cur;
!
if (ste->ste_type == TYPE_CLASS)
return symtable_undo_free(st, child, name);
--- 4495,4499 ----
int v;
PySymtableEntryObject *ste = st->st_cur;
!
if (ste->ste_type == TYPE_CLASS)
return symtable_undo_free(st, child, name);
***************
*** 4489,4492 ****
--- 4502,4506 ----
return symtable_undo_free(st, child, name);
v = PyInt_AS_LONG(o);
+
if (is_free(v) || (v & DEF_GLOBAL))
return symtable_undo_free(st, child, name);
***************
*** 4507,4510 ****
--- 4521,4525 ----
if (ste == NULL)
return -1;
+
info = PyDict_GetItem(ste->ste_symbols, name);
if (info == NULL)
***************
*** 4939,4942 ****
--- 4954,4958 ----
if (st->st_nscopes == 1) {
+ /* XXX must check that we are compiling file_input */
if (symtable_warn(st,
"global statement has no meaning at module level") < 0)