classification
Title: revamp argument errors
Type: enhancement Stage: resolved
Components: Interpreter Core Versions: Python 3.3
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Trundle, benjamin.peterson, chortos, ncoghlan, python-dev, r.david.murray, rogerbinns
Priority: normal Keywords: patch

Created on 2011-06-05 02:20 by benjamin.peterson, last changed 2011-06-07 21:05 by chortos. This issue is now closed.

Files
File name Uploaded Description Edit
argerror.patch benjamin.peterson, 2011-06-05 02:24 review
Messages (8)
msg137676 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2011-06-05 02:20
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 "<stdin>", line 1, in <module>
TypeError: f() takes 0 positional arguments but 1 was given
>>> f(1, kw=4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() got an unexpected keyword argument 'kw'
>>> def f(a, b=2): pass
... 
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes from 1 to 2 positional arguments but 0 were given
>>> f(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
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 "<stdin>", line 1, in <module>
TypeError: f() takes at least 1 positional argument but 0 were given
>>> f(kw=4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
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 "<stdin>", line 1, in <module>
TypeError: f() requires keyword-only argument 'kw'
>>> f(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes 0 positional arguments but 1 was given
>>> f(3, kw=4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes 0 positional arguments but 1 positional arguments (and 1 keyword-only argument) were given
msg137681 - (view) Author: Nick Coghlan (ncoghlan) * (Python committer) Date: 2011-06-05 04:01
Looks good in a desk review. Assuming the full test suite passes, +1 from me.
msg137712 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2011-06-05 20:15
Your parenthetical reads sensibly to me, I can't think of a clearer alternative.
msg137717 - (view) Author: Roger Binns (rogerbinns) Date: 2011-06-05 22:05
Is there any reason it doesn't show the function 'prototype' which is by far the most the useful piece of information and is also a form of documentation (plus fairly hard to work out).  Convoluted technospeak is far harder to understand.  Compare:

TypeError: f() takes from 1 to 2 positional arguments but 0 were given

versus:

TypeError: f(a, b=2) takes from 1 to 2 positional arguments but 0 were given
msg137718 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2011-06-05 23:01
-1 on adding the prototype (especially since I think it isn't always possible to do so).  In many cases it would make the message overlong, and the user can look up the prototype by looking at their source code or using pydoc or their IDE.  The error message should contain the information that isn't available by looking at the source code.
msg137723 - (view) Author: Roger Binns (rogerbinns) Date: 2011-06-06 00:42
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.
msg137725 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2011-06-06 02:06
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.
msg137728 - (view) Author: Roundup Robot (python-dev) Date: 2011-06-06 03:05
New changeset 44d46d74ef4f by Benjamin Peterson in branch 'default':
greatly improve argument parsing error messages (closes #12265)
http://hg.python.org/cpython/rev/44d46d74ef4f
History
Date User Action Args
2011-06-07 21:05:57chortossetnosy: + chortos
2011-06-06 03:05:09python-devsetstatus: open -> closed

nosy: + python-dev
messages: + msg137728

resolution: fixed
stage: patch review -> resolved
2011-06-06 02:06:48r.david.murraysetmessages: + msg137725
2011-06-06 00:42:11rogerbinnssetmessages: + msg137723
2011-06-05 23:01:54r.david.murraysetmessages: + msg137718
2011-06-05 22:05:15rogerbinnssetnosy: + rogerbinns
messages: + msg137717
2011-06-05 20:15:47r.david.murraysetnosy: + r.david.murray
messages: + msg137712
2011-06-05 11:56:22Trundlesetnosy: + Trundle
2011-06-05 04:01:16ncoghlansetnosy: + ncoghlan
messages: + msg137681
2011-06-05 02:24:12benjamin.petersonsetfiles: + argerror.patch
2011-06-05 02:24:02benjamin.petersonsetfiles: - argerror.patch
2011-06-05 02:20:43benjamin.petersoncreate