diff --git a/muppet/puppet/ast.py b/muppet/puppet/ast.py index 028751dda1511518553d3cefd25b3079fc0db152..c80f42866244b50b6e7c4c7cd93fc2c06620dd46 100644 --- a/muppet/puppet/ast.py +++ b/muppet/puppet/ast.py @@ -21,8 +21,8 @@ logger = logging.getLogger(__name__) class HashEntry: """An entry in a hash table.""" - k: 'Puppet' - v: 'Puppet' + k: 'PuppetAST' + v: 'PuppetAST' @dataclass @@ -39,19 +39,19 @@ class PuppetDeclarationParameter: """ k: str - v: Optional['Puppet'] = None - type: Optional['Puppet'] = None + v: Optional['PuppetAST'] = None + type: Optional['PuppetAST'] = None # -------------------------------------------------- @dataclass(kw_only=True) -class Puppet: +class PuppetAST: """Base for puppet item.""" @dataclass -class PuppetLiteral(Puppet): +class PuppetLiteral(PuppetAST): """ A self quoting value. @@ -62,7 +62,7 @@ class PuppetLiteral(Puppet): @dataclass -class PuppetAccess(Puppet): +class PuppetAccess(PuppetAST): """ Array access and similar. @@ -71,36 +71,36 @@ class PuppetAccess(Puppet): how[args] """ - how: Puppet - args: list[Puppet] + how: PuppetAST + args: list[PuppetAST] @dataclass -class PuppetBinaryOperator(Puppet): +class PuppetBinaryOperator(PuppetAST): """An operator with two values.""" op: str - lhs: Puppet - rhs: Puppet + lhs: PuppetAST + rhs: PuppetAST @dataclass -class PuppetUnaryOperator(Puppet): +class PuppetUnaryOperator(PuppetAST): """A prefix operator.""" op: str - x: Puppet + x: PuppetAST @dataclass -class PuppetArray(Puppet): +class PuppetArray(PuppetAST): """An array of values.""" - items: list[Puppet] + items: list[PuppetAST] @dataclass -class PuppetCall(Puppet): +class PuppetCall(PuppetAST): """ A function call. @@ -109,29 +109,29 @@ class PuppetCall(Puppet): func(args) """ - func: Puppet - args: list[Puppet] + func: PuppetAST + args: list[PuppetAST] @dataclass -class PuppetCallMethod(Puppet): +class PuppetCallMethod(PuppetAST): """A method call? TODO.""" - func: Puppet - args: list[Puppet] - block: Optional[Puppet] = None + func: PuppetAST + args: list[PuppetAST] + block: Optional[PuppetAST] = None @dataclass -class PuppetCase(Puppet): +class PuppetCase(PuppetAST): """A case "statement".""" - test: Puppet - cases: list[tuple[list[Puppet], list[Puppet]]] + test: PuppetAST + cases: list[tuple[list[PuppetAST], list[PuppetAST]]] @dataclass -class PuppetInstanciationParameter(Puppet): +class PuppetInstanciationParameter(PuppetAST): """ Key-value pair used when instanciating resources. @@ -148,42 +148,42 @@ class PuppetInstanciationParameter(Puppet): """ k: str - v: Puppet + v: PuppetAST arrow: Literal['=>'] | Literal['+>'] = '=>' @dataclass -class PuppetClass(Puppet): +class PuppetClass(PuppetAST): """A puppet class declaration.""" name: str params: Optional[list[PuppetDeclarationParameter]] = None - body: list[Puppet] = field(default_factory=list) + body: list[PuppetAST] = field(default_factory=list) parent: Optional[str] = None @dataclass -class PuppetConcat(Puppet): +class PuppetConcat(PuppetAST): """A string with interpolated values.""" - fragments: list[Puppet] + fragments: list[PuppetAST] @dataclass -class PuppetCollect(Puppet): +class PuppetCollect(PuppetAST): """ Resource collectors. These should be followed by a query (either exported or virtual). """ - type: Puppet - query: Puppet + type: PuppetAST + query: PuppetAST ops: list[PuppetInstanciationParameter] = field(default_factory=list) @dataclass -class PuppetIfChain(Puppet): +class PuppetIfChain(PuppetAST): """ Puppet if expressions. @@ -204,20 +204,20 @@ class PuppetIfChain(Puppet): ('else', [3])] """ - clauses: list[tuple[Puppet | Literal['else'], list[Puppet]]] + clauses: list[tuple[PuppetAST | Literal['else'], list[PuppetAST]]] @dataclass -class PuppetUnless(Puppet): +class PuppetUnless(PuppetAST): """A puppet unless expression.""" - condition: Puppet - consequent: list[Puppet] - alternative: list[Puppet] = field(default_factory=list) + condition: PuppetAST + consequent: list[PuppetAST] + alternative: list[PuppetAST] = field(default_factory=list) @dataclass -class PuppetKeyword(Puppet): +class PuppetKeyword(PuppetAST): """ A reserved word in the puppet language. @@ -229,7 +229,7 @@ class PuppetKeyword(Puppet): @dataclass -class PuppetExportedQuery(Puppet): +class PuppetExportedQuery(PuppetAST): """ An exported query. @@ -238,11 +238,11 @@ class PuppetExportedQuery(Puppet): <<| filter |>> """ - filter: Optional[Puppet] = None + filter: Optional[PuppetAST] = None @dataclass -class PuppetVirtualQuery(Puppet): +class PuppetVirtualQuery(PuppetAST): """ A virtual query. @@ -251,36 +251,36 @@ class PuppetVirtualQuery(Puppet): <| q |> """ - q: Optional[Puppet] = None + q: Optional[PuppetAST] = None @dataclass -class PuppetFunction(Puppet): +class PuppetFunction(PuppetAST): """Declaration of a Puppet function.""" name: str params: Optional[list[PuppetDeclarationParameter]] = None - returns: Optional[Puppet] = None - body: list[Puppet] = field(default_factory=list) + returns: Optional[PuppetAST] = None + body: list[PuppetAST] = field(default_factory=list) @dataclass -class PuppetHash(Puppet): +class PuppetHash(PuppetAST): """A puppet dictionary.""" entries: list[HashEntry] = field(default_factory=list) @dataclass -class PuppetHeredoc(Puppet): +class PuppetHeredoc(PuppetAST): """A puppet heredoc.""" - fragments: list[Puppet] + fragments: list[PuppetAST] syntax: Optional[str] = None @dataclass -class PuppetLiteralHeredoc(Puppet): +class PuppetLiteralHeredoc(PuppetAST): """A puppet heredoc without any interpolation.""" content: str @@ -288,58 +288,58 @@ class PuppetLiteralHeredoc(Puppet): @dataclass -class PuppetVar(Puppet): +class PuppetVar(PuppetAST): """A puppet variable.""" name: str @dataclass -class PuppetLambda(Puppet): +class PuppetLambda(PuppetAST): """A puppet lambda.""" params: list[PuppetDeclarationParameter] - body: list[Puppet] + body: list[PuppetAST] @dataclass -class PuppetParenthesis(Puppet): +class PuppetParenthesis(PuppetAST): """Forms surrounded by parethesis.""" - form: Puppet + form: PuppetAST @dataclass -class PuppetQn(Puppet): +class PuppetQn(PuppetAST): """Qn TODO.""" name: str @dataclass -class PuppetQr(Puppet): +class PuppetQr(PuppetAST): """Qr TODO.""" name: str @dataclass -class PuppetRegex(Puppet): +class PuppetRegex(PuppetAST): """A regex literal.""" s: str @dataclass -class PuppetResource(Puppet): +class PuppetResource(PuppetAST): """Instansiation of one (or more) puppet resources.""" - type: Puppet - bodies: list[tuple[Puppet, list[PuppetInstanciationParameter]]] + type: PuppetAST + bodies: list[tuple[PuppetAST, list[PuppetInstanciationParameter]]] @dataclass -class PuppetNop(Puppet): +class PuppetNop(PuppetAST): """A no-op.""" def serialize(self, indent: int, **_: Any) -> str: # noqa: D102 @@ -347,23 +347,23 @@ class PuppetNop(Puppet): @dataclass -class PuppetDefine(Puppet): +class PuppetDefine(PuppetAST): """A puppet resource declaration.""" name: str params: Optional[list[PuppetDeclarationParameter]] = None - body: list[Puppet] = field(default_factory=list) + body: list[PuppetAST] = field(default_factory=list) @dataclass -class PuppetString(Puppet): +class PuppetString(PuppetAST): """A puppet string literal.""" s: str @dataclass -class PuppetNumber(Puppet): +class PuppetNumber(PuppetAST): """A puppet numeric literal.""" x: int | float @@ -371,7 +371,7 @@ class PuppetNumber(Puppet): @dataclass -class PuppetInvoke(Puppet): +class PuppetInvoke(PuppetAST): """ A puppet function invocation. @@ -384,13 +384,13 @@ class PuppetInvoke(Puppet): Where func is ``include``, and args is ``[::example]`` """ - func: Puppet - args: list[Puppet] - block: Optional[Puppet] = None + func: PuppetAST + args: list[PuppetAST] + block: Optional[PuppetAST] = None @dataclass -class PuppetResourceDefaults(Puppet): +class PuppetResourceDefaults(PuppetAST): """ Default values for a resource. @@ -401,12 +401,12 @@ class PuppetResourceDefaults(Puppet): } """ - type: Puppet + type: PuppetAST ops: list[PuppetInstanciationParameter] @dataclass -class PuppetResourceOverride(Puppet): +class PuppetResourceOverride(PuppetAST): """ A resource override. @@ -423,20 +423,20 @@ class PuppetResourceOverride(Puppet): } """ - resource: Puppet + resource: PuppetAST ops: list[PuppetInstanciationParameter] @dataclass -class PuppetDeclaration(Puppet): +class PuppetDeclaration(PuppetAST): """A stand-alone variable declaration.""" - k: Puppet # PuppetVar - v: Puppet + k: PuppetAST # PuppetVar + v: PuppetAST @dataclass -class PuppetSelector(Puppet): +class PuppetSelector(PuppetAST): """ A puppet selector. @@ -447,19 +447,19 @@ class PuppetSelector(Puppet): } """ - resource: Puppet - cases: list[tuple[Puppet, Puppet]] + resource: PuppetAST + cases: list[tuple[PuppetAST, PuppetAST]] @dataclass -class PuppetBlock(Puppet): +class PuppetBlock(PuppetAST): """Used if multiple top level items exists.""" - entries: list[Puppet] + entries: list[PuppetAST] @dataclass -class PuppetNode(Puppet): +class PuppetNode(PuppetAST): """ A node declaration. @@ -472,20 +472,20 @@ class PuppetNode(Puppet): } """ - matches: list[Puppet] - body: list[Puppet] + matches: list[PuppetAST] + body: list[PuppetAST] @dataclass -class PuppetTypeAlias(Puppet): +class PuppetTypeAlias(PuppetAST): """A type alias.""" name: str - implementation: Puppet + implementation: PuppetAST @dataclass -class PuppetParseError(Puppet): +class PuppetParseError(PuppetAST): """Anything we don't know how to handle.""" x: Any = None @@ -511,8 +511,8 @@ def parse_puppet_declaration_params(data: dict[str, dict[str, Any]]) \ parameters = [] for name, definition in data.items(): - type: Optional[Puppet] = None - value: Optional[Puppet] = None + type: Optional[PuppetAST] = None + value: Optional[PuppetAST] = None if t := definition.get('type'): type = build_ast(t) if 'value' in definition: @@ -538,7 +538,7 @@ def parse_puppet_instanciation_param(data: list[Any]) -> PuppetInstanciationPara # ---------------------------------------------------------------------- -def build_ast(form: Any) -> Puppet: +def build_ast(form: Any) -> PuppetAST: """ Print everything from a puppet parse tree. @@ -792,7 +792,7 @@ def generate_template() -> None: """Indent string for python code.""" return ' ' * 4 * level - subclasses = sorted(subclass.__name__ for subclass in Puppet.__subclasses__()) + subclasses = sorted(subclass.__name__ for subclass in PuppetAST.__subclasses__()) def tokenize_class(s: str) -> list[str]: """Split a camel or pascal cased string into words.""" diff --git a/muppet/puppet/format/__init__.py b/muppet/puppet/format/__init__.py index 963bceb45ec750c64b7f02f24ce34d0695632645..256a0b6f8653be1c83b11391479b406fe2ebe15b 100644 --- a/muppet/puppet/format/__init__.py +++ b/muppet/puppet/format/__init__.py @@ -1,14 +1,14 @@ """Fromat Puppet AST's into something useful.""" from .base import Serializer -from muppet.puppet.ast import Puppet +from muppet.puppet.ast import PuppetAST from typing import Any, TypeVar T = TypeVar('T') -def serialize(ast: Puppet, serializer: type[Serializer[T]]) -> T: +def serialize(ast: PuppetAST, serializer: type[Serializer[T]]) -> T: """Run the given serializer on the given data.""" return serializer().serialize(ast) diff --git a/muppet/puppet/format/base.py b/muppet/puppet/format/base.py index df3fd1ab19c32a3b27adbcdc5a50bef747820665..b1b1a8b84a3683ebd8d26575413a72e1e93203ee 100644 --- a/muppet/puppet/format/base.py +++ b/muppet/puppet/format/base.py @@ -8,7 +8,7 @@ from typing import ( import logging from muppet.puppet.ast import ( - Puppet, + PuppetAST, PuppetLiteral, PuppetAccess, PuppetBinaryOperator, PuppetUnaryOperator, PuppetArray, PuppetCallMethod, @@ -175,7 +175,7 @@ class Serializer(Generic[T]): return self.__raise("puppet_nop") @final - def serialize(self, form: Puppet) -> T: + def serialize(self, form: PuppetAST) -> T: """Dispatch depending on type.""" # logger.debug("Serializing %s", form) match form: diff --git a/muppet/puppet/format/parser.py b/muppet/puppet/format/parser.py index 42357926339834e277fafec44d4269b48e7a7c01..ee270d258f91daa6c09c75acec49b6b8eee3f7df 100644 --- a/muppet/puppet/format/parser.py +++ b/muppet/puppet/format/parser.py @@ -9,7 +9,7 @@ this allows *really* good syntax highlighting. import logging from .base import Serializer from muppet.puppet.ast import ( - Puppet, + PuppetAST, PuppetAccess, PuppetArray, PuppetBinaryOperator, @@ -221,7 +221,7 @@ class ParserFormatter(Serializer[ParseDirective]): parser &= ws & optional(s(',')) & ws & delim[1] return tag('declaration-parameters', parser) - def known_array(self, delim: str, in_items: list[Puppet]) -> ParseDirective: + def known_array(self, delim: str, in_items: list[PuppetAST]) -> ParseDirective: """ Read a delimted, comma separated, array. @@ -245,7 +245,7 @@ class ParserFormatter(Serializer[ParseDirective]): return parser def if_chain(self, - chain: list[tuple[Puppet | Literal['else'], list[Puppet]]] + chain: list[tuple[PuppetAST | Literal['else'], list[PuppetAST]]] ) -> ParseDirective: """Handle all trailing clauses in an if chain.""" # logger.warning("chain: %a", chain) @@ -281,10 +281,10 @@ class ParserFormatter(Serializer[ParseDirective]): raise ValueError(f"Bad if-chain: {chain!r}") - def s(self, it: Puppet | Sequence[Puppet] | None) -> ParseDirective: + def s(self, it: PuppetAST | Sequence[PuppetAST] | None) -> ParseDirective: """Shorthand for self.serialize, but also handles None and lists.""" match it: - case Puppet(): + case PuppetAST(): return self.serialize(it) case [x, *xs]: parser = ws & self.s(x) diff --git a/tests/test_ast.py b/tests/test_ast.py index 811e98d7451afd9cceea7a73672c5e89f13498a2..8a144819dd2fe0c9e649d4cf9ccfcc0223490540 100644 --- a/tests/test_ast.py +++ b/tests/test_ast.py @@ -27,7 +27,7 @@ str """ from muppet.puppet.ast import ( - Puppet, build_ast, + PuppetAST, build_ast, PuppetLiteral, PuppetAccess, PuppetBinaryOperator, PuppetUnaryOperator, PuppetArray, PuppetCallMethod, @@ -58,12 +58,12 @@ from muppet.puppet.format.text import TextFormatter import pytest -def parse(puppet_source: str) -> Puppet: +def parse(puppet_source: str) -> PuppetAST: """Shorthand for running the parser in tests.""" return build_ast(muppet.puppet.parser.puppet_parser( puppet_source)) -def ser(ast: Puppet) -> str: +def ser(ast: PuppetAST) -> str: return serialize(ast, TextFormatter) diff --git a/tests/test_parse_elsif.py b/tests/test_parse_elsif.py index 521d3f6952df0975684d3dd6ef3873397f9613ef..dcd629c4a0cefb3fef13b90c5f3b145f9b69abd0 100644 --- a/tests/test_parse_elsif.py +++ b/tests/test_parse_elsif.py @@ -31,7 +31,7 @@ import pytest from muppet.puppet.format.parser import ParserFormatter from muppet.puppet.ast import ( build_ast, - Puppet, + PuppetAST, HashEntry, PuppetHash, PuppetNumber, @@ -46,7 +46,7 @@ from typing import Any, Optional def parse_string(s: str, *, - ast: Optional[Puppet] = None, + ast: Optional[PuppetAST] = None, matched: Optional[list[Any]] = None): """ Parse and validate the given puppet fragment.