Description
This follows gh-1020 which was closed by gh-7188. This arises because I am adding type hints to sympy (sympy/sympy#25103).
In the following code we have a subclass whose __new__
method is only guaranteed to return objects that are types of the superclass:
from __future__ import annotations
class A:
def __new__(cls) -> A:
return super().__new__(cls)
class B(A):
def __new__(cls) -> A:
return super().__new__(cls)
reveal_type(B())
With mypy this is rejected and the type of B()
is inferred incorrectly but pyright accepts this and gets the inference for B()
correct:
$ mypy q.py
q.py:8: error: Incompatible return type for "__new__" (returns "A", but must return a subtype of "B") [misc]
q.py:11: note: Revealed type is "q.B"
Found 1 error in 1 file (checked 1 source file)
$ pyright q.py
...
./q.py:11:13 - information: Type of "B()" is "A"
0 errors, 0 warnings, 1 information
Completed in 0.955sec
The fix for __new__
in gh-7188 was:
- If the return type is Any, ignore that and keep the class type as
the return type - Otherwise respect
__new__
's return type - Produce an error if the return type is not a subtype of the class.
The issue here is about mixing the last two points. Here mypy produces an error but then does not respect __new__
's return type. The return type is not respected since mypy infers that it is of type B
unlike pyright which infers type A
as specified by the hint. I don't mind mypy reporting an error here but in context -> A
is the accurate type hint and mypy should respect that because anything else is just not correct. I can add a type ignore to silence the mypy error but the inference will still be wrong in all downstream/user code and is also inconsistent with pyright.