Open serjflint opened 18 hours ago
The problem here is that max_similarity
has type None
, which can't be narrowed into anything meaningful.
If you give max_similarity
a type that can be narrowed, like float | None
, then mypy will narrow the type inside the conditional expression:
max_similarity: float | None = None
average_similarity = 1.0
max_similarity = average_similarity if max_similarity is None else max(average_similarity, max_similarity)
This passes with no errors (playground link)
The reason that the second version "works" is because mypy can statically determine that the else
branch is unreachable, so it doesn't visit it at all. You can verify this enabling --warn-unreachable
, or by adding a type error or a reaveal_type
to the else branch:
max_similarity = None
average_similarity = 1.0
if max_similarity is None or input():
max_similarity = average_similarity
else:
a: str = 1 # E: Statement is unreachable [unreachable]
reveal_type(max_similarity) # no note
max_similarity = max(average_similarity, max_similarity)
See also https://mypy.readthedocs.io/en/stable/common_issues.html#unreachable-code
Bug Report
Mypy fails to narrow Optional with ternary. To me it seems similar to https://github.com/python/mypy/issues/5160
To Reproduce
https://mypy-play.net/?mypy=1.11.2&python=3.8&flags=strict&gist=80aa4ec83bdb4ea7b354f4daa41a6bd6
Expected Behavior
No errors like in https://mypy-play.net/?mypy=1.11.2&python=3.8&flags=strict&gist=16b2794c5c845bf288c81dd6853569bb
Actual Behavior
https://gist.github.com/serjflint/1b6ae0c2a94fb2774496d6779b52724f
Output
```bash main.py:3: error: No overload variant of "max" matches argument types "float", "None" [call-overload] main.py:3: note: Possible overload variants: main.py:3: note: def [SupportsRichComparisonT] max(SupportsRichComparisonT, SupportsRichComparisonT, /, *_args: SupportsRichComparisonT, key: None = ...) -> SupportsRichComparisonT main.py:3: note: def [_T] max(_T, _T, /, *_args: _T, key: Callable[[_T], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]]) -> _T main.py:3: note: def [SupportsRichComparisonT] max(Iterable[SupportsRichComparisonT], /, *, key: None = ...) -> SupportsRichComparisonT main.py:3: note: def [_T] max(Iterable[_T], /, *, key: Callable[[_T], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]]) -> _T main.py:3: note: def [SupportsRichComparisonT, _T] max(Iterable[SupportsRichComparisonT], /, *, key: None = ..., default: _T) -> Union[SupportsRichComparisonT, _T] main.py:3: note: def [_T1, _T2] max(Iterable[_T1], /, *, key: Callable[[_T1], Union[SupportsDunderLT[Any], SupportsDunderGT[Any]]], default: _T2) -> Union[_T1, _T2] Found 1 error in 1 file (checked 1 source file) ```Your Environment
--strict
mypy.ini
(and other config files): Playground