Does the typing
module (or any other module) exhibit an API to typecheck a variable at runtime, similar to isinstance()
but understanding the type classes defined in typing
?
I'd like to be to run something akin to:
from typing import List
assert isinstance([1, 'bob'], List[int]), 'Wrong type'
There is no such function in the typing
module, and most likely there won't 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 it's not a lambda
), checking whether it complies to them is generally undecidable, by Rice's 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))
xs.add("a")
xs.pop()
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"