diff options
-rw-r--r-- | Lib/test/output/test_scope | 1 | ||||
-rw-r--r-- | Lib/test/test_scope.py | 11 | ||||
-rw-r--r-- | Python/compile.c | 26 |
3 files changed, 32 insertions, 6 deletions
diff --git a/Lib/test/output/test_scope b/Lib/test/output/test_scope index af7fe31..fcd4e7a 100644 --- a/Lib/test/output/test_scope +++ b/Lib/test/output/test_scope @@ -17,3 +17,4 @@ test_scope 16. check leaks 17. class and global 18. verify that locals() works +19. var is bound and free in class diff --git a/Lib/test/test_scope.py b/Lib/test/test_scope.py index 358c45a..c42d881 100644 --- a/Lib/test/test_scope.py +++ b/Lib/test/test_scope.py @@ -436,3 +436,14 @@ verify(d.has_key('h')) del d['h'] verify(d == {'x': 2, 'y': 7, 'w': 6}) +print "19. var is bound and free in class" + +def f(x): + class C: + def m(self): + return x + a = x + return C + +inst = f(3)() +verify(inst.a == inst.m()) diff --git a/Python/compile.c b/Python/compile.c index cb85ce3..1f1d44c 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -4057,7 +4057,7 @@ symtable_init_info(struct symbol_info *si) } static int -symtable_resolve_free(struct compiling *c, PyObject *name, +symtable_resolve_free(struct compiling *c, PyObject *name, int flags, struct symbol_info *si) { PyObject *dict, *v; @@ -4067,11 +4067,19 @@ symtable_resolve_free(struct compiling *c, PyObject *name, cell var). If it occurs in a class, then the class has a method and a free variable with the same name. */ - if (c->c_symtable->st_cur->ste_type == TYPE_FUNCTION) { + /* If it isn't declared locally, it can't be a cell. */ + if (!(flags & (DEF_LOCAL | DEF_PARAM))) + return 0; v = PyInt_FromLong(si->si_ncells++); dict = c->c_cellvars; } else { + /* If it is free anyway, then there is no need to do + anything here. + */ + if (is_free(flags ^ DEF_FREE_CLASS) + || flags == DEF_FREE_CLASS) + return 0; v = PyInt_FromLong(si->si_nfrees++); dict = c->c_freevars; } @@ -4357,10 +4365,7 @@ symtable_load_symbols(struct compiling *c) 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); + symtable_resolve_free(c, name, flags, &si); } if (flags & DEF_STAR) { @@ -4420,6 +4425,15 @@ symtable_load_symbols(struct compiling *c) } } + /* + fprintf(stderr, + "cells %d: %s\n" + "frees %d: %s\n", + si.si_ncells, PyObject_REPR(c->c_cellvars), + si.si_nfrees, PyObject_REPR(c->c_freevars)); + */ + assert(PyDict_Size(c->c_freevars) == si.si_nfrees); + if (si.si_ncells > 1) { /* one cell is always in order */ if (symtable_cellvar_offsets(&c->c_cellvars, c->c_argcount, c->c_varnames, c->c_flags) < 0) |