This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add suggestion about keyword arguments to this error message: "builtins.TypeError: my_func() takes 1 positional argument but 2 were given"
Type: enhancement Stage: needs patch
Components: Interpreter Core Versions: Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: cool-RR, emptysquare, r.david.murray, serhiy.storchaka, terry.reedy, ztane
Priority: low Keywords: patch

Created on 2014-10-16 10:33 by cool-RR, last changed 2022-04-11 14:58 by admin.

Files
File name Uploaded Description Edit
issue22652.patch emptysquare, 2015-04-13 16:48 review
Messages (10)
msg229521 - (view) Author: Ram Rachum (cool-RR) * Date: 2014-10-16 10:33
When programming, I just got this exception:

    builtins.TypeError: my_func() takes 1 positional argument but 2 were given

After a couple of minutes of investigation I figured out that the problem is that the function has a `*` in its signature, so arguments must be specified as keyword arguments, not positional arguments.

It would be nice if the exception message would include some text to suggest that, like:

    builtins.TypeError: my_func() takes 1 positional argument but 2 were given. If you were trying to use the keyword-only argument foo, please specify it as foo=value.

It's a little verbose and specific, but maybe it'll help people figure out this problem, especially newbies. We can have logic to show this message only if there are keyword-only arguments.
msg229522 - (view) Author: Ram Rachum (cool-RR) * Date: 2014-10-16 10:34
(I should note that I see this suggestion as low-priority, because it's very specific, so I'll completely understand if it's deemed to not be worth the added complexity.)
msg240541 - (view) Author: Antti Haapala (ztane) * Date: 2015-04-12 05:13
Would it be enough to just have the message say "takes 1 positional argument and keyword-only arguments but 2 positional arguments were given"? And this should of course for **kwargs too.
msg240553 - (view) Author: Ram Rachum (cool-RR) * Date: 2015-04-12 11:36
ztane: I don't think so. You're taking attention away from the "and keyword-only arguments", where in fact this is the piece of information that's likely to save the user the most time, so therefore it should get more attention.
msg240558 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-04-12 14:23
These messages are generated generically, and just because the proble you hit was this one, doesn't someone else won't hit it for a different reason and have other requirements.  (Note that these messages are *way* better than they used to be, thanks to Benjanmi Peterson's work).

The suggestion of adding that the function takes keyword only argumentgs seems reasonable to me, though I'd have to look at Benjamin's code to make sure it makes sense (I thought it already mentioned what argments/types the function took).  As you say, it is low priority.
msg240655 - (view) Author: A. Jesse Jiryu Davis (emptysquare) * Date: 2015-04-13 16:48
Attached patch adds "and N keyword-only argument(s)" to the TypeError message if a function takes keyword-only arguments and the wrong number of positional arguments is provided.
msg368878 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-05-14 23:28
Serhiy, I am nosying you because you have worked on argument issues in the last year.

Minimal example: def f(a, *, b): pass.  In 3.9.0a6,

>>> f(1,2) # ... Same as 5 years ago.
  TypeError: f() takes 1 positional argument but 2 were given

My first inclination was that this is sufficient information.  But ...

>>> f(1,2,b=3) # ...
  TypeError: f() takes 1 positional argument but 2 positional arguments (and 1 keyword-only argument) were given

The simple message is equally sufficiant here, but more is given, and it seems strange to not then give the equivalent for for 'takes'.  So the patch to add more seems plausible (but I am not one to carefully review C code).

Jesse, if you still want your patch, possibly updated, considered, please make a PR.

We now also have positional-only arguments, and I am not sure how that affects my view on this issue.
msg368880 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2020-05-14 23:30
Also, python-ideas list is a good place to get more opinions (too many sometimes) on an enhancement proposal.
msg368940 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2020-05-15 13:06
First, the code for checking arguments was significantly changed in recent versions. So if we are going to make these changes the patch should be not just rebased, but rewritten from zero.

Second, the error messages for wrong number of positional arguments are more diverse.

>>> def func(a, b=1): pass
... 
>>> func()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func() missing 1 required positional argument: 'a'
>>> func(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func() takes from 1 to 2 positional arguments but 3 were given

It differs when you pass less positional arguments than expected, and when there are optional positional parameters.

Third, when you pass incorrect number of keyword arguments, you get error either about missed keyword arguments (they names, not count), or about an unexpected keyword argument (with its name).

Forth, if you change error messages for Python implemented functions, don't forget about functions implemented in C. Those which use PyArg_ParseTupleAndKeywords (and variants), those which use Argument Clinic, and special cases like print(), sorted(), max().

Personally I think that the current error message is correct and complete. But if you want to improve it, remember that additional information should be correct, useful and consistent across different types of functions. Also, too verbose error message can have negative effect on comprehension. It should provide information necessary to identify the source of the error and do not distract from it.
msg368951 - (view) Author: A. Jesse Jiryu Davis (emptysquare) * Date: 2020-05-15 15:07
If the patch requires a rewrite and its value is uncertain then I'll excuse myself from this issue.
History
Date User Action Args
2022-04-11 14:58:09adminsetgithub: 66842
2020-05-15 15:07:20emptysquaresetnosy: terry.reedy, r.david.murray, cool-RR, serhiy.storchaka, ztane, emptysquare
messages: + msg368951
2020-05-15 13:06:23serhiy.storchakasetmessages: + msg368940
2020-05-14 23:30:26terry.reedysetmessages: + msg368880
2020-05-14 23:29:00terry.reedysetnosy: + terry.reedy, serhiy.storchaka

messages: + msg368878
versions: + Python 3.9, - Python 3.5
2015-04-13 16:48:44emptysquaresetfiles: + issue22652.patch

nosy: + emptysquare
messages: + msg240655

keywords: + patch
2015-04-12 14:23:56r.david.murraysetnosy: + r.david.murray
messages: + msg240558
2015-04-12 11:36:58cool-RRsetmessages: + msg240553
2015-04-12 05:13:46ztanesetnosy: + ztane
messages: + msg240541
2014-11-18 10:44:46serhiy.storchakasettype: enhancement
stage: needs patch
2014-10-16 14:32:30benjamin.petersonsetpriority: normal -> low
2014-10-16 10:34:37cool-RRsetmessages: + msg229522
2014-10-16 10:33:37cool-RRcreate