Class factory with `type[TypeVar]` with upper bound not checked correctly (false positive)
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
Class factory, that uses TypeVar with upper bound as a type, suffers from over-inference, thinking that type[SomeTypeVar] gives its upper bound on instantiation.
To Reproduce
from typing import TypeVar, Type, Union
class A:
def __init__(self, x: str) -> None: pass
class B:
def __init__(self, x: int) -> None: pass
class C:
def __init__(self, x: int) -> None: pass
T = TypeVar('T', bound=Union[A, B])
def f(x: Type[T]) -> T:
return x(1) \
# E: Incompatible return value type (got "Union[A, B]", expected "T") \
# E: Argument 1 to "A" has incompatible type "int"; expected "str"
T2 = TypeVar('T2', bound=Union[B, C])
def f2(x: Type[T2]) -> T2:
return x(1) # E: Incompatible return value type (got "Union[B, C]", expected "T2")
Expected Behavior
I expect only 2nd error (invalid constructor arg) to be reported, without replacing a TypeVar with Union bound.
Actual Behavior
main.py:13: error: Incompatible return value type (got "Union[A, B]", expected "T") [return-value]
main.py:13: error: Argument 1 to "A" has incompatible type "int"; expected "str" [arg-type]
main.py:20: error: Incompatible return value type (got "Union[B, C]", expected "T2") [return-value]
Found 3 errors in 1 file (checked 1 source file)
Your Environment
- Mypy version used: 1.0.1 and master, repro's on older versions too
- Mypy command-line flags: none
- Mypy configuration options from
mypy.ini(and other config files): none - Python version used: 3.8-3.11 tested, irrelevant
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 with the provided Python reproduction and compare its diagnostics against the expected two-error result, using the linked mypy-play example if useful. Trace the type inference and constructor-checking entry points involved in type[T] with an upper-bound TypeVar; done means the invalid constructor argument remains reported without the false-positive return-value error, while existing cases still pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100