`__new__()` on a `Generic` class doesn't work with `Self` as return type if the typevar is not specified, picking the first element of the typevar
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
In pandas-stubs, we want to be able to return Series[int], Series[str], etc., as well as just Series from a __new__() constructor. In the current released version, we had return types of Series[S1] and Series and everything worked fine. But pyright made a change and developers there (@erictraut) say that Self needs to be the return type. See discussion starting here: https://github.com/microsoft/pyright/issues/5178#issuecomment-1563478640
With that change, mypy has a strange behavior, where returning Self in an overload that doesn't specify the value of the Generic parameter picks the first value. in the list provided in the TypeVar declaration.
To Reproduce
from typing import Generic, Self, TypeVar, overload, cast
S = TypeVar("S", int, str, bytes)
class Foo(Generic[S]):
@overload
def __new__(cls, dtype: type[S]) -> Self:
...
@overload
def __new__(cls, dtype=None) -> Self:
...
def __new__(cls, dtype: type[S] | None = None) -> Self:
return cast(Self, object.__new__(cls))
f = Foo(None)
reveal_type(f) # Mypy reveals: Foo[int]; should be Foo[Any]
f2 = Foo(str)
reveal_type(f2)
Expected Behavior
Output from pyright:
gennewself.py:20:13 - information: Type of "f" is "Foo[Unknown]"
gennewself.py:23:13 - information: Type of "f2" is "Foo[str]"
Actual Behavior
gennewself.py:20: note: Revealed type is "gennewself.Foo[builtins.int]"
gennewself.py:23: note: Revealed type is "gennewself.Foo[builtins.str]"
The issue here is that the type of f should be Foo[Any], not Foo[int] .
Your Environment
- Mypy version used: 1.3.0
- Mypy command-line flags: None
- Mypy configuration options from
mypy.ini(and other config files): None - Python version used: 3.11.31
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by running the supplied Generic, overload, and Self reproducer with mypy 1.3.0 and compare its revealed types with pyright's output. Trace type inference for an unspecified Generic parameter in new overloads; done means Foo(None) reveals Foo[Any] while Foo(str) remains Foo[str], with regression coverage for both cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100