Closed
Description
Bug Report
For a generic class with __init__
overloads and __get__
overloads, mypy is matching overloads unexpectedly.
To Reproduce
- Run the playground: https://mypy-play.net/?mypy=latest&python=3.9&gist=a0ad74a30c7089c1aa0d9446e635ce93
- Observe the types of
audience.usernames
andaudience.ages
are bothlist[int]
Here's the example code from the playground:
from __future__ import annotations
from typing import Any, Generic, TypeVar, overload, List
from typing_extensions import Literal
_T = TypeVar("_T")
class ListField(Generic[_T]):
@overload
def __init__(
self: ListField[int],
*,
kind: Literal["integer"],
) -> None:
...
@overload
def __init__(
self: ListField[str],
*,
kind: Literal["string"],
) -> None:
...
def __init__(self, *, kind: Any) -> None:
...
@overload
def __get__(
self: ListField[int],
instance: Any,
owner: Any,
) -> List[int]:
...
@overload
def __get__(
self: ListField[str],
instance: Any,
owner: Any,
) -> List[str]:
...
def __get__(self: Any, instance: Any, owner: Any) -> Any:
...
class Audience:
usernames = ListField(kind="string")
ages = ListField(kind="integer")
audience = Audience()
reveal_type(audience.usernames) # Revealed type is list[int]
reveal_type(audience.ages) # Revealed type is list[int]
Expected Behavior
I would expect audience.usernames
to be a list[str]
, because the __init__
overload should create a ListField[str]
, which should then match to __get__
overload for ListField[str]
, returning list[str]
.
Actual Behavior
audience.usernames
is unexpectedly typed as list[int]
.
Your Environment
- Mypy version used: 0.812
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini
(and other config files): none - Python version used: 3.7.8
- Operating system and version: macOS 11.2.3