Python – Wrong number of arguments exception?

Question:

So I have a function like:

def my_code(arg1, *args):
    ....

And I want this function to only be able to take either 2 or 3 arguments (that means *args can only be 1 or 2 arguments). How do I throw an error message if the number of arguments is wrong? If I use a try/exception, is there a specific exception type for this?

Answers:

You can get the length of args with len as you would for any tuple.

def my_code(arg1, *args):
    if not 0 < len(args) < 3:
        raise TypeError('my_code() takes either 2 or 3 arguments ({} given)'
                        .format(len(args) + 1))

my_code(1) # TypeError: my_code() takes either 2 or 3 arguments (1 given)
my_code(1, 2) # pass
my_code(1, 2, 3) # pass
my_code(1, 2, 3, 4) # TypeError: my_code() takes either 2 or 3 arguments (4 given)
Answered By: Olivier Melançon

Your test is:

if len(args) not in (1,2):

though there are of course other ways to phrase that.

As for the exception, if you call a built-in function with the wrong number of arguments, you get a TypeError. If your application doesn’t justify creating your own subclass of Exception, then that is probably the way to go.

Answered By: BoarGules
def my_code(*args):
    if len(args) > 2:
        raise TypeError
    else:
        # code for your function
        pass

Basically *args is a tuple, and if you want a maximum number of arguments you can raise a TypeError.

Answered By: dejanualex

I’m facing a similar problem. I think the ValueError is better suited for this.

https://docs.python.org/3/library/exceptions.html#ValueError

exception ValueError: Raised when an operation or function receives an
argument that has the right type but an inappropriate value, and the
situation is not described by a more precise exception such as
IndexError.

I have a function that can receive two arguments, but should receive only either one of the two, but not both. If both are set, or none of them are set, it’s a problem. I use the ValueError exception for this.

Example code:

def parse_article(self, url: string = None, file: string = None) -> Article:
        if url == None and file == None:
            raise ValueError("Function was called without any arguments. Please set either url or file, but not both.")
        else:
            if url != None and file != None: raise ValueError(
                "Both url and file were given. Please give either url or file, but not both.")
        # Rest of the function.
        # Parse the article at the url or in the file, then return it.
Answered By: Tamas K