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 steven.daprano
Recipients qpeter, steven.daprano
Date 2021-12-22.17:29:31
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1640194171.98.0.908164130549.issue46153@roundup.psfhosted.org>
In-reply-to
Content
> I now want to define a closure with exec. I might want to do something like:
> exec("def f(): return a", globals(), locals())

That doesn't create a closure.


> I would expect f() to look for a in the locals().

I'm sorry, but your expectation that f() will look for a in the locals dict is not correct. That's not how name resolution in Python works. a is looked up as a global. You can't turn it into a local variable just by providing locals.

The names of the parameters are unfortunately confusing. The globals parameter is always the global namespace. But locals is *never* the function's local namespace. Nor is it a surrounding scope (nested functions), but it may be treated as a surrounding *class* scope.

I agree that the behaviour is surprising and complex, but if you work through the documentation carefully, it is behaving as designed.

What we need to realise is that locals describes the namespace where the *def statement* runs, not the namespace used by the body of the function. The function body's locals is always created when the function is called, it is inaccessible from outside the function, and it most certainly does not use the so-called "locals" parameter given to exec().
History
Date User Action Args
2021-12-22 17:29:32steven.dapranosetrecipients: + steven.daprano, qpeter
2021-12-22 17:29:31steven.dapranosetmessageid: <1640194171.98.0.908164130549.issue46153@roundup.psfhosted.org>
2021-12-22 17:29:31steven.dapranolinkissue46153 messages
2021-12-22 17:29:31steven.dapranocreate