You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Overly restrictive narrowing of TypeVar via isinstance #13956
When a value whose type is a TypeVar is tested via isinstance, mypy so aggressively narrows types that it refuses to let them be broadened back to the original TypeVar, even when the value is untouched.
from typing import TypeVar
T = TypeVar('T')
def foo(t: T) -> T:
if isinstance(t, str):
return t + "."
elif isinstance(t, dict):
return t
elif isinstance(t, list):
return t
else:
return t
Expected Behavior
no type errors
Actual Behavior
main.py:8: error: Incompatible return value type (got "str", expected "T")
main.py:10: error: Incompatible return value type (got "Dict[Any, Any]", expected "T")
main.py:12: error: Incompatible return value type (got "List[Any]", expected "T")
Found 3 errors in 1 file (checked 1 source file)
Your Environment
Mypy version used: 0.971 (reproduces in all versions I've tried in the playground)
Mypy command-line flags: N/A
Python version used: 3.7 (reproduces in all versions I've tried in the playground)
The second and third errors do look like bugs. The type of t after isinstance(t, dict) should be revealed as <subclass of "T" and "Dict[Any, Any]"> and it should be OK to return this as a value of type T.
The first one is more subtle. After isinstance(t, str) the type of t should be revealed as <subclass of "T" and "str">. But the string concatenation operator returns a str and T might actually be a subtype of str, so it's not necessarily OK to return that as a value of type T.
Activity
[-]Overly restrictive narrowing of typevar[/-][+]Overly restrictive narrowing of TypeVar via isinstance[/+]tmke8 commentedon Oct 28, 2022
Same as #12800?
kmillikin commentedon Oct 28, 2022
The second and third errors do look like bugs. The type of
tafterisinstance(t, dict)should be revealed as<subclass of "T" and "Dict[Any, Any]">and it should be OK to return this as a value of typeT.The first one is more subtle. After
isinstance(t, str)the type oftshould be revealed as<subclass of "T" and "str">. But the string concatenation operator returns astrandTmight actually be a subtype ofstr, so it's not necessarily OK to return that as a value of typeT.hauntsaninja commentedon Jan 10, 2023
Closing as duplicate of #10817