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