TypeError: got multiple values for argument

This happens when a keyword argument is specified that overwrites a positional argument. For example, let's imagine a function that draws a colored box. The function selects the color to be used and delegates the drawing of the box to another function, relaying all extra arguments.

def color_box(color, *args, **kwargs):
    painter.select_color(color)
    painter.draw_box(*args, **kwargs)

Then the call

color_box("blellow", color="green", height=20, width=30)

will fail because two values are assigned to color: "blellow" as positional and "green" as keyword. (painter.draw_box is supposed to accept the height and width arguments).

This is easy to see in the example, but of course if one mixes up the arguments at call, it may not be easy to debug:

# misplaced height and width
color_box(20, 30, color="green")

Here, color is assigned 20, then args=[30] and color is again assigned "green".


I had the same problem that is really easy to make, but took me a while to see through.

I had copied the declaration to where I was using it and had left the 'self' argument there, but it took me ages to realise that.

I had

self.myFunction(self, a, b, c='123')

but it should have been

self.myFunction(a, b, c='123')

This also happens if you forget selfdeclaration inside class methods.

Example:

class Example():
    def is_overlapping(x1, x2, y1, y2):
        # Thanks to https://stackoverflow.com/a/12888920/940592
        return max(x1, y1) <= min(x2, y2)

Fails calling it like self.is_overlapping(x1=2, x2=4, y1=3, y2=5) with:

{TypeError} is_overlapping() got multiple values for argument 'x1'

WORKS:

class Example():
    def is_overlapping(self, x1, x2, y1, y2):
        # Thanks to https://stackoverflow.com/a/12888920/940592
        return max(x1, y1) <= min(x2, y2)

This exception also will be raised whenever a function has been called with the combination of keyword arguments and args, kwargs

Example:

def function(a, b, c, *args, **kwargs):
    print(f"a: {a}, b: {b}, c: {c}, args: {args}, kwargs: {kwargs}")

function(a=1, b=2, c=3, *(4,))

And it'll raise:

TypeError                                 Traceback (most recent call last)
<ipython-input-4-1dcb84605fe5> in <module>
----> 1 function(a=1, b=2, c=3, *(4,))

TypeError: function() got multiple values for argument 'a'

And Also it'll become more complicated, whenever you misuse it in the inheritance. so be careful we this stuff!

1- Calling a function with keyword arguments and args:

class A:
    def __init__(self, a, b, *args, **kwargs):
        self.a = a
        self.b = b
    
class B(A):
    def __init__(self, *args, **kwargs):

        a = 1
        b = 2
        super(B, self).__init__(a=a, b=b, *args, **kwargs)

B(3, c=2)

Exception:

TypeError                                 Traceback (most recent call last)
<ipython-input-5-17e0c66a5a95> in <module>
     11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
---> 13 B(3, c=2)

<ipython-input-5-17e0c66a5a95> in __init__(self, *args, **kwargs)
      9         a = 1
     10         b = 2
---> 11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
     13 B(3, c=2)

TypeError: __init__() got multiple values for argument 'a'

2- Calling a function with keyword arguments and kwargs which it contains keyword arguments too:

class A:
    def __init__(self, a, b, *args, **kwargs):
        self.a = a
        self.b = b
    
class B(A):
    def __init__(self, *args, **kwargs):

        a = 1
        b = 2
        super(B, self).__init__(a=a, b=b, *args, **kwargs)

B(**{'a': 2})

Exception:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-c465f5581810> in <module>
     11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
---> 13 B(**{'a': 2})

<ipython-input-7-c465f5581810> in __init__(self, *args, **kwargs)
      9         a = 1
     10         b = 2
---> 11         super(B, self).__init__(a=a, b=b, *args, **kwargs)
     12 
     13 B(**{'a': 2})

TypeError: __init__() got multiple values for keyword argument 'a'

Simply put you can't do the following:

class C(object):
    def x(self, y, **kwargs):
        # Which y to use, kwargs or declaration? 
        pass

c = C()
y = "Arbitrary value"
kwargs["y"] = "Arbitrary value"
c.x(y, **kwargs) # FAILS

Because you pass the variable 'y' into the function twice: once as kwargs and once as function declaration.