diff options
author | Anthon van der Neut <anthon@mnt.org> | 2017-08-09 14:17:45 +0200 |
---|---|---|
committer | Anthon van der Neut <anthon@mnt.org> | 2017-08-09 14:17:45 +0200 |
commit | 291b2e6757d22061acb8ee9a581dc04e3a791847 (patch) | |
tree | 3f805ec3551ba2e0baa5ce21b1ebadfd3136ccc5 | |
parent | b3b5301e1b0a21d81a2ec1501df9ef92abac5ce2 (diff) | |
download | ruamel.yaml-291b2e6757d22061acb8ee9a581dc04e3a791847.tar.gz |
fix for indenting non-indented sequence after comment
- solves several expected to fail and fixes two incorrect tests (test_09-Sammy Sosa &
test_before_nested_seq_from_scratch)
- still swaps foo and bar on test_issue_25_03
-rw-r--r-- | _test/test_comments.py | 6 | ||||
-rw-r--r-- | compat.py | 7 | ||||
-rw-r--r-- | emitter.py | 23 | ||||
-rw-r--r-- | parser.py | 230 | ||||
-rw-r--r-- | scanner.py | 2 | ||||
-rw-r--r-- | tokens.py | 21 |
6 files changed, 163 insertions, 126 deletions
diff --git a/_test/test_comments.py b/_test/test_comments.py index 9698fde..8717727 100644 --- a/_test/test_comments.py +++ b/_test/test_comments.py @@ -141,9 +141,9 @@ class TestComments: # 1998 rbi ranking - Sammy Sosa - Ken Griffey - """) + """, indent=4, block_seq_indent=2) - def test_09a(self): + def test_09a(self): round_trip(""" hr: # 1998 hr ranking - Mark McGwire @@ -152,7 +152,7 @@ class TestComments: # 1998 rbi ranking - Sammy Sosa - Ken Griffey - """, indent=4, block_seq_indent=2) + """) def test_simple_map_middle_comment(self): round_trip(""" @@ -125,6 +125,13 @@ DBG_NODE = 4 _debug = None # type: Union[None, int] +if 'RUAMELDEBUG' in os.environ: + _debugx = os.environ.get('RUAMELDEBUG') + if _debugx is None: + _debug = 0 + else: + _debug = int(_debugx) + if bool(_debug): class ObjectCounter(object): @@ -318,10 +318,13 @@ class Emitter(object): self.expect_scalar() elif isinstance(self.event, SequenceStartEvent): if self.event.comment: - self.write_pre_comment(self.event) + if self.write_pre_comment(self.event): + self.indention = False + self.no_newline = True if self.event.flow_style is False and self.event.comment: - self.write_post_comment(self.event) - # print('seq event', self.event) + if self.write_post_comment(self.event): + self.indention = False + self.no_newline = True if self.flow_level or self.canonical or self.event.flow_style or \ self.check_empty_sequence(): self.expect_flow_sequence() @@ -490,7 +493,9 @@ class Emitter(object): else: if self.event.comment and self.event.comment[1]: self.write_pre_comment(self.event) + nonl = self.no_newline self.write_indent() + self.no_newline = nonl self.write_indicator((u' ' * self.block_seq_indent) + u'-', True, indention=True) if self.block_seq_indent + 2 > self.best_indent: self.no_newline = True @@ -1372,27 +1377,29 @@ class Emitter(object): self.write_line_break() def write_pre_comment(self, event): - # type: (Any) -> None + # type: (Any) -> bool comments = event.comment[1] if comments is None: - return + return False try: for comment in comments: if isinstance(event, MappingStartEvent) and \ getattr(comment, 'pre_done', None): continue if self.column != 0: - self.write_line_break() + self.write_line_break() self.write_comment(comment) if isinstance(event, MappingStartEvent): comment.pre_done = True except TypeError: print('eventtt', type(event), event) raise + return True def write_post_comment(self, event): - # type: (Any) -> None + # type: (Any) -> bool if self.event.comment[0] is None: - return + return False comment = event.comment[0] self.write_comment(comment) + return True @@ -80,7 +80,7 @@ from ruamel.yaml.error import MarkedYAMLError from ruamel.yaml.tokens import * # NOQA from ruamel.yaml.events import * # NOQA from ruamel.yaml.scanner import Scanner, RoundTripScanner, ScannerError # NOQA -from ruamel.yaml.compat import utf8 # NOQA +from ruamel.yaml.compat import utf8, nprint # NOQA if False: # MYPY from typing import Any, Dict, Optional, List # NOQA @@ -342,121 +342,131 @@ class Parser(object): token = self.scanner.get_token() event = AliasEvent(token.value, token.start_mark, token.end_mark) # type: Any self.state = self.states.pop() - else: - anchor = None - tag = None - start_mark = end_mark = tag_mark = None - if self.scanner.check_token(AnchorToken): + return event + + anchor = None + tag = None + start_mark = end_mark = tag_mark = None + if self.scanner.check_token(AnchorToken): + token = self.scanner.get_token() + start_mark = token.start_mark + end_mark = token.end_mark + anchor = token.value + if self.scanner.check_token(TagToken): token = self.scanner.get_token() - start_mark = token.start_mark + tag_mark = token.start_mark end_mark = token.end_mark - anchor = token.value - if self.scanner.check_token(TagToken): - token = self.scanner.get_token() - tag_mark = token.start_mark - end_mark = token.end_mark - tag = token.value - elif self.scanner.check_token(TagToken): + tag = token.value + elif self.scanner.check_token(TagToken): + token = self.scanner.get_token() + start_mark = tag_mark = token.start_mark + end_mark = token.end_mark + tag = token.value + if self.scanner.check_token(AnchorToken): token = self.scanner.get_token() start_mark = tag_mark = token.start_mark end_mark = token.end_mark - tag = token.value - if self.scanner.check_token(AnchorToken): - token = self.scanner.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.scanner.peek_token().start_mark - event = None - implicit = (tag is None or tag == u'!') - if indentless_sequence and self.scanner.check_token(BlockEntryToken): - end_mark = self.scanner.peek_token().end_mark - event = SequenceStartEvent(anchor, tag, implicit, - start_mark, end_mark) - self.state = self.parse_indentless_sequence_entry - else: - if self.scanner.check_token(ScalarToken): - token = self.scanner.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.scanner.check_token(FlowSequenceStartToken): - end_mark = self.scanner.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.scanner.check_token(FlowMappingStartToken): - end_mark = self.scanner.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.scanner.check_token(BlockSequenceStartToken): - end_mark = self.scanner.peek_token().start_mark - # should inserting the comment be dependent on the - # indentation? - pt = self.scanner.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.scanner.check_token(BlockMappingStartToken): - end_mark = self.scanner.peek_token().start_mark - comment = self.scanner.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.scanner.peek_token() + 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 %s node" % node, start_mark, - "expected the node content, but found %r" % token.id, - token.start_mark) + "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.scanner.peek_token().start_mark + event = None + implicit = (tag is None or tag == u'!') + if indentless_sequence and self.scanner.check_token(BlockEntryToken): + comment = None + pt = self.scanner.peek_token() + if pt.comment and pt.comment[0]: + comment = [pt.comment[0], []] + pt.comment[0] = None + end_mark = self.scanner.peek_token().end_mark + event = SequenceStartEvent(anchor, tag, implicit, + start_mark, end_mark, comment=comment) + self.state = self.parse_indentless_sequence_entry + return event + + if self.scanner.check_token(ScalarToken): + token = self.scanner.get_token() + # self.scanner.peek_token_same_line_comment(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) + # nprint('se', token.value, token.comment) + event = ScalarEvent( + anchor, tag, implicit, token.value, + start_mark, end_mark, style=token.style, + comment=token.comment + ) + self.state = self.states.pop() + elif self.scanner.check_token(FlowSequenceStartToken): + end_mark = self.scanner.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.scanner.check_token(FlowMappingStartToken): + end_mark = self.scanner.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.scanner.check_token(BlockSequenceStartToken): + end_mark = self.scanner.peek_token().start_mark + # should inserting the comment be dependent on the + # indentation? + pt = self.scanner.peek_token() + comment = pt.comment + # nprint('pt0', type(pt)) + if comment is None or comment[1] is None: + comment = pt.split_comment() + # nprint('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.scanner.check_token(BlockMappingStartToken): + end_mark = self.scanner.peek_token().start_mark + comment = self.scanner.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.scanner.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 # block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* @@ -32,7 +32,7 @@ from __future__ import print_function, absolute_import, division, unicode_litera from ruamel.yaml.error import MarkedYAMLError from ruamel.yaml.tokens import * # NOQA -from ruamel.yaml.compat import utf8, unichr, PY3, check_anchorname_char +from ruamel.yaml.compat import utf8, unichr, PY3, check_anchorname_char, nprint # NOQA if False: # MYPY from typing import Any, Dict, Optional, List, Union, Text # NOQA @@ -4,6 +4,7 @@ if False: # MYPY from typing import Any, Dict, Optional, List # NOQA +SHOWLINES = True class Token(object): __slots__ = 'start_mark', 'end_mark', '_comment', @@ -15,12 +16,18 @@ class Token(object): def __repr__(self): # type: () -> Any - attributes = [key for key in self.__slots__ if not key.endswith('_mark') and - hasattr('self', key)] + # attributes = [key for key in self.__slots__ if not key.endswith('_mark') and + # hasattr('self', key)] + attributes = [key for key in self.__slots__ if not key.endswith('_mark')] attributes.sort() arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) for key in attributes]) - return '%s(%s)' % (self.__class__.__name__, arguments) + if SHOWLINES: + try: + arguments += u', line: ' + str(self.start_mark.line) + except: + pass + return u'{}({})'.format(self.__class__.__name__, arguments) def add_post_comment(self, comment): # type: (Any) -> None @@ -261,4 +268,10 @@ class CommentToken(Token): def __repr__(self): # type: () -> Any - return 'CommentToken({!r})'.format(self.value) + v = self.value + if SHOWLINES: + try: + v += u', line: ' + str(self.start_mark.line) + except: + pass + return 'CommentToken({!r})'.format(v) |