Skip to content

Incorrect type narrowing when swapping variables after isinstance check #21586

@p-sawicki

Description

@p-sawicki

Bug Report

Swapping the variables doesn't seem to make mypy swap their types and the second variable is left with its type as before the swap.

Changing the example below to use a temp variable fixes the issue:

tmp = a
a, b = b, tmp
reveal_type(a)  # note: Revealed type is "test.Sub1"
reveal_type(b)  # note: Revealed type is "test.Sub2"

To Reproduce

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)  # note: Revealed type is "test.Sub1"
        reveal_type(b)  # note: Revealed type is "test.Sub1"

Expected Behavior

Type of b is Sub2 after the swap.

Actual Behavior

Type of b is Sub1 after the swap.

Your Environment

  • Mypy version used: mypy 2.2.0+dev.52de0c739d2f066ea06fa9a886bc8fcc9fa079c6
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): None
  • Python version used: 3.13.5

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-type-narrowingConditional type narrowing / binder
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions