This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author hawkett
Recipients ajaksu2, arigo, georg.brandl, hawkett, jhylton, josiahcarlson, nickjacobson
Date 2010-05-26.07:52:52
SpamBayes Score 2.0751159e-08
Marked as misclassified No
Message-id <1274860375.56.0.439369632991.issue991196@psf.upfronthosting.co.za>
In-reply-to
Content
#8819 was closed as duplicate. That issue linked a description of the problem on stack overflow http://stackoverflow.com/questions/2904274/globals-and-locals-in-python-exec. I would like to argue that this is a bug, and should be fixed in 2.6+. The definition of bug here is that python does not behave as documented - that variable name resolution does *not* check the locals() of the enclosing scope. The fact that the code mistakenly assumes locals and globals would be the same thing in this situation does not mean it is not a bug.

The statement in the previous comment - 'if you want exec to mimc the top level environment, you need to pass it a single dictionary' is true, but it hides that fact that this is the *only* thing you can do - if you *don't* want exec to mimic the top level environment, what's the approach? Doing anything else just creates a unique, undocumented, oddly behaving scope that doesn't apply closures correctly.

What are the use cases for passing in locals? Doing so means your code behaves abnormally, unless you think carefully about how you write it, and that's not good - 'Write python code like this, except for this situation where it doesn't work, and you have to write your python like this, avoiding certain closure scenarios that would otherwise work.' What's the exec() API with locals for?

If you don't pass in locals, or make globals and locals the same dictionary, then its an absolute pain to retrieve the definitions created in the exec'd code - they're mixed in with all the globals python adds, and if you don't know in advance what is being defined in the code block, it's close to impossible. To me, this is the primary use case for locals being passed in, and was surely the intention when the API was constructed.  This bug prevents this use case.

I'm guessing that somewhere in the python source there is some code that  goes (pseudo)

if scope == module: check_globals()
else:
  check_locals()
  check_globals()

and that this is done for performance reasons, but surely the check could be different without giving up much, and fix the problem?

if locals() is globals(): check_globals()
else:
  check_locals()
  check_globals()
History
Date User Action Args
2010-05-26 07:52:55hawkettsetrecipients: + hawkett, jhylton, arigo, georg.brandl, josiahcarlson, nickjacobson, ajaksu2
2010-05-26 07:52:55hawkettsetmessageid: <1274860375.56.0.439369632991.issue991196@psf.upfronthosting.co.za>
2010-05-26 07:52:54hawkettlinkissue991196 messages
2010-05-26 07:52:52hawkettcreate