diff options
| author | Marc Mueller <30130371+cdce8p@users.noreply.github.com> | 2021-05-29 13:20:56 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-29 13:20:56 +0200 |
| commit | 0689f0e3cd29aae24c135d64c53b05dcf73d4d33 (patch) | |
| tree | 063db60d2e93c53ee5f40b3ae2702fa52526311a /astroid/node_classes.py | |
| parent | 8d7019531868eab63f72eefc1b9ee5e59b6d1299 (diff) | |
| download | astroid-git-0689f0e3cd29aae24c135d64c53b05dcf73d4d33.tar.gz | |
Add initial support for pattern matching py310 (#986)
* Add initial support for pattern matching py310
* Add typing_extensions
Diffstat (limited to 'astroid/node_classes.py')
| -rw-r--r-- | astroid/node_classes.py | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/astroid/node_classes.py b/astroid/node_classes.py index f8d0b23c..5b92345d 100644 --- a/astroid/node_classes.py +++ b/astroid/node_classes.py @@ -36,6 +36,7 @@ import builtins as builtins_mod import itertools import pprint import sys +import typing from functools import lru_cache from functools import singledispatch as _singledispatch @@ -43,6 +44,12 @@ from astroid import as_string, bases from astroid import context as contextmod from astroid import decorators, exceptions, manager, mixins, util +try: + from typing import Literal +except ImportError: + # typing.Literal was added in Python 3.8 + from typing_extensions import Literal + BUILTINS = builtins_mod.__name__ MANAGER = manager.AstroidManager() PY38 = sys.version_info[:2] >= (3, 8) @@ -4801,6 +4808,233 @@ class EvaluatedObject(NodeNG): yield self.value +# Pattern matching ####################################################### + + +class Match(NodeNG): + """Class representing a :class:`ast.Match` node.""" + + _astroid_fields = ("subject", "cases") + subject: typing.Optional[NodeNG] = None + cases: typing.Optional[typing.List["MatchCase"]] = None + + def postinit( + self, + *, + subject: typing.Optional[NodeNG] = None, + cases: typing.Optional[typing.List["MatchCase"]] = None, + ) -> None: + self.subject = subject + self.cases = cases + + def get_children(self) -> typing.Generator[NodeNG, None, None]: + if self.subject is not None: + yield self.subject + if self.cases is not None: + yield from self.cases + + +class MatchCase(NodeNG): + """Class representing a :class:`ast.match_case` node.""" + + _astroid_fields = ("pattern", "guard", "body") + pattern: typing.Optional["PatternTypes"] = None + guard: typing.Optional[NodeNG] = None # can actually be None + body: typing.Optional[typing.List[NodeNG]] = None + + def postinit( + self, + *, + pattern=None, + guard: typing.Optional[NodeNG] = None, + body: typing.Optional[typing.List[NodeNG]] = None, + ) -> None: + self.pattern = pattern + self.guard = guard + self.body = body + + def get_children(self) -> typing.Generator[NodeNG, None, None]: + if self.pattern is not None: + yield self.pattern + if self.guard is not None: + yield self.guard + if self.body is not None: + yield from self.body + + +class MatchValue(NodeNG): + """Class representing a :class:`ast.MatchValue` node.""" + + _astroid_fields = ("value",) + value: typing.Optional[NodeNG] = None + + def postinit(self, *, value: NodeNG) -> None: + self.value = value + + def get_children(self) -> typing.Generator[NodeNG, None, None]: + if self.value is not None: + yield self.value + + +class MatchSingleton(NodeNG): + """Class representing a :class:`ast.MatchSingleton` node.""" + + _other_fields = ("value",) + + def __init__( + self, + lineno: int, + col_offset: int, + parent: NodeNG, + *, + value: Literal[True, False, None], + ) -> None: + self.value = value + super().__init__(lineno, col_offset, parent) + + +class MatchSequence(NodeNG): + """Class representing a :class:`ast.MatchSequence` node.""" + + _astroid_fields = ("patterns",) + patterns: typing.Optional[typing.List["PatternTypes"]] = None + + def postinit( + self, *, patterns: typing.Optional[typing.List["PatternTypes"]] + ) -> None: + self.patterns = patterns + + def get_children(self) -> typing.Generator["PatternTypes", None, None]: + if self.patterns is not None: + yield from self.patterns + + +class MatchMapping(NodeNG): + """Class representing a :class:`ast.MatchMapping` node.""" + + _astroid_fields = ("keys", "patterns") + _other_fields = ("rest",) + keys: typing.Optional[typing.List[NodeNG]] = None + patterns: typing.Optional[typing.List["PatternTypes"]] = None + rest: typing.Optional[str] = None + + def postinit( + self, + *, + keys=None, + patterns: typing.Optional[typing.List["PatternTypes"]] = None, + rest: typing.Optional[str] = None, + ) -> None: + self.keys = keys + self.patterns = patterns + self.rest = rest + + def get_children(self) -> typing.Generator[NodeNG, None, None]: + if self.keys is not None: + yield from self.keys + if self.patterns is not None: + yield from self.patterns + + +class MatchClass(NodeNG): + """Class representing a :class:`ast.MatchClass` node.""" + + _astroid_fields = ("cls", "patterns", "kwd_attrs", "kwd_patterns") + cls: typing.Optional[NodeNG] = None + patterns: typing.Optional[typing.List["PatternTypes"]] = None + kwd_attrs: typing.Optional[typing.List[str]] = None + kwd_patterns: typing.Optional[typing.List["PatternTypes"]] = None + + def postinit( + self, + *, + cls: typing.Optional[NodeNG] = None, + patterns: typing.Optional[typing.List["PatternTypes"]] = None, + kwd_attrs: typing.Optional[typing.List[str]] = None, + kwd_patterns: typing.Optional[typing.List["PatternTypes"]] = None, + ) -> None: + self.cls = cls + self.patterns = patterns + self.kwd_attrs = kwd_attrs + self.kwd_patterns = kwd_patterns + + def get_children(self) -> typing.Generator[NodeNG, None, None]: + if self.cls is not None: + yield self.cls + if self.patterns is not None: + yield from self.patterns + if self.kwd_patterns is not None: + yield from self.kwd_patterns + + +class MatchStar(NodeNG): + """Class representing a :class:`ast.MatchStar` node.""" + + _other_fields = ("name",) + name: typing.Optional[str] = None + + def __init__( + self, + lineno: int, + col_offset: int, + parent: NodeNG, + *, + name: typing.Optional[str], + ) -> None: + self.name = name + super().__init__(lineno, col_offset, parent) + + +class MatchAs(NodeNG): + """Class representing a :class:`ast.MatchAs` node.""" + + _astroid_fields = ("pattern",) + _other_fields = ("name",) + pattern: typing.Optional["PatternTypes"] = None + name: typing.Optional[str] = None + + def postinit( + self, + *, + pattern: typing.Optional["PatternTypes"] = None, + name: typing.Optional[str] = None, + ) -> None: + self.pattern = pattern + self.name = name + + def get_children(self) -> typing.Generator["PatternTypes", None, None]: + if self.pattern is not None: + yield self.pattern + + +class MatchOr(NodeNG): + """Class representing a :class:`ast.MatchOr` node.""" + + _astroid_fields = ("patterns",) + patterns: typing.Optional[typing.List["PatternTypes"]] = None + + def postinit( + self, *, patterns: typing.Optional[typing.List["PatternTypes"]] + ) -> None: + self.patterns = patterns + + def get_children(self) -> typing.Generator["PatternTypes", None, None]: + if self.patterns is not None: + yield from self.patterns + + +PatternTypes = typing.Union[ + MatchValue, + MatchSingleton, + MatchSequence, + MatchMapping, + MatchClass, + MatchStar, + MatchAs, + MatchOr, +] + + # constants ############################################################## CONST_CLS = { |
