mirror of
https://github.com/python/cpython.git
synced 2025-07-23 03:05:38 +00:00
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().
This commit is contained in:
parent
4233ff3ee4
commit
46496f9d12
7 changed files with 74 additions and 31 deletions
|
@ -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);
|
||||
|
@ -5315,15 +5313,21 @@ PyEval_GetFrame(void)
|
|||
return tstate->frame;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue