Skip to content

Narrow mapping types when pattern-matching an empty mapping #18950

Open
@fofoni

Description

@fofoni

Feature

I believe mypy's behavior when encountering the pattern {} should be the same as for the collections.abc.Mapping() pattern.

Consider:

value: str | dict[str, float]

match value:
    case str():  reveal_type(value)  # str
    case _:      reveal_type(value)  # dict[str, float]

match value:
    case dict(): reveal_type(value)  # dict[str, float]
    case _:      reveal_type(value)  # str

In both examples above, mypy correctly narrows each case. However:

match value:
    case {}:     reveal_type(value)  # str | dict[str, float]
    case _:      reveal_type(value)  # str | dict[str, float]

Mypy won't narrow here. I suspect this is because a generic mapping pattern really can't be used for narrowing, since the generic mapping pattern only captures mapping with specific keys, which the typing knows nothing about (unless maybe if value was a typed dict?).

However, the empty mapping pattern {} simply captures any mapping, and could therefore be used for type-narrowing.

Tested in mypy-play with master branch: https://mypy-play.net/?mypy=master&python=3.12&gist=f8c39599ed8a952a04cc796fabf01f54

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions