Editor

Type-Checked Arguments

#343 · Functions · Intermediate · 90 XP · about 20 min

Type annotations like def greet(name: str, times: int) are notes for the reader: Python itself does not check them. Write a decorator validate(func) that does.

When the decorated function is called:

  • Match the arguments to the parameters of func the way Python does (positional and keyword arguments both count).
  • For every parameter that received an argument and has an annotation, check that the value is an instance of the annotation, with isinstance (so True passes as an int).
  • If a value fails, raise TypeError with the message <parameter> must be <expected>, got <actual>, where <expected> is the annotation's __name__ and <actual> is the __name__ of the value's type. If several values fail, report the first one in the order the parameters are defined. In that case func is not called.
  • Otherwise, call func and return its result.

Parameters without an annotation accept anything, default values are not checked, and the return annotation is ignored.

Examples

@validate
def repeat(word: str, times: int = 2, sep=' '):
    return sep.join([word] * times)

repeat('hi', 3)            # returns 'hi hi hi'
repeat('hi', sep='-')      # returns 'hi-hi'
repeat('hi', times='3')    # raises TypeError('times must be int, got str')
repeat(5)                  # raises TypeError('word must be str, got int')

Constraints

  • Every annotation in the tests is a class, such as int, str, list or a class of your own
  • Functions have ordinary and keyword-only parameters, never *args or **kwargs
  • Calls always give a valid number of arguments

Fastest solvers

Leaderboard

First solves only, ranked by stars and then time.