summaryrefslogtreecommitdiffstats
path: root/Modules/_testcapimodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_testcapimodule.c')
-rw-r--r--Modules/_testcapimodule.c141
1 files changed, 140 insertions, 1 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 5e47f49..5a6097e 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -2237,7 +2237,7 @@ dict_get_version(PyObject *self, PyObject *args)
return NULL;
_Py_COMP_DIAG_PUSH
- _Py_COMP_DIAG_IGNORE_DEPR_DECLS
+ _Py_COMP_DIAG_IGNORE_DEPR_DECLS
version = dict->ma_version_tag;
_Py_COMP_DIAG_POP
@@ -3065,6 +3065,144 @@ eval_get_func_desc(PyObject *self, PyObject *func)
}
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,
+ c_args_len,
+ c_kwargs,
+ c_kwargs_len,
+ c_defaults,
+ 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))
{
PyObject *result = PyDict_New();
@@ -3385,6 +3523,7 @@ static PyMethodDef TestMethods[] = {
{"set_exc_info", test_set_exc_info, METH_VARARGS},
{"argparsing", argparsing, METH_VARARGS},
{"code_newempty", code_newempty, METH_VARARGS},
+ {"eval_code_ex", eval_eval_code_ex, METH_VARARGS},
{"make_exception_with_doc", _PyCFunction_CAST(make_exception_with_doc),
METH_VARARGS | METH_KEYWORDS},
{"make_memoryview_from_NULL_pointer", make_memoryview_from_NULL_pointer,