473,407 Members | 2,546 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

exec throws an exception...why?

This works fine:

x = 1
def execfunc():
print x
execfunc()

So why doesn't this?

s = \
"""
x = 1
def execfunc():
print x
execfunc()
"""

codeobj = compile(s, "<string>", "exec")
d = {}
e = {}
exec codeobj in d, e

Error message:
Traceback (most recent call last):
File "C:\Nick\proj\python1.py", line 17, in ?
exec codeobj in d, e
File "<string>", line 6, in ?
File "<string>", line 5, in execfunc
NameError: global name 'x' is not defined

I'm using ActiveState Python 2.3.2 on Windows XP Pro. Thanks!

P.S. It does work if I say
exec codeobj in d
but I don't understand why.
Jul 18 '05 #1
5 1850
On 5 Jun 2004 18:46:11 -0700, ni***********@yahoo.com (Nick Jacobson)
wrote:
This works fine:

x = 1
def execfunc():
print x
execfunc()

So why doesn't this?

s = \
"""
x = 1
def execfunc():
print x
execfunc()
"""

codeobj = compile(s, "<string>", "exec")
d = {}
e = {}
exec codeobj in d, e

Error message:
Traceback (most recent call last):
File "C:\Nick\proj\python1.py", line 17, in ?
exec codeobj in d, e
File "<string>", line 6, in ?
File "<string>", line 5, in execfunc
NameError: global name 'x' is not defined

I'm using ActiveState Python 2.3.2 on Windows XP Pro. Thanks!

P.S. It does work if I say
exec codeobj in d
but I don't understand why.
It works because the local and global namespaces are both 'd'. it
doesn't work in the first because it puts 'x' in the local and then
looks in global.

Now, why it puts 'x' in local, I don't know. If this was a quiz, I'd
put "Nested Scope" and pray.
<{{{*>

Jul 18 '05 #2
fishboy <fi*****@spamspamspam.com> wrote in message news:<34********************************@4ax.com>. ..
On 5 Jun 2004 18:46:11 -0700, ni***********@yahoo.com (Nick Jacobson)
wrote:
This works fine:

x = 1
def execfunc():
print x
execfunc()

So why doesn't this?

s = \
"""
x = 1
def execfunc():
print x
execfunc()
"""

codeobj = compile(s, "<string>", "exec")
d = {}
e = {}
exec codeobj in d, e

Error message:
Traceback (most recent call last):
File "C:\Nick\proj\python1.py", line 17, in ?
exec codeobj in d, e
File "<string>", line 6, in ?
File "<string>", line 5, in execfunc
NameError: global name 'x' is not defined

I'm using ActiveState Python 2.3.2 on Windows XP Pro. Thanks!

P.S. It does work if I say
exec codeobj in d
but I don't understand why.


It works because the local and global namespaces are both 'd'. it
doesn't work in the first because it puts 'x' in the local and then
looks in global.

Now, why it puts 'x' in local, I don't know. If this was a quiz, I'd
put "Nested Scope" and pray.
<{{{*>


I don't know either, that's why I asked ;)

And I don't see why assigning both the local and global namespaces to
the variable 'd' fixes it. But to answer that, the latter question
has to be addressed first.

--Nick
Jul 18 '05 #3
ni***********@yahoo.com (Nick Jacobson) wrote:
Now, why it puts 'x' in local, I don't know.


I don't know either, that's why I asked ;)


The name binding in assignment seems to proceed only for locals,
unless a variable is declared as global explicitly. That is, by
default, the supplied global dictionary is read-only, unless the
'global' statment is used explicitly for those variables that you want
to override. Think of this behavior as if the code defined in the s
string were executed inside another nameless function.

#--------------- try this first in console
s='''
x = 1
def f():
print 'globals', globals().keys()
print 'locals', locals().keys()
print x
print 'globals', globals().keys()
print 'locals', locals().keys()
f()
'''
d={}
e={}
a = compile(s, '<string>', 'exec')
exec a in d, e
#--------------- output
globals ['__builtins__']
locals ['x', 'f']
globals ['__builtins__']
locals []
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<string>", line 9, in ?
File "<string>", line 6, in f
NameError: global name 'x' is not defined

#--------------- now try this in console
s='''
global x
x = 1
def f():
print 'globals', globals().keys()
print 'locals', locals().keys()
print x
print 'globals', globals().keys()
print 'locals', locals().keys()
f()
'''
d={}
e={}
a = compile(s, '<string>', 'exec')
exec a in d, e
#--------------- output
globals ['__builtins__', 'x']
locals ['f']
globals ['__builtins__', 'x']
locals []

#--------------- also try this from fresh console
s='''
x = 1
def f():
print 'globals', globals().keys()
print 'locals', locals().keys()
print x
print 'globals', globals().keys()
print 'locals', locals().keys()
f()
'''
a = compile(s, '<string>', 'exec')
exec a
#--------------- output
globals ['a', 's', 'x', '__builtins__', '__name__', 'f', '__doc__']
locals ['a', 's', 'x', '__builtins__', '__name__', 'f', '__doc__']
globals ['a', 's', 'x', '__builtins__', '__name__', 'f', '__doc__']
locals []
1

-------------------------------------------
Therefore, when no dictionary is supplied, it works because it uses
the current globals() and locals() of the current scope, which in the
case of console or module level (i.e., zero indentation) are referring
to the same dictionary. The assignment 'x=1' was performed on the
locals() dictionary for writing. But inside the f() function, the
statement 'print x' pulls the value from the globals() dictionary.
This coincidence of two dictionaries only happens when you run the
code from the module level. If you put the above code inside a
function, it won't work.

#--------------- from a fresh console
def test():
s='''
x = 1
def f():
print 'globals', globals().keys()
print 'locals', locals().keys()
print x
print 'globals', globals().keys()
print 'locals', locals().keys()
f()
'''
a = compile(s, '<string>', 'exec')
exec a

test()
#--------------- output
globals ['__builtins__', '__name__', 'test', '__doc__']
locals ['a', 'x', 's', 'f']
globals ['__builtins__', '__name__', 'test', '__doc__']
locals []
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 14, in test
File "<string>", line 9, in ?
File "<string>", line 6, in f
NameError: global name 'x' is not defined

regards,

Hung Jung
Jul 18 '05 #4
Thank you very much for the detailed response. But there's still a
problem.
The name binding in assignment seems to proceed only for locals,
unless a variable is declared as global explicitly. That is, by
default, the supplied global dictionary is read-only, unless the
'global' statment is used explicitly for those variables that you want
to override.


Agreed. The global dictionary is not modified.

But here's the thing. From the Python Ref. Manual:

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

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

def main():
y = 3
def execfunc():
print y
execfunc()
if __name__ == '__main__':
main()

But, 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()

Why not? Because it doesn't realize it's in main()! It thinks it's
on the module level! (I guess the indentation is a clue.)

Now, if it WERE simply code on the module level, it would also work:

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

because as you explained, y goes in globals(). This is probably why
the scopes don't nest at this level: they normally don't need to.

Conclusion:

Is code from the exec statement on the module level or not? It
doesn't get its locals mapped to globals. But it also doesn't get its
local variables nested. So it gets neither benefit. IMO it should
get one or the other. i.e. the second piece of code should work.

--Nick
Jul 18 '05 #5
ni***********@yahoo.com (Nick Jacobson) wrote:

"If the [local variable] definition occurs in a function block, the
scope extends to any blocks contained within the defining one..."
Strictly speaking, the above statement still holds true. That is, from
a lawyer's point of view. :)
But, 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()
Very good example.
Conclusion:

Is code from the exec statement on the module level or not? It
doesn't get its locals mapped to globals. But it also doesn't get its
local variables nested. So it gets neither benefit. IMO it should
get one or the other. i.e. the second piece of code should work.


The exec statement is usually considered an slightly advanced topic.
And frankly I think people that use it at the module level would be
minority. So, having its behavior parallel to the case of nested-scope
would seem to make more sense, to me. Remember also that the "global"
statement can be used inside the code string, which is reminiscence
that we are inside a local scope, just like the case of function. So,
if you wish, the inconsistency could be considered as a bug in Python,
and it may even be good idea to submit a bug report. After all, nested
scope is considered a relative new feature, given Python's history
(over a decade.)

Or there may be some obscure way of tweaking things so to convince
Python that it is inside a function scope at the moment of "def
execfunc():"... Anyway, we are talking about voodoo magic here... :)

regards,

Hung Jung
Jul 18 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Hal Vaughan | last post by:
I've been using Runtime.exec() like this: Runtime rt = Runtime.getRuntime(); try {Process p = rt.exec("MyCommand.bat");} catch (Exception e) {do stuff} When I start my Java classes, I start...
1
by: Chad | last post by:
I need my java program to exec an external .exe file, but the problem is that this program being exec()'ed prompts the user for two pieces of information. I am trying to get my java program to...
0
by: Jon Wayne | last post by:
Hi I'm using tomcat 4.0 on a solaris platform, and using the internal API CGIServlet.java to handle the CGI's. The servlet spawns off a Process and writes on it's output stream...
5
by: Toby Donaldson | last post by:
Hi all, I'm designing an educational application that will run Python code and check the output against a pre-define answer. I want to use the "exec" statement to run the code, but I don't know...
0
by: John Allison | last post by:
Hi everybody I'm very new to python so please forgive any idiotic mistakes: I'm writing a MUD-like text game in python and I want to support dynamic ingame scripting to deal with user commands. I...
2
by: Daniel | last post by:
if System.IO.StreamWriter write throws an exception, is there anyway to close the System.IO.StreamWriter object? it seems to stay open when this happens then future attempts to write to that same...
17
by: comp.lang.tcl | last post by:
The TCL command I am using will do a command-line action on a PHP script: set cannotRunPHP I have to do it this way as both the TCL script and the PHP script run as CLI. However, "info.php"...
4
by: Michael | last post by:
Hi, I'm having difficulty finding any previous discussion on this -- I keep finding people either having problems calling os.exec(lepev), or with using python's exec statement. Neither of...
7
by: gregory.lielens | last post by:
Hi, I am using a small python file as an input file (defining constants, parameters, input data, ...) for a python application. The input file is simply read by an exec statement in a specific...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.