[Python-Dev] nested scopes and global: some corner cases

Samuele Pedroni pedroni@inf.ethz.ch
Sun, 11 Mar 2001 17:17:38 +0100


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.