summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-06-06 15:45:22 (GMT)
committerGitHub <noreply@github.com>2017-06-06 15:45:22 (GMT)
commit5eb788bf7f54a8e04429e18fc332db858edd64b6 (patch)
treeff7ea360d2765c1ec18ad02fcfc1de473a1d7b65 /Objects
parent5cefb6cfdd089d237ba6724bb5311ee4f04be59f (diff)
downloadcpython-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.c49
-rw-r--r--Objects/descrobject.c2
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;
}