From 92ddc93971e04b4e6036648b883b8b74160e8c91 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Sat, 24 Sep 2022 13:12:38 -0700 Subject: [PATCH 1/4] test --- test-data/unit/check-python310.test | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test-data/unit/check-python310.test b/test-data/unit/check-python310.test index 22af3ddc0700d..5cbead8584ebb 100644 --- a/test-data/unit/check-python310.test +++ b/test-data/unit/check-python310.test @@ -1695,3 +1695,18 @@ match input_arg: case GenericDataclass(x=a): reveal_type(a) # N: Revealed type is "builtins.str" [builtins fixtures/dataclasses.pyi] + +[case testMatchValueConstrainedTypeVar] +from typing import TypeVar, Iterable + +S = TypeVar("S", int, str) + +def my_func(pairs: Iterable[tuple[S, S]]) -> None: + for pair in pairs: + reveal_type(pair) # N: Revealed type is "Tuple[builtins.int, builtins.int]" \ + # N: Revealed type is "Tuple[builtins.str, builtins.str]" + match pair: + case _: + reveal_type(pair) # N: Revealed type is "Tuple[builtins.int, builtins.int]" \ + # N: Revealed type is "Tuple[builtins.str, builtins.str]" +[builtins fixtures/tuple.pyi] From 2d3ad6444c76c40d6d669d47317a2bdebefb29a9 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Sat, 24 Sep 2022 13:13:04 -0700 Subject: [PATCH 2/4] fix --- mypy/treetransform.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/mypy/treetransform.py b/mypy/treetransform.py index ca50afde75565..d27d1f861b1b6 100644 --- a/mypy/treetransform.py +++ b/mypy/treetransform.py @@ -49,6 +49,7 @@ LambdaExpr, ListComprehension, ListExpr, + MatchStmt, MemberExpr, MypyFile, NamedTupleExpr, @@ -381,6 +382,14 @@ def visit_with_stmt(self, node: WithStmt) -> WithStmt: new.analyzed_types = [self.type(typ) for typ in node.analyzed_types] return new + def visit_match_stmt(self, o: MatchStmt) -> MatchStmt: + return MatchStmt( + subject=self.expr(o.subject), + patterns=o.patterns, + guards=self.optional_expressions(o.guards), + bodies=self.blocks(o.bodies), + ) + def visit_star_expr(self, node: StarExpr) -> StarExpr: return StarExpr(node.expr) From 7bcd0b531e96cc2bee91bb60356c621fa0ef4130 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Sun, 25 Sep 2022 14:54:21 -0700 Subject: [PATCH 3/4] visit all the patterns --- mypy/treetransform.py | 57 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/mypy/treetransform.py b/mypy/treetransform.py index d27d1f861b1b6..26cc9022a08c3 100644 --- a/mypy/treetransform.py +++ b/mypy/treetransform.py @@ -91,6 +91,17 @@ YieldExpr, YieldFromExpr, ) +from mypy.patterns import ( + Pattern, + AsPattern, + OrPattern, + ValuePattern, + SingletonPattern, + SequencePattern, + StarredPattern, + MappingPattern, + ClassPattern, +) from mypy.traverser import TraverserVisitor from mypy.types import FunctionLike, ProperType, Type from mypy.util import replace_object_state @@ -382,10 +393,48 @@ def visit_with_stmt(self, node: WithStmt) -> WithStmt: new.analyzed_types = [self.type(typ) for typ in node.analyzed_types] return new + def visit_as_pattern(self, p: AsPattern) -> AsPattern: + return AsPattern( + pattern=self.pattern(p.pattern) if p.pattern is not None else None, + name=self.duplicate_name(p.name) if p.name is not None else None, + ) + + def visit_or_pattern(self, p: OrPattern) -> OrPattern: + return OrPattern([self.pattern(pat) for pat in p.patterns]) + + def visit_value_pattern(self, p: ValuePattern) -> ValuePattern: + return ValuePattern(self.expr(p.expr)) + + def visit_singleton_pattern(self, p: SingletonPattern) -> SingletonPattern: + return SingletonPattern(p.value) + + def visit_sequence_pattern(self, p: SequencePattern) -> SequencePattern: + return SequencePattern([self.pattern(pat) for pat in p.patterns]) + + def visit_starred_pattern(self, p: StarredPattern) -> StarredPattern: + return StarredPattern(self.duplicate_name(p.capture) if p.capture is not None else None) + + def visit_mapping_pattern(self, p: MappingPattern) -> MappingPattern: + return MappingPattern( + keys=[self.expr(expr) for expr in p.keys], + values=[self.pattern(pat) for pat in p.values], + rest=self.duplicate_name(p.rest) if p.rest is not None else None, + ) + + def visit_class_pattern(self, p: ClassPattern) -> ClassPattern: + class_ref = p.class_ref.accept(self) + assert isinstance(class_ref, RefExpr) + return ClassPattern( + class_ref=class_ref, + positionals=[self.pattern(pat) for pat in p.positionals], + keyword_keys=list(p.keyword_keys), + keyword_values=[self.pattern(pat) for pat in p.keyword_values], + ) + def visit_match_stmt(self, o: MatchStmt) -> MatchStmt: return MatchStmt( subject=self.expr(o.subject), - patterns=o.patterns, + patterns=[self.pattern(p) for p in o.patterns], guards=self.optional_expressions(o.guards), bodies=self.blocks(o.bodies), ) @@ -646,6 +695,12 @@ def stmt(self, stmt: Statement) -> Statement: new.set_line(stmt) return new + def pattern(self, pattern: Pattern) -> Pattern: + new = pattern.accept(self) + assert isinstance(new, Pattern) + new.set_line(pattern) + return new + # Helpers # # All the node helpers also propagate line numbers. From d5eb68d089c4643885c5626f2c436573e75d5965 Mon Sep 17 00:00:00 2001 From: hauntsaninja Date: Sun, 25 Sep 2022 15:18:31 -0700 Subject: [PATCH 4/4] isort --- mypy/treetransform.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mypy/treetransform.py b/mypy/treetransform.py index 26cc9022a08c3..d7f159d02a229 100644 --- a/mypy/treetransform.py +++ b/mypy/treetransform.py @@ -92,15 +92,15 @@ YieldFromExpr, ) from mypy.patterns import ( - Pattern, AsPattern, + ClassPattern, + MappingPattern, OrPattern, - ValuePattern, - SingletonPattern, + Pattern, SequencePattern, + SingletonPattern, StarredPattern, - MappingPattern, - ClassPattern, + ValuePattern, ) from mypy.traverser import TraverserVisitor from mypy.types import FunctionLike, ProperType, Type