Closed
Description
Bug Report
It is not possible to infer the type of a TypeVar
declared in a Generic
with another TypeVar
in __init__
by adding a type hint to self
.
To Reproduce
from typing import Any, Generic, TypeVar, overload
DTOPacketT = TypeVar("DTOPacketT")
SentPacketT = TypeVar("SentPacketT")
ReceivedPacketT = TypeVar("ReceivedPacketT")
class Serializer(Generic[DTOPacketT]):
...
class Converter(Generic[SentPacketT, ReceivedPacketT, DTOPacketT]):
...
class Protocol(Generic[SentPacketT, ReceivedPacketT]):
@overload
def __init__(
self: Protocol[DTOPacketT, DTOPacketT],
serializer: Serializer[DTOPacketT],
converter: None = ...,
) -> None:
...
@overload
def __init__(
self,
serializer: Serializer[DTOPacketT],
converter: Converter[SentPacketT, ReceivedPacketT, DTOPacketT],
) -> None:
...
def __init__(
self,
serializer: Serializer[Any],
converter: Converter[SentPacketT, ReceivedPacketT, Any] | None = None,
) -> None:
...
# This case works
serializer: Serializer[str] = Serializer()
converter: Converter[dict[str, Any], dict[str, Any], str] = Converter()
protocol_with_converter = Protocol(serializer, converter=converter)
reveal_type(protocol_with_converter) # Revealed type is "__main__.Protocol[builtins.dict[builtins.str, Any], builtins.dict[builtins.str, Any]]"
# This case fails
protocol_without_converter = Protocol(serializer, converter=None)
reveal_type(protocol_without_converter)
There is a mypy-play available here:
https://mypy-play.net/?mypy=latest&python=3.11&gist=282865693449e3786dde94d2f45bfb30
Expected Behavior
protocol_without_converter
should be inferred as Protocol[str, str]
Actual Behavior
main.py:49: error: Argument 1 to "Protocol" has incompatible type "Serializer[str]"; expected "Serializer[<nothing>]" [arg-type]
main.py:50: note: Revealed type is "__main__.Protocol[DTOPacketT`-1, DTOPacketT`-1]"
EDIT: A workaround to get this to work is to do the following:
@overload
def __init__(
self,
serializer: Serializer[SentPacketT | ReceivedPacketT],
converter: None = ...,
) -> None:
...
Mypy playground: https://mypy-play.net/?mypy=latest&python=3.11&gist=77ee74bfd5e80a91e3c0ff654a502d1f
Your Environment
- Mypy version used: 1.5.1
- Mypy command-line flags: (none)
- Mypy configuration options from
mypy.ini
(and other config files): (none) - Python version used: 3.11.2