[Samuele Pedroni]
... I have tried them with python 2.1b1 and I wonder if the results are consistent with the proposed rule: a free variable is bound according to the nearest outer scope binding (assign-like or global decl), class scopes (for backw-comp) are ignored wrt this.
"exec" and "import*" always complicate everything, though.
(I) from __future__ import nested_scopes
x='top' def ta(): global x def tata(): exec "x=1" in locals() return x # LOAD_NAME return tata
print ta()() prints 1, I believed it should print 'top' and a LOAD_GLOBAL should have been produced.
I doubt this will change. In the presence of exec, the compiler has no idea what's local anymore, so it deliberately generates LOAD_NAME. When Guido says he intends to "deprecate" exec-without-in, he should also always say "and also deprecate exec in locals()/global() too". But he'll have to think about that and get back to you <wink>. Note that modifications to locals() already have undefined behavior (according to the Ref Man), so exec-in-locals() is undefined too if the exec'ed code tries to (re)bind any names.
In this case the global binding is somehow ignored. Note: putting a global decl in tata xor removing the exec make tata deliver 'top' as I expected (LOAD_GLOBALs are emitted). Is this a bug or I'm missing something?
It's an accident either way (IMO), so it's a bug either way too -- or a feature either way. It's basically senseless! What you're missing is the layers of hackery in support of exec even before 2.1; this "give up on static identification of locals entirely in the presence of exec" goes back many years.
(II) from __future__ import nested_scopes
x='top' def ta(): x='ta' class A: global x def tata(self): return x # LOAD_GLOBAL return A
print ta()().tata() # -> 'top'
should not the global decl in class scope be ignored and so x be bound to x in ta, resulting in 'ta' as output?
Yes, this one is clearly a bug. Good catch!