blob: 4c0324b9bec762247ed09c01e47c5ffdf0a86db3 [file] [log] [blame] [edit]
-- Capture Pattern --
[case testCapturePatternType]
class A: ...
m: A
match m:
case a:
reveal_type(a) # N: Revealed type is "__main__.A"
-- Literal Pattern --
[case testLiteralPatternNarrows]
m: object
match m:
case 1:
reveal_type(m) # N: Revealed type is "Literal[1]?"
[case testLiteralPatternAlreadyNarrower]
m: bool
match m:
case 1:
reveal_type(m) # N: Revealed type is "builtins.bool"
[case testLiteralPatternUnreachable]
# primitives are needed because otherwise mypy doesn't see that int and str are incompatible
m: int
match m:
case "str":
reveal_type(m)
[builtins fixtures/primitives.pyi]
-- Value Pattern --
[case testValuePatternNarrows]
import b
m: object
match m:
case b.b:
reveal_type(m) # N: Revealed type is "builtins.int"
[file b.py]
b: int
[case testValuePatternAlreadyNarrower]
import b
m: bool
match m:
case b.b:
reveal_type(m) # N: Revealed type is "builtins.bool"
[file b.py]
b: int
[case testValuePatternIntersect]
import b
class A: ...
m: A
match m:
case b.b:
reveal_type(m) # N: Revealed type is "__main__.<subclass of "A" and "B">"
[file b.py]
class B: ...
b: B
[case testValuePatternUnreachable]
# primitives are needed because otherwise mypy doesn't see that int and str are incompatible
import b
m: int
match m:
case b.b:
reveal_type(m)
[file b.py]
b: str
[builtins fixtures/primitives.pyi]
-- Sequence Pattern --
[case testSequencePatternCaptures]
from typing import List
m: List[int]
match m:
case [a]:
reveal_type(a) # N: Revealed type is "builtins.int*"
[builtins fixtures/list.pyi]
[case testSequencePatternCapturesStarred]
from typing import Sequence
m: Sequence[int]
match m:
case [a, *b]:
reveal_type(a) # N: Revealed type is "builtins.int*"
reveal_type(b) # N: Revealed type is "builtins.list[builtins.int*]"
[builtins fixtures/list.pyi]
[case testSequencePatternNarrowsInner]
from typing import Sequence
m: Sequence[object]
match m:
case [1, True]:
reveal_type(m) # N: Revealed type is "typing.Sequence[builtins.int]"
[case testSequencePatternNarrowsOuter]
from typing import Sequence
m: object
match m:
case [1, True]:
reveal_type(m) # N: Revealed type is "typing.Sequence[builtins.int]"
[case testSequencePatternAlreadyNarrowerInner]
from typing import Sequence
m: Sequence[bool]
match m:
case [1, True]:
reveal_type(m) # N: Revealed type is "typing.Sequence[builtins.bool]"
[case testSequencePatternAlreadyNarrowerOuter]
from typing import Sequence
m: Sequence[object]
match m:
case [1, True]:
reveal_type(m) # N: Revealed type is "typing.Sequence[builtins.int]"
[case testSequencePatternAlreadyNarrowerBoth]
from typing import Sequence
m: Sequence[bool]
match m:
case [1, True]:
reveal_type(m) # N: Revealed type is "typing.Sequence[builtins.bool]"
[case testNestedSequencePatternNarrowsInner]
from typing import Sequence
m: Sequence[Sequence[object]]
match m:
case [[1], [True]]:
reveal_type(m) # N: Revealed type is "typing.Sequence[typing.Sequence[builtins.int]]"
[case testNestedSequencePatternNarrowsOuter]
from typing import Sequence
m: object
match m:
case [[1], [True]]:
reveal_type(m) # N: Revealed type is "typing.Sequence[typing.Sequence[builtins.int]]"
[case testSequencePatternDoesntNarrowInvariant]
from typing import List
m: List[object]
match m:
case [1]:
reveal_type(m) # N: Revealed type is "builtins.list[builtins.object]"
[builtins fixtures/list.pyi]
[case testSequencePatternMatches]
import array, collections
from typing import Sequence, Iterable
m1: object
m2: Sequence[int]
m3: array.array[int]
m4: collections.deque[int]
m5: list[int]
m6: memoryview
m7: range
m8: tuple[int]
m9: str
m10: bytes
m11: bytearray
match m1:
case [a]:
reveal_type(a) # N: Revealed type is "builtins.object"
match m2:
case [b]:
reveal_type(b) # N: Revealed type is "builtins.int*"
match m3:
case [c]:
reveal_type(c) # N: Revealed type is "builtins.int*"
match m4:
case [d]:
reveal_type(d) # N: Revealed type is "builtins.int*"
match m5:
case [e]:
reveal_type(e) # N: Revealed type is "builtins.int*"
match m6:
case [f]:
reveal_type(f) # N: Revealed type is "builtins.int*"
match m7:
case [g]:
reveal_type(g) # N: Revealed type is "builtins.int*"
match m8:
case [h]:
reveal_type(h) # N: Revealed type is "builtins.int"
match m9:
case [i]:
reveal_type(i)
match m10:
case [j]:
reveal_type(j)
match m11:
case [k]:
reveal_type(k)
[builtins fixtures/primitives.pyi]
[typing fixtures/typing-full.pyi]
[case testSequencePatternCapturesTuple]
from typing import Tuple
m: Tuple[int, str, bool]
match m:
case [a, b, c]:
reveal_type(a) # N: Revealed type is "builtins.int"
reveal_type(b) # N: Revealed type is "builtins.str"
reveal_type(c) # N: Revealed type is "builtins.bool"
reveal_type(m) # N: Revealed type is "Tuple[builtins.int, builtins.str, builtins.bool]"
[builtins fixtures/list.pyi]
[case testSequencePatternTupleTooLong]
from typing import Tuple
m: Tuple[int, str]
match m:
case [a, b, c]:
reveal_type(a)
reveal_type(b)
reveal_type(c)
[builtins fixtures/list.pyi]
[case testSequencePatternTupleTooShort]
from typing import Tuple
m: Tuple[int, str, bool]
match m:
case [a, b]:
reveal_type(a)
reveal_type(b)
[builtins fixtures/list.pyi]
[case testSequencePatternTupleNarrows]
from typing import Tuple
m: Tuple[object, object]
match m:
case [1, "str"]:
reveal_type(m) # N: Revealed type is "Tuple[Literal[1]?, Literal['str']?]"
[builtins fixtures/list.pyi]
[case testSequencePatternTupleStarred]
from typing import Tuple
m: Tuple[int, str, bool]
match m:
case [a, *b, c]:
reveal_type(a) # N: Revealed type is "builtins.int"
reveal_type(b) # N: Revealed type is "builtins.list[builtins.str]"
reveal_type(c) # N: Revealed type is "builtins.bool"
reveal_type(m) # N: Revealed type is "Tuple[builtins.int, builtins.str, builtins.bool]"
[builtins fixtures/list.pyi]
[case testSequencePatternTupleStarredUnion]
from typing import Tuple
m: Tuple[int, str, float, bool]
match m:
case [a, *b, c]:
reveal_type(a) # N: Revealed type is "builtins.int"
reveal_type(b) # N: Revealed type is "builtins.list[Union[builtins.str, builtins.float]]"
reveal_type(c) # N: Revealed type is "builtins.bool"
reveal_type(m) # N: Revealed type is "Tuple[builtins.int, builtins.str, builtins.float, builtins.bool]"
[builtins fixtures/list.pyi]
[case testSequencePatternTupleStarredTooShort]
from typing import Tuple
m: Tuple[int]
reveal_type(m) # N: Revealed type is "Tuple[builtins.int]"
match m:
case [a, *b, c]:
reveal_type(a)
reveal_type(b)
reveal_type(c)
[builtins fixtures/list.pyi]
[case testNonMatchingSequencePattern]
from typing import List
x: List[int]
match x:
case [str()]:
pass
[case testSequenceUnion-skip]
from typing import List, Union
m: Union[List[List[str]], str]
match m:
case [list(['str'])]:
reveal_type(m) # N: Revealed type is "builtins.list[builtins.list[builtins.str]]"
[builtins fixtures/list.pyi]
-- Mapping Pattern --
[case testMappingPatternCaptures]
from typing import Dict
import b
m: Dict[str, int]
match m:
case {"key": v}:
reveal_type(v) # N: Revealed type is "builtins.int*"
case {b.b: v2}:
reveal_type(v2) # N: Revealed type is "builtins.int*"
[file b.py]
b: str
[builtins fixtures/dict.pyi]
[case testMappingPatternCapturesWrongKeyType]
# This is not actually unreachable, as a subclass of dict could accept keys with different types
from typing import Dict
import b
m: Dict[str, int]
match m:
case {1: v}:
reveal_type(v) # N: Revealed type is "builtins.int*"
case {b.b: v2}:
reveal_type(v2) # N: Revealed type is "builtins.int*"
[file b.py]
b: int
[builtins fixtures/dict.pyi]
[case testMappingPatternCapturesTypedDict]
from typing import TypedDict
class A(TypedDict):
a: str
b: int
m: A
match m:
case {"a": v}:
reveal_type(v) # N: Revealed type is "builtins.str"
case {"b": v2}:
reveal_type(v2) # N: Revealed type is "builtins.int"
case {"a": v3, "b": v4}:
reveal_type(v3) # N: Revealed type is "builtins.str"
reveal_type(v4) # N: Revealed type is "builtins.int"
case {"o": v5}:
reveal_type(v5) # N: Revealed type is "builtins.object*"
[typing fixtures/typing-typeddict.pyi]
[case testMappingPatternCapturesTypedDictWithLiteral]
from typing import TypedDict
import b
class A(TypedDict):
a: str
b: int
m: A
match m:
case {b.a: v}:
reveal_type(v) # N: Revealed type is "builtins.str"
case {b.b: v2}:
reveal_type(v2) # N: Revealed type is "builtins.int"
case {b.a: v3, b.b: v4}:
reveal_type(v3) # N: Revealed type is "builtins.str"
reveal_type(v4) # N: Revealed type is "builtins.int"
case {b.o: v5}:
reveal_type(v5) # N: Revealed type is "builtins.object*"
[file b.py]
from typing import Final, Literal
a: Final = "a"
b: Literal["b"] = "b"
o: Final[str] = "o"
[typing fixtures/typing-typeddict.pyi]
[case testMappingPatternCapturesTypedDictWithNonLiteral]
from typing import TypedDict
import b
class A(TypedDict):
a: str
b: int
m: A
match m:
case {b.a: v}:
reveal_type(v) # N: Revealed type is "builtins.object*"
[file b.py]
from typing import Final, Literal
a: str
[typing fixtures/typing-typeddict.pyi]
[case testMappingPatternCapturesTypedDictUnreachable]
# TypedDict keys are always str, so this is actually unreachable
from typing import TypedDict
import b
class A(TypedDict):
a: str
b: int
m: A
match m:
case {1: v}:
reveal_type(v)
case {b.b: v2}:
reveal_type(v2)
[file b.py]
b: int
[typing fixtures/typing-typeddict.pyi]
[case testMappingPatternCaptureRest]
m: object
match m:
case {'k': 1, **r}:
reveal_type(r) # N: Revealed type is "builtins.dict[builtins.object, builtins.object]"
[builtins fixtures/dict.pyi]
[case testMappingPatternCaptureRestFromMapping]
from typing import Mapping
m: Mapping[str, int]
match m:
case {'k': 1, **r}:
reveal_type(r) # N: Revealed type is "builtins.dict[builtins.str*, builtins.int*]"
[builtins fixtures/dict.pyi]
-- Mapping patterns currently don't narrow --
-- Class Pattern --
[case testClassPatternCapturePositional]
from typing import Final
class A:
__match_args__: Final = ("a", "b")
a: str
b: int
m: A
match m:
case A(i, j):
reveal_type(i) # N: Revealed type is "builtins.str"
reveal_type(j) # N: Revealed type is "builtins.int"
[builtins fixtures/tuple.pyi]
[case testClassPatternMemberClassCapturePositional]
import b
m: b.A
match m:
case b.A(i, j):
reveal_type(i) # N: Revealed type is "builtins.str"
reveal_type(j) # N: Revealed type is "builtins.int"
[file b.py]
from typing import Final
class A:
__match_args__: Final = ("a", "b")
a: str
b: int
[builtins fixtures/tuple.pyi]
[case testClassPatternCaptureKeyword]
class A:
a: str
b: int
m: A
match m:
case A(a=i, b=j):
reveal_type(i) # N: Revealed type is "builtins.str"
reveal_type(j) # N: Revealed type is "builtins.int"
[case testClassPatternCaptureSelf]
m: object
match m:
case bool(a):
reveal_type(a) # N: Revealed type is "builtins.bool"
case bytearray(b):
reveal_type(b) # N: Revealed type is "builtins.bytearray"
case bytes(c):
reveal_type(c) # N: Revealed type is "builtins.bytes"
case dict(d):
reveal_type(d) # N: Revealed type is "builtins.dict[Any, Any]"
case float(e):
reveal_type(e) # N: Revealed type is "builtins.float"
case frozenset(f):
reveal_type(f) # N: Revealed type is "builtins.frozenset[Any]"
case int(g):
reveal_type(g) # N: Revealed type is "builtins.int"
case list(h):
reveal_type(h) # N: Revealed type is "builtins.list[Any]"
case set(i):
reveal_type(i) # N: Revealed type is "builtins.set[Any]"
case str(j):
reveal_type(j) # N: Revealed type is "builtins.str"
case tuple(k):
reveal_type(k) # N: Revealed type is "builtins.tuple[Any, ...]"
[builtins fixtures/primitives.pyi]
[case testClassPatternNarrowSelfCapture]
m: object
match m:
case bool():
reveal_type(m) # N: Revealed type is "builtins.bool"
case bytearray():
reveal_type(m) # N: Revealed type is "builtins.bytearray"
case bytes():
reveal_type(m) # N: Revealed type is "builtins.bytes"
case dict():
reveal_type(m) # N: Revealed type is "builtins.dict[Any, Any]"
case float():
reveal_type(m) # N: Revealed type is "builtins.float"
case frozenset():
reveal_type(m) # N: Revealed type is "builtins.frozenset[Any]"
case int():
reveal_type(m) # N: Revealed type is "builtins.int"
case list():
reveal_type(m) # N: Revealed type is "builtins.list[Any]"
case set():
reveal_type(m) # N: Revealed type is "builtins.set[Any]"
case str():
reveal_type(m) # N: Revealed type is "builtins.str"
case tuple():
reveal_type(m) # N: Revealed type is "builtins.tuple[Any, ...]"
[builtins fixtures/primitives.pyi]
[case testClassPatternCaptureDataclass]
from dataclasses import dataclass
@dataclass
class A:
a: str
b: int
m: A
match m:
case A(i, j):
reveal_type(i) # N: Revealed type is "builtins.str"
reveal_type(j) # N: Revealed type is "builtins.int"
[builtins fixtures/dataclasses.pyi]
[case testClassPatternCaptureDataclassNoMatchArgs]
from dataclasses import dataclass
@dataclass(match_args=False)
class A:
a: str
b: int
m: A
match m:
case A(i, j): # E: Class "__main__.A" doesn't define "__match_args__"
pass
[builtins fixtures/dataclasses.pyi]
[case testClassPatternCaptureDataclassPartialMatchArgs]
from dataclasses import dataclass, field
@dataclass
class A:
a: str
b: int = field(init=False)
m: A
match m:
case A(i, j): # E: Too many positional patterns for class pattern
pass
case A(k):
reveal_type(k) # N: Revealed type is "builtins.str"
[builtins fixtures/dataclasses.pyi]
[case testClassPatternCaptureNamedTupleInline]
from collections import namedtuple
A = namedtuple("A", ["a", "b"])
m: A
match m:
case A(i, j):
reveal_type(i) # N: Revealed type is "Any"
reveal_type(j) # N: Revealed type is "Any"
[builtins fixtures/list.pyi]
[case testClassPatternCaptureNamedTupleInlineTyped]
from typing import NamedTuple
A = NamedTuple("A", [("a", str), ("b", int)])
m: A
match m:
case A(i, j):
reveal_type(i) # N: Revealed type is "builtins.str"
reveal_type(j) # N: Revealed type is "builtins.int"
[builtins fixtures/list.pyi]
[case testClassPatternCaptureNamedTupleClass]
from typing import NamedTuple
class A(NamedTuple):
a: str
b: int
m: A
match m:
case A(i, j):
reveal_type(i) # N: Revealed type is "builtins.str"
reveal_type(j) # N: Revealed type is "builtins.int"
[builtins fixtures/tuple.pyi]
[case testClassPatternCaptureGeneric]
from typing import Generic, TypeVar
T = TypeVar('T')
class A(Generic[T]):
a: T
m: object
match m:
case A(a=i):
reveal_type(m) # N: Revealed type is "__main__.A[Any]"
reveal_type(i) # N: Revealed type is "Any"
[case testClassPatternCaptureGenericAlreadyKnown]
from typing import Generic, TypeVar
T = TypeVar('T')
class A(Generic[T]):
a: T
m: A[int]
match m:
case A(a=i):
reveal_type(m) # N: Revealed type is "__main__.A[builtins.int]"
reveal_type(i) # N: Revealed type is "builtins.int*"
[case testClassPatternCaptureFilledGenericTypeAlias]
from typing import Generic, TypeVar
T = TypeVar('T')
class A(Generic[T]):
a: T
B = A[int]
m: object
match m:
case B(a=i): # E: Class pattern class must not be a type alias with type parameters
reveal_type(i)
[case testClassPatternCaptureGenericTypeAlias]
from typing import Generic, TypeVar
T = TypeVar('T')
class A(Generic[T]):
a: T
B = A
m: object
match m:
case B(a=i):
pass
[case testClassPatternNarrows]
from typing import Final
class A:
__match_args__: Final = ("a", "b")
a: str
b: int
m: object
match m:
case A():
reveal_type(m) # N: Revealed type is "__main__.A"
case A(i, j):
reveal_type(m) # N: Revealed type is "__main__.A"
[builtins fixtures/tuple.pyi]
[case testClassPatternNarrowsUnion]
from typing import Final, Union
class A:
__match_args__: Final = ("a", "b")
a: str
b: int
class B:
__match_args__: Final = ("a", "b")
a: int
b: str
m: Union[A, B]
match m:
case A():
reveal_type(m) # N: Revealed type is "__main__.A"
match m:
case A(i, j):
reveal_type(m) # N: Revealed type is "__main__.A"
reveal_type(i) # N: Revealed type is "builtins.str"
reveal_type(j) # N: Revealed type is "builtins.int"
match m:
case B():
reveal_type(m) # N: Revealed type is "__main__.B"
match m:
case B(k, l):
reveal_type(m) # N: Revealed type is "__main__.B"
reveal_type(k) # N: Revealed type is "builtins.int"
reveal_type(l) # N: Revealed type is "builtins.str"
[builtins fixtures/tuple.pyi]
[case testClassPatternAlreadyNarrower]
from typing import Final
class A:
__match_args__: Final = ("a", "b")
a: str
b: int
class B(A): ...
m: B
match m:
case A():
reveal_type(m) # N: Revealed type is "__main__.B"
match m:
case A(i, j):
reveal_type(m) # N: Revealed type is "__main__.B"
[builtins fixtures/tuple.pyi]
[case testClassPatternIntersection]
from typing import Final
class A:
__match_args__: Final = ("a", "b")
a: str
b: int
class B: ...
m: B
match m:
case A():
reveal_type(m) # N: Revealed type is "__main__.<subclass of "B" and "A">"
case A(i, j):
reveal_type(m) # N: Revealed type is "__main__.<subclass of "B" and "A">1"
[builtins fixtures/tuple.pyi]
[case testClassPatternNonexistentKeyword]
class A: ...
m: object
match m:
case A(a=j): # E: Class "__main__.A" has no attribute "a"
reveal_type(m) # N: Revealed type is "__main__.A"
reveal_type(j) # N: Revealed type is "Any"
[case testClassPatternDuplicateKeyword]
class A:
a: str
m: object
match m:
case A(a=i, a=j): # E: Duplicate keyword pattern "a"
pass
[case testClassPatternDuplicateImplicitKeyword]
from typing import Final
class A:
__match_args__: Final = ("a",)
a: str
m: object
match m:
case A(i, a=j): # E: Keyword "a" already matches a positional pattern
pass
[builtins fixtures/tuple.pyi]
[case testClassPatternTooManyPositionals]
from typing import Final
class A:
__match_args__: Final = ("a", "b")
a: str
b: int
m: object
match m:
case A(i, j, k): # E: Too many positional patterns for class pattern
pass
[builtins fixtures/tuple.pyi]
[case testClassPatternIsNotType]
a = 1
m: object
match m:
case a(i, j): # E: Expected type in class pattern; found "builtins.int"
reveal_type(i)
reveal_type(j)
[case testClassPatternNestedGenerics]
# From cpython test_patma.py
x = [[{0: 0}]]
match x:
case list([({-0-0j: int(real=0+0j, imag=0-0j) | (1) as z},)]):
y = 0
reveal_type(x) # N: Revealed type is "builtins.list[builtins.list*[builtins.dict*[builtins.int*, builtins.int*]]]"
reveal_type(y) # N: Revealed type is "builtins.int"
reveal_type(z) # N: Revealed type is "builtins.int*"
[builtins fixtures/dict.pyi]
[case testNonFinalMatchArgs]
class A:
__match_args__ = ("a", "b") # N: __match_args__ must be final for checking of match statements to work
a: str
b: int
m: object
match m:
case A(i, j):
reveal_type(i) # N: Revealed type is "Any"
reveal_type(j) # N: Revealed type is "Any"
[builtins fixtures/tuple.pyi]
[case testAnyTupleMatchArgs]
from typing import Tuple, Any
class A:
__match_args__: Tuple[Any, ...]
a: str
b: int
m: object
match m:
case A(i, j, k):
reveal_type(i) # N: Revealed type is "Any"
reveal_type(j) # N: Revealed type is "Any"
reveal_type(k) # N: Revealed type is "Any"
[builtins fixtures/tuple.pyi]
[case testNonLiteralMatchArgs]
from typing import Final
b: str = "b"
class A:
__match_args__: Final = ("a", b) # N: __match_args__ must be a tuple containing string literals for checking of match statements to work
a: str
b: int
m: object
match m:
case A(i, j, k): # E: Too many positional patterns for class pattern
pass
case A(i, j):
reveal_type(i) # N: Revealed type is "builtins.str"
reveal_type(j) # N: Revealed type is "Any"
[builtins fixtures/tuple.pyi]
[case testExternalMatchArgs]
from typing import Final, Literal
args: Final = ("a", "b")
class A:
__match_args__: Final = args
a: str
b: int
arg: Final = "a"
arg2: Literal["b"] = "b"
class B:
__match_args__: Final = (arg, arg2)
a: str
b: int
[builtins fixtures/tuple.pyi]
[typing fixtures/typing-medium.pyi]
-- As Pattern --
[case testAsPattern]
m: int
match m:
case x as l:
reveal_type(x) # N: Revealed type is "builtins.int"
reveal_type(l) # N: Revealed type is "builtins.int"
[case testAsPatternNarrows]
m: object
match m:
case int() as l:
reveal_type(l) # N: Revealed type is "builtins.int"
[case testAsPatternCapturesOr]
m: object
match m:
case 1 | 2 as n:
reveal_type(n) # N: Revealed type is "Union[Literal[1]?, Literal[2]?]"
[case testAsPatternAlreadyNarrower]
m: bool
match m:
case int() as l:
reveal_type(l) # N: Revealed type is "builtins.bool"
-- Or Pattern --
[case testOrPatternNarrows]
m: object
match m:
case 1 | 2:
reveal_type(m) # N: Revealed type is "Union[Literal[1]?, Literal[2]?]"
[case testOrPatternNarrowsStr]
m: object
match m:
case "foo" | "bar":
reveal_type(m) # N: Revealed type is "Union[Literal['foo']?, Literal['bar']?]"
[case testOrPatternNarrowsUnion]
m: object
match m:
case 1 | "foo":
reveal_type(m) # N: Revealed type is "Union[Literal[1]?, Literal['foo']?]"
[case testOrPatterCapturesMissing]
from typing import List
m: List[int]
match m:
case [x, y] | list(x): # E: Alternative patterns bind different names
reveal_type(x) # N: Revealed type is "builtins.object"
reveal_type(y) # N: Revealed type is "builtins.int*"
[builtins fixtures/list.pyi]
[case testOrPatternCapturesJoin]
m: object
match m:
case list(x) | dict(x):
reveal_type(x) # N: Revealed type is "typing.Iterable[Any]"
[builtins fixtures/dict.pyi]
-- Interactions --
[case testCapturePatternMultipleCases]
m: object
match m:
case int(x):
reveal_type(x) # N: Revealed type is "builtins.int"
case str(x):
reveal_type(x) # N: Revealed type is "builtins.str"
reveal_type(x) # N: Revealed type is "Union[builtins.int, builtins.str]"
[case testCapturePatternMultipleCaptures]
from typing import Iterable
m: Iterable[int]
match m:
case [x, x]: # E: Multiple assignments to name "x" in pattern
reveal_type(x) # N: Revealed type is "builtins.int"
[builtins fixtures/list.pyi]
[case testCapturePatternPreexistingSame]
a: int
m: int
match m:
case a:
reveal_type(a) # N: Revealed type is "builtins.int"
[case testCapturePatternPreexistingIncompatible]
a: str
m: int
match m:
case a: # E: Incompatible types in capture pattern (pattern captures type "int", variable has type "str")
reveal_type(a) # N: Revealed type is "builtins.str"
[case testCapturePatternPreexistingIncompatibleLater]
a: str
m: object
match m:
case str(a):
reveal_type(a) # N: Revealed type is "builtins.str"
case int(a): # E: Incompatible types in capture pattern (pattern captures type "int", variable has type "str")
reveal_type(a) # N: Revealed type is "builtins.str"
-- Guards --
[case testSimplePatternGuard]
m: str
def guard() -> bool: ...
match m:
case a if guard():
reveal_type(a) # N: Revealed type is "builtins.str"
[case testAlwaysTruePatternGuard]
m: str
match m:
case a if True:
reveal_type(a) # N: Revealed type is "builtins.str"
[case testAlwaysFalsePatternGuard]
m: str
match m:
case a if False:
reveal_type(a)
[case testRedefiningPatternGuard]
# flags: --strict-optional
m: str
match m:
case a if a := 1: # E: Incompatible types in assignment (expression has type "int", variable has type "str")
reveal_type(a) # N: Revealed type is "<nothing>"
[case testAssigningPatternGuard]
m: str
match m:
case a if a := "test":
reveal_type(a) # N: Revealed type is "builtins.str"
[case testNarrowingPatternGuard]
m: object
match m:
case a if isinstance(a, str):
reveal_type(a) # N: Revealed type is "builtins.str"
[builtins fixtures/isinstancelist.pyi]
[case testIncompatiblePatternGuard]
class A: ...
class B: ...
m: A
match m:
case a if isinstance(a, B):
reveal_type(a) # N: Revealed type is "__main__.<subclass of "A" and "B">"
[builtins fixtures/isinstancelist.pyi]
[case testUnreachablePatternGuard]
m: str
match m:
case a if isinstance(a, int):
reveal_type(a)
[builtins fixtures/isinstancelist.pyi]
-- Exhaustiveness --
[case testUnionNegativeNarrowing-skip]
from typing import Union
m: Union[str, int]
match m:
case str(a):
reveal_type(a) # N: Revealed type is "builtins.str"
reveal_type(m) # N: Revealed type is "builtins.str"
case b:
reveal_type(b) # N: Revealed type is "builtins.int"
reveal_type(m) # N: Revealed type is "builtins.int"
[case testOrPatternNegativeNarrowing-skip]
from typing import Union
m: Union[str, bytes, int]
match m:
case str(a) | bytes(a):
reveal_type(a) # N: Revealed type is "builtins.object"
reveal_type(m) # N: Revealed type is "Union[builtins.str, builtins.bytes]"
case b:
reveal_type(b) # N: Revealed type is "builtins.int"
[case testExhaustiveReturn-skip]
def foo(value) -> int:
match value:
case "bar":
return 1
case _:
return 2
[case testNoneExhaustiveReturn-skip]
def foo(value) -> int: # E: Missing return statement
match value:
case "bar":
return 1
case 2:
return 2