from __future__ import absolute_import _H='yaml_implicit_resolvers' _G='-+0123456789' _F='tag:yaml.org,2002:int' _E='-+0123456789.' _D='tag:yaml.org,2002:float' _C='tag:yaml.org,2002:bool' _B=False _A=None import re if _B:from typing import Any,Dict,List,Union,Text,Optional;from.compat import VersionType from.compat import string_types,_DEFAULT_YAML_VERSION from.error import* from.nodes import MappingNode,ScalarNode,SequenceNode from.util import RegExp __all__=['BaseResolver','Resolver','VersionedResolver'] implicit_resolvers=[([(1,2)],_C,RegExp('^(?:true|True|TRUE|false|False|FALSE)$',re.X),list('tTfF')),([(1,1)],_C,RegExp('^(?:y|Y|yes|Yes|YES|n|N|no|No|NO\n |true|True|TRUE|false|False|FALSE\n |on|On|ON|off|Off|OFF)$',re.X),list('yYnNtTfFoO')),([(1,2)],_D,RegExp('^(?:\n [-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?\n |[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)\n |[-+]?\\.[0-9_]+(?:[eE][-+][0-9]+)?\n |[-+]?\\.(?:inf|Inf|INF)\n |\\.(?:nan|NaN|NAN))$',re.X),list(_E)),([(1,1)],_D,RegExp('^(?:\n [-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?\n |[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)\n |\\.[0-9_]+(?:[eE][-+][0-9]+)?\n |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]* # sexagesimal float\n |[-+]?\\.(?:inf|Inf|INF)\n |\\.(?:nan|NaN|NAN))$',re.X),list(_E)),([(1,2)],_F,RegExp('^(?:[-+]?0b[0-1_]+\n |[-+]?0o?[0-7_]+\n |[-+]?[0-9_]+\n |[-+]?0x[0-9a-fA-F_]+)$',re.X),list(_G)),([(1,1)],_F,RegExp('^(?:[-+]?0b[0-1_]+\n |[-+]?0?[0-7_]+\n |[-+]?(?:0|[1-9][0-9_]*)\n |[-+]?0x[0-9a-fA-F_]+\n |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$',re.X),list(_G)),([(1,2),(1,1)],'tag:yaml.org,2002:merge',RegExp('^(?:<<)$'),['<']),([(1,2),(1,1)],'tag:yaml.org,2002:null',RegExp('^(?: ~\n |null|Null|NULL\n | )$',re.X),['~','n','N','']),([(1,2),(1,1)],'tag:yaml.org,2002:timestamp',RegExp('^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\n |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]?\n (?:[Tt]|[ \\t]+)[0-9][0-9]?\n :[0-9][0-9] :[0-9][0-9] (?:\\.[0-9]*)?\n (?:[ \\t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$',re.X),list('0123456789')),([(1,2),(1,1)],'tag:yaml.org,2002:value',RegExp('^(?:=)$'),['=']),([(1,2),(1,1)],'tag:yaml.org,2002:yaml',RegExp('^(?:!|&|\\*)$'),list('!&*'))] class ResolverError(YAMLError):0 class BaseResolver: DEFAULT_SCALAR_TAG='tag:yaml.org,2002:str';DEFAULT_SEQUENCE_TAG='tag:yaml.org,2002:seq';DEFAULT_MAPPING_TAG='tag:yaml.org,2002:map';yaml_implicit_resolvers={};yaml_path_resolvers={} def __init__(self,loadumper=_A): self.loadumper=loadumper if self.loadumper is not _A and getattr(self.loadumper,'_resolver',_A)is _A:self.loadumper._resolver=self.loadumper self._loader_version=_A;self.resolver_exact_paths=[];self.resolver_prefix_paths=[] @property def parser(self): if self.loadumper is not _A: if hasattr(self.loadumper,'typ'):return self.loadumper.parser return self.loadumper._parser @classmethod def add_implicit_resolver_base(cls,tag,regexp,first): if _H not in cls.__dict__:cls.yaml_implicit_resolvers=dict((k,cls.yaml_implicit_resolvers[k][:])for k in cls.yaml_implicit_resolvers) if first is _A:first=[_A] for ch in first:cls.yaml_implicit_resolvers.setdefault(ch,[]).append((tag,regexp)) @classmethod def add_implicit_resolver(cls,tag,regexp,first): if _H not in cls.__dict__:cls.yaml_implicit_resolvers=dict((k,cls.yaml_implicit_resolvers[k][:])for k in cls.yaml_implicit_resolvers) if first is _A:first=[_A] 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_path_resolver(cls,tag,path,kind=_A): if'yaml_path_resolvers'not in cls.__dict__:cls.yaml_path_resolvers=cls.yaml_path_resolvers.copy() new_path=[] 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=_A;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 _A:raise ResolverError('Invalid node checker: %s'%(node_check,)) if not isinstance(index_check,(string_types,int))and index_check is not _A: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 _A:raise ResolverError('Invalid node kind: %s'%(kind,)) cls.yaml_path_resolvers[tuple(new_path),kind]=tag def descend_resolver(self,current_node,current_index): 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): 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): node_check,index_check=path[depth-1] if isinstance(node_check,string_types): if current_node.tag!=node_check:return _B elif node_check is not _A: if not isinstance(current_node,node_check):return _B if index_check is True and current_index is not _A:return _B if(index_check is _B or index_check is _A)and current_index is _A:return _B if isinstance(index_check,string_types): if not(isinstance(current_index,ScalarNode)and index_check==current_index.value):return _B elif isinstance(index_check,int)and not isinstance(index_check,bool): if index_check!=current_index:return _B return True def resolve(self,kind,value,implicit): 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(_A,[]) 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 _A in exact_paths:return exact_paths[_A] 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):0 class Resolver(BaseResolver):0 for ir in implicit_resolvers: if(1,2)in ir[0]:Resolver.add_implicit_resolver_base(*ir[1:]) class VersionedResolver(BaseResolver): def __init__(self,version=_A,loader=_A,loadumper=_A): if loader is _A and loadumper is not _A:loader=loadumper BaseResolver.__init__(self,loader);self._loader_version=self.get_loader_version(version);self._version_implicit_resolver={} def add_version_implicit_resolver(self,version,tag,regexp,first): if first is _A:first=[_A] 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): if version is _A or isinstance(version,tuple):return version if isinstance(version,list):return tuple(version) return tuple(map(int,version.split('.'))) @property def versioned_resolver(self): 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): 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(_A,[]) 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 _A in exact_paths:return exact_paths[_A] 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): try:version=self.loadumper._scanner.yaml_version except AttributeError: try: if hasattr(self.loadumper,'typ'):version=self.loadumper.version else:version=self.loadumper._serializer.use_version except AttributeError:version=_A if version is _A: version=self._loader_version if version is _A:version=_DEFAULT_YAML_VERSION return version