diff --git a/mypy/checker.py b/mypy/checker.py index 33705c98e10c..32d9dbc8f1b3 100644 --- a/mypy/checker.py +++ b/mypy/checker.py @@ -4175,7 +4175,19 @@ def check_assignment_to_multiple_lvalues( lr_pairs.append((star_lv.expr, rv_list)) lr_pairs.extend(zip(right_lvs, right_rvs)) + captured_pairs: list[tuple[Lvalue, Expression]] = [] + for lv, rv in lr_pairs: + if isinstance(rv, NameExpr): + narrowed = self.binder.get(rv) + + if narrowed is not None: + captured_pairs.append((lv, self.temp_node(narrowed, context=rv))) + continue + + captured_pairs.append((lv, rv)) + + for lv, rv in captured_pairs: self.check_assignment(lv, rv, infer_lvalue_type) else: self.check_multi_assignment(lvalues, rvalue, context, infer_lvalue_type) diff --git a/test-data/unit/check-isinstance.test b/test-data/unit/check-isinstance.test index acd81839fcdc..ccd1d624f371 100644 --- a/test-data/unit/check-isinstance.test +++ b/test-data/unit/check-isinstance.test @@ -3377,3 +3377,21 @@ def f2(x: A | None, t: type[A]): else: reveal_type(x) # N: Revealed type is "None" [builtins fixtures/isinstancelist.pyi] + +[case testTupleSwapAfterIsinstance] +class Base: pass +class Sub1(Base): pass +class Sub2(Base): pass + +def f(a: Base, b: Base) -> None: + if isinstance(b, Sub1) and isinstance(a, Sub2): + t = (b, a) + + reveal_type(t) # N: Revealed type is "tuple[__main__.Sub1, __main__.Sub2]" + + a, b = t + + reveal_type(a) # N: Revealed type is "__main__.Sub1" + reveal_type(b) # N: Revealed type is "__main__.Sub2" + +[builtins fixtures/isinstancelist.pyi] diff --git a/test-data/unit/check-narrowing.test b/test-data/unit/check-narrowing.test index 7bab7baa6ceb..39c161222397 100644 --- a/test-data/unit/check-narrowing.test +++ b/test-data/unit/check-narrowing.test @@ -4281,3 +4281,21 @@ def func(y: H) -> H: else: return y [builtins fixtures/primitives.pyi] + +[case testIsInstanceVariableSwapNarrowing] +class Base: + pass + +class Sub1(Base): + pass + +class Sub2(Base): + pass + +def f(a: Base, b: Base) -> None: + if isinstance(b, Sub1) and isinstance(a, Sub2): + a, b = b, a + reveal_type(a) # N: Revealed type is "__main__.Sub1" + reveal_type(b) # N: Revealed type is "__main__.Sub2" + +[builtins fixtures/isinstancelist.pyi]