diff env/lib/python3.7/site-packages/ruamel/yaml/resolver.py @ 0:26e78fe6e8c4 draft

"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author shellac
date Sat, 02 May 2020 07:14:21 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/env/lib/python3.7/site-packages/ruamel/yaml/resolver.py	Sat May 02 07:14:21 2020 -0400
@@ -0,0 +1,399 @@
+# coding: utf-8
+
+from __future__ import absolute_import
+
+import re
+
+if False:  # MYPY
+    from typing import Any, Dict, List, Union, Text, Optional  # NOQA
+    from ruamel.yaml.compat import VersionType  # NOQA
+
+from ruamel.yaml.compat import string_types, _DEFAULT_YAML_VERSION  # NOQA
+from ruamel.yaml.error import *  # NOQA
+from ruamel.yaml.nodes import MappingNode, ScalarNode, SequenceNode  # NOQA
+from ruamel.yaml.util import RegExp  # NOQA
+
+__all__ = ['BaseResolver', 'Resolver', 'VersionedResolver']
+
+
+# fmt: off
+# resolvers consist of
+# - a list of applicable version
+# - a tag
+# - a regexp
+# - a list of first characters to match
+implicit_resolvers = [
+    ([(1, 2)],
+        u'tag:yaml.org,2002:bool',
+        RegExp(u'''^(?:true|True|TRUE|false|False|FALSE)$''', re.X),
+        list(u'tTfF')),
+    ([(1, 1)],
+        u'tag:yaml.org,2002:bool',
+        RegExp(u'''^(?:y|Y|yes|Yes|YES|n|N|no|No|NO
+        |true|True|TRUE|false|False|FALSE
+        |on|On|ON|off|Off|OFF)$''', re.X),
+        list(u'yYnNtTfFoO')),
+    ([(1, 2)],
+        u'tag:yaml.org,2002:float',
+        RegExp(u'''^(?:
+         [-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
+        |[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)
+        |[-+]?\\.[0-9_]+(?:[eE][-+][0-9]+)?
+        |[-+]?\\.(?:inf|Inf|INF)
+        |\\.(?:nan|NaN|NAN))$''', re.X),
+        list(u'-+0123456789.')),
+    ([(1, 1)],
+        u'tag:yaml.org,2002:float',
+        RegExp(u'''^(?:
+         [-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
+        |[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)
+        |\\.[0-9_]+(?:[eE][-+][0-9]+)?
+        |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*  # sexagesimal float
+        |[-+]?\\.(?:inf|Inf|INF)
+        |\\.(?:nan|NaN|NAN))$''', re.X),
+        list(u'-+0123456789.')),
+    ([(1, 2)],
+        u'tag:yaml.org,2002:int',
+        RegExp(u'''^(?:[-+]?0b[0-1_]+
+        |[-+]?0o?[0-7_]+
+        |[-+]?[0-9_]+
+        |[-+]?0x[0-9a-fA-F_]+)$''', re.X),
+        list(u'-+0123456789')),
+    ([(1, 1)],
+        u'tag:yaml.org,2002:int',
+        RegExp(u'''^(?:[-+]?0b[0-1_]+
+        |[-+]?0?[0-7_]+
+        |[-+]?(?:0|[1-9][0-9_]*)
+        |[-+]?0x[0-9a-fA-F_]+
+        |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X),  # sexagesimal int
+        list(u'-+0123456789')),
+    ([(1, 2), (1, 1)],
+        u'tag:yaml.org,2002:merge',
+        RegExp(u'^(?:<<)$'),
+        [u'<']),
+    ([(1, 2), (1, 1)],
+        u'tag:yaml.org,2002:null',
+        RegExp(u'''^(?: ~
+        |null|Null|NULL
+        | )$''', re.X),
+        [u'~', u'n', u'N', u'']),
+    ([(1, 2), (1, 1)],
+        u'tag:yaml.org,2002:timestamp',
+        RegExp(u'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
+        |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]?
+        (?:[Tt]|[ \\t]+)[0-9][0-9]?
+        :[0-9][0-9] :[0-9][0-9] (?:\\.[0-9]*)?
+        (?:[ \\t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X),
+        list(u'0123456789')),
+    ([(1, 2), (1, 1)],
+        u'tag:yaml.org,2002:value',
+        RegExp(u'^(?:=)$'),
+        [u'=']),
+    # The following resolver is only for documentation purposes. It cannot work
+    # because plain scalars cannot start with '!', '&', or '*'.
+    ([(1, 2), (1, 1)],
+        u'tag:yaml.org,2002:yaml',
+        RegExp(u'^(?:!|&|\\*)$'),
+        list(u'!&*')),
+]
+# fmt: on
+
+
+class ResolverError(YAMLError):
+    pass
+
+
+class BaseResolver(object):
+
+    DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str'
+    DEFAULT_SEQUENCE_TAG = u'tag:yaml.org,2002:seq'
+    DEFAULT_MAPPING_TAG = u'tag:yaml.org,2002:map'
+
+    yaml_implicit_resolvers = {}  # type: Dict[Any, Any]
+    yaml_path_resolvers = {}  # type: Dict[Any, Any]
+
+    def __init__(self, loadumper=None):
+        # type: (Any, Any) -> None
+        self.loadumper = loadumper
+        if self.loadumper is not None and getattr(self.loadumper, '_resolver', None) is None:
+            self.loadumper._resolver = self.loadumper
+        self._loader_version = None  # type: Any
+        self.resolver_exact_paths = []  # type: List[Any]
+        self.resolver_prefix_paths = []  # type: List[Any]
+
+    @property
+    def parser(self):
+        # type: () -> Any
+        if self.loadumper is not None:
+            if hasattr(self.loadumper, 'typ'):
+                return self.loadumper.parser
+            return self.loadumper._parser
+        return None
+
+    @classmethod
+    def add_implicit_resolver_base(cls, tag, regexp, first):
+        # type: (Any, Any, Any) -> None
+        if 'yaml_implicit_resolvers' not in cls.__dict__:
+            # deepcopy doesn't work here
+            cls.yaml_implicit_resolvers = dict(
+                (k, cls.yaml_implicit_resolvers[k][:]) for k in cls.yaml_implicit_resolvers
+            )
+        if first is None:
+            first = [None]
+        for ch in first:
+            cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp))
+
+    @classmethod
+    def add_implicit_resolver(cls, tag, regexp, first):
+        # type: (Any, Any, Any) -> None
+        if 'yaml_implicit_resolvers' not in cls.__dict__:
+            # deepcopy doesn't work here
+            cls.yaml_implicit_resolvers = dict(
+                (k, cls.yaml_implicit_resolvers[k][:]) for k in cls.yaml_implicit_resolvers
+            )
+        if first is None:
+            first = [None]
+        for ch in first:
+            cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp))
+        implicit_resolvers.append(([(1, 2), (1, 1)], tag, regexp, first))
+
+    # @classmethod
+    # def add_implicit_resolver(cls, tag, regexp, first):
+
+    @classmethod
+    def add_path_resolver(cls, tag, path, kind=None):
+        # type: (Any, Any, Any) -> None
+        # Note: `add_path_resolver` is experimental.  The API could be changed.
+        # `new_path` is a pattern that is matched against the path from the
+        # root to the node that is being considered.  `node_path` elements are
+        # tuples `(node_check, index_check)`.  `node_check` is a node class:
+        # `ScalarNode`, `SequenceNode`, `MappingNode` or `None`.  `None`
+        # matches any kind of a node.  `index_check` could be `None`, a boolean
+        # value, a string value, or a number.  `None` and `False` match against
+        # any _value_ of sequence and mapping nodes.  `True` matches against
+        # any _key_ of a mapping node.  A string `index_check` matches against
+        # a mapping value that corresponds to a scalar key which content is
+        # equal to the `index_check` value.  An integer `index_check` matches
+        # against a sequence value with the index equal to `index_check`.
+        if 'yaml_path_resolvers' not in cls.__dict__:
+            cls.yaml_path_resolvers = cls.yaml_path_resolvers.copy()
+        new_path = []  # type: List[Any]
+        for element in path:
+            if isinstance(element, (list, tuple)):
+                if len(element) == 2:
+                    node_check, index_check = element
+                elif len(element) == 1:
+                    node_check = element[0]
+                    index_check = True
+                else:
+                    raise ResolverError('Invalid path element: %s' % (element,))
+            else:
+                node_check = None
+                index_check = element
+            if node_check is str:
+                node_check = ScalarNode
+            elif node_check is list:
+                node_check = SequenceNode
+            elif node_check is dict:
+                node_check = MappingNode
+            elif (
+                node_check not in [ScalarNode, SequenceNode, MappingNode]
+                and not isinstance(node_check, string_types)
+                and node_check is not None
+            ):
+                raise ResolverError('Invalid node checker: %s' % (node_check,))
+            if not isinstance(index_check, (string_types, int)) and index_check is not None:
+                raise ResolverError('Invalid index checker: %s' % (index_check,))
+            new_path.append((node_check, index_check))
+        if kind is str:
+            kind = ScalarNode
+        elif kind is list:
+            kind = SequenceNode
+        elif kind is dict:
+            kind = MappingNode
+        elif kind not in [ScalarNode, SequenceNode, MappingNode] and kind is not None:
+            raise ResolverError('Invalid node kind: %s' % (kind,))
+        cls.yaml_path_resolvers[tuple(new_path), kind] = tag
+
+    def descend_resolver(self, current_node, current_index):
+        # type: (Any, Any) -> None
+        if not self.yaml_path_resolvers:
+            return
+        exact_paths = {}
+        prefix_paths = []
+        if current_node:
+            depth = len(self.resolver_prefix_paths)
+            for path, kind in self.resolver_prefix_paths[-1]:
+                if self.check_resolver_prefix(depth, path, kind, current_node, current_index):
+                    if len(path) > depth:
+                        prefix_paths.append((path, kind))
+                    else:
+                        exact_paths[kind] = self.yaml_path_resolvers[path, kind]
+        else:
+            for path, kind in self.yaml_path_resolvers:
+                if not path:
+                    exact_paths[kind] = self.yaml_path_resolvers[path, kind]
+                else:
+                    prefix_paths.append((path, kind))
+        self.resolver_exact_paths.append(exact_paths)
+        self.resolver_prefix_paths.append(prefix_paths)
+
+    def ascend_resolver(self):
+        # type: () -> None
+        if not self.yaml_path_resolvers:
+            return
+        self.resolver_exact_paths.pop()
+        self.resolver_prefix_paths.pop()
+
+    def check_resolver_prefix(self, depth, path, kind, current_node, current_index):
+        # type: (int, Text, Any, Any, Any) -> bool
+        node_check, index_check = path[depth - 1]
+        if isinstance(node_check, string_types):
+            if current_node.tag != node_check:
+                return False
+        elif node_check is not None:
+            if not isinstance(current_node, node_check):
+                return False
+        if index_check is True and current_index is not None:
+            return False
+        if (index_check is False or index_check is None) and current_index is None:
+            return False
+        if isinstance(index_check, string_types):
+            if not (
+                isinstance(current_index, ScalarNode) and index_check == current_index.value
+            ):
+                return False
+        elif isinstance(index_check, int) and not isinstance(index_check, bool):
+            if index_check != current_index:
+                return False
+        return True
+
+    def resolve(self, kind, value, implicit):
+        # type: (Any, Any, Any) -> Any
+        if kind is ScalarNode and implicit[0]:
+            if value == "":
+                resolvers = self.yaml_implicit_resolvers.get("", [])
+            else:
+                resolvers = self.yaml_implicit_resolvers.get(value[0], [])
+            resolvers += self.yaml_implicit_resolvers.get(None, [])
+            for tag, regexp in resolvers:
+                if regexp.match(value):
+                    return tag
+            implicit = implicit[1]
+        if bool(self.yaml_path_resolvers):
+            exact_paths = self.resolver_exact_paths[-1]
+            if kind in exact_paths:
+                return exact_paths[kind]
+            if None in exact_paths:
+                return exact_paths[None]
+        if kind is ScalarNode:
+            return self.DEFAULT_SCALAR_TAG
+        elif kind is SequenceNode:
+            return self.DEFAULT_SEQUENCE_TAG
+        elif kind is MappingNode:
+            return self.DEFAULT_MAPPING_TAG
+
+    @property
+    def processing_version(self):
+        # type: () -> Any
+        return None
+
+
+class Resolver(BaseResolver):
+    pass
+
+
+for ir in implicit_resolvers:
+    if (1, 2) in ir[0]:
+        Resolver.add_implicit_resolver_base(*ir[1:])
+
+
+class VersionedResolver(BaseResolver):
+    """
+    contrary to the "normal" resolver, the smart resolver delays loading
+    the pattern matching rules. That way it can decide to load 1.1 rules
+    or the (default) 1.2 rules, that no longer support octal without 0o, sexagesimals
+    and Yes/No/On/Off booleans.
+    """
+
+    def __init__(self, version=None, loader=None, loadumper=None):
+        # type: (Optional[VersionType], Any, Any) -> None
+        if loader is None and loadumper is not None:
+            loader = loadumper
+        BaseResolver.__init__(self, loader)
+        self._loader_version = self.get_loader_version(version)
+        self._version_implicit_resolver = {}  # type: Dict[Any, Any]
+
+    def add_version_implicit_resolver(self, version, tag, regexp, first):
+        # type: (VersionType, Any, Any, Any) -> None
+        if first is None:
+            first = [None]
+        impl_resolver = self._version_implicit_resolver.setdefault(version, {})
+        for ch in first:
+            impl_resolver.setdefault(ch, []).append((tag, regexp))
+
+    def get_loader_version(self, version):
+        # type: (Optional[VersionType]) -> Any
+        if version is None or isinstance(version, tuple):
+            return version
+        if isinstance(version, list):
+            return tuple(version)
+        # assume string
+        return tuple(map(int, version.split(u'.')))
+
+    @property
+    def versioned_resolver(self):
+        # type: () -> Any
+        """
+        select the resolver based on the version we are parsing
+        """
+        version = self.processing_version
+        if version not in self._version_implicit_resolver:
+            for x in implicit_resolvers:
+                if version in x[0]:
+                    self.add_version_implicit_resolver(version, x[1], x[2], x[3])
+        return self._version_implicit_resolver[version]
+
+    def resolve(self, kind, value, implicit):
+        # type: (Any, Any, Any) -> Any
+        if kind is ScalarNode and implicit[0]:
+            if value == "":
+                resolvers = self.versioned_resolver.get("", [])
+            else:
+                resolvers = self.versioned_resolver.get(value[0], [])
+            resolvers += self.versioned_resolver.get(None, [])
+            for tag, regexp in resolvers:
+                if regexp.match(value):
+                    return tag
+            implicit = implicit[1]
+        if bool(self.yaml_path_resolvers):
+            exact_paths = self.resolver_exact_paths[-1]
+            if kind in exact_paths:
+                return exact_paths[kind]
+            if None in exact_paths:
+                return exact_paths[None]
+        if kind is ScalarNode:
+            return self.DEFAULT_SCALAR_TAG
+        elif kind is SequenceNode:
+            return self.DEFAULT_SEQUENCE_TAG
+        elif kind is MappingNode:
+            return self.DEFAULT_MAPPING_TAG
+
+    @property
+    def processing_version(self):
+        # type: () -> Any
+        try:
+            version = self.parser.yaml_version
+        except AttributeError:
+            try:
+                if hasattr(self.loadumper, 'typ'):
+                    version = self.loadumper.version
+                else:
+                    version = self.loadumper._serializer.use_version  # dumping
+            except AttributeError:
+                version = None
+        if version is None:
+            version = self._loader_version
+            if version is None:
+                version = _DEFAULT_YAML_VERSION
+        return version