exec() can run either a string or a code object. Usually the code object run in exec() is produced directly using compile(). But it's completely fine to pull the code object out of a function object and execute it with exec(). This can be useful if you want to run the code object in some exotic environment, e.g. with a modified globals.
Some code objects refer to free variables, and can only run when a closure is set. Currently, exec() simply rejects these code objects--you aren't permitted to use them with exec(), it throws an exception if you try.
It's possible to work around this limitation. Instead of using exec(), one could simply bind a new function using the code object and whatever closure or globals you wanted. But this seems like an unnecessary limitation on the functionality of exec().
I propose to add a closure keyword-only argument to eval(). It can only be specified if the code object uses free variables. When specified, it must be a tuple, with exactly the number of cell variables referenced by the code object. closure has a default value of None, and it must be None if the code object doesn't refer to any free variables.
We do have a use case for this, in conjunction with PEP 649. Carl Meyer proposes to pull the code object out of a co_annotations function, and run it with a globals object that enables us to handle undefined (forward-defined) names.
The text was updated successfully, but these errors were encountered:
Add a closure keyword-only parameter to exec(). It can only be specified when exec-ing a code object that uses free variables. When specified, it must be a tuple, with exactly the number of cell variables referenced by the code object. closure has a default value of None, and it must be None if the code object doesn't refer to any free variables.
Feature or enhancement
exec()
can run either a string or a code object. Usually the code object run inexec()
is produced directly usingcompile()
. But it's completely fine to pull the code object out of a function object and execute it withexec()
. This can be useful if you want to run the code object in some exotic environment, e.g. with a modifiedglobals
.Some code objects refer to free variables, and can only run when a closure is set. Currently,
exec()
simply rejects these code objects--you aren't permitted to use them withexec()
, it throws an exception if you try.It's possible to work around this limitation. Instead of using
exec()
, one could simply bind a new function using the code object and whatever closure or globals you wanted. But this seems like an unnecessary limitation on the functionality ofexec()
.I propose to add a closure keyword-only argument to
eval()
. It can only be specified if the code object uses free variables. When specified, it must be a tuple, with exactly the number of cell variables referenced by the code object. closure has a default value ofNone
, and it must beNone
if the code object doesn't refer to any free variables.We do have a use case for this, in conjunction with PEP 649. Carl Meyer proposes to pull the code object out of a co_annotations function, and run it with a globals object that enables us to handle undefined (forward-defined) names.
The text was updated successfully, but these errors were encountered: