diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2017-06-06 15:45:22 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-06 15:45:22 (GMT) |
commit | 5eb788bf7f54a8e04429e18fc332db858edd64b6 (patch) | |
tree | ff7ea360d2765c1ec18ad02fcfc1de473a1d7b65 /Objects | |
parent | 5cefb6cfdd089d237ba6724bb5311ee4f04be59f (diff) | |
download | cpython-5eb788bf7f54a8e04429e18fc332db858edd64b6.zip cpython-5eb788bf7f54a8e04429e18fc332db858edd64b6.tar.gz cpython-5eb788bf7f54a8e04429e18fc332db858edd64b6.tar.bz2 |
bpo-30534: Fixed error messages when pass keyword arguments (#1901)
to functions implemented in C that don't support this.
Also unified error messages for functions that don't take positional or keyword
arguments.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/call.c | 49 | ||||
-rw-r--r-- | Objects/descrobject.c | 2 |
2 files changed, 26 insertions, 25 deletions
diff --git a/Objects/call.c b/Objects/call.c index 4c74eab..6c8a640 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -466,6 +466,10 @@ _PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, PyObject **arg switch (flags) { case METH_NOARGS: + if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { + goto no_keyword_error; + } + if (nargs != 0) { PyErr_Format(PyExc_TypeError, "%.200s() takes no arguments (%zd given)", @@ -473,14 +477,14 @@ _PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, PyObject **arg goto exit; } - if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { - goto no_keyword_error; - } - result = (*meth) (self, NULL); break; case METH_O: + if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { + goto no_keyword_error; + } + if (nargs != 1) { PyErr_Format(PyExc_TypeError, "%.200s() takes exactly one argument (%zd given)", @@ -488,16 +492,11 @@ _PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, PyObject **arg goto exit; } - if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { - goto no_keyword_error; - } - result = (*meth) (self, args[0]); break; case METH_VARARGS: - if (!(flags & METH_KEYWORDS) - && kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { + if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { goto no_keyword_error; } /* fall through next case */ @@ -592,7 +591,7 @@ _PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self, PyObject * PyCFunction meth = method->ml_meth; int flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST); - Py_ssize_t nkwargs = kwnames == NULL ? 0 : PyTuple_Size(kwnames); + Py_ssize_t nkwargs = kwnames == NULL ? 0 : PyTuple_GET_SIZE(kwnames); PyObject *result = NULL; if (Py_EnterRecursiveCall(" while calling a Python object")) { @@ -602,6 +601,10 @@ _PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self, PyObject * switch (flags) { case METH_NOARGS: + if (nkwargs) { + goto no_keyword_error; + } + if (nargs != 0) { PyErr_Format(PyExc_TypeError, "%.200s() takes no arguments (%zd given)", @@ -609,14 +612,14 @@ _PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self, PyObject * goto exit; } - if (nkwargs) { - goto no_keyword_error; - } - result = (*meth) (self, NULL); break; case METH_O: + if (nkwargs) { + goto no_keyword_error; + } + if (nargs != 1) { PyErr_Format(PyExc_TypeError, "%.200s() takes exactly one argument (%zd given)", @@ -624,10 +627,6 @@ _PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self, PyObject * goto exit; } - if (nkwargs) { - goto no_keyword_error; - } - result = (*meth) (self, args[0]); break; @@ -637,16 +636,17 @@ _PyMethodDef_RawFastCallKeywords(PyMethodDef *method, PyObject *self, PyObject * break; case METH_VARARGS: + if (nkwargs) { + goto no_keyword_error; + } + /* fall through next case */ + case METH_VARARGS | METH_KEYWORDS: { /* Slow-path: create a temporary tuple for positional arguments and a temporary dict for keyword arguments */ PyObject *argtuple; - if (!(flags & METH_KEYWORDS) && nkwargs) { - goto no_keyword_error; - } - argtuple = _PyStack_AsTuple(args, nargs); if (argtuple == NULL) { goto exit; @@ -717,6 +717,7 @@ 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); @@ -732,7 +733,7 @@ cfunction_call_varargs(PyObject *func, PyObject *args, PyObject *kwargs) Py_LeaveRecursiveCall(); } else { - if (kwargs != NULL && PyDict_Size(kwargs) != 0) { + 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; diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 1d11605..c20ca9b 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -1176,7 +1176,7 @@ wrapper_call(wrapperobject *wp, PyObject *args, PyObject *kwds) if (kwds != NULL && (!PyDict_Check(kwds) || PyDict_GET_SIZE(kwds) != 0)) { PyErr_Format(PyExc_TypeError, - "wrapper %s doesn't take keyword arguments", + "wrapper %s() takes no keyword arguments", wp->descr->d_base->name); return NULL; } |