diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2017-01-17 00:57:29 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2017-01-17 00:57:29 (GMT) |
commit | 998c20962ca3e2e693c1635efe76c0144dde76fc (patch) | |
tree | 400922db5ea9f99e4e1bdabe23a02fc439ade5ed | |
parent | 29d39cc8f50f314a62226d69ac014cbd0bd66792 (diff) | |
download | cpython-998c20962ca3e2e693c1635efe76c0144dde76fc.zip cpython-998c20962ca3e2e693c1635efe76c0144dde76fc.tar.gz cpython-998c20962ca3e2e693c1635efe76c0144dde76fc.tar.bz2 |
_PyStack_UnpackDict() now returns -1 on error
Issue #29286. Change _PyStack_UnpackDict() prototype to be able to notify of
failure when args is NULL.
-rw-r--r-- | Include/abstract.h | 13 | ||||
-rw-r--r-- | Objects/abstract.c | 16 | ||||
-rw-r--r-- | Objects/methodobject.c | 4 |
3 files changed, 19 insertions, 14 deletions
diff --git a/Include/abstract.h b/Include/abstract.h index 43bf251..961279d 100644 --- a/Include/abstract.h +++ b/Include/abstract.h @@ -177,20 +177,23 @@ PyAPI_FUNC(PyObject *) _PyStack_AsDict( PyObject **values, PyObject *kwnames); -/* Convert (args, nargs, kwargs) into a (stack, nargs, kwnames). +/* Convert (args, nargs, kwargs: dict) into a (stack, nargs, kwnames: tuple). - Return a new stack which should be released by PyMem_Free(), or return - args unchanged if kwargs is NULL or an empty dictionary. + Return 0 on success, raise an exception and return -1 on error. + + Write the new stack into *p_stack. If *p_stack is differen than args, it + must be released by PyMem_Free(). The stack uses borrowed references. The type of keyword keys is not checked, these checks should be done later (ex: _PyArg_ParseStackAndKeywords). */ -PyAPI_FUNC(PyObject **) _PyStack_UnpackDict( +PyAPI_FUNC(int) _PyStack_UnpackDict( PyObject **args, Py_ssize_t nargs, PyObject *kwargs, - PyObject **kwnames, + PyObject ***p_stack, + PyObject **p_kwnames, PyObject *func); /* Suggested size (number of positional arguments) for arrays of PyObject* diff --git a/Objects/abstract.c b/Objects/abstract.c index 48fdf65..ee50f02 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -2421,9 +2421,9 @@ _PyStack_AsDict(PyObject **values, PyObject *kwnames) return kwdict; } -PyObject ** +int _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs, - PyObject **p_kwnames, PyObject *func) + PyObject ***p_stack, PyObject **p_kwnames, PyObject *func) { PyObject **stack, **kwstack; Py_ssize_t nkwargs; @@ -2435,25 +2435,26 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs, assert(kwargs == NULL || PyDict_CheckExact(kwargs)); if (kwargs == NULL || (nkwargs = PyDict_GET_SIZE(kwargs)) == 0) { + *p_stack = args; *p_kwnames = NULL; - return args; + return 0; } if ((size_t)nargs > PY_SSIZE_T_MAX / sizeof(stack[0]) - (size_t)nkwargs) { PyErr_NoMemory(); - return NULL; + return -1; } stack = PyMem_Malloc((nargs + nkwargs) * sizeof(stack[0])); if (stack == NULL) { PyErr_NoMemory(); - return NULL; + return -1; } kwnames = PyTuple_New(nkwargs); if (kwnames == NULL) { PyMem_Free(stack); - return NULL; + return -1; } /* Copy position arguments (borrowed references) */ @@ -2472,8 +2473,9 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs, i++; } + *p_stack = stack; *p_kwnames = kwnames; - return stack; + return 0; } PyObject * diff --git a/Objects/methodobject.c b/Objects/methodobject.c index 1e9ad0d..7bff6a0 100644 --- a/Objects/methodobject.c +++ b/Objects/methodobject.c @@ -240,8 +240,8 @@ _PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs, PyObject *kwnames; _PyCFunctionFast fastmeth = (_PyCFunctionFast)meth; - stack = _PyStack_UnpackDict(args, nargs, kwargs, &kwnames, func_obj); - if (stack == NULL) { + if (_PyStack_UnpackDict(args, nargs, kwargs, + &stack, &kwnames, func_obj) < 0) { return NULL; } |