Hi. [Tim Peters on from __future__ import nested_scopes x='top' def ta(): global x def tata(): exec "x=1" in locals() return x # LOAD_NAME vs LOAD_GLOBAL? return tata print ta()() # 1 vs. 'top' ? ] -- snip --
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. (Just a joke) I'm not such a "newbie" that the guess I'm missing something is right with probability > .5. At least I hope so. The same hackery is there in jython codebase and I have taken much care in preserving it <wink>.
The point is simply that 'exec in locals()' is like a bare exec but it has been decided to allow 'exec in' even in presence of nested scopes and we cannot detect the 'locals()' special case (at compile time) because in python 'locals' is the builtin only with high probability. So we face the problem, how to *implement* an undefined behaviour, (the ref says that changing locals is undef,: everybody knows) that historically has never been to seg fault, in the new (nested scopes) context? It also true that what we are doing is "impossible", that's why it has been decided to raise a SyntaxError in the bare exec case <wink>. To be honest, I have just implemented things in jython my/some way, and then discovered that jython CVS version and python 21.b1 (here) behave differently. A posteriori I just tried to solve/explain things using the old problem pattern: I give you a (number) sequence, guess the next term: the sequence is: (over this jython and python agree) from __future__ import nested_scopes def a(): exec "x=1" in locals() return x # LOAD_NAME (jython does the equivalent) def b(): global x exec "x=1" in locals() return x # LOAD_GLOBAL def c(): global x def cc(): return x # LOAD_GLOBAL return cc def d(): x='d' def dd(): exec "x=1" in locals() # without 'in locals()' => SynError return x # LOAD_DEREF (x in d) return dd and then the term to guess: def z(): global x def zz(): exec "x=1" in locals() # without 'in locals()' => SynError return x # ???? python guesses LOAD_NAME, jython the equiv of LOAD_GLOBAL return zz Should python and jython agree here too? Anybody wants to spend some time convincing me that I should change jython meaning of undefined? I will not spend more time to do the converse <wink>. regards, Samuele Pedroni. PS: It is also possible that trying to solve pdb+nested scopes problem we will have to consider the grab the locals problem with more care.