-
-
Notifications
You must be signed in to change notification settings - Fork 31.1k
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
bpo-42990: Functions inherit current builtins #24564
Conversation
@markshannon: Does it sounds like a reasonable default behavior according to you? If someone wants to run a function in a builtins namespace different than the current builtins, it should be set explicitly in Once this PR will be merged, I plan to write a 3rd PR to add an optional builtins keyword-only parameter to the function constructor (FunctionType). |
This would allow code to access the builtins by creating a new function, side stepping any sand boxing in |
I added an unit test on the By the way, Python doesn't support sandboxes. There are many ways to access builtins. It has been proved by a very long list of "exploits" on the various Python sandbox attempts in the past. |
I had assumed that Would you mind putting the relevant changes in one PR and refactor in another? Also, do we really need yet another |
Without this PR, func_builtins2.py of https://bugs.python.org/issue43228 currently fails on master: "NameError: name 'len' is not defined". With this PR, func_builtins2.py works as expected (no exception). |
To be honest, I also "re-discovered" that exec() has this special behavior.
Right, sorry. I created PR #24566. I will merge it, and then rebase this one on top of it. |
The rationale for passing explicitly tstate is that getting the current Python Thread State may become slower when https://bugs.python.org/issue40522 will be fixed (to run multiple interpreters in parallel). I also expect that the compiler will be able to emit faster machine code, especially when using LTO, if tstate is passed explicitly. For example, I expect _PyErr_Occurred() to be inlined. |
I rebased my PR to restrict this change to the FunctionType constructor change. I merged the refactoring changes in a separated PR. |
I completed the documentation to clarify that this change makes types.FunctionType constructor more consistent with other Python functions like eval() and exec(). |
@gvanrossum @pablogsal: Does this behavior change sound reasonable to you? |
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.
LGTM, just two doc nits.
Misc/NEWS.d/next/Core and Builtins/2021-02-18-15-12-30.bpo-42990.toAqBH.rst
Outdated
Show resolved
Hide resolved
Misc/NEWS.d/next/Core and Builtins/2021-02-18-15-12-30.bpo-42990.toAqBH.rst
Outdated
Show resolved
Hide resolved
The types.FunctionType constructor now inherits the current builtins if the globals dictionary has no "__builtins__" key, rather than using {"None": None} as builtins: same behavior as eval() and exec() functions. Defining a function with "def function(...): ..." in Python is not affected, globals cannot be overriden with this syntax: it also inherits the current builtins. PyFrame_New(), PyEval_EvalCode(), PyEval_EvalCodeEx(), PyFunction_New() and PyFunction_NewWithQualName() now inherits the current builtins namespace if the globals dictionary has no "__builtins__" key. * Add _PyEval_GetBuiltins() function. * _PyEval_BuiltinsFromGlobals() now uses _PyEval_GetBuiltins() if builtins cannot be found in globals. * Add tstate parameter to _PyEval_BuiltinsFromGlobals().
@gvanrossum: Thanks for the review, I merged my PR. |
bpo-42990: Functions inherit current builtins (pythonGH-24564)
The types.FunctionType constructor now inherits the current builtins if the globals dictionary has no "__builtins__" key, rather than using {"None": None} as builtins: same behavior as eval() and exec() functions. Defining a function with "def function(...): ..." in Python is not affected, globals cannot be overriden with this syntax: it also inherits the current builtins. PyFrame_New(), PyEval_EvalCode(), PyEval_EvalCodeEx(), PyFunction_New() and PyFunction_NewWithQualName() now inherits the current builtins namespace if the globals dictionary has no "__builtins__" key. * Add _PyEval_GetBuiltins() function. * _PyEval_BuiltinsFromGlobals() now uses _PyEval_GetBuiltins() if builtins cannot be found in globals. * Add tstate parameter to _PyEval_BuiltinsFromGlobals().
Python code doesn't like to run without `__builtins__`, so adding them if missing seems to be a good idea. Also that's what CPython >3.10 does. See python/cpython#24564 Resolves PyO3#3370
Python code doesn't like to run without `__builtins__`, so adding them if missing seems to be a good idea. Also that's what CPython >3.10 does. See python/cpython#24564 Resolves PyO3#3370
Python code doesn't like to run without `__builtins__`, so adding them if missing seems to be a good idea. Also that's what CPython >3.10 does. See python/cpython#24564 Resolves PyO3#3370
Python code doesn't like to run without `__builtins__`, so adding them if missing seems to be a good idea. Also that's what CPython >3.10 does. See python/cpython#24564 Resolves PyO3#3370
Python code doesn't like to run without `__builtins__`, so adding them if missing seems to be a good idea. Also that's what CPython >3.10 does. See python/cpython#24564 Resolves PyO3#3370
The types.FunctionType constructor now inherits the current builtins
if the globals parameter is used and the globals dictionary has no
"builtins" key, rather than rather than using {"None": None} as
builtins: same behavior than eval() and exec() functions.
Defining a function with "def function(...): ..." in Python is not
affected, globals cannot be overriden with this syntax: it also
inherits the current builtins.
PyFrame_New(), PyEval_EvalCode(), PyEval_EvalCodeEx(),
PyFunction_New() and PyFunction_NewWithQualName() now inherits the
current builtins namespace if the globals dictionary has no
"builtins" key.
builtins cannot be found in globals.
https://bugs.python.org/issue42990