ruff/crates/ty_python_semantic/resources/mdtest/narrow/match.md
2025-06-24 20:27:37 +00:00

4.1 KiB

Narrowing for match statements

[environment]
python-version = "3.10"

Single match pattern

def _(flag: bool):
    x = None if flag else 1

    reveal_type(x)  # revealed: None | Literal[1]

    y = 0

    match x:
        case None:
            y = x

    reveal_type(y)  # revealed: Literal[0] | None

Class patterns

def get_object() -> object:
    return object()

class A: ...
class B: ...

x = get_object()

reveal_type(x)  # revealed: object

match x:
    case A():
        reveal_type(x)  # revealed: A
    case B():
        reveal_type(x)  # revealed: B & ~A

reveal_type(x)  # revealed: object

Class pattern with guard

def get_object() -> object:
    return object()

class A:
    def y() -> int:
        return 1

class B: ...

x = get_object()

reveal_type(x)  # revealed: object

match x:
    case A() if reveal_type(x):  # revealed: A
        pass
    case B() if reveal_type(x):  # revealed: B
        pass

reveal_type(x)  # revealed: object

Value patterns

def get_object() -> object:
    return object()

x = get_object()

reveal_type(x)  # revealed: object

match x:
    case "foo":
        reveal_type(x)  # revealed: Literal["foo"]
    case 42:
        reveal_type(x)  # revealed: Literal[42]
    case 6.0:
        reveal_type(x)  # revealed: float
    case 1j:
        reveal_type(x)  # revealed: complex
    case b"foo":
        reveal_type(x)  # revealed: Literal[b"foo"]

reveal_type(x)  # revealed: object

Value patterns with guard

def get_object() -> object:
    return object()

x = get_object()

reveal_type(x)  # revealed: object

match x:
    case "foo" if reveal_type(x):  # revealed: Literal["foo"]
        pass
    case 42 if reveal_type(x):  # revealed: Literal[42]
        pass
    case 6.0 if reveal_type(x):  # revealed: float
        pass
    case 1j if reveal_type(x):  # revealed: complex
        pass
    case b"foo" if reveal_type(x):  # revealed: Literal[b"foo"]
        pass

reveal_type(x)  # revealed: object

Or patterns

def get_object() -> object:
    return object()

x = get_object()

reveal_type(x)  # revealed: object

match x:
    case "foo" | 42 | None:
        reveal_type(x)  # revealed: Literal["foo", 42] | None
    case "foo" | tuple():
        reveal_type(x)  # revealed: tuple[Unknown, ...]
    case True | False:
        reveal_type(x)  # revealed: bool
    case 3.14 | 2.718 | 1.414:
        reveal_type(x)  # revealed: float

reveal_type(x)  # revealed: object

Or patterns with guard

def get_object() -> object:
    return object()

x = get_object()

reveal_type(x)  # revealed: object

match x:
    case "foo" | 42 | None if reveal_type(x):  # revealed: Literal["foo", 42] | None
        pass
    case "foo" | tuple() if reveal_type(x):  # revealed: Literal["foo"] | tuple[Unknown, ...]
        pass
    case True | False if reveal_type(x):  # revealed: bool
        pass
    case 3.14 | 2.718 | 1.414 if reveal_type(x):  # revealed: float
        pass

reveal_type(x)  # revealed: object

Narrowing due to guard

def get_object() -> object:
    return object()

x = get_object()

reveal_type(x)  # revealed: object

match x:
    case str() | float() if type(x) is str:
        reveal_type(x)  #  revealed: str
    case "foo" | 42 | None if isinstance(x, int):
        reveal_type(x)  #  revealed: Literal[42]
    case False if x:
        reveal_type(x)  #  revealed: Never
    case "foo" if x := "bar":
        reveal_type(x)  # revealed: Literal["bar"]

reveal_type(x)  # revealed: object

Guard and reveal_type in guard

def get_object() -> object:
    return object()

x = get_object()

reveal_type(x)  # revealed: object

match x:
    case str() | float() if type(x) is str and reveal_type(x):  # revealed: str
        pass
    case "foo" | 42 | None if isinstance(x, int) and reveal_type(x):  #  revealed: Literal[42]
        pass
    case False if x and reveal_type(x):  #  revealed: Never
        pass
    case "foo" if (x := "bar") and reveal_type(x):  #  revealed: Literal["bar"]
        pass

reveal_type(x)  # revealed: object