-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
gh-135443: Sometimes Fall Back to __main__.__dict__ For Globals #135491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-135443: Sometimes Fall Back to __main__.__dict__ For Globals #135491
Conversation
Objects/object.c
Outdated
if (_PyEval_GetFrame() != NULL) { | ||
locals = _PyEval_GetFrameLocals(); | ||
} | ||
PyThreadState *tstate = _PyThreadState_GET(); | ||
locals = _PyEval_GetGlobalsFromRunningMain(tstate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_PyEval_GetFrameLocals()
returns a new reference (leak), which is overwritten by _PyEval_GetGlobalsFromRunningMain()
. Thus the fallback mechanism looks to be missing.
The same goes for builtin_vars()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@@ -1414,6 +1414,41 @@ def test_call_invalid(self): | |||
with self.assertRaises(interpreters.NotShareableError): | |||
interp.call(func, op, 'eggs!') | |||
|
|||
def test_callable_requires_frame(self): | |||
# There are various functions tha require a current frame. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a typo in the comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
notshareable = [ | ||
globals, | ||
locals, | ||
vars, | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If "notshareable" here means that the result of the functions cannot be pickled, could NotShareableError
differentiate the round-trip in the future? Also, interpreters.is_shareable()
returns False
for both globals
and dir
, which might be confusing at first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
🤖 New build scheduled with the buildbot fleet by @ericsnowcurrently for commit c93f890 🤖 Results will be shown at: https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F135491%2Fmerge If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again. |
Thanks @ericsnowcurrently for the PR 🌮🎉.. I'm working now to backport this PR to: 3.14. |
…pythongh-135491) For several builtin functions, we now fall back to __main__.__dict__ for the globals when there is no current frame and _PyInterpreterState_IsRunningMain() returns true. This allows those functions to be run with Interpreter.call(). The affected builtins: * exec() * eval() * globals() * locals() * vars() * dir() We take a similar approach with "stateless" functions, which don't use any global variables. (cherry picked from commit a450a0d) Co-authored-by: Eric Snow <[email protected]>
GH-135593 is a backport of this pull request to the 3.14 branch. |
gh-135593) For several builtin functions, we now fall back to __main__.__dict__ for the globals when there is no current frame and _PyInterpreterState_IsRunningMain() returns true. This allows those functions to be run with Interpreter.call(). The affected builtins: * exec() * eval() * globals() * locals() * vars() * dir() We take a similar approach with "stateless" functions, which don't use any global variables. (cherry picked from commit a450a0d, AKA gh-135491) Co-authored-by: Eric Snow <[email protected]>
For several builtin functions, we now fall back to
__main__.__dict__
for the globalswhen there is no current frame and
_PyInterpreterState_IsRunningMain()
returnstrue. This allows those functions to be run with
Interpreter.call()
.The affected builtins:
exec()
eval()
globals()
locals()
vars()
dir()