Gregory Piñero <gr********@gmail.comwrote:
I'm curious why this code isn't working how I expect it to:
import sys
d=3
def func1(a,b,c):
print a,b,c,d
print sys.path
exec "func1(1,2,3)" in {'func1':func1}
----
returns:
1 2 3 3
[ sys.path stuff ....]
Since I'm telling exec to operate only within the context of the
dictionary I give it, why does it still see sys.path and d? I figured
it would throw a NameError.
Is there a way to call exec such that it won't have access to any more
objects than I explicitly give it?
func1 accesses its globals through func1.func_globals (which you can't
reassign -- it's a read-only attribute).
You may make a new function object w/ a different globals dict...:
>>g = type(func1)(func1.func_code, {})
and that will fail (even when called directly, but similarly if exec'd)
as it's missing key 'd' in its globals:
>>g(1, 2, 3)
1 2 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in func1
NameError: global name 'd' is not defined
The globals dict you pass to exec is the globals at the time of CALL,
not the globals seen from INSIDE func1; that's always going to be the
func_globals attribute of the function object, so you need to control
that (by suitably building a new function object as you require).
Alex