changeset: 103706:2558bc4a4ebf user: Victor Stinner date: Mon Sep 12 13:37:07 2016 +0200 files: Include/abstract.h Objects/abstract.c Objects/methodobject.c Python/ceval.c description: Document kwnames in _PyObject_FastCallKeywords() and _PyStack_AsDict() Issue #27213. diff -r e372c0ad32ce -r 2558bc4a4ebf Include/abstract.h --- a/Include/abstract.h Mon Sep 12 13:30:02 2016 +0200 +++ b/Include/abstract.h Mon Sep 12 13:37:07 2016 +0200 @@ -273,6 +273,13 @@ PyObject **stack, Py_ssize_t nargs); + /* Convert keyword arguments from the (stack, kwnames) format to a Python + dictionary. + + kwnames must only contains str strings, no subclass, and all keys must + be unique. kwnames is not checked, usually these checks are done before or later + calling _PyStack_AsDict(). For example, _PyArg_ParseStack() raises an + error if a key is not a string. */ PyAPI_FUNC(PyObject *) _PyStack_AsDict( PyObject **values, PyObject *kwnames); @@ -293,36 +300,39 @@ PyObject **kwnames, PyObject *func); - /* Call the callable object func with the "fast call" calling convention: - args is a C array for positional arguments (nargs is the number of - positional arguments), kwargs is a dictionary for keyword arguments. + /* Call the callable object func with the "fast call" calling convention: + args is a C array for positional arguments (nargs is the number of + positional arguments), kwargs is a dictionary for keyword arguments. - If nargs is equal to zero, args can be NULL. kwargs can be NULL. - nargs must be greater or equal to zero. + If nargs is equal to zero, args can be NULL. kwargs can be NULL. + nargs must be greater or equal to zero. - Return the result on success. Raise an exception on return NULL on - error. */ - PyAPI_FUNC(PyObject *) _PyObject_FastCallDict(PyObject *func, - PyObject **args, Py_ssize_t nargs, - PyObject *kwargs); + Return the result on success. Raise an exception on return NULL on + error. */ + PyAPI_FUNC(PyObject *) _PyObject_FastCallDict(PyObject *func, + PyObject **args, Py_ssize_t nargs, + PyObject *kwargs); - /* Call the callable object func with the "fast call" calling convention: - args is a C array for positional arguments followed by values of - keyword arguments. Keys of keyword arguments are stored as a tuple - of strings in kwnames. nargs is the number of positional parameters at - the beginning of stack. The size of kwnames gives the number of keyword - values in the stack after positional arguments. + /* Call the callable object func with the "fast call" calling convention: + args is a C array for positional arguments followed by values of + keyword arguments. Keys of keyword arguments are stored as a tuple + of strings in kwnames. nargs is the number of positional parameters at + the beginning of stack. The size of kwnames gives the number of keyword + values in the stack after positional arguments. + + kwnames must only contains str strings, no subclass, and all keys must + be unique. - If nargs is equal to zero and there is no keyword argument (kwnames is - NULL or its size is zero), args can be NULL. + If nargs is equal to zero and there is no keyword argument (kwnames is + NULL or its size is zero), args can be NULL. - Return the result on success. Raise an exception and return NULL on - error. */ - PyAPI_FUNC(PyObject *) _PyObject_FastCallKeywords - (PyObject *func, - PyObject **args, - Py_ssize_t nargs, - PyObject *kwnames); + Return the result on success. Raise an exception and return NULL on + error. */ + PyAPI_FUNC(PyObject *) _PyObject_FastCallKeywords + (PyObject *func, + PyObject **args, + Py_ssize_t nargs, + PyObject *kwnames); #define _PyObject_FastCall(func, args, nargs) \ _PyObject_FastCallDict((func), (args), (nargs), NULL) diff -r e372c0ad32ce -r 2558bc4a4ebf Objects/abstract.c --- a/Objects/abstract.c Mon Sep 12 13:30:02 2016 +0200 +++ b/Objects/abstract.c Mon Sep 12 13:37:07 2016 +0200 @@ -2457,6 +2457,9 @@ assert(nargs >= 0); assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); assert((nargs == 0 && nkwargs == 0) || stack != NULL); + /* kwnames must only contains str strings, no subclass, and all keys must + be unique: these are implemented in Python/ceval.c and + _PyArg_ParseStack(). */ if (PyFunction_Check(func)) { return _PyFunction_FastCallKeywords(func, stack, nargs, kwnames); diff -r e372c0ad32ce -r 2558bc4a4ebf Objects/methodobject.c --- a/Objects/methodobject.c Mon Sep 12 13:30:02 2016 +0200 +++ b/Objects/methodobject.c Mon Sep 12 13:37:07 2016 +0200 @@ -276,6 +276,11 @@ Py_ssize_t nkwargs; assert(PyCFunction_Check(func)); + assert(nargs >= 0); + assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); + assert((nargs == 0 && nkwargs == 0) || stack != NULL); + /* kwnames must only contains str strings, no subclass, and all keys must + be unique */ nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); if (nkwargs > 0) { diff -r e372c0ad32ce -r 2558bc4a4ebf Python/ceval.c --- a/Python/ceval.c Mon Sep 12 13:30:02 2016 +0200 +++ b/Python/ceval.c Mon Sep 12 13:37:07 2016 +0200 @@ -4863,7 +4863,12 @@ Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); Py_ssize_t nd; + assert(PyFunction_Check(func)); + assert(nargs >= 0); + assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); assert((nargs == 0 && nkwargs == 0) || stack != NULL); + /* kwnames must only contains str strings, no subclass, and all keys must + be unique */ PCALL(PCALL_FUNCTION); PCALL(PCALL_FAST_FUNCTION);