Return type hint fails with multiple supplied type vars
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
I'm not 100% sure how to word this but mypy fails to detect the proper return type if multiple types are supplied. It works just fine if only a single type is specified.
This scenario works just fine with pyright/pylance.
To Reproduce
import typing as t
class BaseClass:
...
class Sub1(BaseClass):
...
class Sub2(BaseClass):
...
ClassType = t.TypeVar("ClassType", bound=BaseClass)
def testing_union() -> t.Union[Sub1, Sub2]:
res = sub_method(Sub1, Sub2)
reveal_type(res)
return res
def testing_single() -> Sub1:
res = sub_method(Sub1)
return res
def sub_method(*output_type: t.Type[ClassType]) -> ClassType:
return # type: ignore[return-value]
Expected Behavior
I expect mypy to work for both testing_union() and testing_single().
Actual Behavior
A return-value occurs in testing_union as it thinks the value is the bound base class. Using reveal_type we can see that mypy detects the type as BaseClass whereas pylance/pyright detects it as the expect3ed Sub1 | Sub2 type.

The output from the mypy check is
mypy-test.py:21: note: Revealed type is "mypy-test.BaseClass"
mypy-test.py:23: error: Incompatible return value type (got "BaseClass", expected "Union[Sub1, Sub2]") [return-value]
Found 1 error in 1 file (checked 1 source file)
Your Environment
- Mypy version used: mypy 1.0.0 (compiled: yes)
- Mypy command-line flags:
python -m mypy file.py - Mypy configuration options from
mypy.ini(and other config files): N/A - Python version used: Python 3.11.0
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 by running the supplied reproducer with mypy 1.0.0 and compare the revealed type for multiple versus single type arguments. Trace the type inference behavior for sub_method's variadic TypeVar arguments; done means the union case reveals Sub1 | Sub2 and passes the declared return check without weakening the single-type case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- compilers, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100