Skip to content

gh-133438: Fix the use of the terms "argument" and "parameter" in error messages for invalid function calls #135172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Lib/inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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" %
Expand Down Expand Up @@ -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.
Expand All @@ -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}'
Expand Down
12 changes: 6 additions & 6 deletions Lib/test/test_extcall.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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:

Expand Down Expand Up @@ -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'

"""

Expand Down
6 changes: 3 additions & 3 deletions Lib/test/test_inspect/test_inspect.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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, /):
Expand Down
6 changes: 3 additions & 3 deletions Lib/test/test_positional_only_arg.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix the use of the terms "argument" and "parameter" in error messages for
invalid function calls.
4 changes: 2 additions & 2 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not keeping keyword-only here, it's correct, no?

>>> def f(*, x): pass
... 
>>> f()
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    f()
    ~^^
TypeError: f() missing 1 required keyword-only argument: 'x'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Keyword-only" is a qualifier of a parameter. Arguments can be "positional" or "keyword".

PyObject *missing_names;

/* Compute the names of the arguments that are missing. */
Expand Down Expand Up @@ -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,
Expand Down
Loading