Open JukkaL opened 7 years ago
I almost fixed it inside #3070, but then I realized that the required change to typeshed
(from Union[type, Tuple[Union[type, Tuple[Any, ...]], ...]]
to Union[object, Tuple[Union[object, Tuple[Any, ...]], ...]]
) effectively eliminates type checking of the 2nd argument to isinstance
. That would be quite disappointing.
What else can we do?
Map Type
to be something other than object
during type inference? Perhaps a special singleton class TypeObject
?
Yeah, that would be equivalent to making the type object
. But there's special-casing for isinstance()
calls in mypy -- maybe we can expand that to manually check that the recursive tuple is valid? Or maybe we can implement recursive type aliases, at last (#731).
I guess a narrow fix could be to redefine Type
in typing.pyi
as class Type: ...
instead of Type = object()
. This would pass the type check for isinstance(x, Type)
.
We would still have to add some code elsewhere to make @JukkaL example pass, since at present Type[int]
is not recognized as a subtype of Type
, so mypy
thinks that everything after isinstance(x, Type)
is unreachable.
Is this about mypy or runtime? Making the behaviors of isinstance()/issubclass() match between static checks and runtime can be tricky.
I think mypy. It seems Python runtime returns True
on isinstance(c, Type)
whenever c
is of type type
. This is precisely what mypy should do as well (of course, assuming it can statically infer that c
of type type
).
On current master the error is even worse:
Argument 2 to "isinstance" has incompatible type "_SpecialForm";
expected "Union[type, Tuple[Union[type, Tuple[Any, ...]], ...]]"
isinstance(x, Type)
generates in an error, even though it should probably be considered equivalent toisinstance(x, type)
. Example: