Mypy doesn't recognize that different string literals in if/else statement match a union of string literals
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Bug Report
When a function has a type signature like def foo(bar: Literal["a", "b"]) -> None: ... mypy throws an error if the argument passed in can be either a or b as it implies a general string.
To Reproduce
from typing import Literal
CHOICE = bool(...)
def foo(bar: Literal["a", "b"]) -> None: ...
def main() -> None:
bar = "a"
if CHOICE:
bar = "b"
foo(bar)
Expected Behavior
It would be nice if mypy recognized that bar here could only be Literal["a"] or Literal["b"], i.e Literal["a", "b"].
Actual Behavior
mre.py:12: error: Argument 1 to "foo" has incompatible type "str"; expected "Literal['a', 'b']" [arg-type]
Your Environment
- Mypy version used: 1.14.1
- Mypy command-line flags: Default
- Mypy configuration options from
mypy.ini(and other config files): Default - Python version used: 3.13
Context
This came up because of a recent change in typeshed https://github.com/python/typeshed/pull/12181 which causes this pip code to trigger a mypy error: https://github.com/pypa/pip/blob/24.3.1/src/pip/_internal/utils/unpacking.py#L179
I assume this issue of different implicit Literal / str types inside branches has been discussed before but I couldn't find it searching through the GitHub issues.
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
Reproduce the diagnostic in mre.py with mypy 1.14.1 using the shown branch-assignment example, then trace how the type checker infers bar across the if/else paths. Use the pip unpacking.py reference as a real-world case; done means both examples accept the union of string literals without an incompatible-type error.
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
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 52/100