SIGN IN SIGN UP

Respect explicit return type of __new__() (#21441)

Fixes https://github.com/python/mypy/issues/8330
Fixes https://github.com/python/mypy/issues/15182
Closes https://github.com/python/mypy/pull/16020
Closes https://github.com/python/mypy/pull/14471
Fixes https://github.com/python/mypy/issues/13824
Fixes https://github.com/python/mypy/issues/14502

With this PR will still give an error if the explicit return `__new__()`
is not a subtype of current class, but now we will actually use it.
There are _two exceptions_ (to preserve backwards compatibility):
* If the return type is `Any` with still use current class as the return
type.
* If the explicit return type comes from a superclass and is a supertype
of implicit return type.

```python
class A:
    def __new__(cls): ...
reveal_type(A())  # still __main__.A

class B:
    def __new__(cls) -> B:
        return cls()
class C(B): ...
reveal_type(C())  # still __main__.C
```

This uses a more principled implementation than some earlier attempts:
adding a new dedicated attribute to `CallableType` for this purpose.
Some comments:
* This PR has a bit for boilerplate, but this is expected. When adding a
new attribute to a type, one needs to update most visitors.
* While doing the above I noticed that `CallableType.type_guard` and
`CallableType.type_is` were not handled in dependency visitors (neither
coarse-grained nor fine-grained). IMO they definitely should be handled
there, so I now handle them.
* I try to reduce the size of `CallableType` a bit to compensate for new
attribute by removing (rarely used) `min_args` attribute. I also use
compact flags serialization.
* I skimmed the code base and updated all places where we "casually" use
`CallableType.ret_type` for various type object edge cases.
* Note that I don't assert that `instance_type` is set when
`is_type_obj()` returns `True`. This is mostly to avoid breaking 3rd
party plugins.
* I didn't add a test case for each edge case, but I added (improved)
test cases from https://github.com/python/mypy/pull/16020 plus some
more. Suggestions for more test cases are welcome.
* It looks like this exposes a pre-existing bug where we leaked type
variables in `type[T]`. It is relatively niche edge case, but it looks
important for NumPy stubs, so I am trying to fix it here.
I
Ivan Levkivskyi committed
938dbe2fe79359e6d97ff5319a40b61f7af446fd
Parent: 668733d
Committed by GitHub <noreply@github.com> on 5/27/2026, 1:13:09 AM