Skip to content

Honor return type of __new__ even if not a subclass #15182

Open
@oscarbenjamin

Description

@oscarbenjamin

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions