Incorrect widening of `T | None` with unions to `builtins.object` in generic functions
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
Generic function with signature (fun: Callable[[], T | None]) -> T | None has its type incorrectly widened to builtins.object when T is a union type
To Reproduce
import typing
T = typing.TypeVar("T")
def gen_fun_one(fun: typing.Callable[[], T | int]) -> T | int:
return fun()
def gen_fun_two(fun: typing.Callable[[], T | None]) -> T | None:
return fun()
def foo() -> int | str | None:
pass
typing.reveal_type(gen_fun_one(foo)) # Union[builtins.str, None, builtins.int]
typing.reveal_type(gen_fun_two(foo)) # builtins.object
Gist URL: https://gist.github.com/mypy-play/f2401bd493520f4c72cad4a416195e19
Playground URL: https://mypy-play.net/?mypy=latest&python=3.12&gist=f2401bd493520f4c72cad4a416195e19
Expected Behavior
Both gen_fun_one(foo) and gen_fun_two(foo) are of type str | int | None
Actual Behavior
Function gen_fun_two(foo) is of type builtins.object
Your Environment
- Mypy version used: 1.9.0
- Python version used: 3.12
- Default Mypy playground settings
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 provided Python reproduction in the linked mypy playground and compare the reveal_type results for gen_fun_one and gen_fun_two. Trace the generic union inference involved in the second call; the work is done when it infers str | int | None rather than builtins.object, with coverage for the reported case.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 44/100