Skip to content

Incorrect narrowing between two different unions #20820

@A5rocks

Description

@A5rocks

Bug Report

Narrowing via isinstance and two unions does not seem to do a full crossproduct of possibilities. Spotted when reviewing #20743.

To Reproduce

from __future__ import annotations

class A: ...

class B: ...

class C: ...

def f1(x: A | C, t: type[A] | type[B]):
    if isinstance(x, t):
        reveal_type(x)  # N: Revealed type is "__main__.A"
    else:
        reveal_type(x)  # Revealed type is "__main__.A | __main__.C"

Expected Behavior

I would expect the revealed types to be a superset of the results if we did a crossproduct. However, note that <subclass of C and B> is missing. (probably the best way to express this would be to have intersections but... yeah...)

Actual Behavior

Positive branch just has A.

Your Environment

Reproduced in mypy-play

  • Mypy version used: master
  • Mypy command-line flags: N/A
  • Mypy configuration options from mypy.ini (and other config files): N/A
  • Python version used: 3.12

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrongtopic-type-narrowingConditional type narrowing / binder

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions