Skip to content

Commit a04126d

Browse files
committed
Also support set expressions.
1 parent bd145d1 commit a04126d

File tree

3 files changed

+17
-16
lines changed

3 files changed

+17
-16
lines changed

docs/source/literal_types.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,8 @@ without a value:
368368
elif x == 'two':
369369
return False
370370
371-
For the sake of brevity, you can use the ``in`` operator in combination with list or tuple
372-
expressions (lists or tuples created "on the fly"):
371+
For the sake of brevity, you can use the ``in`` operator in combination with
372+
list, set, or tuple expressions (lists, sets, or tuples created "on the fly"):
373373

374374
.. code-block:: python
375375

mypy/checker.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@
117117
RaiseStmt,
118118
RefExpr,
119119
ReturnStmt,
120+
SetExpr,
120121
StarExpr,
121122
Statement,
122123
StrExpr,
@@ -4685,11 +4686,11 @@ def check_return_stmt(self, s: ReturnStmt) -> None:
46854686
if self.in_checked_function():
46864687
self.fail(message_registry.RETURN_VALUE_EXPECTED, s)
46874688

4688-
def _make_tupleexpr_with_literals_narrowable_by_using_in(self, e: Expression) -> Expression:
4689+
def _transform_sequence_expressions_for_narrowing_with_in(self, e: Expression) -> Expression:
46894690
"""
46904691
Transform an expression like
46914692
4692-
(x is None) and (x in (1, 2)) and (x not in (3, 4))
4693+
(x is None) and (x in (1, 2)) and (x not in [3, 4])
46934694
46944695
into
46954696
@@ -4700,15 +4701,15 @@ def _make_tupleexpr_with_literals_narrowable_by_using_in(self, e: Expression) ->
47004701
implement additional narrowing logic.
47014702
"""
47024703
if isinstance(e, OpExpr):
4703-
e.left = self._make_tupleexpr_with_literals_narrowable_by_using_in(e.left)
4704-
e.right = self._make_tupleexpr_with_literals_narrowable_by_using_in(e.right)
4704+
e.left = self._transform_sequence_expressions_for_narrowing_with_in(e.left)
4705+
e.right = self._transform_sequence_expressions_for_narrowing_with_in(e.right)
47054706
return e
47064707

47074708
if not (
47084709
isinstance(e, ComparisonExpr)
47094710
and isinstance(left := e.operands[0], NameExpr)
47104711
and ((op_in := e.operators[0]) in ("in", "not in"))
4711-
and isinstance(litu := e.operands[1], (ListExpr, TupleExpr))
4712+
and isinstance(litu := e.operands[1], (ListExpr, SetExpr, TupleExpr))
47124713
):
47134714
return e
47144715

@@ -4748,7 +4749,7 @@ def visit_if_stmt(self, s: IfStmt) -> None:
47484749
with self.binder.frame_context(can_skip=False, conditional_frame=True, fall_through=0):
47494750
for e, b in zip(s.expr, s.body):
47504751

4751-
e = self._make_tupleexpr_with_literals_narrowable_by_using_in(e)
4752+
e = self._transform_sequence_expressions_for_narrowing_with_in(e)
47524753

47534754
t = get_proper_type(self.expr_checker.accept(e))
47544755

test-data/unit/check-narrowing.test

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2334,7 +2334,7 @@ def f(x: C) -> None:
23342334
f(C(5))
23352335
[builtins fixtures/primitives.pyi]
23362336

2337-
[case testNarrowLiteralsInListOrTupleExpression]
2337+
[case testNarrowLiteralsInListOrSetOrTupleExpression]
23382338
# flags: --warn-unreachable
23392339

23402340
from typing import Optional
@@ -2347,7 +2347,7 @@ def f(v: Optional[Literal[1, 2, 3, 4]]) -> None:
23472347
reveal_type(v) # N: Revealed type is "Union[Literal[1], Literal[2]]"
23482348
elif v in [1]:
23492349
reveal_type(v) # E: Statement is unreachable
2350-
elif v is None or v in [3, x]:
2350+
elif v is None or v in {3, x}:
23512351
reveal_type(v) # N: Revealed type is "Union[Literal[3], Literal[4], None]"
23522352
elif v in ():
23532353
reveal_type(v) # E: Statement is unreachable
@@ -2356,7 +2356,7 @@ def f(v: Optional[Literal[1, 2, 3, 4]]) -> None:
23562356
reveal_type(v) # N: Revealed type is "Union[Literal[1], Literal[2], Literal[3], Literal[4], None]"
23572357
[builtins fixtures/primitives.pyi]
23582358

2359-
[case testNarrowLiteralsNotInListOrTupleExpression]
2359+
[case testNarrowLiteralsNotInListOrSetOrTupleExpression]
23602360
# flags: --warn-unreachable
23612361

23622362
from typing import Optional
@@ -2365,7 +2365,7 @@ from typing_extensions import Literal
23652365
x: int
23662366

23672367
def f(v: Optional[Literal[1, 2, 3, 4, 5]]) -> None:
2368-
if v not in (0, 1, 2, 3):
2368+
if v not in {0, 1, 2, 3}:
23692369
reveal_type(v) # N: Revealed type is "Union[Literal[4], Literal[5], None]"
23702370
elif v not in [1, 2, 3, 4]: # E: Right operand of "and" is never evaluated
23712371
reveal_type(v) # E: Statement is unreachable
@@ -2378,7 +2378,7 @@ def f(v: Optional[Literal[1, 2, 3, 4, 5]]) -> None:
23782378
reveal_type(v) # N: Revealed type is "Union[Literal[1], Literal[2], Literal[3], Literal[4], Literal[5], None]"
23792379
[builtins fixtures/primitives.pyi]
23802380

2381-
[case testNarrowEnumsInListOrTupleExpression]
2381+
[case testNarrowEnumsInListOrSetOrTupleExpression]
23822382
from enum import Enum
23832383
from typing import Final
23842384

@@ -2397,7 +2397,7 @@ def f(v: E) -> None:
23972397
reveal_type(v) # N: Revealed type is "Union[Literal[__main__.E.A], Literal[__main__.E.B]]"
23982398
elif v in [E.A]:
23992399
reveal_type(v)
2400-
elif v in (C,):
2400+
elif v in {C}:
24012401
reveal_type(v) # N: Revealed type is "Literal[__main__.E.C]"
24022402
elif v in ():
24032403
reveal_type(v)
@@ -2406,7 +2406,7 @@ def f(v: E) -> None:
24062406
reveal_type(v) # N: Revealed type is "__main__.E"
24072407
[builtins fixtures/primitives.pyi]
24082408

2409-
[case testNarrowEnumsNotInListOrTupleExpression]
2409+
[case testNarrowEnumsNotInListOrSetOrTupleExpression]
24102410
from enum import Enum
24112411
from typing import Final
24122412

@@ -2426,7 +2426,7 @@ def f(v: E) -> None:
24262426
reveal_type(v) # N: Revealed type is "Union[Literal[__main__.E.D], Literal[__main__.E.E]]"
24272427
elif v not in [E.A, E.B, E.C, E.C]:
24282428
reveal_type(v)
2429-
elif v not in (C,):
2429+
elif v not in {C}:
24302430
reveal_type(v) # N: Revealed type is "Union[Literal[__main__.E.A], Literal[__main__.E.B]]"
24312431
elif v not in []:
24322432
reveal_type(v) # N: Revealed type is "Literal[__main__.E.C]"

0 commit comments

Comments
 (0)