Invalid unpacking arguments

Question:

I was reading an online document explaining unpacking (*args and **kwargs). Getting confused by the following two asserts, not sure why the second function is invalid. Could anyone help me to understand the reason?

def f(x, y, z):
    return [x, y, z]

t = (3,)  
d = {"z": 4}
assert f(2, *t, **d) == [2, 3, 4]
assert f(x=2, *t, **d) == [2, 3, 4]  # TypeError: f() got multiple values for argument 'x'

Reference
https://caisbalderas.com/blog/python-function-unpacking-args-and-kwargs/


Note: This question differs from TypeError: got multiple values for argument because it requires additional knowledge of how argument unpacking works in Python.

Asked By: r0n9

||

Answers:

You are trying to place a positional argument after a keyword argument. The actual error message is confusing. I am honestly surprised placing tuple unpacking after a keyword is allowed.

It is the similar to doing:

f(x=2, 3, 4)

Which raises a SyntaxError.

I believe the difference is that the tuple unpacking is handled first and shifts keyword arguments to the right. So effectively, you have this equivalency:

f(x=2, *t, **d)

is that same as

f(*t, x=2, **d)

Which is why you are getting TypeError: f() got multiple values for argument 'x'

Answered By: James
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.