From 2f4bd298c8326994529561711b76fe354586a6e3 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Wed, 7 Sep 2022 16:16:25 +0300 Subject: [PATCH 1/2] Fix type inference in pattern matching by positional argument --- mypy/expandtype.py | 2 +- test-data/unit/check-python310.test | 46 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/mypy/expandtype.py b/mypy/expandtype.py index 959983ae66d1..c8d15566e810 100644 --- a/mypy/expandtype.py +++ b/mypy/expandtype.py @@ -136,7 +136,7 @@ def visit_erased_type(self, t: ErasedType) -> Type: def visit_instance(self, t: Instance) -> Type: args = self.expand_types_with_unpack(list(t.args)) if isinstance(args, list): - return Instance(t.type, args, t.line, t.column) + return t.copy_modified(args=args) else: return args diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 298ec9e45998..21972ede73bf 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -1628,3 +1628,49 @@ match var: case ("yes", b): reveal_type(b) # N: Revealed type is "Union[builtins.int, builtins.str]" [builtins fixtures/tuple.pyi] + +[case testMatchNamedAndKeywordsAreTheSame] +from typing import Generic, TypeVar, Union +from typing_extensions import Final + +T = TypeVar("T") + +class Regular: + x: str + y: int + __match_args__ = ("x",) +class ReveresedOrder: + x: int + y: str + __match_args__ = ("y",) +class GenericRegular(Generic[T]): + x: T + __match_args__ = ("x",) +class GenericWithFinal(Generic[T]): + x: T + __match_args__: Final = ("x",) + +input_arg: Union[Regular, ReveresedOrder, GenericRegular[str], GenericWithFinal[str]] + +# Positional: +match input_arg: + case Regular(a): + reveal_type(a) # N: Revealed type is "builtins.str" + case ReveresedOrder(a): + reveal_type(a) # N: Revealed type is "builtins.str" + case GenericRegular(a): + reveal_type(a) # N: Revealed type is "builtins.str" + case GenericWithFinal(a): + reveal_type(a) # N: Revealed type is "builtins.str" + +# Keywords: +match input_arg: + case Regular(x=a): + reveal_type(a) # N: Revealed type is "builtins.str" + case ReveresedOrder(x=b): # note, that order is different + reveal_type(b) # N: Revealed type is "builtins.int" + case GenericRegular(x=a): + reveal_type(a) # N: Revealed type is "builtins.str" + case GenericWithFinal(x=a): + reveal_type(a) # N: Revealed type is "builtins.str" +[builtins fixtures/tuple.pyi] From 311e6fc473ac16b2644abf6ebdb096422c6e8bb1 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Wed, 7 Sep 2022 18:06:39 +0300 Subject: [PATCH 2/2] More tests --- test-data/unit/check-python310.test | 31 ++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 21972ede73bf..22af3ddc0700 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -1632,6 +1632,7 @@ match var: [case testMatchNamedAndKeywordsAreTheSame] from typing import Generic, TypeVar, Union from typing_extensions import Final +from dataclasses import dataclass T = TypeVar("T") @@ -1649,8 +1650,20 @@ class GenericRegular(Generic[T]): class GenericWithFinal(Generic[T]): x: T __match_args__: Final = ("x",) +class RegularSubtype(GenericRegular[str]): ... + +@dataclass +class GenericDataclass(Generic[T]): + x: T -input_arg: Union[Regular, ReveresedOrder, GenericRegular[str], GenericWithFinal[str]] +input_arg: Union[ + Regular, + ReveresedOrder, + GenericRegular[str], + GenericWithFinal[str], + RegularSubtype, + GenericDataclass[str], +] # Positional: match input_arg: @@ -1658,19 +1671,27 @@ match input_arg: reveal_type(a) # N: Revealed type is "builtins.str" case ReveresedOrder(a): reveal_type(a) # N: Revealed type is "builtins.str" + case GenericWithFinal(a): + reveal_type(a) # N: Revealed type is "builtins.str" + case RegularSubtype(a): + reveal_type(a) # N: Revealed type is "builtins.str" case GenericRegular(a): reveal_type(a) # N: Revealed type is "builtins.str" - case GenericWithFinal(a): + case GenericDataclass(a): reveal_type(a) # N: Revealed type is "builtins.str" # Keywords: match input_arg: case Regular(x=a): reveal_type(a) # N: Revealed type is "builtins.str" - case ReveresedOrder(x=b): # note, that order is different + case ReveresedOrder(x=b): # Order is different reveal_type(b) # N: Revealed type is "builtins.int" + case GenericWithFinal(x=a): + reveal_type(a) # N: Revealed type is "builtins.str" + case RegularSubtype(x=a): + reveal_type(a) # N: Revealed type is "builtins.str" case GenericRegular(x=a): reveal_type(a) # N: Revealed type is "builtins.str" - case GenericWithFinal(x=a): + case GenericDataclass(x=a): reveal_type(a) # N: Revealed type is "builtins.str" -[builtins fixtures/tuple.pyi] +[builtins fixtures/dataclasses.pyi]