[match-case]: `TypedDict` interaction with mapping pattern
topic: documentation
It seems match-cases [mapping pattern](https://peps.python.org/pep-0634/#mapping-patterns) is predestined to work well with `TypedDict`, but currently the spec is silent regarding `TypedDict` subtyping with respect to match case: https://typing.python.org/en/latest/spec/typeddict.html#subtyping-with-mapping
At the time of writing, not a single type checker (tested with `mypy=1.19.1`, `pyright=1.1.408`, `ty=0.0.17`, `pyrefly=0.53.0` and `zuban=0.6.0`) can solve the following tests[^1], suggesting that some standardization / typing spec guidance may be useful.
```python
from typing import TypedDict, assert_type, assert_never
class D(TypedDict):
name: str
value: int
def test_match_key(x: D | int) -> None:
match x:
case {"name": _}:
# runtime equivalent to (isinstance(x, Mapping) and "name" in x)
assert_type(x, D)
case _:
assert_type(x, int)
def test_match_key_and_value(x: D | int) -> None:
match x:
case {"name": str()}:
# runtime equivalent to (isinstance(x, Mapping)
# and "name" in x and isinstance(x["name"], str))
assert_type(x, D)
case _:
assert_type(x, int)
def test_non_match(x: D | int) -> None:
match x:
case {"value": str()}:
# runtime equivalent to (isinstance(x, Mapping)
# and "value" in x and isinstance(x["value"], str))
assert_never(x)
case _:
assert_type(x, D | int)
```
[^1]: technically, it is possible to make a shared subclass of `int` and `collections.abc.Mapping`, so the `assert_type` in the `case {...}` are debatable, though the inference in the `case _` branches should not be affected.
0 条评论