[ python-Bugs-991196 ] An inconsistency with nested scopes

SourceForge.net noreply at sourceforge.net
Thu Jul 22 18:55:41 CEST 2004


Bugs item #991196, was opened at 2004-07-14 14:30
Message generated for change (Comment added) made by josiahcarlson
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=991196&group_id=5470

Category: Python Interpreter Core
Group: Python 2.3
Status: Open
Resolution: None
Priority: 5
Submitted By: Nick Jacobson (nickjacobson)
Assigned to: Nobody/Anonymous (nobody)
Summary: An inconsistency with nested scopes

Initial Comment:
There's an inconsistency with nested scopes.

>From the Python Ref. Manual:

"If [a local variable] definition occurs in a function block, 
the scope extends to any blocks contained within the 
defining one..."

i.e. So as long as code is not on the module level, 
scopes are extended.  Therefore this works:

def main():
	y = 3
	def execfunc():
		print y
	execfunc()

if __name__ == '__main__':
	main()

In addition, if code IS on the module level, its variables 
go in globals().  So this works too:

y = 3
def execfunc():
	print y
execfunc()

However, (here's the inconsistency) the following code 
fails, saying that y is undefined:

def main():
	s = """
y = 3
def execfunc():
	print y
execfunc()
"""
	d = {}
	e = {}
	exec s in d, e

if __name__ == '__main__':
	main()

In this case, the code in s is treated like it's on the 
module level, and the nested scope treatment of y 
doesn't occur.  BUT, unlike normal code on the module 
level, y doesn't go in globals().  I think globals() is 
locked or something?


Conclusion:

The latter piece of code should work; that is, y should 
be nested and therefore recognized by execfunc().


----------------------------------------------------------------------

Comment By: Josiah Carlson (josiahcarlson)
Date: 2004-07-22 09:55

Message:
Logged In: YES 
user_id=341410

>>> def f():
...     y = 5
...     print 'y' in globals(), 'y' in locals()
...     def i():
...         print 'y' in globals(), 'y' in locals()
...     i()
...
>>> f()
False True
False False
>>>
>>> def g():
...     gl = {};lo={}
...     exec '''y = 5
... print 'y' in globals(), 'y' in locals()
... def i():
...     print 'y' in globals(), 'y' in locals()
... i()
... ''' in gl, lo
...
>>> g()
False True
False False

That looks constant...but what if we print out 'y'?

>>> def s():
...     y = 5
...     print 'y' in globals(), 'y' in locals(), y
...     def i():
...         print 'y' in globals(), 'y' in locals(), y
...     i()
...
>>> s()
False True 5
False True 5
>>>
>>> def t():
...     gl = {};lo = {}
...     exec '''y = 5
... print 'y' in globals(), 'y' in locals(), y
... def i():
...     print 'y' in globals(), 'y' in locals(), y
... i()
... ''' in gl, lo
...
>>> t()
False True 5
False False
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 3, in t
  File "<string>", line 5, in ?
  File "<string>", line 4, in i
NameError: global name 'y' is not defined

Now why did 'y' stick itself into the locals() of i() in
s()?  Is this another bug?

What if we remove the namespaces gl and lo?

>>> def u():
...     exec '''y = 5
... print 'y' in globals(), 'y' in locals(), y
... def i():
...     print 'y' in globals(), 'y' in locals(), y
... i()
... '''
...
>>> u()
False True 5
False False
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 2, in u
  File "<string>", line 5, in ?
  File "<string>", line 4, in i
NameError: global name 'y' is not defined

Nope, still dies.  It does seem to be a bug in exec.  I'm
still curious why 'y' was placed into i()'s local namespace
in s().

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=991196&group_id=5470


More information about the Python-bugs-list mailing list