Gregory Piñero <[EMAIL PROTECTED]> wrote:

> 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
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to