简体   繁体   中英

mypy differences in isinstance and issubclass from python 3.5 to 3.6 in parameterized generics

Before I upgraded to python 3.6 from python 3.5 this worked:

import typing
issubclass(list, typing.List[int])  # returns True
isinstance([1, 2 ,3], typing.List[int]) # returns True

now in python 3.6 both of these raise the following exception:

TypeError: Parameterized generics cannot be used with class or instance checks

Is this new intended behavior or a bug? If it is intended how can I perform the checks the code above is doing in python 3.6?

It is intentional, you shouldn't be mixing classes with types as defined in typing , at least, that's the gist of it from what I've understood. A great deal of discussion for this is contained in the issue #136 Kill __subclasscheck__ which also introduced this change. The commit message also references how the isinstance / subclass checks will raise TypeError s:

Using isinstance() or issubclass() raises TypeError for almost everything. There are exceptions: [...]

You can compare without specifying the contained types for the generic types, ie:

isinstance(list, typing.List[int])

but that's the best you can do afaik.

If you want to have better type safety in python your options are somewhat limited. A technique I have employed is to subclass list or dict without overriding any properties, methods etc.

class ListInts(list):
    pass

new_obj = ListInts()
new_obj += [1, 2, 3, 4, 5, 6]
print(isinstance(new_obj, ListInts)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM