gh-117694: Improve tests for PyEval_EvalCodeEx() (GH-117695)

This commit is contained in:
Serhiy Storchaka 2024-04-15 12:44:54 +03:00 committed by GitHub
parent a9107fe5c0
commit 57bdb75975
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 114 additions and 91 deletions

View file

@ -2645,107 +2645,60 @@ eval_eval_code_ex(PyObject *mod, PyObject *pos_args)
PyObject **c_kwargs = NULL;
if (!PyArg_UnpackTuple(pos_args,
"eval_code_ex",
2,
8,
&code,
&globals,
&locals,
&args,
&kwargs,
&defaults,
&kw_defaults,
&closure))
if (!PyArg_ParseTuple(pos_args,
"OO|OO!O!O!OO:eval_code_ex",
&code,
&globals,
&locals,
&PyTuple_Type, &args,
&PyDict_Type, &kwargs,
&PyTuple_Type, &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;
}
NULLABLE(code);
NULLABLE(globals);
NULLABLE(locals);
NULLABLE(kw_defaults);
NULLABLE(closure);
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);
}
if (args) {
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! */
if (kwargs) {
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)) {
if (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,