Skip to content
Prev Previous commit
Next Next commit
Merge branch 'main' into trim-code-object-2
  • Loading branch information
markshannon committed Feb 13, 2023
commit d81c0423a4517c3c3652ea4e2184108056c1de21
138 changes: 138 additions & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3074,6 +3074,144 @@ gen_get_code(PyObject *self, PyObject *gen)
return (PyObject *)PyGen_GetCode((PyGenObject *)gen);
}

static PyObject *
eval_eval_code_ex(PyObject *mod, PyObject *pos_args)
{
PyObject *result = NULL;
PyObject *code;
PyObject *globals;
PyObject *locals = NULL;
PyObject *args = NULL;
PyObject *kwargs = NULL;
PyObject *defaults = NULL;
PyObject *kw_defaults = NULL;
PyObject *closure = NULL;

PyObject **c_kwargs = NULL;

if (!PyArg_UnpackTuple(pos_args,
"eval_code_ex",
2,
8,
&code,
&globals,
&locals,
&args,
&kwargs,
&defaults,
&kw_defaults,
&closure))
{
goto exit;
}

if (!PyCode_Check(code)) {
PyErr_SetString(PyExc_TypeError,
"code must be a Python code object");
goto exit;
}

if (!PyDict_Check(globals)) {
PyErr_SetString(PyExc_TypeError, "globals must be a dict");
goto exit;
}

if (locals && !PyMapping_Check(locals)) {
PyErr_SetString(PyExc_TypeError, "locals must be a mapping");
goto exit;
}
if (locals == Py_None) {
locals = NULL;
}

PyObject **c_args = NULL;
Py_ssize_t c_args_len = 0;

if (args)
{
if (!PyTuple_Check(args)) {
PyErr_SetString(PyExc_TypeError, "args must be a tuple");
goto exit;
} else {
c_args = &PyTuple_GET_ITEM(args, 0);
c_args_len = PyTuple_Size(args);
}
}

Py_ssize_t c_kwargs_len = 0;

if (kwargs)
{
if (!PyDict_Check(kwargs)) {
PyErr_SetString(PyExc_TypeError, "keywords must be a dict");
goto exit;
} else {
c_kwargs_len = PyDict_Size(kwargs);
if (c_kwargs_len > 0) {
c_kwargs = PyMem_NEW(PyObject*, 2 * c_kwargs_len);
if (!c_kwargs) {
PyErr_NoMemory();
goto exit;
}

Py_ssize_t i = 0;
Py_ssize_t pos = 0;

while (PyDict_Next(kwargs,
&pos,
&c_kwargs[i],
&c_kwargs[i + 1]))
{
i += 2;
}
c_kwargs_len = i / 2;
/* XXX This is broken if the caller deletes dict items! */
}
}
}


PyObject **c_defaults = NULL;
Py_ssize_t c_defaults_len = 0;

if (defaults && PyTuple_Check(defaults)) {
c_defaults = &PyTuple_GET_ITEM(defaults, 0);
c_defaults_len = PyTuple_Size(defaults);
}

if (kw_defaults && !PyDict_Check(kw_defaults)) {
PyErr_SetString(PyExc_TypeError, "kw_defaults must be a dict");
goto exit;
}

if (closure && !PyTuple_Check(closure)) {
PyErr_SetString(PyExc_TypeError, "closure must be a tuple of cells");
goto exit;
}


result = PyEval_EvalCodeEx(
code,
globals,
locals,
c_args,
(int)c_args_len,
c_kwargs,
(int)c_kwargs_len,
c_defaults,
(int)c_defaults_len,
kw_defaults,
closure
);

exit:
if (c_kwargs) {
PyMem_DEL(c_kwargs);
}

return result;
}

static PyObject *
get_feature_macros(PyObject *self, PyObject *Py_UNUSED(args))
{
Expand Down
3 changes: 1 addition & 2 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -1658,8 +1658,7 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
goto fail;
}
_PyFrame_Initialize(frame, func, locals, code, 0);
PyObject **localsarray = &frame->localsplus[0];
if (initialize_locals(tstate, func, localsarray, args, argcount, kwnames)) {
if (initialize_locals(tstate, func, frame->localsplus, args, argcount, kwnames)) {
assert(frame->owner == FRAME_OWNED_BY_THREAD);
clear_thread_frame(tstate, frame);
return NULL;
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.