patterns.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. """Classes for representing match statement patterns."""
  2. from __future__ import annotations
  3. from typing import TypeVar
  4. from mypy_extensions import trait
  5. from mypy.nodes import Expression, NameExpr, Node, RefExpr
  6. from mypy.visitor import PatternVisitor
  7. T = TypeVar("T")
  8. @trait
  9. class Pattern(Node):
  10. """A pattern node."""
  11. __slots__ = ()
  12. def accept(self, visitor: PatternVisitor[T]) -> T:
  13. raise RuntimeError("Not implemented")
  14. class AsPattern(Pattern):
  15. """The pattern <pattern> as <name>"""
  16. # The python ast, and therefore also our ast merges capture, wildcard and as patterns into one
  17. # for easier handling.
  18. # If pattern is None this is a capture pattern. If name and pattern are both none this is a
  19. # wildcard pattern.
  20. # Only name being None should not happen but also won't break anything.
  21. pattern: Pattern | None
  22. name: NameExpr | None
  23. def __init__(self, pattern: Pattern | None, name: NameExpr | None) -> None:
  24. super().__init__()
  25. self.pattern = pattern
  26. self.name = name
  27. def accept(self, visitor: PatternVisitor[T]) -> T:
  28. return visitor.visit_as_pattern(self)
  29. class OrPattern(Pattern):
  30. """The pattern <pattern> | <pattern> | ..."""
  31. patterns: list[Pattern]
  32. def __init__(self, patterns: list[Pattern]) -> None:
  33. super().__init__()
  34. self.patterns = patterns
  35. def accept(self, visitor: PatternVisitor[T]) -> T:
  36. return visitor.visit_or_pattern(self)
  37. class ValuePattern(Pattern):
  38. """The pattern x.y (or x.y.z, ...)"""
  39. expr: Expression
  40. def __init__(self, expr: Expression):
  41. super().__init__()
  42. self.expr = expr
  43. def accept(self, visitor: PatternVisitor[T]) -> T:
  44. return visitor.visit_value_pattern(self)
  45. class SingletonPattern(Pattern):
  46. # This can be exactly True, False or None
  47. value: bool | None
  48. def __init__(self, value: bool | None):
  49. super().__init__()
  50. self.value = value
  51. def accept(self, visitor: PatternVisitor[T]) -> T:
  52. return visitor.visit_singleton_pattern(self)
  53. class SequencePattern(Pattern):
  54. """The pattern [<pattern>, ...]"""
  55. patterns: list[Pattern]
  56. def __init__(self, patterns: list[Pattern]):
  57. super().__init__()
  58. self.patterns = patterns
  59. def accept(self, visitor: PatternVisitor[T]) -> T:
  60. return visitor.visit_sequence_pattern(self)
  61. class StarredPattern(Pattern):
  62. # None corresponds to *_ in a list pattern. It will match multiple items but won't bind them to
  63. # a name.
  64. capture: NameExpr | None
  65. def __init__(self, capture: NameExpr | None):
  66. super().__init__()
  67. self.capture = capture
  68. def accept(self, visitor: PatternVisitor[T]) -> T:
  69. return visitor.visit_starred_pattern(self)
  70. class MappingPattern(Pattern):
  71. keys: list[Expression]
  72. values: list[Pattern]
  73. rest: NameExpr | None
  74. def __init__(self, keys: list[Expression], values: list[Pattern], rest: NameExpr | None):
  75. super().__init__()
  76. assert len(keys) == len(values)
  77. self.keys = keys
  78. self.values = values
  79. self.rest = rest
  80. def accept(self, visitor: PatternVisitor[T]) -> T:
  81. return visitor.visit_mapping_pattern(self)
  82. class ClassPattern(Pattern):
  83. """The pattern Cls(...)"""
  84. class_ref: RefExpr
  85. positionals: list[Pattern]
  86. keyword_keys: list[str]
  87. keyword_values: list[Pattern]
  88. def __init__(
  89. self,
  90. class_ref: RefExpr,
  91. positionals: list[Pattern],
  92. keyword_keys: list[str],
  93. keyword_values: list[Pattern],
  94. ):
  95. super().__init__()
  96. assert len(keyword_keys) == len(keyword_values)
  97. self.class_ref = class_ref
  98. self.positionals = positionals
  99. self.keyword_keys = keyword_keys
  100. self.keyword_values = keyword_values
  101. def accept(self, visitor: PatternVisitor[T]) -> T:
  102. return visitor.visit_class_pattern(self)