Search code examples
pythonpython-3.xkeyword-argument

Which exception should be raised on unknown keyword arguments?


In Python, which exception should be raised when an unknown keyword argument is passed to the function? Should it be SyntaxError? I saw that Python itself raises TypeError, but I am not sure why.

For example:

def add(**kwargs):
    a = kwargs.pop('a', 0.)
    b = kwargs.pop('b', 0.)

    if kwargs:
        # what to raise here?
        raise SyntaxError('Unknown keyword arguments: ' + list(kwargs.keys()))
        # or ? 
        # raise TypeError('Unknown keyword arguments: ' + list(kwargs.keys()))

    return a + b

Solution

  • The appropriate error for unexpected or missing arguments is TypeError.

    >>> def add(a, b=0.): ...
    >>> add(a=3, c=5)
    TypeError: add() got an unexpected keyword argument 'c'
    >>> add(1, 2, 3)
    TypeError: add() takes from 1 to 2 positional arguments but 3 were given
    >>> add()
    TypeError: add() missing 1 required positional argument: 'a'
    

    While the concrete type of a function is just function, Python semantically uses the common function type model in which the type of a function is its signature, i.e. Parameters -> Result. For example, the function

    def add(a, b): return a + b
    

    has the type (a: Any, b: Any) -> Any. As far as types are concerned, it is exchangeable with any other function of the same signature. This is codified by Python's optional static type support as well.

    Calling a function means supplying matching Parameters. This uses Python's rules for matching arguments to parameters, e.g. add(b=3, a=1) still matches add(a: Any, b: Any).

    A call with incompatible signature, e.g. add(1, 2, 3), means a function of different type is expected at the call site, e.g. (:Any, :Any, :Any) -> Any in this case. This means the type/signature of the call and the function do not match. Thus, TypeError is appropriate.