A canonical "isinstance" implementation for typing types?

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 like isinstance(myvar, Dict[str, int])

I feel like the equivalent function that works for typing types must exist somewhere, maybe in mypy project? (there’s a lot of complicated code in there and I couldn’t find it)

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?

No bites here…

I got some good responses on Stack Overflow: https://stackoverflow.com/questions/60988674/is-there-a-canonical-isinstance-implementation-for-typing-types?noredirect=1#comment107899690_60988674

Basically the answer is “no”.

I gathered from comments there that this feature is not just missing from the core typing library but there seems to be some resistance to the idea of adding it, that core devs prefer typing to be used in static-analysis only.

I can understand not wanting to encourage overuse of runtime type-checking. At the same time I think this makes it unnecessarily difficult for libraries which make use of type introspection to provide a nice API. I was thinking mainly of serialization/validation libs like Pydantic.

Then the other day I came across this example from the stdlib:


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.