Exec woes

Stephen Hansen apt.shansen at gmail.com
Tue Jan 27 12:45:48 EST 2009


> IDLE 1.1.3      ==== No Subprocess ====
> >>> help(exec)
> SyntaxError: invalid syntax
> >>>
> Its the same under Linux SuSe, Python 2.5.1.
>
> I think this is a BUG.
>

Exec is a statement, not a function nor an object: even though you can
enclose parens around its arguments like you do later on, they don't have
any syntax meaning.

You can't help(print) or help(import) either.


> Anyway, my real problem looks like this:
>
> >>> def Somefunc():
>            def excrescence():
>                 exec('BUILD = "someString"')
>                 return BUILD
>
> SyntaxError: unqualified exec is not allowed in function 'excrescence
> it is a nested function (<pyshell#11>, line 3)
> >>>
>
> Now this works if it is not nested, and it works if it is a method in a
> class.
> Why the complaint about the nestedness?
>

Once upon a time, Python had only two scopes or namespaces: local and
globals. It'd look up variables in the local scope and if it didn't find
them, it'd look them up in the global scope. (There's also the builtin
namespace but to not digress...)

Under this scenario, if you define some attributes in Somefunc() those will
NOT be visible within excrescence(). So:

    def foo():
        a = 5
        def bar():
            print a # error

wouldn't work.

Then PEP227 came around to add nested scopes -- or lexical scopes. Its what
made "nested" functions like that actually useful: it's what brought
closures into the scenario. As of Python 2.2, within bar() it would be able
to see the definition of a because namespaces can now be nested.

This addition was a problem for a couple features: doing "from blah import
*" within a function, and a bare exec (an exec without an explicit globals()
and locals()) that happened in certain places-- in this case a nested
function. They introduced that SyntaxError to make sure it wouldn't
accidentally hit you. Read up on PEP227 for the full details.

To get around this, you need to specify exactly what scope you want exec to
happen in when you're in a place where the 'current' scope is nested. You
qualify exec--


>
> So there is some namespace thing happening that is too subtle for me, and I
> would like to know what "unqualified" means in the above message, and
> what one must do to "qualify" the statement, if that is what is needed.
>

by doing:

   exec code in <global dictionary>, <local dictionary>

In your situation:

    >>> def Somefunc():
               def excrescence():
                   exec "BUILD = 'someString'" in globals(), locals()

is probably sufficient. globals() returns the dictionary of the global
namespace, locals() the dictionary of the current functions (non-nested)
namespace.

HTH,

--Stephen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20090127/4cd79991/attachment.html>


More information about the Python-list mailing list