You can’t use typing types like Dict[str, int]
in an isinstance
check:
Python 3.7.6 (default, Dec 30 2019, 19:38:28)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.12.0 -- An enhanced Interactive Python. Type '?' for help.
In [1]: from typing import Dict
In [2]: myvar = {"a": 1}
In [3]: isinstance(myvar, Dict[str, int])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-a8fee57141ae> in <module>
----> 1 isinstance(myvar, Dict[str, int])
However any library that does type-checking needs to be able to do something kind of like isinstance(myvar, Dict[str, int])
(...I realise it should be called something different than isinstance
, that this is not the exactly same thing)
I feel like the equivalent function that works for typing must exist somewhere, maybe in mypy project? (but there’s a lot of complicated code in there and I couldn’t find it so far)
There are plenty of projects besides mypy which need this, libraries like pydantic for example, and AFAICT they all have complicated hand-rolled implementations and it seems like there are lots of edge cases (or just… ‘cases’) which have to be enumerated and covered. This leads to bugs/limited type recognition e.g. https://github.com/bloomberg/attrs-strict/issues/27
It seems like there is a need for a canonical implementation of this functionality. Does one exist already somewhere that I haven’t found?
I give you a motivating example from the Python stdlib:
https://docs.python.org/3/library/functools.html#functools.singledispatch
For functions annotated with types, the decorator will infer the type of the first argument automatically:
>>> @fun.register
... def _(arg: int, verbose=False):
... if verbose:
... print("Strength in numbers, eh?", end=" ")
... print(arg)
...
>>> @fun.register
... def _(arg: list, verbose=False):
... if verbose:
... print("Enumerate this:")
... for i, elem in enumerate(arg):
... print(i, elem)
Well that's pretty cool. But it's cheating, because these days generally we wouldn't annotate the second function using list
builtin, but rather something like List[str]
... and that doesn't work, because singledispatch
is just doing a naive isinstance
check, and that can't handle typing generics. So singledispatch
doesn't really support dispatch by type-annotation like it claims to.