Python >=3.5: Checking type annotation at runtime

Python >=3.5: Checking type annotation at runtime

I was looking for something similar and found the library typeguard. This can automatically do runtime type checks wherever you want. Checking types directly as in the question is also supported. From the docs,

from typeguard import check_type

# Raises TypeError if theres a problem
check_type(variablename, [1234], List[int])

There is no such function in the typing module, and most likely there wont ever be.

Checking whether an object is an instance of a class – which only means this object was created by the class constructor – is a simple matter of testing some tagging.

However, checking whether an object is an instance of a type is not necessarily decidable:

assert isinstance(foo, Callable[[int], str]), Wrong type

Although it is easy to inspect the typing annotations of foo (assuming its not a lambda), checking whether it complies to them is generally undecidable, by Rices theorem.

Even with simpler types, such as List[int] the test will easily become far too inefficient to be used for anything but the smallest toy examples.

xs = set(range(10000))
assert isinstance(xs, Set[int]), Wrong type

The trick that allows type checker to perform this operation in a relatively efficient way, is to be conservative: the type checker tries to prove that foo always return int. If it fails, it rejects the program, even though the program may be valid, i.e. this function is likely to be rejected, although it is perfectly safe:

def foo() -> int:
    if a.startswith(a):
        return 1
    return x

Python >=3.5: Checking type annotation at runtime

This is what I have discovered recently, basically this decorator does type checking at runtime raising exception if some type definition did not match. It can also do type checking for nested types (dict of strings, etc)


from strongtyping.strong_typing import match_typing

def func_a(a: str, b: int, c: list):

func_a(1, 2, [i for i in range(5)])
# >>> True

func_a(1, 2, [i for i in range(5)])
# >>> will raise a TypeMismatch Exception

Leave a Reply

Your email address will not be published. Required fields are marked *