Tipragot
628be439b8
Cela permet de ne pas avoir de problèmes de compatibilité car python est dans le git.
149 lines
3.9 KiB
Python
149 lines
3.9 KiB
Python
"""Classes for representing match statement patterns."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TypeVar
|
|
|
|
from mypy_extensions import trait
|
|
|
|
from mypy.nodes import Expression, NameExpr, Node, RefExpr
|
|
from mypy.visitor import PatternVisitor
|
|
|
|
T = TypeVar("T")
|
|
|
|
|
|
@trait
|
|
class Pattern(Node):
|
|
"""A pattern node."""
|
|
|
|
__slots__ = ()
|
|
|
|
def accept(self, visitor: PatternVisitor[T]) -> T:
|
|
raise RuntimeError("Not implemented", type(self))
|
|
|
|
|
|
class AsPattern(Pattern):
|
|
"""The pattern <pattern> as <name>"""
|
|
|
|
# The python ast, and therefore also our ast merges capture, wildcard and as patterns into one
|
|
# for easier handling.
|
|
# If pattern is None this is a capture pattern. If name and pattern are both none this is a
|
|
# wildcard pattern.
|
|
# Only name being None should not happen but also won't break anything.
|
|
pattern: Pattern | None
|
|
name: NameExpr | None
|
|
|
|
def __init__(self, pattern: Pattern | None, name: NameExpr | None) -> None:
|
|
super().__init__()
|
|
self.pattern = pattern
|
|
self.name = name
|
|
|
|
def accept(self, visitor: PatternVisitor[T]) -> T:
|
|
return visitor.visit_as_pattern(self)
|
|
|
|
|
|
class OrPattern(Pattern):
|
|
"""The pattern <pattern> | <pattern> | ..."""
|
|
|
|
patterns: list[Pattern]
|
|
|
|
def __init__(self, patterns: list[Pattern]) -> None:
|
|
super().__init__()
|
|
self.patterns = patterns
|
|
|
|
def accept(self, visitor: PatternVisitor[T]) -> T:
|
|
return visitor.visit_or_pattern(self)
|
|
|
|
|
|
class ValuePattern(Pattern):
|
|
"""The pattern x.y (or x.y.z, ...)"""
|
|
|
|
expr: Expression
|
|
|
|
def __init__(self, expr: Expression):
|
|
super().__init__()
|
|
self.expr = expr
|
|
|
|
def accept(self, visitor: PatternVisitor[T]) -> T:
|
|
return visitor.visit_value_pattern(self)
|
|
|
|
|
|
class SingletonPattern(Pattern):
|
|
# This can be exactly True, False or None
|
|
value: bool | None
|
|
|
|
def __init__(self, value: bool | None):
|
|
super().__init__()
|
|
self.value = value
|
|
|
|
def accept(self, visitor: PatternVisitor[T]) -> T:
|
|
return visitor.visit_singleton_pattern(self)
|
|
|
|
|
|
class SequencePattern(Pattern):
|
|
"""The pattern [<pattern>, ...]"""
|
|
|
|
patterns: list[Pattern]
|
|
|
|
def __init__(self, patterns: list[Pattern]):
|
|
super().__init__()
|
|
self.patterns = patterns
|
|
|
|
def accept(self, visitor: PatternVisitor[T]) -> T:
|
|
return visitor.visit_sequence_pattern(self)
|
|
|
|
|
|
class StarredPattern(Pattern):
|
|
# None corresponds to *_ in a list pattern. It will match multiple items but won't bind them to
|
|
# a name.
|
|
capture: NameExpr | None
|
|
|
|
def __init__(self, capture: NameExpr | None):
|
|
super().__init__()
|
|
self.capture = capture
|
|
|
|
def accept(self, visitor: PatternVisitor[T]) -> T:
|
|
return visitor.visit_starred_pattern(self)
|
|
|
|
|
|
class MappingPattern(Pattern):
|
|
keys: list[Expression]
|
|
values: list[Pattern]
|
|
rest: NameExpr | None
|
|
|
|
def __init__(self, keys: list[Expression], values: list[Pattern], rest: NameExpr | None):
|
|
super().__init__()
|
|
assert len(keys) == len(values)
|
|
self.keys = keys
|
|
self.values = values
|
|
self.rest = rest
|
|
|
|
def accept(self, visitor: PatternVisitor[T]) -> T:
|
|
return visitor.visit_mapping_pattern(self)
|
|
|
|
|
|
class ClassPattern(Pattern):
|
|
"""The pattern Cls(...)"""
|
|
|
|
class_ref: RefExpr
|
|
positionals: list[Pattern]
|
|
keyword_keys: list[str]
|
|
keyword_values: list[Pattern]
|
|
|
|
def __init__(
|
|
self,
|
|
class_ref: RefExpr,
|
|
positionals: list[Pattern],
|
|
keyword_keys: list[str],
|
|
keyword_values: list[Pattern],
|
|
):
|
|
super().__init__()
|
|
assert len(keyword_keys) == len(keyword_values)
|
|
self.class_ref = class_ref
|
|
self.positionals = positionals
|
|
self.keyword_keys = keyword_keys
|
|
self.keyword_values = keyword_values
|
|
|
|
def accept(self, visitor: PatternVisitor[T]) -> T:
|
|
return visitor.visit_class_pattern(self)
|