diff options
author | Victor Stinner <vstinner@python.org> | 2021-02-20 15:17:18 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-20 15:17:18 +0100 |
commit | 46496f9d12582bf11f4911ad0f23315d6f277907 (patch) | |
tree | 8382b24a5036df07fe75c59f0a45cd401d84b17a /Python/ceval.c | |
parent | 4233ff3ee4add287b3617f38943d01a7a6f4d7c4 (diff) | |
download | cpython3-46496f9d12582bf11f4911ad0f23315d6f277907.tar.gz |
bpo-42990: Functions inherit current builtins (GH-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().
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 7ccb8fcf5a..e2b2d211fb 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -889,10 +889,11 @@ static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **); PyObject * PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) { + PyThreadState *tstate = PyThreadState_GET(); if (locals == NULL) { locals = globals; } - PyObject *builtins = _PyEval_BuiltinsFromGlobals(globals); + PyObject *builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); if (builtins == NULL) { return NULL; } @@ -906,10 +907,7 @@ PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals) .fc_kwdefaults = NULL, .fc_closure = NULL }; - PyThreadState *tstate = PyThreadState_GET(); - PyObject *res = _PyEval_Vector(tstate, &desc, locals, NULL, 0, NULL); - Py_DECREF(builtins); - return res; + return _PyEval_Vector(tstate, &desc, locals, NULL, 0, NULL); } @@ -4733,12 +4731,13 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, PyObject *const *defs, int defcount, PyObject *kwdefs, PyObject *closure) { + PyThreadState *tstate = _PyThreadState_GET(); PyObject *res; PyObject *defaults = _PyTuple_FromArray(defs, defcount); if (defaults == NULL) { return NULL; } - PyObject *builtins = _PyEval_BuiltinsFromGlobals(globals); + PyObject *builtins = _PyEval_BuiltinsFromGlobals(tstate, globals); if (builtins == NULL) { Py_DECREF(defaults); return NULL; @@ -4797,7 +4796,6 @@ PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, .fc_kwdefaults = kwdefs, .fc_closure = closure }; - PyThreadState *tstate = _PyThreadState_GET(); res = _PyEval_Vector(tstate, &constr, locals, allargs, argcount, kwnames); @@ -5316,14 +5314,20 @@ PyEval_GetFrame(void) } PyObject * +_PyEval_GetBuiltins(PyThreadState *tstate) +{ + PyFrameObject *frame = tstate->frame; + if (frame != NULL) { + return frame->f_builtins; + } + return tstate->interp->builtins; +} + +PyObject * PyEval_GetBuiltins(void) { PyThreadState *tstate = _PyThreadState_GET(); - PyFrameObject *current_frame = tstate->frame; - if (current_frame == NULL) - return tstate->interp->builtins; - else - return current_frame->f_builtins; + return _PyEval_GetBuiltins(tstate); } /* Convenience function to get a builtin from its name */ |