TypeError : function() takes X positional arguments but Y were given
For more information about argument types and parameter types, see Argument Types in Python Functions, Parameter Types in Python Functions.
Explanation of the Error
This type of error can occur both in standalone functions and in class methods that are also functions.
Function:
... function(<some arguments here>) TypeError : function() takes X positional argument but Y were given
__init__
method:
... class_instance = MyClass(<some arguments here>) TypeError : MyClass.__init__() takes X positional argument but Y were given
Other methods of the class:
... class_instance.method(<some arguments here>) TypeError : MyClass.method() takes X positional argument but Y were given
What does the error message mean?
In short, this error message means that the arguments you are passing do not match the parameters of a function.
The error message contains a hint that the function accepts a certain number of arguments (X), but a different number of arguments (Y) was given when the function was called.
See this post if you have an error in the __init__
method and the error message is TypeError: __init__() takes 1 positional argument but X were given
or TypeError: MyClass.__init__() takes 1 positional argument but X were given
.
Inconsistent Arguments and Parameters
The number of arguments (values) passed to the function must match the number of parameters in the function signature.
def function(param1, param2): # <-- two parameters pass # two arguments passed - OK function("some value", "other value") # three arguments passed - this will throw a TypeError! function("some value", "other value", "excess") # TypeError: function() takes 2 positional arguments but 3 were given
The same goes for class methods.
class A: def __init__(self, param2): # <-- two parameters pass # two arguments passed - self and "value" - OK a = A("value") # three arguments passed - this will throw a TypeError! a = A("value", "excess") # TypeError: function() takes 2 positional arguments but 3 were given
A special feature of the class method is the presence of the mandatory parameter "self". Although we don't need to explicitly pass a value for this parameter, its value is still included in the number of positional arguments.
Functions may take no arguments at all.
def function(): # <-- no parameters pass # no arguments passed - OK function() # argument passed - this will throw a TypeError! function("excess argument") # TypeError: function() takes 0 positional arguments but 1 were given
Class methods take at least one argument: value for self
.
class A: def __init__(self): pass def do(self): # <-- one parameter pass # args: the current instance of the class a = A() # two arguments passed - this will throw a TypeError! # args: the current instance of the class and "excess argument" a.do("excess argument") # TypeError: A.do() takes 1 positional argument but 2 were given
Cases With Keyword Arguments
The error may occur when the function/method accepts only X positional arguments, all other arguments are keyword arguments.
A keyword argument means that the parameter must be associated with a value when the function is called. E.g., function(param=value)
.
The use of keyword arguments in a function can be made mandatory by adding special characters to the signature. We can use an asterisk (*) in the named parameter list or add **kwargs
to indicate that the function can take arbitrary keyword arguments.
Examples with functions
def function(param1, *, param2): # param2 is a keyword-only parameter pass # one positional argument and one keyword argument - OK function("some value", param2="other value")
def function(param1, **kwargs): pass # one positional argument and one keyword argument - OK function("some value", param2="other value")
Examples with classes
The same keyword arguments apply to class methods. The first positional argument is always an instance of the class (the value for the self
parameter). But we don't need to explicitly pass this to the methods. All parameters after the asterisks are keyword-only parameters. Therefore, we must use keyword arguments.
class A: def __init__(self, *, param2): pass def do(self, param2, *, param3): pass a = A(param2="value") a.do("some value", param3="other value")
**kwargs
can also be used in class methods.
class A: def __init__(self, **kwargs): pass def do(self, param2, **kwargs): pass a = A(param2="value") a.do("some value", param3="other value")