mirror of
https://github.com/python/cpython.git
synced 2025-08-31 05:58:33 +00:00
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.
This commit is contained in:
parent
5cefb6cfdd
commit
5eb788bf7f
5 changed files with 116 additions and 45 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue