diff --git a/mypy/checkpattern.py b/mypy/checkpattern.py index 6b4fa35f9c49..a7121712a6db 100644 --- a/mypy/checkpattern.py +++ b/mypy/checkpattern.py @@ -693,7 +693,9 @@ def visit_class_pattern(self, o: ClassPattern) -> PatternType: def should_self_match(self, typ: Type) -> bool: typ = get_proper_type(typ) - if isinstance(typ, Instance) and typ.type.is_named_tuple: + if isinstance(typ, Instance) and typ.type.get("__match_args__") is not None: + # Named tuples and other subtypes of builtins that define __match_args__ + # should not self match. return False for other in self.self_match_types: if is_subtype(typ, other): diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 58b70d7b74d8..8187f27353a9 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -648,6 +648,25 @@ match m: reveal_type(m) # N: Revealed type is "builtins.tuple[Any, ...]" [builtins fixtures/primitives.pyi] +[case testMatchClassPatternCaptureSelfSubtype] +class A(str): + pass + +class B(str): + __match_args__ = ("b",) + b: int + +def f1(x: A): + match x: + case A(a): + reveal_type(a) # N: Revealed type is "__main__.A" + +def f2(x: B): + match x: + case B(b): + reveal_type(b) # N: Revealed type is "builtins.int" +[builtins fixtures/tuple.pyi] + [case testMatchInvalidClassPattern] m: object