From e19eb6f4fa60270dbb0751f478d14af7eabaab65 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 5 Jun 2025 12:51:57 +0300 Subject: [PATCH] gh-133438: Fix the use of the terms "argument" and "parameter" in error messages for invalid function calls --- Lib/inspect.py | 8 ++++---- Lib/test/test_extcall.py | 12 ++++++------ Lib/test/test_inspect/test_inspect.py | 6 +++--- Lib/test/test_positional_only_arg.py | 6 +++--- .../2025-06-05-12-51-52.gh-issue-133438.-3S9y4.rst | 2 ++ Python/ceval.c | 4 ++-- 6 files changed, 20 insertions(+), 18 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-06-05-12-51-52.gh-issue-133438.-3S9y4.rst diff --git a/Lib/inspect.py b/Lib/inspect.py index 183e67fabf966e..e459a6bd899ed3 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -1391,7 +1391,7 @@ def _missing_arguments(f_name, argnames, pos, values): s = ", ".join(names) + tail raise TypeError("%s() missing %i required %s argument%s: %s" % (f_name, missing, - "positional" if pos else "keyword-only", + "positional" if pos else "keyword", "" if missing == 1 else "s", s)) def _too_many(f_name, args, kwonly, varargs, defcount, given, values): @@ -1408,7 +1408,7 @@ def _too_many(f_name, args, kwonly, varargs, defcount, given, values): sig = str(len(args)) kwonly_sig = "" if kwonly_given: - msg = " positional argument%s (and %d keyword-only argument%s)" + msg = " positional argument%s (and %d keyword argument%s)" kwonly_sig = (msg % ("s" if given != 1 else "", kwonly_given, "s" if kwonly_given != 1 else "")) raise TypeError("%s() takes %s positional argument%s but %d%s %s given" % @@ -3107,7 +3107,7 @@ def _bind(self, args, kwargs, *, partial=False): elif param.name in kwargs: if param.kind == _POSITIONAL_ONLY: if param.default is _empty: - msg = f'missing a required positional-only argument: {param.name!r}' + msg = f'missing a required positional argument: {param.name!r}' raise TypeError(msg) # Raise a TypeError once we are sure there is no # **kwargs param later. @@ -3130,7 +3130,7 @@ def _bind(self, args, kwargs, *, partial=False): break else: if param.kind == _KEYWORD_ONLY: - argtype = ' keyword-only' + argtype = ' keyword' else: argtype = '' msg = 'missing a required{argtype} argument: {arg!r}' diff --git a/Lib/test/test_extcall.py b/Lib/test/test_extcall.py index d9d85fe79af883..21fcac59d254d0 100644 --- a/Lib/test/test_extcall.py +++ b/Lib/test/test_extcall.py @@ -401,7 +401,7 @@ >>> s3(**md) Traceback (most recent call last): ... - TypeError: s3() missing 1 required keyword-only argument: 'n' + TypeError: s3() missing 1 required keyword argument: 'n' Another helper function @@ -487,17 +487,17 @@ >>> f(1, kw=3) Traceback (most recent call last): ... - TypeError: f() takes 0 positional arguments but 1 positional argument (and 1 keyword-only argument) were given + TypeError: f() takes 0 positional arguments but 1 positional argument (and 1 keyword argument) were given >>> def f(*, kw, b): pass >>> f(1, 2, 3, b=3, kw=3) Traceback (most recent call last): ... - TypeError: f() takes 0 positional arguments but 3 positional arguments (and 2 keyword-only arguments) were given + TypeError: f() takes 0 positional arguments but 3 positional arguments (and 2 keyword arguments) were given >>> def f(a, b=2, *, kw): pass >>> f(2, 3, 4, kw=4) Traceback (most recent call last): ... - TypeError: f() takes from 1 to 2 positional arguments but 3 positional arguments (and 1 keyword-only argument) were given + TypeError: f() takes from 1 to 2 positional arguments but 3 positional arguments (and 1 keyword argument) were given Too few and missing arguments: @@ -533,12 +533,12 @@ >>> f() Traceback (most recent call last): ... - TypeError: f() missing 1 required keyword-only argument: 'w' + TypeError: f() missing 1 required keyword argument: 'w' >>> def f(*, a, b, c, d, e): pass >>> f() Traceback (most recent call last): ... - TypeError: f() missing 5 required keyword-only arguments: 'a', 'b', 'c', 'd', and 'e' + TypeError: f() missing 5 required keyword arguments: 'a', 'b', 'c', 'd', and 'e' """ diff --git a/Lib/test/test_inspect/test_inspect.py b/Lib/test/test_inspect/test_inspect.py index e584fb417b9d54..68c851b7700e05 100644 --- a/Lib/test/test_inspect/test_inspect.py +++ b/Lib/test/test_inspect/test_inspect.py @@ -2243,7 +2243,7 @@ def test_errors(self): # kwonlydefaults and raises a wrong TypeError def f5(*, a): pass with self.assertRaisesRegex(TypeError, - 'missing 1 required keyword-only'): + 'missing 1 required keyword argument'): inspect.getcallargs(f5) @@ -5405,7 +5405,7 @@ def test(foo, *, bar): self.call(test, 1, bar=2, spam='ham') with self.assertRaisesRegex(TypeError, - "missing a required keyword-only " + "missing a required keyword " "argument: 'bar'"): self.call(test, 1) @@ -5462,7 +5462,7 @@ def test(a_po, b_po, c_po=3, /, foo=42, *, bar=50, **kwargs): self.assertEqual(self.call(test, 1, 2, c_po=4), (1, 2, 3, 42, 50, {'c_po': 4})) - with self.assertRaisesRegex(TypeError, "missing a required positional-only argument: 'a_po'"): + with self.assertRaisesRegex(TypeError, "missing a required positional argument: 'a_po'"): self.call(test, a_po=1, b_po=2) def without_var_kwargs(c_po=3, d_po=4, /): diff --git a/Lib/test/test_positional_only_arg.py b/Lib/test/test_positional_only_arg.py index e412cb1d58d5db..7fac5472fb3994 100644 --- a/Lib/test/test_positional_only_arg.py +++ b/Lib/test/test_positional_only_arg.py @@ -166,9 +166,9 @@ def test_positional_only_and_kwonlyargs_invalid_calls(self): def f(a, b, /, c, *, d, e): pass f(1, 2, 3, d=1, e=2) # does not raise - with self.assertRaisesRegex(TypeError, r"missing 1 required keyword-only argument: 'd'"): + with self.assertRaisesRegex(TypeError, r"missing 1 required keyword argument: 'd'"): f(1, 2, 3, e=2) - with self.assertRaisesRegex(TypeError, r"missing 2 required keyword-only arguments: 'd' and 'e'"): + with self.assertRaisesRegex(TypeError, r"missing 2 required keyword arguments: 'd' and 'e'"): f(1, 2, 3) with self.assertRaisesRegex(TypeError, r"f\(\) missing 1 required positional argument: 'c'"): f(1, 2) @@ -177,7 +177,7 @@ def f(a, b, /, c, *, d, e): with self.assertRaisesRegex(TypeError, r" missing 3 required positional arguments: 'a', 'b', and 'c'"): f() with self.assertRaisesRegex(TypeError, r"f\(\) takes 3 positional arguments but 6 positional arguments " - r"\(and 2 keyword-only arguments\) were given"): + r"\(and 2 keyword arguments\) were given"): f(1, 2, 3, 4, 5, 6, d=7, e=8) with self.assertRaisesRegex(TypeError, r"f\(\) got an unexpected keyword argument 'f'"): f(1, 2, 3, d=1, e=4, f=56) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-06-05-12-51-52.gh-issue-133438.-3S9y4.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-05-12-51-52.gh-issue-133438.-3S9y4.rst new file mode 100644 index 00000000000000..b950c30264879e --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-05-12-51-52.gh-issue-133438.-3S9y4.rst @@ -0,0 +1,2 @@ +Fix the use of the terms "argument" and "parameter" in error messages for +invalid function calls. diff --git a/Python/ceval.c b/Python/ceval.c index 7aec196cb85704..eb5cd28ee050db 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1318,7 +1318,7 @@ missing_arguments(PyThreadState *tstate, PyCodeObject *co, Py_ssize_t i, j = 0; Py_ssize_t start, end; int positional = (defcount != -1); - const char *kind = positional ? "positional" : "keyword-only"; + const char *kind = positional ? "positional" : "keyword"; PyObject *missing_names; /* Compute the names of the arguments that are missing. */ @@ -1380,7 +1380,7 @@ too_many_positional(PyThreadState *tstate, PyCodeObject *co, if (sig == NULL) return; if (kwonly_given) { - const char *format = " positional argument%s (and %zd keyword-only argument%s)"; + const char *format = " positional argument%s (and %zd keyword argument%s)"; kwonly_sig = PyUnicode_FromFormat(format, given != 1 ? "s" : "", kwonly_given,