Why does isinstance([1, 2, 3], List[str]) evaluate to true?
Question: I was playing around a bit with the new type hinting / typing module with
python3.5 trying to find a way to confirm if the hinted type is equal to the
actual type of the variable and came across something that rather surprised
me.

    
    
    >>> from typing import List
    >>> someList = [1, 2, 3]
    >>> isinstance(someList, List[str])
    True
    

Continuing my search for finding a way to compare a variable to it's hinted
type I've also tried this:

    
    
    >>> anotherList = ["foo", "bar"]
    >>> type(anotherList) is List[str]
    False
    

Would anyone be able to explain why exactly the former evaluates to True?

And continuing onwards, is there a sound way to check if a variable's type is
equal to a type coming from the typing module?


Answer: [`isinstance`](https://docs.python.org/3/library/functions.html#isinstance)
does not do real [PEP 484](https://www.python.org/dev/peps/pep-0484/) type
checking. [The
documentation](https://docs.python.org/3/library/typing.html#typing.TypeVar)
notes this in passing:

> In general, `isinstance()` and `issubclass()` should not be used with types.

The `typing` module, as well as the `collections.abc` and `abc` modules it’s
based on, use extensive [`__instancecheck__` and
`__subclasscheck__`](https://docs.python.org/3/reference/datamodel.html#customizing-
instance-and-subclass-checks) magic to make `isinstance` and `issubclass`
behave reasonably. But they’re not doing enough to support your case. Nor is
it their goal to support it.

> is there a sound way to check if a variable's type is equal to a type coming
> from the typing module?

You’re not looking for type _equality_. As you have noted yourself, the type
of `[1, 2, 3]` is `list`, which is not _equal_ to `List[str]`, nor to
`List[int]`. You’re looking for type _checking_ , which is much more
complicated.

Consider this:

    
    
    def my_function():
        # ... 1000 lines of very complicated code ...
    
    print(isinstance(my_function, Callable[[], int]))
    

What would you expect this program to print? You can’t expect `isinstance` to
dig into `my_function` at runtime and infer that it always returns `int`. This
is not feasible in Python. You need either a “compile” time type checker that
has access to the structure of `my_function`, or explicit type annotations,
or—most likely—both.

