classification
Title: execfile() fails on files that use global variables inside functions
Type: Stage:
Components: Documentation, Library (Lib) Versions: Python 3.3, Python 3.2, Python 2.7
process
Status: closed Resolution: duplicate
Dependencies: Superseder: exec of list comprehension fails on NameError
View: 13557
Assigned To: docs@python Nosy List: docs@python, techtonik, terry.reedy
Priority: normal Keywords:

Created on 2012-02-18 12:59 by techtonik, last changed 2012-02-25 00:15 by terry.reedy. This issue is now closed.

Messages (2)
msg153643 - (view) Author: anatoly techtonik (techtonik) Date: 2012-02-18 12:59
main.py below fails to execute local.py, which work ok (outputs '2') when processed directly in console.

Docs are not explaining anything. They spread fear and uncertainty around locals, but nothing is said why globals may fail.
http://docs.python.org/library/functions.html#execfile


---[cut main.py]---
values = {}
glavues = {}
execfile('local.py', glavues, values)
---[/cut]-----------

---[cut local.py]---
x = 1
def weird():
    y = x + 1
    return y
print weird()
---[/cut]-----------



Traceback (most recent call last):
  File "main.py", line 5, in <module>
    execfile('local.py', glavues, values)
  File "local.py", line 7, in <module>
    print weird()
  File "local.py", line 5, in weird
    y = x + 1
NameError: global name 'x' is not defined
msg154173 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2012-02-25 00:15
Searching on 'exec NameError' shows that this issue is a duplicate of (behavior issue) #1167300 which contained an essentially identical example"

>>> exec """\
... x = 3
... def f():
...     print x
... f()
... """ in {}, {}

#1167300 was closed as a duplicate of (behavior issue) #991196, which in turn was closed as 'won't fix' (ie, works as it must). Doc issue #4831, which resulted in some doc changes, seems related to this but is not the same. I believe this issue is a duplicate of #13557, which has a patch. I will add my proposed change there.

Anyway, my comments:

In 3.2.2, this runs

#prog='''\
x = 1
def weird():
    y = x + 1
    return y
print(weird())
#'''
#exec(prog)

The same uncommented does also, as does adding ',{}' to the call.
Adding ',{},{}' gives the NameError.
With one named {} arg passed twice, as follows, it runs.

d = {}
exec(prog, d, d)

The reasons for these results are:
1. assignments are *always* to the local namespace.
2. normally, for module code, the local and global namespaces are the same.
3. in the example, 'x=1' is the same as "values['x']=1", while within the function, 'y=x+1' looks up x in gvalues.

This is the same explanation as given in #1167300.
History
Date User Action Args
2012-02-25 00:15:24terry.reedysetstatus: open -> closed

superseder: exec of list comprehension fails on NameError
versions: + Python 3.2, Python 3.3
nosy: + terry.reedy

messages: + msg154173
resolution: duplicate
2012-02-18 12:59:58techtonikcreate