| #include "Python.h" | 
 | #include "pycore_object.h" | 
 | #include "pycore_pystate.h" | 
 | #include "pycore_tupleobject.h" | 
 | #include "frameobject.h" | 
 |  | 
 |  | 
 | static PyObject * | 
 | cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs); | 
 |  | 
 | static PyObject *const * | 
 | _PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, | 
 |                     PyObject **p_kwnames); | 
 |  | 
 | static void | 
 | _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, | 
 |                          PyObject *kwnames); | 
 |  | 
 |  | 
 | static PyObject * | 
 | null_error(void) | 
 | { | 
 |     if (!PyErr_Occurred()) | 
 |         PyErr_SetString(PyExc_SystemError, | 
 |                         "null argument to internal routine"); | 
 |     return NULL; | 
 | } | 
 |  | 
 |  | 
 | PyObject* | 
 | _Py_CheckFunctionResult(PyObject *callable, PyObject *result, const char *where) | 
 | { | 
 |     int err_occurred = (PyErr_Occurred() != NULL); | 
 |  | 
 |     assert((callable != NULL) ^ (where != NULL)); | 
 |  | 
 |     if (result == NULL) { | 
 |         if (!err_occurred) { | 
 |             if (callable) | 
 |                 PyErr_Format(PyExc_SystemError, | 
 |                              "%R returned NULL without setting an error", | 
 |                              callable); | 
 |             else | 
 |                 PyErr_Format(PyExc_SystemError, | 
 |                              "%s returned NULL without setting an error", | 
 |                              where); | 
 | #ifdef Py_DEBUG | 
 |             /* Ensure that the bug is caught in debug mode */ | 
 |             Py_FatalError("a function returned NULL without setting an error"); | 
 | #endif | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |     else { | 
 |         if (err_occurred) { | 
 |             Py_DECREF(result); | 
 |  | 
 |             if (callable) { | 
 |                 _PyErr_FormatFromCause(PyExc_SystemError, | 
 |                         "%R returned a result with an error set", | 
 |                         callable); | 
 |             } | 
 |             else { | 
 |                 _PyErr_FormatFromCause(PyExc_SystemError, | 
 |                         "%s returned a result with an error set", | 
 |                         where); | 
 |             } | 
 | #ifdef Py_DEBUG | 
 |             /* Ensure that the bug is caught in debug mode */ | 
 |             Py_FatalError("a function returned a result with an error set"); | 
 | #endif | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | /* --- Core PyObject call functions ------------------------------- */ | 
 |  | 
 | /* Call a callable Python object without any arguments */ | 
 | PyObject * | 
 | PyObject_CallNoArgs(PyObject *func) | 
 | { | 
 |     return _PyObject_CallNoArg(func); | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, | 
 |                        size_t nargsf, PyObject *kwargs) | 
 | { | 
 |     /* _PyObject_FastCallDict() must not be called with an exception set, | 
 |        because it can clear it (directly or indirectly) and so the | 
 |        caller loses its exception */ | 
 |     assert(!PyErr_Occurred()); | 
 |     assert(callable != NULL); | 
 |  | 
 |     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | 
 |     assert(nargs >= 0); | 
 |     assert(nargs == 0 || args != NULL); | 
 |     assert(kwargs == NULL || PyDict_Check(kwargs)); | 
 |  | 
 |     vectorcallfunc func = _PyVectorcall_Function(callable); | 
 |     if (func == NULL) { | 
 |         /* Use tp_call instead */ | 
 |         return _PyObject_MakeTpCall(callable, args, nargs, kwargs); | 
 |     } | 
 |  | 
 |     PyObject *res; | 
 |     if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) { | 
 |         res = func(callable, args, nargsf, NULL); | 
 |     } | 
 |     else { | 
 |         PyObject *kwnames; | 
 |         PyObject *const *newargs; | 
 |         newargs = _PyStack_UnpackDict(args, nargs, kwargs, &kwnames); | 
 |         if (newargs == NULL) { | 
 |             return NULL; | 
 |         } | 
 |         res = func(callable, newargs, | 
 |                    nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); | 
 |         _PyStack_UnpackDict_Free(newargs, nargs, kwnames); | 
 |     } | 
 |     return _Py_CheckFunctionResult(callable, res, NULL); | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | _PyObject_MakeTpCall(PyObject *callable, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) | 
 | { | 
 |     /* Slow path: build a temporary tuple for positional arguments and a | 
 |      * temporary dictionary for keyword arguments (if any) */ | 
 |     ternaryfunc call = Py_TYPE(callable)->tp_call; | 
 |     if (call == NULL) { | 
 |         PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", | 
 |                      Py_TYPE(callable)->tp_name); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     assert(nargs >= 0); | 
 |     assert(nargs == 0 || args != NULL); | 
 |     assert(keywords == NULL || PyTuple_Check(keywords) || PyDict_Check(keywords)); | 
 |     PyObject *argstuple = _PyTuple_FromArray(args, nargs); | 
 |     if (argstuple == NULL) { | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     PyObject *kwdict; | 
 |     if (keywords == NULL || PyDict_Check(keywords)) { | 
 |         kwdict = keywords; | 
 |     } | 
 |     else { | 
 |         if (PyTuple_GET_SIZE(keywords)) { | 
 |             assert(args != NULL); | 
 |             kwdict = _PyStack_AsDict(args + nargs, keywords); | 
 |             if (kwdict == NULL) { | 
 |                 Py_DECREF(argstuple); | 
 |                 return NULL; | 
 |             } | 
 |         } | 
 |         else { | 
 |             keywords = kwdict = NULL; | 
 |         } | 
 |     } | 
 |  | 
 |     PyObject *result = NULL; | 
 |     if (Py_EnterRecursiveCall(" while calling a Python object") == 0) | 
 |     { | 
 |         result = call(callable, argstuple, kwdict); | 
 |         Py_LeaveRecursiveCall(); | 
 |     } | 
 |  | 
 |     Py_DECREF(argstuple); | 
 |     if (kwdict != keywords) { | 
 |         Py_DECREF(kwdict); | 
 |     } | 
 |  | 
 |     result = _Py_CheckFunctionResult(callable, result, NULL); | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) | 
 | { | 
 |     /* get vectorcallfunc as in _PyVectorcall_Function, but without | 
 |      * the _Py_TPFLAGS_HAVE_VECTORCALL check */ | 
 |     Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset; | 
 |     if (offset <= 0) { | 
 |         PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", | 
 |                      Py_TYPE(callable)->tp_name); | 
 |         return NULL; | 
 |     } | 
 |     vectorcallfunc func = *(vectorcallfunc *)(((char *)callable) + offset); | 
 |     if (func == NULL) { | 
 |         PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall", | 
 |                      Py_TYPE(callable)->tp_name); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     Py_ssize_t nargs = PyTuple_GET_SIZE(tuple); | 
 |  | 
 |     /* Fast path for no keywords */ | 
 |     if (kwargs == NULL || PyDict_GET_SIZE(kwargs) == 0) { | 
 |         return func(callable, _PyTuple_ITEMS(tuple), nargs, NULL); | 
 |     } | 
 |  | 
 |     /* Convert arguments & call */ | 
 |     PyObject *const *args; | 
 |     PyObject *kwnames; | 
 |     args = _PyStack_UnpackDict(_PyTuple_ITEMS(tuple), nargs, kwargs, &kwnames); | 
 |     if (args == NULL) { | 
 |         return NULL; | 
 |     } | 
 |     PyObject *result = func(callable, args, | 
 |                             nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); | 
 |     _PyStack_UnpackDict_Free(args, nargs, kwnames); | 
 |     return _Py_CheckFunctionResult(callable, result, NULL); | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) | 
 | { | 
 |     ternaryfunc call; | 
 |     PyObject *result; | 
 |  | 
 |     /* PyObject_Call() must not be called with an exception set, | 
 |        because it can clear it (directly or indirectly) and so the | 
 |        caller loses its exception */ | 
 |     assert(!PyErr_Occurred()); | 
 |     assert(PyTuple_Check(args)); | 
 |     assert(kwargs == NULL || PyDict_Check(kwargs)); | 
 |  | 
 |     if (_PyVectorcall_Function(callable) != NULL) { | 
 |         return PyVectorcall_Call(callable, args, kwargs); | 
 |     } | 
 |     else if (PyCFunction_Check(callable)) { | 
 |         /* This must be a METH_VARARGS function, otherwise we would be | 
 |          * in the previous case */ | 
 |         return cfunction_call_varargs(callable, args, kwargs); | 
 |     } | 
 |     else { | 
 |         call = callable->ob_type->tp_call; | 
 |         if (call == NULL) { | 
 |             PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", | 
 |                          callable->ob_type->tp_name); | 
 |             return NULL; | 
 |         } | 
 |  | 
 |         if (Py_EnterRecursiveCall(" while calling a Python object")) | 
 |             return NULL; | 
 |  | 
 |         result = (*call)(callable, args, kwargs); | 
 |  | 
 |         Py_LeaveRecursiveCall(); | 
 |  | 
 |         return _Py_CheckFunctionResult(callable, result, NULL); | 
 |     } | 
 | } | 
 |  | 
 |  | 
 | /* --- PyFunction call functions ---------------------------------- */ | 
 |  | 
 | static PyObject* _Py_HOT_FUNCTION | 
 | function_code_fastcall(PyCodeObject *co, PyObject *const *args, Py_ssize_t nargs, | 
 |                        PyObject *globals) | 
 | { | 
 |     PyFrameObject *f; | 
 |     PyThreadState *tstate = _PyThreadState_GET(); | 
 |     PyObject **fastlocals; | 
 |     Py_ssize_t i; | 
 |     PyObject *result; | 
 |  | 
 |     assert(globals != NULL); | 
 |     /* XXX Perhaps we should create a specialized | 
 |        _PyFrame_New_NoTrack() that doesn't take locals, but does | 
 |        take builtins without sanity checking them. | 
 |        */ | 
 |     assert(tstate != NULL); | 
 |     f = _PyFrame_New_NoTrack(tstate, co, globals, NULL); | 
 |     if (f == NULL) { | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     fastlocals = f->f_localsplus; | 
 |  | 
 |     for (i = 0; i < nargs; i++) { | 
 |         Py_INCREF(*args); | 
 |         fastlocals[i] = *args++; | 
 |     } | 
 |     result = PyEval_EvalFrameEx(f,0); | 
 |  | 
 |     if (Py_REFCNT(f) > 1) { | 
 |         Py_DECREF(f); | 
 |         _PyObject_GC_TRACK(f); | 
 |     } | 
 |     else { | 
 |         ++tstate->recursion_depth; | 
 |         Py_DECREF(f); | 
 |         --tstate->recursion_depth; | 
 |     } | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | _PyFunction_Vectorcall(PyObject *func, PyObject* const* stack, | 
 |                        size_t nargsf, PyObject *kwnames) | 
 | { | 
 |     PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); | 
 |     PyObject *globals = PyFunction_GET_GLOBALS(func); | 
 |     PyObject *argdefs = PyFunction_GET_DEFAULTS(func); | 
 |     PyObject *kwdefs, *closure, *name, *qualname; | 
 |     PyObject **d; | 
 |     Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); | 
 |     Py_ssize_t nd; | 
 |  | 
 |     assert(PyFunction_Check(func)); | 
 |     Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); | 
 |     assert(nargs >= 0); | 
 |     assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); | 
 |     assert((nargs == 0 && nkwargs == 0) || stack != NULL); | 
 |     /* kwnames must only contain strings and all keys must be unique */ | 
 |  | 
 |     if (co->co_kwonlyargcount == 0 && nkwargs == 0 && | 
 |         (co->co_flags & ~PyCF_MASK) == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) | 
 |     { | 
 |         if (argdefs == NULL && co->co_argcount == nargs) { | 
 |             return function_code_fastcall(co, stack, nargs, globals); | 
 |         } | 
 |         else if (nargs == 0 && argdefs != NULL | 
 |                  && co->co_argcount == PyTuple_GET_SIZE(argdefs)) { | 
 |             /* function called with no arguments, but all parameters have | 
 |                a default value: use default values as arguments .*/ | 
 |             stack = _PyTuple_ITEMS(argdefs); | 
 |             return function_code_fastcall(co, stack, PyTuple_GET_SIZE(argdefs), | 
 |                                           globals); | 
 |         } | 
 |     } | 
 |  | 
 |     kwdefs = PyFunction_GET_KW_DEFAULTS(func); | 
 |     closure = PyFunction_GET_CLOSURE(func); | 
 |     name = ((PyFunctionObject *)func) -> func_name; | 
 |     qualname = ((PyFunctionObject *)func) -> func_qualname; | 
 |  | 
 |     if (argdefs != NULL) { | 
 |         d = _PyTuple_ITEMS(argdefs); | 
 |         nd = PyTuple_GET_SIZE(argdefs); | 
 |     } | 
 |     else { | 
 |         d = NULL; | 
 |         nd = 0; | 
 |     } | 
 |     return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL, | 
 |                                     stack, nargs, | 
 |                                     nkwargs ? _PyTuple_ITEMS(kwnames) : NULL, | 
 |                                     stack + nargs, | 
 |                                     nkwargs, 1, | 
 |                                     d, (int)nd, kwdefs, | 
 |                                     closure, name, qualname); | 
 | } | 
 |  | 
 |  | 
 | /* --- PyCFunction call functions --------------------------------- */ | 
 |  | 
 | static PyObject * | 
 | cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs) | 
 | { | 
 |     assert(!PyErr_Occurred()); | 
 |     assert(kwargs == NULL || PyDict_Check(kwargs)); | 
 |  | 
 |     PyCFunction meth = PyCFunction_GET_FUNCTION(func); | 
 |     PyObject *self = PyCFunction_GET_SELF(func); | 
 |     PyObject *result; | 
 |  | 
 |     assert(PyCFunction_GET_FLAGS(func) & METH_VARARGS); | 
 |     if (PyCFunction_GET_FLAGS(func) & METH_KEYWORDS) { | 
 |         if (Py_EnterRecursiveCall(" while calling a Python object")) { | 
 |             return NULL; | 
 |         } | 
 |  | 
 |         result = (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, args, kwargs); | 
 |  | 
 |         Py_LeaveRecursiveCall(); | 
 |     } | 
 |     else { | 
 |         if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { | 
 |             PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", | 
 |                          ((PyCFunctionObject*)func)->m_ml->ml_name); | 
 |             return NULL; | 
 |         } | 
 |  | 
 |         if (Py_EnterRecursiveCall(" while calling a Python object")) { | 
 |             return NULL; | 
 |         } | 
 |  | 
 |         result = (*meth)(self, args); | 
 |  | 
 |         Py_LeaveRecursiveCall(); | 
 |     } | 
 |  | 
 |     return _Py_CheckFunctionResult(func, result, NULL); | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwargs) | 
 | { | 
 |     /* For METH_VARARGS, we cannot use vectorcall as the vectorcall pointer | 
 |      * is NULL. This is intentional, since vectorcall would be slower. */ | 
 |     if (PyCFunction_GET_FLAGS(func) & METH_VARARGS) { | 
 |         return cfunction_call_varargs(func, args, kwargs); | 
 |     } | 
 |     return PyVectorcall_Call(func, args, kwargs); | 
 | } | 
 |  | 
 |  | 
 | /* --- More complex call functions -------------------------------- */ | 
 |  | 
 | /* External interface to call any callable object. | 
 |    The args must be a tuple or NULL.  The kwargs must be a dict or NULL. */ | 
 | PyObject * | 
 | PyEval_CallObjectWithKeywords(PyObject *callable, | 
 |                               PyObject *args, PyObject *kwargs) | 
 | { | 
 | #ifdef Py_DEBUG | 
 |     /* PyEval_CallObjectWithKeywords() must not be called with an exception | 
 |        set. It raises a new exception if parameters are invalid or if | 
 |        PyTuple_New() fails, and so the original exception is lost. */ | 
 |     assert(!PyErr_Occurred()); | 
 | #endif | 
 |  | 
 |     if (args != NULL && !PyTuple_Check(args)) { | 
 |         PyErr_SetString(PyExc_TypeError, | 
 |                         "argument list must be a tuple"); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     if (kwargs != NULL && !PyDict_Check(kwargs)) { | 
 |         PyErr_SetString(PyExc_TypeError, | 
 |                         "keyword list must be a dictionary"); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     if (args == NULL) { | 
 |         return _PyObject_FastCallDict(callable, NULL, 0, kwargs); | 
 |     } | 
 |     else { | 
 |         return PyObject_Call(callable, args, kwargs); | 
 |     } | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | PyObject_CallObject(PyObject *callable, PyObject *args) | 
 | { | 
 |     assert(!PyErr_Occurred()); | 
 |     if (args == NULL) { | 
 |         return _PyObject_CallNoArg(callable); | 
 |     } | 
 |     if (!PyTuple_Check(args)) { | 
 |         PyErr_SetString(PyExc_TypeError, | 
 |                         "argument list must be a tuple"); | 
 |         return NULL; | 
 |     } | 
 |     return PyObject_Call(callable, args, NULL); | 
 | } | 
 |  | 
 |  | 
 | /* Call callable(obj, *args, **kwargs). */ | 
 | PyObject * | 
 | _PyObject_Call_Prepend(PyObject *callable, | 
 |                        PyObject *obj, PyObject *args, PyObject *kwargs) | 
 | { | 
 |     PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; | 
 |     PyObject **stack; | 
 |     Py_ssize_t argcount; | 
 |     PyObject *result; | 
 |  | 
 |     assert(PyTuple_Check(args)); | 
 |  | 
 |     argcount = PyTuple_GET_SIZE(args); | 
 |     if (argcount + 1 <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { | 
 |         stack = small_stack; | 
 |     } | 
 |     else { | 
 |         stack = PyMem_Malloc((argcount + 1) * sizeof(PyObject *)); | 
 |         if (stack == NULL) { | 
 |             PyErr_NoMemory(); | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |  | 
 |     /* use borrowed references */ | 
 |     stack[0] = obj; | 
 |     memcpy(&stack[1], | 
 |            _PyTuple_ITEMS(args), | 
 |            argcount * sizeof(PyObject *)); | 
 |  | 
 |     result = _PyObject_FastCallDict(callable, | 
 |                                     stack, argcount + 1, | 
 |                                     kwargs); | 
 |     if (stack != small_stack) { | 
 |         PyMem_Free(stack); | 
 |     } | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | /* --- Call with a format string ---------------------------------- */ | 
 |  | 
 | static PyObject * | 
 | _PyObject_CallFunctionVa(PyObject *callable, const char *format, | 
 |                          va_list va, int is_size_t) | 
 | { | 
 |     PyObject* small_stack[_PY_FASTCALL_SMALL_STACK]; | 
 |     const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack); | 
 |     PyObject **stack; | 
 |     Py_ssize_t nargs, i; | 
 |     PyObject *result; | 
 |  | 
 |     if (callable == NULL) { | 
 |         return null_error(); | 
 |     } | 
 |  | 
 |     if (!format || !*format) { | 
 |         return _PyObject_CallNoArg(callable); | 
 |     } | 
 |  | 
 |     if (is_size_t) { | 
 |         stack = _Py_VaBuildStack_SizeT(small_stack, small_stack_len, | 
 |                                        format, va, &nargs); | 
 |     } | 
 |     else { | 
 |         stack = _Py_VaBuildStack(small_stack, small_stack_len, | 
 |                                  format, va, &nargs); | 
 |     } | 
 |     if (stack == NULL) { | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     if (nargs == 1 && PyTuple_Check(stack[0])) { | 
 |         /* Special cases for backward compatibility: | 
 |            - PyObject_CallFunction(func, "O", tuple) calls func(*tuple) | 
 |            - PyObject_CallFunction(func, "(OOO)", arg1, arg2, arg3) calls | 
 |              func(*(arg1, arg2, arg3)): func(arg1, arg2, arg3) */ | 
 |         PyObject *args = stack[0]; | 
 |         result = _PyObject_FastCall(callable, | 
 |                                     _PyTuple_ITEMS(args), | 
 |                                     PyTuple_GET_SIZE(args)); | 
 |     } | 
 |     else { | 
 |         result = _PyObject_FastCall(callable, stack, nargs); | 
 |     } | 
 |  | 
 |     for (i = 0; i < nargs; ++i) { | 
 |         Py_DECREF(stack[i]); | 
 |     } | 
 |     if (stack != small_stack) { | 
 |         PyMem_Free(stack); | 
 |     } | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | PyObject_CallFunction(PyObject *callable, const char *format, ...) | 
 | { | 
 |     va_list va; | 
 |     PyObject *result; | 
 |  | 
 |     va_start(va, format); | 
 |     result = _PyObject_CallFunctionVa(callable, format, va, 0); | 
 |     va_end(va); | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | /* PyEval_CallFunction is exact copy of PyObject_CallFunction. | 
 |  * This function is kept for backward compatibility. | 
 |  */ | 
 | PyObject * | 
 | PyEval_CallFunction(PyObject *callable, const char *format, ...) | 
 | { | 
 |     va_list va; | 
 |     PyObject *result; | 
 |  | 
 |     va_start(va, format); | 
 |     result = _PyObject_CallFunctionVa(callable, format, va, 0); | 
 |     va_end(va); | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...) | 
 | { | 
 |     va_list va; | 
 |     PyObject *result; | 
 |  | 
 |     va_start(va, format); | 
 |     result = _PyObject_CallFunctionVa(callable, format, va, 1); | 
 |     va_end(va); | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | static PyObject* | 
 | callmethod(PyObject* callable, const char *format, va_list va, int is_size_t) | 
 | { | 
 |     assert(callable != NULL); | 
 |  | 
 |     if (!PyCallable_Check(callable)) { | 
 |         PyErr_Format(PyExc_TypeError, | 
 |                      "attribute of type '%.200s' is not callable", | 
 |                      Py_TYPE(callable)->tp_name); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     return _PyObject_CallFunctionVa(callable, format, va, is_size_t); | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) | 
 | { | 
 |     va_list va; | 
 |     PyObject *callable, *retval; | 
 |  | 
 |     if (obj == NULL || name == NULL) { | 
 |         return null_error(); | 
 |     } | 
 |  | 
 |     callable = PyObject_GetAttrString(obj, name); | 
 |     if (callable == NULL) | 
 |         return NULL; | 
 |  | 
 |     va_start(va, format); | 
 |     retval = callmethod(callable, format, va, 0); | 
 |     va_end(va); | 
 |  | 
 |     Py_DECREF(callable); | 
 |     return retval; | 
 | } | 
 |  | 
 |  | 
 | /* PyEval_CallMethod is exact copy of PyObject_CallMethod. | 
 |  * This function is kept for backward compatibility. | 
 |  */ | 
 | PyObject * | 
 | PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...) | 
 | { | 
 |     va_list va; | 
 |     PyObject *callable, *retval; | 
 |  | 
 |     if (obj == NULL || name == NULL) { | 
 |         return null_error(); | 
 |     } | 
 |  | 
 |     callable = PyObject_GetAttrString(obj, name); | 
 |     if (callable == NULL) | 
 |         return NULL; | 
 |  | 
 |     va_start(va, format); | 
 |     retval = callmethod(callable, format, va, 0); | 
 |     va_end(va); | 
 |  | 
 |     Py_DECREF(callable); | 
 |     return retval; | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | _PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name, | 
 |                        const char *format, ...) | 
 | { | 
 |     va_list va; | 
 |     PyObject *callable, *retval; | 
 |  | 
 |     if (obj == NULL || name == NULL) { | 
 |         return null_error(); | 
 |     } | 
 |  | 
 |     callable = _PyObject_GetAttrId(obj, name); | 
 |     if (callable == NULL) | 
 |         return NULL; | 
 |  | 
 |     va_start(va, format); | 
 |     retval = callmethod(callable, format, va, 0); | 
 |     va_end(va); | 
 |  | 
 |     Py_DECREF(callable); | 
 |     return retval; | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | _PyObject_CallMethod_SizeT(PyObject *obj, const char *name, | 
 |                            const char *format, ...) | 
 | { | 
 |     va_list va; | 
 |     PyObject *callable, *retval; | 
 |  | 
 |     if (obj == NULL || name == NULL) { | 
 |         return null_error(); | 
 |     } | 
 |  | 
 |     callable = PyObject_GetAttrString(obj, name); | 
 |     if (callable == NULL) | 
 |         return NULL; | 
 |  | 
 |     va_start(va, format); | 
 |     retval = callmethod(callable, format, va, 1); | 
 |     va_end(va); | 
 |  | 
 |     Py_DECREF(callable); | 
 |     return retval; | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | _PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name, | 
 |                              const char *format, ...) | 
 | { | 
 |     va_list va; | 
 |     PyObject *callable, *retval; | 
 |  | 
 |     if (obj == NULL || name == NULL) { | 
 |         return null_error(); | 
 |     } | 
 |  | 
 |     callable = _PyObject_GetAttrId(obj, name); | 
 |     if (callable == NULL) { | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     va_start(va, format); | 
 |     retval = callmethod(callable, format, va, 1); | 
 |     va_end(va); | 
 |  | 
 |     Py_DECREF(callable); | 
 |     return retval; | 
 | } | 
 |  | 
 |  | 
 | /* --- Call with "..." arguments ---------------------------------- */ | 
 |  | 
 | static PyObject * | 
 | object_vacall(PyObject *base, PyObject *callable, va_list vargs) | 
 | { | 
 |     PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; | 
 |     PyObject **stack; | 
 |     Py_ssize_t nargs; | 
 |     PyObject *result; | 
 |     Py_ssize_t i; | 
 |     va_list countva; | 
 |  | 
 |     if (callable == NULL) { | 
 |         return null_error(); | 
 |     } | 
 |  | 
 |     /* Count the number of arguments */ | 
 |     va_copy(countva, vargs); | 
 |     nargs = base ? 1 : 0; | 
 |     while (1) { | 
 |         PyObject *arg = va_arg(countva, PyObject *); | 
 |         if (arg == NULL) { | 
 |             break; | 
 |         } | 
 |         nargs++; | 
 |     } | 
 |     va_end(countva); | 
 |  | 
 |     /* Copy arguments */ | 
 |     if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { | 
 |         stack = small_stack; | 
 |     } | 
 |     else { | 
 |         stack = PyMem_Malloc(nargs * sizeof(stack[0])); | 
 |         if (stack == NULL) { | 
 |             PyErr_NoMemory(); | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |  | 
 |     i = 0; | 
 |     if (base) { | 
 |         stack[i++] = base; | 
 |     } | 
 |  | 
 |     for (; i < nargs; ++i) { | 
 |         stack[i] = va_arg(vargs, PyObject *); | 
 |     } | 
 |  | 
 |     /* Call the function */ | 
 |     result = _PyObject_FastCall(callable, stack, nargs); | 
 |  | 
 |     if (stack != small_stack) { | 
 |         PyMem_Free(stack); | 
 |     } | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | _PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, | 
 |                            size_t nargsf, PyObject *kwnames) | 
 | { | 
 |     assert(name != NULL); | 
 |     assert(args != NULL); | 
 |     assert(PyVectorcall_NARGS(nargsf) >= 1); | 
 |  | 
 |     PyObject *callable = NULL; | 
 |     /* Use args[0] as "self" argument */ | 
 |     int unbound = _PyObject_GetMethod(args[0], name, &callable); | 
 |     if (callable == NULL) { | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     if (unbound) { | 
 |         /* We must remove PY_VECTORCALL_ARGUMENTS_OFFSET since | 
 |          * that would be interpreted as allowing to change args[-1] */ | 
 |         nargsf &= ~PY_VECTORCALL_ARGUMENTS_OFFSET; | 
 |     } | 
 |     else { | 
 |         /* Skip "self". We can keep PY_VECTORCALL_ARGUMENTS_OFFSET since | 
 |          * args[-1] in the onward call is args[0] here. */ | 
 |         args++; | 
 |         nargsf--; | 
 |     } | 
 |     PyObject *result = _PyObject_Vectorcall(callable, args, nargsf, kwnames); | 
 |     Py_DECREF(callable); | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) | 
 | { | 
 |     if (obj == NULL || name == NULL) { | 
 |         return null_error(); | 
 |     } | 
 |  | 
 |     PyObject *callable = NULL; | 
 |     int is_method = _PyObject_GetMethod(obj, name, &callable); | 
 |     if (callable == NULL) { | 
 |         return NULL; | 
 |     } | 
 |     obj = is_method ? obj : NULL; | 
 |  | 
 |     va_list vargs; | 
 |     va_start(vargs, name); | 
 |     PyObject *result = object_vacall(obj, callable, vargs); | 
 |     va_end(vargs); | 
 |  | 
 |     Py_DECREF(callable); | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | _PyObject_CallMethodIdObjArgs(PyObject *obj, | 
 |                               struct _Py_Identifier *name, ...) | 
 | { | 
 |     if (obj == NULL || name == NULL) { | 
 |         return null_error(); | 
 |     } | 
 |  | 
 |     PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ | 
 |     if (!oname) { | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     PyObject *callable = NULL; | 
 |     int is_method = _PyObject_GetMethod(obj, oname, &callable); | 
 |     if (callable == NULL) { | 
 |         return NULL; | 
 |     } | 
 |     obj = is_method ? obj : NULL; | 
 |  | 
 |     va_list vargs; | 
 |     va_start(vargs, name); | 
 |     PyObject *result = object_vacall(obj, callable, vargs); | 
 |     va_end(vargs); | 
 |  | 
 |     Py_DECREF(callable); | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | PyObject * | 
 | PyObject_CallFunctionObjArgs(PyObject *callable, ...) | 
 | { | 
 |     va_list vargs; | 
 |     PyObject *result; | 
 |  | 
 |     va_start(vargs, callable); | 
 |     result = object_vacall(NULL, callable, vargs); | 
 |     va_end(vargs); | 
 |  | 
 |     return result; | 
 | } | 
 |  | 
 |  | 
 | /* --- PyStack functions ------------------------------------------ */ | 
 |  | 
 | PyObject * | 
 | _PyStack_AsDict(PyObject *const *values, PyObject *kwnames) | 
 | { | 
 |     Py_ssize_t nkwargs; | 
 |     PyObject *kwdict; | 
 |     Py_ssize_t i; | 
 |  | 
 |     assert(kwnames != NULL); | 
 |     nkwargs = PyTuple_GET_SIZE(kwnames); | 
 |     kwdict = _PyDict_NewPresized(nkwargs); | 
 |     if (kwdict == NULL) { | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     for (i = 0; i < nkwargs; i++) { | 
 |         PyObject *key = PyTuple_GET_ITEM(kwnames, i); | 
 |         PyObject *value = *values++; | 
 |         /* If key already exists, replace it with the new value */ | 
 |         if (PyDict_SetItem(kwdict, key, value)) { | 
 |             Py_DECREF(kwdict); | 
 |             return NULL; | 
 |         } | 
 |     } | 
 |     return kwdict; | 
 | } | 
 |  | 
 |  | 
 | /* Convert (args, nargs, kwargs: dict) into a (stack, nargs, kwnames: tuple). | 
 |  | 
 |    Allocate a new argument vector and keyword names tuple. Return the argument | 
 |    vector; return NULL with exception set on error. Return the keyword names | 
 |    tuple in *p_kwnames. | 
 |  | 
 |    This also checks that all keyword names are strings. If not, a TypeError is | 
 |    raised. | 
 |  | 
 |    The newly allocated argument vector supports PY_VECTORCALL_ARGUMENTS_OFFSET. | 
 |  | 
 |    When done, you must call _PyStack_UnpackDict_Free(stack, nargs, kwnames) */ | 
 | static PyObject *const * | 
 | _PyStack_UnpackDict(PyObject *const *args, Py_ssize_t nargs, PyObject *kwargs, | 
 |                     PyObject **p_kwnames) | 
 | { | 
 |     assert(nargs >= 0); | 
 |     assert(kwargs != NULL); | 
 |     assert(PyDict_Check(kwargs)); | 
 |  | 
 |     Py_ssize_t nkwargs = PyDict_GET_SIZE(kwargs); | 
 |     /* Check for overflow in the PyMem_Malloc() call below. The subtraction | 
 |      * in this check cannot overflow: both maxnargs and nkwargs are | 
 |      * non-negative signed integers, so their difference fits in the type. */ | 
 |     Py_ssize_t maxnargs = PY_SSIZE_T_MAX / sizeof(args[0]) - 1; | 
 |     if (nargs > maxnargs - nkwargs) { | 
 |         PyErr_NoMemory(); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     /* Add 1 to support PY_VECTORCALL_ARGUMENTS_OFFSET */ | 
 |     PyObject **stack = PyMem_Malloc((1 + nargs + nkwargs) * sizeof(args[0])); | 
 |     if (stack == NULL) { | 
 |         PyErr_NoMemory(); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     PyObject *kwnames = PyTuple_New(nkwargs); | 
 |     if (kwnames == NULL) { | 
 |         PyMem_Free(stack); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     stack++;  /* For PY_VECTORCALL_ARGUMENTS_OFFSET */ | 
 |  | 
 |     /* Copy positional arguments */ | 
 |     for (Py_ssize_t i = 0; i < nargs; i++) { | 
 |         Py_INCREF(args[i]); | 
 |         stack[i] = args[i]; | 
 |     } | 
 |  | 
 |     PyObject **kwstack = stack + nargs; | 
 |     /* This loop doesn't support lookup function mutating the dictionary | 
 |        to change its size. It's a deliberate choice for speed, this function is | 
 |        called in the performance critical hot code. */ | 
 |     Py_ssize_t pos = 0, i = 0; | 
 |     PyObject *key, *value; | 
 |     unsigned long keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; | 
 |     while (PyDict_Next(kwargs, &pos, &key, &value)) { | 
 |         keys_are_strings &= Py_TYPE(key)->tp_flags; | 
 |         Py_INCREF(key); | 
 |         Py_INCREF(value); | 
 |         PyTuple_SET_ITEM(kwnames, i, key); | 
 |         kwstack[i] = value; | 
 |         i++; | 
 |     } | 
 |  | 
 |     /* keys_are_strings has the value Py_TPFLAGS_UNICODE_SUBCLASS if that | 
 |      * flag is set for all keys. Otherwise, keys_are_strings equals 0. | 
 |      * We do this check once at the end instead of inside the loop above | 
 |      * because it simplifies the deallocation in the failing case. | 
 |      * It happens to also make the loop above slightly more efficient. */ | 
 |     if (!keys_are_strings) { | 
 |         PyErr_SetString(PyExc_TypeError, | 
 |                         "keywords must be strings"); | 
 |         _PyStack_UnpackDict_Free(stack, nargs, kwnames); | 
 |         return NULL; | 
 |     } | 
 |  | 
 |     *p_kwnames = kwnames; | 
 |     return stack; | 
 | } | 
 |  | 
 | static void | 
 | _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, | 
 |                          PyObject *kwnames) | 
 | { | 
 |     Py_ssize_t n = PyTuple_GET_SIZE(kwnames) + nargs; | 
 |     for (Py_ssize_t i = 0; i < n; i++) { | 
 |         Py_DECREF(stack[i]); | 
 |     } | 
 |     PyMem_Free((PyObject **)stack - 1); | 
 |     Py_DECREF(kwnames); | 
 | } |