Open
Description
Currently mypy doesn't complain about this code:
from typing import Type
class A:
def __init__(self, x: int) -> None: pass
def f(t: Type[object]) -> None:
t() # ok, since `object()` is valid
f(A) # no error reported!
This is caused by __init__
overrides not needing to be compatible with base classes.
It's not clear how to type check such code. Here are some ideas, some of which have been discussed before:
- We could reject calling
Type[C]
and requireType[[ArgType, ...], C]
for type objects that can be called. The argument types would specify a signature for__init__
. This would require a PEP 484 (and atyping
change). This has the problem of being backward incompatible. Additionally, it's not clear how to specify signatures with keyword arguments or optional arguments. - Similar to above, but by default
Type[C]
would take the__init__
signature fromC
, similar to how it behaves now. Unlike now,Type[D]
would only be a subtype ofType[C]
if the__init__
signature is compatible.Type[None, C]
would be a type object that is not callable.Type[[X, ...], C]
would also be supported and would support specifying a specific signature instead of just taking it fromC
. Type[..., C]
would be a callable type object which accepts arbitrary arguments.Type[[T], C[T]]
would perhaps also be valid for generic classes (T
is a type variable).
Class methods also have this issue. We could support specifying the type of cls
explicitly. For example:
class A:
...
@classmethod
def f(cls: Type[[int], A]) -> A:
return cls(1) # ok
(I known that this is an old issue, but I couldn't find a previous open issue.)