Skip to content

Commit 96c7c06

Browse files
SylvainDeserhiy-storchaka
authored andcommitted
bpo-20627: Fix error message when keyword arguments are used (#2115)
1 parent 8acb4cf commit 96c7c06

File tree

4 files changed

+48
-14
lines changed

4 files changed

+48
-14
lines changed

Lib/test/test_call.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import _testcapi
66
except ImportError:
77
_testcapi = None
8+
import struct
9+
import collections
810

911
# The test cases here cover several paths through the function calling
1012
# code. They depend on the METH_XXX flag that is used to define a C
@@ -160,6 +162,30 @@ def test_varargs5_kw(self):
160162
msg = r"^hasattr\(\) takes no keyword arguments$"
161163
self.assertRaisesRegex(TypeError, msg, hasattr, x=2)
162164

165+
def test_varargs6_kw(self):
166+
msg = r"^getattr\(\) takes no keyword arguments$"
167+
self.assertRaisesRegex(TypeError, msg, getattr, x=2)
168+
169+
def test_varargs7_kw(self):
170+
msg = r"^next\(\) takes no keyword arguments$"
171+
self.assertRaisesRegex(TypeError, msg, next, x=2)
172+
173+
def test_varargs8_kw(self):
174+
msg = r"^pack\(\) takes no keyword arguments$"
175+
self.assertRaisesRegex(TypeError, msg, struct.pack, x=2)
176+
177+
def test_varargs9_kw(self):
178+
msg = r"^pack_into\(\) takes no keyword arguments$"
179+
self.assertRaisesRegex(TypeError, msg, struct.pack_into, x=2)
180+
181+
def test_varargs10_kw(self):
182+
msg = r"^index\(\) takes no keyword arguments$"
183+
self.assertRaisesRegex(TypeError, msg, collections.deque().index, x=2)
184+
185+
def test_varargs11_kw(self):
186+
msg = r"^pack\(\) takes no keyword arguments$"
187+
self.assertRaisesRegex(TypeError, msg, struct.Struct.pack, struct.Struct(""), x=2)
188+
163189
def test_oldargs0_1(self):
164190
msg = r"keys\(\) takes no arguments \(1 given\)"
165191
self.assertRaisesRegex(TypeError, msg, {}.keys, 0)

Modules/_hashopenssl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -931,11 +931,11 @@ generate_hash_name_list(void)
931931
Py_buffer view = { 0 }; \
932932
PyObject *ret_obj; \
933933
\
934-
if (!_PyArg_ParseStack(args, nargs, "|O:" #NAME , &data_obj)) { \
934+
if (!_PyArg_NoStackKeywords(#NAME, kwnames)) { \
935935
return NULL; \
936936
} \
937937
\
938-
if (!_PyArg_NoStackKeywords(#NAME, kwnames)) { \
938+
if (!_PyArg_ParseStack(args, nargs, "|O:" #NAME , &data_obj)) { \
939939
return NULL; \
940940
} \
941941
\

Modules/_struct.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,6 +1823,9 @@ s_pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
18231823
PyObject *result;
18241824

18251825
/* Validate arguments. */
1826+
if (!_PyArg_NoStackKeywords("pack", kwnames)) {
1827+
return NULL;
1828+
}
18261829
soself = (PyStructObject *)self;
18271830
assert(PyStruct_Check(self));
18281831
assert(soself->s_codes != NULL);
@@ -1832,9 +1835,6 @@ s_pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
18321835
"pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
18331836
return NULL;
18341837
}
1835-
if (!_PyArg_NoStackKeywords("pack", kwnames)) {
1836-
return NULL;
1837-
}
18381838

18391839
/* Allocate a new buffer */
18401840
result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size);
@@ -1866,6 +1866,9 @@ s_pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames
18661866
Py_ssize_t offset;
18671867

18681868
/* Validate arguments. +1 is for the first arg as buffer. */
1869+
if (!_PyArg_NoStackKeywords("pack_into", kwnames)) {
1870+
return NULL;
1871+
}
18691872
soself = (PyStructObject *)self;
18701873
assert(PyStruct_Check(self));
18711874
assert(soself->s_codes != NULL);
@@ -1886,9 +1889,6 @@ s_pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames
18861889
}
18871890
return NULL;
18881891
}
1889-
if (!_PyArg_NoStackKeywords("pack_into", kwnames)) {
1890-
return NULL;
1891-
}
18921892

18931893
/* Extract a writable memory buffer from the first argument */
18941894
if (!PyArg_Parse(args[0], "w*", &buffer))
@@ -2131,6 +2131,10 @@ pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
21312131
PyObject *s_object = NULL;
21322132
PyObject *format, *result;
21332133

2134+
if (!_PyArg_NoStackKeywords("pack", kwnames)) {
2135+
return NULL;
2136+
}
2137+
21342138
if (nargs == 0) {
21352139
PyErr_SetString(PyExc_TypeError, "missing format argument");
21362140
return NULL;
@@ -2159,6 +2163,10 @@ pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
21592163
PyObject *s_object = NULL;
21602164
PyObject *format, *result;
21612165

2166+
if (!_PyArg_NoStackKeywords("pack_into", kwnames)) {
2167+
return NULL;
2168+
}
2169+
21622170
if (nargs == 0) {
21632171
PyErr_SetString(PyExc_TypeError, "missing format argument");
21642172
return NULL;

Python/bltinmodule.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -997,13 +997,13 @@ builtin_getattr(PyObject *self, PyObject **args, Py_ssize_t nargs,
997997
PyObject *v, *result, *dflt = NULL;
998998
PyObject *name;
999999

1000-
if (!_PyArg_UnpackStack(args, nargs, "getattr", 2, 3, &v, &name, &dflt))
1001-
return NULL;
1002-
10031000
if (!_PyArg_NoStackKeywords("getattr", kwnames)) {
10041001
return NULL;
10051002
}
10061003

1004+
if (!_PyArg_UnpackStack(args, nargs, "getattr", 2, 3, &v, &name, &dflt))
1005+
return NULL;
1006+
10071007
if (!PyUnicode_Check(name)) {
10081008
PyErr_SetString(PyExc_TypeError,
10091009
"getattr(): attribute name must be string");
@@ -1307,13 +1307,13 @@ builtin_next(PyObject *self, PyObject **args, Py_ssize_t nargs,
13071307
PyObject *it, *res;
13081308
PyObject *def = NULL;
13091309

1310-
if (!_PyArg_UnpackStack(args, nargs, "next", 1, 2, &it, &def))
1311-
return NULL;
1312-
13131310
if (!_PyArg_NoStackKeywords("next", kwnames)) {
13141311
return NULL;
13151312
}
13161313

1314+
if (!_PyArg_UnpackStack(args, nargs, "next", 1, 2, &it, &def))
1315+
return NULL;
1316+
13171317
if (!PyIter_Check(it)) {
13181318
PyErr_Format(PyExc_TypeError,
13191319
"'%.200s' object is not an iterator",

0 commit comments

Comments
 (0)