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: f(a=1, *args) should be a SyntaxError
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: BTaskaya, iritkatriel, metaxm, pablogsal, serhiy.storchaka
Priority: normal Keywords:

Created on 2018-10-03 08:01 by metaxm, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (5)
msg326945 - (view) Author: metaxm (metaxm) Date: 2018-10-03 08:01
>>> def f(a, b, c):
...     pass
>>> f(a=1, 2, 3)
SyntaxError: positional argument follows keyword argument
>>> f(a=1, *(2, 3))
TypeError: f() got multiple values for argument 'a'


f(a=1, 2, 3) will cause a SyntaxError, but f(a=1, *(2, 3)) will cause a TypeError. This makes me feel confused.

As keyword arguments must follow positional arguments, I suppose a SyntaxError rather than a TypeError should be reported if a variadic argument follows keyword arguments. Would you kindly explain why the CPython takes different actions for these two cases?
msg326951 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-10-03 09:11
See the thread "Order of positional and keyword arguments" on the Python-Dev mailing lists at 2018-04-26:

https://mail.python.org/pipermail/python-dev/2018-April/153157.html
msg399699 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-08-16 22:55
Reproduced in 3.11:

>>> f(a=1, 2, 3)
  File "<stdin>", line 1
    f(a=1, 2, 3)
               ^
SyntaxError: positional argument follows keyword argument
>>> f(a=1, *(2, 3))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() got multiple values for argument 'a'
>>>
msg399701 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-08-16 23:05
This is not a bug, check the thread that Serhiy attached. The grammar is, in principle, correct. For instance, you can do:

def f(a,b,c):

    pass
def wrapper(*args, **kw):
    return f(c=1, *args, **kw)

wrapper(2,b=2)

And you don't want that to be a syntax error.
msg399702 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2021-08-16 23:07
Also, just to make it clear: changing this would be backwards incompatible, so if someone is interested, a bigger discussion is needed (starting with python-ideas/python-dev).
History
Date User Action Args
2022-04-11 14:59:06adminsetgithub: 79063
2021-08-16 23:07:27pablogsalsetmessages: + msg399702
2021-08-16 23:05:57pablogsalsetstatus: open -> closed
stage: resolved
2021-08-16 23:05:52pablogsalsetresolution: not a bug
messages: + msg399701
2021-08-16 22:55:50iritkatrielsetnosy: + iritkatriel

messages: + msg399699
versions: + Python 3.9, Python 3.10, Python 3.11, - Python 3.6, Python 3.7, Python 3.8
2020-03-16 02:13:32BTaskayasetnosy: + BTaskaya
2018-10-13 12:47:46pablogsalsetnosy: + pablogsal
2018-10-03 14:52:27gvanrossumsetnosy: - gvanrossum
2018-10-03 09:11:21serhiy.storchakasetnosy: + serhiy.storchaka, gvanrossum
messages: + msg326951
2018-10-03 08:01:12metaxmcreate