(🐞) `overload`s that exhaust finite `Literal`s(`bool`/`Enum`) not treated as exhaustive
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
@overload
def foo(a: Literal[True]) -> int: ...
@overload
def foo(a: Literal[False]) -> str: ...
def foo(a: bool) -> object: ...
a: bool
reveal_type(foo(a)) # error: No overload variant of "foo" matches argument type "bool"
@overload
def foo(a: Literal[True]) -> int: ...
@overload
def foo(a: Literal[False]) -> str: ...
@overload
def foo(a: bool) -> object: ... # no error regarding impossible to match overload
a: bool
reveal_type(foo(a)) # object
@overload
def foo(a: Literal[True, False]) -> int | str: ...
@overload
def foo(a: bool) -> object: ... # error: Overloaded function signature 2 will never be matched: signature 1's parameter type(s) are the same or broader
def foo(a: bool) -> object: ...
a: bool
reveal_type(foo(a)) # int | str
Here mypy incorrectly forces us to implement a completely redundant overload for the non Literal case when it is already exhaustively covered by both literals. It is only when the literals are in the same overload (useless in practice, but just for demonstration) that mypy correctly handles this case.
Mypy should be doing 'union math' (or what ever it's called) to apply both literal overloads at once.
This also affects all other exhaustible Literals such as Enums.
This example is pulled directly from the docs, so I think they should be updated as well to an example that doesn't contain this confusing defect.
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 reproducing the overload examples in the issue and read the linked Literal types documentation. Trace mypy's overload matching and handling of finite Literal and Enum values. Done means exhaustively covered separate literal overloads no longer require a redundant non-Literal overload, with the affected documentation example updated.
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
- 38/100