Skip to content

Walrus in match expression leads to type not correctly inferred in case expression #14843

@WilkenSteiner

Description

@WilkenSteiner

Bug Report

Using a walrus in a match expression fails the matched type in the cases to be correctly inferred. This seems to be a regression from 0.982.

To Reproduce

class A:
    a = 1

def returns_a_or_none() -> A | None:
    return A()

def returns_a() -> A:
    return A()

async def f() -> None:
    match x := returns_a_or_none():
        case A():
            print(x.a)  # Item "None" of "Optional[A]" has no attribute "a"
    match x := returns_a():
        case A():
            print(x.a)  # Ok
    y = returns_a_or_none()
    match y:
        case A():
            print(y.a)  # Ok

Here are the links to the playground and Gist.

Expected Behavior

The example should pass.

Actual Behavior

A warning message is emitted: Item "None" of "Optional[A]" has no attribute "a"

Your Environment

  • Mypy version used: 1.0.1, 1.0.0 (on playground) and 0.982. In 0.982 this example passes, in 1.0.x not anymore.
  • Mypy command-line flags: None
  • Mypy configuration options from mypy.ini (and other config files): Not used
  • Python version used: 3.11.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions