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: Inconsistent TypeError message on function calls with wrong number of arguments
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.2, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Alexander.Belopolsky, benjamin.peterson, chortos, ezio.melotti, gsakkis, hagen
Priority: normal Keywords: patch

Created on 2009-07-13 14:36 by hagen, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
6474.patch gsakkis, 2010-03-19 17:25
Messages (9)
msg90485 - (view) Author: Hagen Fürstenau (hagen) Date: 2009-07-13 14:36
I think the following error messages are inconsistent and confusing:

>>> def f(a, b): pass
...
>>> f(a=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes exactly 2 non-keyword positional arguments (1 given)
>>> f(b=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes exactly 2 non-keyword positional arguments (0 given)


Strictly speaking, no positional arguments are given in either case, so
it should say "(0 given)" in both cases. On the other hand, the given
keyword arguments are filled into the positional argument slots, so
stating something like "(1 missing)" or "(1 unspecified)" in both cases
seems to make more sense. Any opinions?
msg101334 - (view) Author: George Sakkis (gsakkis) Date: 2010-03-19 16:32
Which version are you running ? I don't get the "positional" word in 2.6 and 2.7a4.

In my opinion it should report how many required arguments are passed, regardless of how they are passed (positionally or by name). So in your example it should say "1 given" in both examples.
msg101337 - (view) Author: George Sakkis (gsakkis) Date: 2010-03-19 17:25
Attached patch for displaying the number of missing required arguments.
msg101454 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2010-03-21 20:21
Fixed in r79235.
msg136265 - (view) Author: Oleg Oshmyan (chortos) Date: 2011-05-19 00:34
$ python3.2
Python 3.2 (r32:88445, Mar 28 2011, 16:46:36) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from distutils.core import Extension
>>> Extension('myext', define_macros=[])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() takes at least 3 arguments (3 given)
>>> 
$ python3.1
Python 3.1.3 (r313:86834, Mar 28 2011, 16:44:43) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from distutils.core import Extension
>>> Extension('myext', define_macros=[])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() takes at least 3 non-keyword positional arguments (2 given)
>>> 

Looking at the patch committed in r79235, it changes the message to display the total number of arguments passed in and not just required ones. This specific change should be reversed since it produces messages like the one quoted above. (In case you were wondering, passing another optional keyword argument does indeed result in a complaint that at least 3 arguments are taken but 4 are passed.) For even better results, I would suggest rewording the message to make it clear that the requirement refers only to arguments without default values.
msg137859 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2011-06-07 17:11
Hopefully this situation was improved by #12265.
msg137864 - (view) Author: Oleg Oshmyan (chortos) Date: 2011-06-07 17:29
Unfortunately it was not.

>>> Extension('myext', define_macros=[])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() takes from 3 to 17 positional arguments but 3 were given

The issue is that the message tries to differentiate between positional and keyword arguments, while it really should differentiate between required and optional ones.
msg138951 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2011-06-24 14:41
Maybe #12356 then?
msg139029 - (view) Author: Oleg Oshmyan (chortos) Date: 2011-06-25 09:17
Yes, thank you. I am (yet) unable to create a misleading error message now. :-)
History
Date User Action Args
2022-04-11 14:56:50adminsetgithub: 50723
2011-06-25 09:17:47chortossetmessages: + msg139029
2011-06-24 14:41:24benjamin.petersonsetmessages: + msg138951
2011-06-07 17:29:34chortossetmessages: + msg137864
2011-06-07 17:11:51benjamin.petersonsetmessages: + msg137859
2011-05-19 00:34:37chortossetnosy: + chortos
messages: + msg136265
2010-03-21 20:21:24benjamin.petersonsetstatus: open -> closed

nosy: + benjamin.peterson
messages: + msg101454

resolution: fixed
2010-03-19 17:25:22gsakkissetfiles: + 6474.patch
keywords: + patch
messages: + msg101337
2010-03-19 16:32:00gsakkissetmessages: + msg101334
2010-03-19 05:09:02Alexander.Belopolskysetnosy: + Alexander.Belopolsky
2010-03-19 02:42:52ezio.melottisetsuperseder: Misleading reported number of given arguments on function call TypeError ->
2010-03-19 02:41:59ezio.melottisetnosy: + gsakkis, ezio.melotti
superseder: Misleading reported number of given arguments on function call TypeError
2009-07-13 14:36:43hagencreate