-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Labels
as designedNot a bug, working as intendedNot a bug, working as intended
Description
Describe the bug
Inferring literals when TypeVars have bounds may not be sound.
To Reproduce
from typing import Any, Iterable, List, Literal, Protocol, TypeVar
_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)
_T_contra = TypeVar("_T_contra", contravariant=True)
class SupportsAdd(Protocol[_T_contra, _T_co]):
def __add__(self, __x: _T_contra) -> _T_co: ...
_SupportsSumSimple = TypeVar("_SupportsSumSimple", bound=SupportsAdd[Any, Any])
def my_sum(__iterable: Iterable[_SupportsSumSimple]) -> _SupportsSumSimple:
vs = list(__iterable)
assert vs
r = vs[0]
for v in vs[1:]:
r += v
return r
class SupportsRAdd(Protocol[_T_contra, _T_co]):
def __radd__(self, __x: _T_contra) -> _T_co: ...
class _SupportsSumWithNoDefaultGiven(SupportsAdd[Any, Any], SupportsRAdd[int, Any], Protocol): ...
_SupportsSumNoDefaultT = TypeVar("_SupportsSumNoDefaultT", bound=_SupportsSumWithNoDefaultGiven)
def life_like_sum(__iterable: Iterable[_SupportsSumNoDefaultT]) -> _SupportsSumNoDefaultT | Literal[0]: ...
Z2 = Literal[0, 1]
def f() -> None:
l: List[Z2] = [0, 1, 1]
reveal_type(my_sum(l))
reveal_type(life_like_sum(l))
pyright gives me:
pyright 1.1.277
/Users/shantanu/dev/mypy/lit.py
/Users/shantanu/dev/mypy/lit.py:33:17 - information: Type of "my_sum(l)" is "Literal[0, 1]"
/Users/shantanu/dev/mypy/lit.py:34:17 - information: Type of "life_like_sum(l)" is "Literal[0, 1]"
When obviously the value is 2.
Note that mypy matches pyright's (unsound) behaviour.
This was originally filed on typeshed, but only came to my attention recently:
python/typeshed#8230
This was worked around for builtins.sum in python/typeshed#8231 , but there's clearly a more general problem here.
Metadata
Metadata
Assignees
Labels
as designedNot a bug, working as intendedNot a bug, working as intended