Skip to content

[match-case]: mapping pattern narrowing inconsistent with equivalent isinstance #2865

@randolf-scholz

Description

@randolf-scholz

Summary

https://play.ty.dev/934e624f-af08-4e8a-bc92-8d9ea8ecde5a

from typing import reveal_type
from collections.abc import Mapping

def test_instance(x: dict | int) -> None:
    if isinstance(x, Mapping):
        reveal_type(x)
    else:
        reveal_type(x)

def test_match(x: dict | int) -> None:
    match x:
        case {}:  # equivalent to isinstance(x, Mapping)
            reveal_type(x)
        case _:
            reveal_type(x)
Revealed type: `dict[Unknown, Unknown] | (int & Top[Mapping[Unknown, object]])` (revealed-type) [Ln 6, Col 21]
Revealed type: `int & ~Top[Mapping[Unknown, object]]` (revealed-type) [Ln 8, Col 21]
Revealed type: `dict[Unknown, Unknown] | int` (revealed-type) [Ln 13, Col 25]
Revealed type: `dict[Unknown, Unknown] | int` (revealed-type) [Ln 15, Col 25]

The isinstance(x, Mapping) and case {} are equivalent at runtime and should produce the same narrowing.

Version

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions