Skip to content

Commit bb4cabf

Browse files
committed
gh-137626: fix error messages of dict() and dict().update()
1 parent deb0020 commit bb4cabf

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

Lib/test/test_dict.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,23 @@ def test_constructor(self):
2828
self.assertEqual(dict(), {})
2929
self.assertIsNot(dict(), {})
3030

31+
def test_constructor_positional_argument_error_messages(self):
32+
with self.assertRaisesRegex(TypeError,
33+
r"dict expected at most 1 positional argument, got 2"):
34+
dict('John', 36)
35+
with self.assertRaisesRegex(TypeError,
36+
r"dict expected at most 1 positional argument, got 3"):
37+
dict('a', 'b', 'c')
38+
39+
def test_update_positional_argument_error_messages(self):
40+
d = {}
41+
with self.assertRaisesRegex(TypeError,
42+
r"update expected at most 1 positional argument, got 2"):
43+
d.update('John', 36)
44+
with self.assertRaisesRegex(TypeError,
45+
r"update expected at most 1 positional argument, got 3"):
46+
d.update('a', 'b', 'c')
47+
3148
def test_literal_constructor(self):
3249
# check literal constructor for different sized dicts
3350
# (to exercise the BUILD_MAP oparg).

Python/getargs.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2740,11 +2740,15 @@ _PyArg_CheckPositional(const char *name, Py_ssize_t nargs,
27402740
assert(min <= max);
27412741

27422742
if (nargs < min) {
2743-
if (name != NULL)
2743+
if (name != NULL) {
2744+
// Use "positional argument" for dict functions, "argument" for others
2745+
const char *arg_type = (strcmp(name, "dict") == 0 || strcmp(name, "update") == 0)
2746+
? "positional argument" : "argument";
27442747
PyErr_Format(
27452748
PyExc_TypeError,
2746-
"%.200s expected %s%zd argument%s, got %zd",
2747-
name, (min == max ? "" : "at least "), min, min == 1 ? "" : "s", nargs);
2749+
"%.200s expected %s%zd %s%s, got %zd",
2750+
name, (min == max ? "" : "at least "), min, arg_type, min == 1 ? "" : "s", nargs);
2751+
}
27482752
else
27492753
PyErr_Format(
27502754
PyExc_TypeError,
@@ -2759,11 +2763,15 @@ _PyArg_CheckPositional(const char *name, Py_ssize_t nargs,
27592763
}
27602764

27612765
if (nargs > max) {
2762-
if (name != NULL)
2766+
if (name != NULL) {
2767+
// Use "positional argument" for dict functions, "argument" for others
2768+
const char *arg_type = (strcmp(name, "dict") == 0 || strcmp(name, "update") == 0)
2769+
? "positional argument" : "argument";
27632770
PyErr_Format(
27642771
PyExc_TypeError,
2765-
"%.200s expected %s%zd argument%s, got %zd",
2766-
name, (min == max ? "" : "at most "), max, max == 1 ? "" : "s", nargs);
2772+
"%.200s expected %s%zd %s%s, got %zd",
2773+
name, (min == max ? "" : "at most "), max, arg_type, max == 1 ? "" : "s", nargs);
2774+
}
27672775
else
27682776
PyErr_Format(
27692777
PyExc_TypeError,

0 commit comments

Comments
 (0)