TypeError: function() takes from 1 to 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 from 1 to X positional arguments but Y were given
__init__
method:
... class_instance = MyClass(<some arguments here>) TypeError : MyClass.__init__() takes from 1 to X positional arguments but Y were given
Other methods of the class:
... class_instance.method(<some arguments here>) TypeError: MyClass.method() takes from 1 to X positional arguments but Y were given
What does the error message mean?
This error is common for functions whose parameters have default values. When there are defaults, there is no need to pass all the arguments to the function. Therefore, the error message indicates the range of the number of arguments, not a specific number.
There are two typical cases when this TypeError
occurs:
In the first case, you passed too many arguments to the function. The solution in this case is to make sure the number of arguments matches the number of function parameters.
In the second case, part of the function arguments must be only keyword arguments. Such arguments are passed to the function in the form parameter=value
.
Cases Where There Are More Positional Arguments Than Necessary
In the following examples, when we call a function, we pass more positional arguments to it than we should.
An example with a function
Here it is obvious that the extra argument leads to an error.
def function(param1, param2=True): pass function("value", False, "excess") # TypeError: function() takes from 1 to 2 positional arguments but 3 were given
Examples with classes
class A: def __init__(self, param2, param3=True): pass a = A("value", False, "excess") # TypeError: A.__init__() takes from 2 to 3 positional arguments but 4 were given
Let's count our parameters and arguments: self
- class instance, param2
- "value"
, param3
- True
or False
by choice, ? - "excess"
.
"excess"
is the fourth positional argument, which should not be here. This argument has no matching parameter.
Cases With Keyword Arguments
The function may accept arguments only in the form of a parameter=value
pair. This can be done in two ways. A function signature may contain an asterisk (*) and/or **kwargs
.
Examples with a function
In the following example, the second argument (False
) is not redundant. You just need to pass it correctly to the function.
def function(param1=None, *, param2=True): pass function("value", False) # TypeError: function() takes from 0 to 1 positional arguments but 2 were given
This 1 positional argument in the error message is param1
. Since param1
has a default value, the number of positional arguments passed to the function can be 0.
The function takes a maximum of 1 positional argument, the second must be a keyword argument. All arguments that match parameters specified after an asterisk (*) must be keyword arguments.
Should be:
function("value", param2=False)
The next example shows a case where arbitrary keyword arguments can be provided (**kwargs
).
def function(param1="value", **kwargs): pass function("other value", 10) # TypeError: function() takes from 0 to 1 positional arguments but 2 were given
As in the previous example, the positional argument here can only be param1
. Except for the first argument, all arguments must be keyword arguments in this example.
function("other value", param2=10)
Examples with a class
An error can occur when a class method takes 1 to X positional arguments, all other arguments are keyword arguments.
class A: def __init__(self, param2="value", *, param3=True): pass a = A("other value", False) TypeError: A.__init__() takes from 1 to 2 positional arguments but 3 were given
self
). The second positional argument here is param2
. There must be one keyword argument, param3=False
. All arguments that match parameters specified after an asterisk (*) must be keyword arguments.Should be:
a = A("other value", param3=False)
**kwargs
can also be used in class methods.
class A: def __init__(self, param2=True, **kwargs): pass a = A(False, "value") TypeError: A.__init__() takes from 1 to 2 positional arguments but 3 were given
Except for the first two arguments, all arguments should be keyword arguments in this example. The instance of the class (the value for the self
parameter) is the very first argument. The second argument is False
. So param3
is the keyword argument.
a = A(False, param3="value")