def compose_node(self, parent, index): if self.check_event(AliasEvent): event = self.get_event() alias = event.anchor if alias not in self.anchors: raise ComposerError( None, None, "found undefined alias %r" % utf8(alias), event.start_mark) return self.anchors[alias] event = self.peek_event() anchor = event.anchor if anchor is not None: # have an anchor if anchor in self.anchors: raise ComposerError( "found duplicate anchor %r; first occurence" % utf8(anchor), self.anchors[anchor].start_mark, "second occurence", event.start_mark) self.descend_resolver(parent, index) if self.check_event(ScalarEvent): node = self.compose_scalar_node(anchor) elif self.check_event(SequenceStartEvent): node = self.compose_sequence_node(anchor) elif self.check_event(MappingStartEvent): node = self.compose_mapping_node(anchor) self.ascend_resolver() return node
def prepare_anchor(self, anchor): if not anchor: raise EmitterError("anchor must not be empty") for ch in anchor: if not check_anchorname_char(ch): raise EmitterError("invalid character %r in the anchor: %r" % (utf8(ch), utf8(anchor))) return anchor
def prepare_anchor(self, anchor): if not anchor: raise EmitterError("anchor must not be empty") for ch in anchor: if not (u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' or ch in u'-_'): raise EmitterError("invalid character %r in the anchor: %r" % (utf8(ch), utf8(anchor))) return anchor
def prepare_tag_handle(self, handle): if not handle: raise EmitterError("tag handle must not be empty") if handle[0] != u'!' or handle[-1] != u'!': raise EmitterError("tag handle must start and end with '!': %r" % (utf8(handle))) for ch in handle[1:-1]: if not (u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' or ch in u'-_'): raise EmitterError("invalid character %r in the tag handle: %r" % (utf8(ch), utf8(handle))) return handle
def process_directives(self): self.yaml_version = None self.tag_handles = {} while self.check_token(DirectiveToken): token = self.get_token() if token.name == u'YAML': if self.yaml_version is not None: raise ParserError( None, None, "found duplicate YAML directive", token.start_mark) major, minor = token.value if major != 1: raise ParserError( None, None, "found incompatible YAML document (version 1.* is " "required)", token.start_mark) self.yaml_version = token.value elif token.name == u'TAG': handle, prefix = token.value if handle in self.tag_handles: raise ParserError(None, None, "duplicate tag handle %r" % utf8(handle), token.start_mark) self.tag_handles[handle] = prefix if self.tag_handles: value = self.yaml_version, self.tag_handles.copy() else: value = self.yaml_version, None for key in self.DEFAULT_TAGS: if key not in self.tag_handles: self.tag_handles[key] = self.DEFAULT_TAGS[key] return value
def prepare_tag(self, tag): if not tag: raise EmitterError("tag must not be empty") if tag == u'!': return tag handle = None suffix = tag prefixes = sorted(self.tag_prefixes.keys()) for prefix in prefixes: if tag.startswith(prefix) \ and (prefix == u'!' or len(prefix) < len(tag)): handle = self.tag_prefixes[prefix] suffix = tag[len(prefix):] chunks = [] start = end = 0 while end < len(suffix): ch = suffix[end] if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ or ch in u'-;/?:@&=+$,_.~*\'()[]' \ or (ch == u'!' and handle != u'!'): end += 1 else: if start < end: chunks.append(suffix[start:end]) start = end = end+1 data = utf8(ch) for ch in data: chunks.append(u'%%%02X' % ord(ch)) if start < end: chunks.append(suffix[start:end]) suffix_text = u''.join(chunks) if handle: return u'%s%s' % (handle, suffix_text) else: return u'!<%s>' % suffix_text
def compose_node(self, parent, index): # type: (Any, Any) -> Any if self.parser.check_event(AliasEvent): event = self.parser.get_event() alias = event.anchor if alias not in self.anchors: raise ComposerError(None, None, "found undefined alias %r" % utf8(alias), event.start_mark) return self.anchors[alias] event = self.parser.peek_event() anchor = event.anchor if anchor is not None: # have an anchor if anchor in self.anchors: # raise ComposerError( # "found duplicate anchor %r; first occurrence" # % utf8(anchor), self.anchors[anchor].start_mark, # "second occurrence", event.start_mark) ws = "\nfound duplicate anchor {!r}\nfirst occurrence {}\nsecond occurrence "\ "{}".format( (anchor), self.anchors[anchor].start_mark, event.start_mark) warnings.warn(ws, ReusedAnchorWarning) self.resolver.descend_resolver(parent, index) if self.parser.check_event(ScalarEvent): node = self.compose_scalar_node(anchor) elif self.parser.check_event(SequenceStartEvent): node = self.compose_sequence_node(anchor) elif self.parser.check_event(MappingStartEvent): node = self.compose_mapping_node(anchor) self.resolver.ascend_resolver() return node
def get_snippet(self, indent=4, max_length=75): # type: (int, int) -> Any if self.buffer is None: # always False return None head = '' start = self.pointer while (start > 0 and self.buffer[start - 1] not in u'\0\r\n\x85\u2028\u2029'): start -= 1 if self.pointer - start > max_length / 2 - 1: head = ' ... ' start += 5 break tail = '' end = self.pointer while (end < len(self.buffer) and self.buffer[end] not in u'\0\r\n\x85\u2028\u2029'): end += 1 if end - self.pointer > max_length / 2 - 1: tail = ' ... ' end -= 5 break snippet = utf8(self.buffer[start:end]) caret = '^' caret = '^ (line: {})'.format(self.line + 1) return ' '*indent + head + snippet + tail + '\n' \ + ' '*(indent+self.pointer-start+len(head)) + caret
def prepare_tag(self, tag): if not tag: raise EmitterError("tag must not be empty") if tag == u'!': return tag handle = None suffix = tag prefixes = sorted(self.tag_prefixes.keys()) for prefix in prefixes: if tag.startswith(prefix) \ and (prefix == u'!' or len(prefix) < len(tag)): handle = self.tag_prefixes[prefix] suffix = tag[len(prefix):] chunks = [] start = end = 0 while end < len(suffix): ch = suffix[end] if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ or ch in u'-;/?:@&=+$,_.~*\'()[]' \ or (ch == u'!' and handle != u'!'): end += 1 else: if start < end: chunks.append(suffix[start:end]) start = end = end + 1 data = utf8(ch) for ch in data: chunks.append(u'%%%02X' % ord(ch)) if start < end: chunks.append(suffix[start:end]) suffix_text = u''.join(chunks) if handle: return u'%s%s' % (handle, suffix_text) else: return u'!<%s>' % suffix_text
def process_directives(self): self.yaml_version = None self.tag_handles = {} while self.check_token(DirectiveToken): token = self.get_token() if token.name == u'YAML': if self.yaml_version is not None: raise ParserError(None, None, "found duplicate YAML directive", token.start_mark) major, minor = token.value if major != 1: raise ParserError( None, None, "found incompatible YAML document (version 1.* is " "required)", token.start_mark) self.yaml_version = token.value elif token.name == u'TAG': handle, prefix = token.value if handle in self.tag_handles: raise ParserError(None, None, "duplicate tag handle %r" % utf8(handle), token.start_mark) self.tag_handles[handle] = prefix if self.tag_handles: value = self.yaml_version, self.tag_handles.copy() else: value = self.yaml_version, None for key in self.DEFAULT_TAGS: if key not in self.tag_handles: self.tag_handles[key] = self.DEFAULT_TAGS[key] return value
def construct_python_module(self, suffix, node): value = self.construct_scalar(node) if value: raise ConstructorError( "while constructing a Python module", node.start_mark, "expected the empty value, but found %r" % utf8(value), node.start_mark) return self.find_python_module(suffix, node.start_mark)
def find_python_module(self, name, mark): if not name: raise ConstructorError( "while constructing a Python module", mark, "expected non-empty name appended to the tag", mark) try: __import__(name) except ImportError as exc: raise ConstructorError( "while constructing a Python module", mark, "cannot find module %r (%s)" % (utf8(name), exc), mark) return sys.modules[name]
def find_python_name(self, name, mark): if not name: raise ConstructorError( "while constructing a Python object", mark, "expected non-empty name appended to the tag", mark) if u'.' in name: module_name, object_name = name.rsplit('.', 1) else: module_name = builtins_module object_name = name try: __import__(module_name) except ImportError as exc: raise ConstructorError( "while constructing a Python object", mark, "cannot find module %r (%s)" % (utf8(module_name), exc), mark) module = sys.modules[module_name] if not hasattr(module, object_name): raise ConstructorError( "while constructing a Python object", mark, "cannot find %r in the module %r" % (utf8(object_name), module.__name__), mark) return getattr(module, object_name)
def construct_undefined(self, node): try: data = CommentedMap() data._yaml_set_line_col(node.start_mark.line, node.start_mark.column) if node.flow_style is True: data.fa.set_flow_style() elif node.flow_style is False: data.fa.set_block_style() data.yaml_set_tag(node.tag) yield data self.construct_mapping(node, data) except: raise ConstructorError( None, None, "could not determine a constructor for the tag %r" % utf8(node.tag), node.start_mark)
def process_directives(self): # type: () -> Any yaml_version = None self.tag_handles = {} while self.scanner.check_token(DirectiveToken): token = self.scanner.get_token() if token.name == u'YAML': if yaml_version is not None: raise ParserError(None, None, 'found duplicate YAML directive', token.start_mark) major, minor = token.value if major != 1: raise ParserError( None, None, 'found incompatible YAML document (version 1.* is ' 'required)', token.start_mark, ) yaml_version = token.value elif token.name == u'TAG': handle, prefix = token.value if handle in self.tag_handles: raise ParserError(None, None, 'duplicate tag handle %r' % utf8(handle), token.start_mark) self.tag_handles[handle] = prefix if bool(self.tag_handles): value = yaml_version, self.tag_handles.copy() # type: Any else: value = yaml_version, None if self.loader is not None and hasattr(self.loader, 'tags'): self.loader.version = yaml_version if self.loader.tags is None: self.loader.tags = {} for k in self.tag_handles: self.loader.tags[k] = self.tag_handles[k] for key in self.DEFAULT_TAGS: if key not in self.tag_handles: self.tag_handles[key] = self.DEFAULT_TAGS[key] return value
def prepare_tag_prefix(self, prefix): if not prefix: raise EmitterError("tag prefix must not be empty") chunks = [] start = end = 0 if prefix[0] == u'!': end = 1 while end < len(prefix): ch = prefix[end] if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ or ch in u'-;/?!:@&=+$,_.~*\'()[]': end += 1 else: if start < end: chunks.append(prefix[start:end]) start = end = end+1 data = utf8(ch) for ch in data: chunks.append(u'%%%02X' % ord(ch)) if start < end: chunks.append(prefix[start:end]) return u''.join(chunks)
def prepare_tag_prefix(self, prefix): if not prefix: raise EmitterError("tag prefix must not be empty") chunks = [] start = end = 0 if prefix[0] == u'!': end = 1 while end < len(prefix): ch = prefix[end] if u'0' <= ch <= u'9' or u'A' <= ch <= u'Z' or u'a' <= ch <= u'z' \ or ch in u'-;/?!:@&=+$,_.~*\'()[]': end += 1 else: if start < end: chunks.append(prefix[start:end]) start = end = end + 1 data = utf8(ch) for ch in data: chunks.append(u'%%%02X' % ord(ch)) if start < end: chunks.append(prefix[start:end]) return u''.join(chunks)
def get_snippet(self, indent=4, max_length=75): if self.buffer is None: return None head = '' start = self.pointer while (start > 0 and self.buffer[start - 1] not in u'\0\r\n\x85\u2028\u2029'): start -= 1 if self.pointer - start > max_length / 2 - 1: head = ' ... ' start += 5 break tail = '' end = self.pointer while (end < len(self.buffer) and self.buffer[end] not in u'\0\r\n\x85\u2028\u2029'): end += 1 if end - self.pointer > max_length / 2 - 1: tail = ' ... ' end -= 5 break snippet = utf8(self.buffer[start:end]) return ' '*indent + head + snippet + tail + '\n' \ + ' '*(indent+self.pointer-start+len(head)) + '^'
def get_snippet(self, indent=4, max_length=75): if self.buffer is None: return None head = '' start = self.pointer while (start > 0 and self.buffer[start-1] not in u'\0\r\n\x85\u2028\u2029'): start -= 1 if self.pointer-start > max_length/2-1: head = ' ... ' start += 5 break tail = '' end = self.pointer while (end < len(self.buffer) and self.buffer[end] not in u'\0\r\n\x85\u2028\u2029'): end += 1 if end-self.pointer > max_length/2-1: tail = ' ... ' end -= 5 break snippet = utf8(self.buffer[start:end]) return ' '*indent + head + snippet + tail + '\n' \ + ' '*(indent+self.pointer-start+len(head)) + '^'
def construct_python_str(self, node): return utf8(self.construct_scalar(node))
def parse_node(self, block=False, indentless_sequence=False): if self.check_token(AliasToken): token = self.get_token() event = AliasEvent(token.value, token.start_mark, token.end_mark) self.state = self.states.pop() else: anchor = None tag = None start_mark = end_mark = tag_mark = None if self.check_token(AnchorToken): token = self.get_token() start_mark = token.start_mark end_mark = token.end_mark anchor = token.value if self.check_token(TagToken): token = self.get_token() tag_mark = token.start_mark end_mark = token.end_mark tag = token.value elif self.check_token(TagToken): token = self.get_token() start_mark = tag_mark = token.start_mark end_mark = token.end_mark tag = token.value if self.check_token(AnchorToken): token = self.get_token() end_mark = token.end_mark anchor = token.value if tag is not None: handle, suffix = tag if handle is not None: if handle not in self.tag_handles: raise ParserError( "while parsing a node", start_mark, "found undefined tag handle %r" % utf8(handle), tag_mark) tag = self.transform_tag(handle, suffix) else: tag = suffix # if tag == u'!': # raise ParserError("while parsing a node", start_mark, # "found non-specific tag '!'", tag_mark, # "Please check 'http://pyyaml.org/wiki/YAMLNonSpecificTag' # and share your opinion.") if start_mark is None: start_mark = end_mark = self.peek_token().start_mark event = None implicit = (tag is None or tag == u'!') if indentless_sequence and self.check_token(BlockEntryToken): end_mark = self.peek_token().end_mark event = SequenceStartEvent(anchor, tag, implicit, start_mark, end_mark) self.state = self.parse_indentless_sequence_entry else: if self.check_token(ScalarToken): token = self.get_token() end_mark = token.end_mark if (token.plain and tag is None) or tag == u'!': implicit = (True, False) elif tag is None: implicit = (False, True) else: implicit = (False, False) event = ScalarEvent(anchor, tag, implicit, token.value, start_mark, end_mark, style=token.style, comment=token.comment) self.state = self.states.pop() elif self.check_token(FlowSequenceStartToken): end_mark = self.peek_token().end_mark event = SequenceStartEvent(anchor, tag, implicit, start_mark, end_mark, flow_style=True) self.state = self.parse_flow_sequence_first_entry elif self.check_token(FlowMappingStartToken): end_mark = self.peek_token().end_mark event = MappingStartEvent(anchor, tag, implicit, start_mark, end_mark, flow_style=True) self.state = self.parse_flow_mapping_first_key elif block and self.check_token(BlockSequenceStartToken): end_mark = self.peek_token().start_mark # should inserting the comment be dependent on the # indentation? pt = self.peek_token() comment = pt.comment # print('pt0', type(pt)) if comment is None or comment[1] is None: comment = pt.split_comment() # print('pt1', comment) event = SequenceStartEvent( anchor, tag, implicit, start_mark, end_mark, flow_style=False, comment=comment, ) self.state = self.parse_block_sequence_first_entry elif block and self.check_token(BlockMappingStartToken): end_mark = self.peek_token().start_mark comment = self.peek_token().comment event = MappingStartEvent(anchor, tag, implicit, start_mark, end_mark, flow_style=False, comment=comment) self.state = self.parse_block_mapping_first_key elif anchor is not None or tag is not None: # Empty scalars are allowed even if a tag or an anchor is # specified. event = ScalarEvent(anchor, tag, (implicit, False), u'', start_mark, end_mark) self.state = self.states.pop() else: if block: node = 'block' else: node = 'flow' token = self.peek_token() raise ParserError( "while parsing a %s node" % node, start_mark, "expected the node content, but found %r" % token.id, token.start_mark) return event
def parse_node(self, block=False, indentless_sequence=False): if self.check_token(AliasToken): token = self.get_token() event = AliasEvent(token.value, token.start_mark, token.end_mark) self.state = self.states.pop() else: anchor = None tag = None start_mark = end_mark = tag_mark = None if self.check_token(AnchorToken): token = self.get_token() start_mark = token.start_mark end_mark = token.end_mark anchor = token.value if self.check_token(TagToken): token = self.get_token() tag_mark = token.start_mark end_mark = token.end_mark tag = token.value elif self.check_token(TagToken): token = self.get_token() start_mark = tag_mark = token.start_mark end_mark = token.end_mark tag = token.value if self.check_token(AnchorToken): token = self.get_token() end_mark = token.end_mark anchor = token.value if tag is not None: handle, suffix = tag if handle is not None: if handle not in self.tag_handles: raise ParserError( "while parsing a node", start_mark, "found undefined tag handle %r" % utf8(handle), tag_mark) tag = self.tag_handles[handle]+suffix else: tag = suffix # if tag == u'!': # raise ParserError("while parsing a node", start_mark, # "found non-specific tag '!'", tag_mark, # "Please check 'http://pyyaml.org/wiki/YAMLNonSpecificTag' # and share your opinion.") if start_mark is None: start_mark = end_mark = self.peek_token().start_mark event = None implicit = (tag is None or tag == u'!') if indentless_sequence and self.check_token(BlockEntryToken): end_mark = self.peek_token().end_mark event = SequenceStartEvent(anchor, tag, implicit, start_mark, end_mark) self.state = self.parse_indentless_sequence_entry else: if self.check_token(ScalarToken): token = self.get_token() end_mark = token.end_mark if (token.plain and tag is None) or tag == u'!': implicit = (True, False) elif tag is None: implicit = (False, True) else: implicit = (False, False) event = ScalarEvent( anchor, tag, implicit, token.value, start_mark, end_mark, style=token.style, comment=token.comment ) self.state = self.states.pop() elif self.check_token(FlowSequenceStartToken): end_mark = self.peek_token().end_mark event = SequenceStartEvent( anchor, tag, implicit, start_mark, end_mark, flow_style=True) self.state = self.parse_flow_sequence_first_entry elif self.check_token(FlowMappingStartToken): end_mark = self.peek_token().end_mark event = MappingStartEvent( anchor, tag, implicit, start_mark, end_mark, flow_style=True) self.state = self.parse_flow_mapping_first_key elif block and self.check_token(BlockSequenceStartToken): end_mark = self.peek_token().start_mark # should inserting the comment be dependent on the # indentation? pt = self.peek_token() comment = pt.comment # print('pt0', type(pt)) if comment is None or comment[1] is None: comment = pt.split_comment() # print('pt1', comment) event = SequenceStartEvent( anchor, tag, implicit, start_mark, end_mark, flow_style=False, comment=comment, ) self.state = self.parse_block_sequence_first_entry elif block and self.check_token(BlockMappingStartToken): end_mark = self.peek_token().start_mark comment = self.peek_token().comment event = MappingStartEvent( anchor, tag, implicit, start_mark, end_mark, flow_style=False, comment=comment) self.state = self.parse_block_mapping_first_key elif anchor is not None or tag is not None: # Empty scalars are allowed even if a tag or an anchor is # specified. event = ScalarEvent(anchor, tag, (implicit, False), u'', start_mark, end_mark) self.state = self.states.pop() else: if block: node = 'block' else: node = 'flow' token = self.peek_token() raise ParserError( "while parsing a %s node" % node, start_mark, "expected the node content, but found %r" % token.id, token.start_mark) return event
def construct_undefined(self, node): raise ConstructorError( None, None, "could not determine a constructor for the tag %r" % utf8(node.tag), node.start_mark)