diff -r f9dd607dc04c Modules/_testcapimodule.c --- a/Modules/_testcapimodule.c Tue Jan 03 02:01:42 2017 +0100 +++ b/Modules/_testcapimodule.c Tue Jan 03 02:30:42 2017 +0100 @@ -4039,6 +4039,60 @@ dict_get_version(PyObject *self, PyObjec return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)version); } +static Py_uintptr_t compute_stack_start; + +static PyObject* +compute_stacksize(PyObject *self, PyObject *args) +{ + PyObject *func, *n2, *res; + Py_ssize_t n; + Py_uintptr_t stack; + size_t stack_size; + + if (!PyArg_ParseTuple(args, "On", &func, &n)) { + return NULL; + } + + stack = (Py_uintptr_t)&func; + if (stack > compute_stack_start) { + stack_size = stack - compute_stack_start; + } + else { + stack_size = compute_stack_start - stack; + } + + if (n == 0) { + return PyLong_FromSize_t(stack_size); + } + + n2 = PyLong_FromSsize_t(n - 1); + if (n2 == NULL) { + return NULL; + } + + res = PyObject_CallFunctionObjArgs(func, func, n2, NULL); + Py_DECREF(n2); + return res; +} + +static PyObject* +pyobjectl_callfunctionobjargs_stacksize(PyObject *self, PyObject *arg) +{ + PyMethodDef meth = {"compute_stacksize", compute_stacksize, METH_VARARGS}; + PyObject *func, *res; + + compute_stack_start = (Py_uintptr_t)&meth; + func = PyCFunction_NewEx(&meth, self, NULL); + if (func == NULL) { + return NULL; + } + + res = PyObject_CallFunctionObjArgs(func, func, arg, NULL); + Py_DECREF(func); + + return res; +} + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, @@ -4244,6 +4298,8 @@ static PyMethodDef TestMethods[] = { {"tracemalloc_untrack", tracemalloc_untrack, METH_VARARGS}, {"tracemalloc_get_traceback", tracemalloc_get_traceback, METH_VARARGS}, {"dict_get_version", dict_get_version, METH_VARARGS}, + {"pyobjectl_callfunctionobjargs_stacksize", + pyobjectl_callfunctionobjargs_stacksize, METH_O}, {NULL, NULL} /* sentinel */ };