STINNER Victor added the comment:
Example with a builtin function, abs(), which uses METH_O.
Before:
haypo@selma$ python3
Python 3.5.3 (default, Apr 24 2017, 13:32:13)
>>> abs(x=5)
TypeError: abs() takes no keyword arguments
After:
haypo@selma$ ./python
Python 3.7.0a0 (heads/master:85aba23, May 31 2017, 10:29:03)
>>> abs(x=5)
TypeError: abs() takes exactly one argument (0 given)
In Python 3.5, PyCFunction_Call() starts by checking keyword arguments:
if (flags == (METH_VARARGS | METH_KEYWORDS)) {
...
}
else {
if (kwds != NULL && PyDict_Size(kwds) != 0) {
PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
f->m_ml->ml_name);
return NULL;
}
switch (flags) {
case METH_NOARGS:
size = PyTuple_GET_SIZE(args);
if (size != 0) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes no arguments (%zd given)",
f->m_ml->ml_name, size);
return NULL;
}
...
In Python 3.7, _PyMethodDef_RawFastCallKeywords() first check positional
arguments:
switch (flags)
{
case METH_NOARGS:
if (nargs != 0) {
PyErr_Format(PyExc_TypeError,
"%.200s() takes no arguments (%zd given)",
method->ml_name, nargs);
goto exit;
}
if (nkwargs) {
goto no_keyword_error;
}
...
We can easily exchange the two checks, but IMHO we need an unit test (at least
decorated by @cpython_only) to avoid regressions in the future.
----------
nosy: +rhettinger
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue30534>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com