Module metaloaders.cloudformation

Metaloader for JSON documents.

Expand source code Browse git
"""Metaloader for JSON documents.
"""

# Standard library
from typing import (
    Any,
)

# Third party libraries
from ruamel import (
    yaml as _yaml,
)

# Local libraries
from metaloaders.exceptions import (
    MetaloaderError,
    MetaloaderNotImplemented,
)
from metaloaders.model import (
    Node,
    Type,
)
from metaloaders.yaml import (
    Loader as YAMLLoader,
    load as load_as_yaml,
)
from metaloaders.json import (
    load as load_as_json,
)


class Loader(YAMLLoader):  # pylint: disable=abstract-method,too-many-ancestors
    """YAML loader with overridden constructors that propagate positions.

    In normal circumstances you should not use this directly, but it is left
    here in order to ease extension when needed.
    """


def load(stream: str, fmt: str) -> Node:
    if fmt in {'yml', 'yaml'}:
        return load_as_yaml(stream, loader_cls=Loader)

    if fmt in {'json'}:
        return load_as_json(stream)

    raise NotImplementedError(fmt)


def _multi_constructor(
    loader: Loader,
    tag_suffix: str,
    node: _yaml.Node,  # type: ignore
) -> Any:
    if tag_suffix not in {'Condition', 'Ref'}:
        tag_suffix = f'Fn::{tag_suffix}'

    if tag_suffix == "Fn::GetAtt":
        constructor: Any = construct_getatt
    elif isinstance(node, _yaml.ScalarNode):  # type: ignore
        constructor = loader.construct_scalar
    elif isinstance(node, _yaml.SequenceNode):  # type: ignore
        constructor = loader.construct_sequence
    elif isinstance(node, _yaml.MappingNode):  # type: ignore
        constructor = loader.construct_mapping
    else:
        raise MetaloaderNotImplemented(f'Bad tag: !{tag_suffix}')

    return Node(
        data={tag_suffix: constructor(node)},
        data_type=Type.OBJECT,
        end_column=node.end_mark.column,
        end_line=node.end_mark.line + 1,
        start_column=node.start_mark.column,
        start_line=node.start_mark.line + 1,
    )


def construct_getatt(
    node: _yaml.Node,  # type: ignore
) -> Any:
    if isinstance(node.value, str):
        return node.value.split(".", 1)

    if isinstance(node.value, list):
        return [s.value for s in node.value]

    raise MetaloaderError(f'Unexpected node type: {type(node.value)}')


def _override() -> None:
    Loader.add_multi_constructor("!", _multi_constructor)


# Side effects
_override()

Functions

def load(stream: str, fmt: str) ‑> Node
Expand source code Browse git
def load(stream: str, fmt: str) -> Node:
    if fmt in {'yml', 'yaml'}:
        return load_as_yaml(stream, loader_cls=Loader)

    if fmt in {'json'}:
        return load_as_json(stream)

    raise NotImplementedError(fmt)
def construct_getatt(node: ruamel.yaml.nodes.Node) ‑> Any
Expand source code Browse git
def construct_getatt(
    node: _yaml.Node,  # type: ignore
) -> Any:
    if isinstance(node.value, str):
        return node.value.split(".", 1)

    if isinstance(node.value, list):
        return [s.value for s in node.value]

    raise MetaloaderError(f'Unexpected node type: {type(node.value)}')

Classes

class Loader (stream, version=None, preserve_quotes=None)

YAML loader with overridden constructors that propagate positions.

In normal circumstances you should not use this directly, but it is left here in order to ease extension when needed.

Initialize the scanner.

Expand source code Browse git
class Loader(YAMLLoader):  # pylint: disable=abstract-method,too-many-ancestors
    """YAML loader with overridden constructors that propagate positions.

    In normal circumstances you should not use this directly, but it is left
    here in order to ease extension when needed.
    """

Ancestors

  • Loader
  • ruamel.yaml.loader.SafeLoader
  • ruamel.yaml.reader.Reader
  • ruamel.yaml.scanner.Scanner
  • ruamel.yaml.parser.Parser
  • ruamel.yaml.composer.Composer
  • ruamel.yaml.constructor.SafeConstructor
  • ruamel.yaml.constructor.BaseConstructor
  • ruamel.yaml.resolver.VersionedResolver
  • ruamel.yaml.resolver.BaseResolver

Class variables

var yaml_multi_constructors