Skip to content

Commit 1567e36

Browse files
authored
Consider reversed operands order when comparing version info (#10288)
Closes #10264. Consider reversed order of operands when trying to compare version info. When reversed order is used, operator is reversed as well for correct comparison.
1 parent ee05821 commit 1567e36

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

mypy/reachability.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@
2727
MYPY_FALSE: MYPY_TRUE,
2828
} # type: Final
2929

30+
reverse_op = {"==": "==",
31+
"!=": "!=",
32+
"<": ">",
33+
">": "<",
34+
"<=": ">=",
35+
">=": "<=",
36+
} # type: Final
37+
3038

3139
def infer_reachability_of_if_statement(s: IfStmt, options: Options) -> None:
3240
for i in range(len(s.expr)):
@@ -127,10 +135,13 @@ def consider_sys_version_info(expr: Expression, pyversion: Tuple[int, ...]) -> i
127135
op = expr.operators[0]
128136
if op not in ('==', '!=', '<=', '>=', '<', '>'):
129137
return TRUTH_VALUE_UNKNOWN
130-
thing = contains_int_or_tuple_of_ints(expr.operands[1])
131-
if thing is None:
132-
return TRUTH_VALUE_UNKNOWN
138+
133139
index = contains_sys_version_info(expr.operands[0])
140+
thing = contains_int_or_tuple_of_ints(expr.operands[1])
141+
if index is None or thing is None:
142+
index = contains_sys_version_info(expr.operands[1])
143+
thing = contains_int_or_tuple_of_ints(expr.operands[0])
144+
op = reverse_op[op]
134145
if isinstance(index, int) and isinstance(thing, int):
135146
# sys.version_info[i] <compare_op> k
136147
if 0 <= index <= 1:

test-data/unit/check-unreachable-code.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,16 @@ reveal_type(foo()) # N: Revealed type is "builtins.str"
196196
[builtins_py2 fixtures/ops.pyi]
197197
[out]
198198

199+
[case testSysVersionInfoReversedOperandsOrder]
200+
import sys
201+
if (3,) <= sys.version_info:
202+
def foo() -> int: return 0
203+
else:
204+
def foo() -> str: return ''
205+
reveal_type(foo()) # N: Revealed type is "builtins.int"
206+
[builtins fixtures/ops.pyi]
207+
[out]
208+
199209
[case testSysVersionInfoNegated]
200210
import sys
201211
if not (sys.version_info[0] < 3):

0 commit comments

Comments
 (0)