Issue 12265: revamp argument errors (original) (raw)
This patch completely rewrites errors given for positional error mismatches. The goal is to give more informative and correct errors.
Some examples:
def f(): pass ... f(1) Traceback (most recent call last): File "", line 1, in TypeError: f() takes 0 positional arguments but 1 was given f(1, kw=4) Traceback (most recent call last): File "", line 1, in TypeError: f() got an unexpected keyword argument 'kw' def f(a, b=2): pass ... f() Traceback (most recent call last): File "", line 1, in TypeError: f() takes from 1 to 2 positional arguments but 0 were given f(1, 2, 3) Traceback (most recent call last): File "", line 1, in TypeError: f() takes from 1 to 2 positional arguments but 3 were given def f(a, *b): pass ... f() Traceback (most recent call last): File "", line 1, in TypeError: f() takes at least 1 positional argument but 0 were given f(kw=4) Traceback (most recent call last): File "", line 1, in TypeError: f() got an unexpected keyword argument 'kw'
When keyword-only arguments come into play, things get a bit more complicated. When a positional argument error occurs, it's confusing to report only the positional arguments, but not completely relevant to report keyword-only arguments. I comprise by putting the keyword-only argument information in parenthesis. Tell me if you have a better idea.
def f(*, kw): pass ... f() Traceback (most recent call last): File "", line 1, in TypeError: f() requires keyword-only argument 'kw' f(1) Traceback (most recent call last): File "", line 1, in TypeError: f() takes 0 positional arguments but 1 was given f(3, kw=4) Traceback (most recent call last): File "", line 1, in TypeError: f() takes 0 positional arguments but 1 positional arguments (and 1 keyword-only argument) were given
Obviously the prototype can't be provided when it isn't known. But the pseudo-English text is trying to describe the prototype and is far less clear than the actual prototype. ie the developer communicated the prototype to Python in Python syntax, why not have Python do the same rather than use a different and very unfamiliar language. (Try using the Python documentation to work out what the word 'positional' means.)
As for looking it up in the source code, that is one of the harder things for newbies to do, and certainly very difficult for a lot of people. How would they know where the standard library source is on their system? Heck I don't even know where the source is for third party packages on my Ubuntu system as the last I looked they used convoluted sequences of version numbers, symbolic links and who knows what else. The popularity of eggs makes it even harder to look up.
That's why I said "their own source or pydoc...".
The language of the error message is trying to describe the error as the interpreter knows about it at the time the error is generated. That has a strong relationship to the prototype, but the two things are not the same.
IMO the added complexity of finding and displaying the prototype is not worth it. But it is Benjamin who was willing to tackle trying to fix the current problems with the error messages, so I'm happy to leave that decision up to him.