diff options
-rw-r--r-- | CHANGES | 4 | ||||
-rw-r--r-- | README.rst | 8 | ||||
-rw-r--r-- | __init__.py | 4 | ||||
-rw-r--r-- | _doc/_static/pypi.svg | 2 | ||||
-rw-r--r-- | comments.py | 24 | ||||
-rw-r--r-- | compat.py | 1 | ||||
-rw-r--r-- | constructor.py | 5 | ||||
-rw-r--r-- | emitter.py | 11 | ||||
-rw-r--r-- | events.py | 20 | ||||
-rw-r--r-- | main.py | 2 | ||||
-rw-r--r-- | parser.py | 15 | ||||
-rw-r--r-- | representer.py | 18 | ||||
-rw-r--r-- | scanner.py | 109 | ||||
-rw-r--r-- | serializer.py | 5 | ||||
-rw-r--r-- | tokens.py | 29 |
15 files changed, 164 insertions, 93 deletions
@@ -1,3 +1,7 @@ +[0, 17, 5]: 2021-05-30 + - fix for issue 384 !!set with aliased entry resulting in broken YAML on rt + reported by `William Kimball <https://sourceforge.net/u/william303/>`__) + [0, 17, 4]: 2021-04-07 - prevent (empty) comments from throwing assertion error (issue 351 reported by `William Kimball <https://sourceforge.net/u/william303/>`__) @@ -4,8 +4,8 @@ ruamel.yaml ``ruamel.yaml`` is a YAML 1.2 loader/dumper package for Python. -:version: 0.17.4 -:updated: 2021-04-07 +:version: 0.17.5 +:updated: 2021-05-30 :documentation: http://yaml.readthedocs.io :repository: https://sourceforge.net/projects/ruamel-yaml/ :pypi: https://pypi.org/project/ruamel.yaml/ @@ -65,6 +65,10 @@ ChangeLog .. should insert NEXT: at the beginning of line for next key (with empty line) +0.17.5 (2021-05-30): + - fix for issue 384 !!set with aliased entry resulting in broken YAML on rt + reported by `William Kimball <https://sourceforge.net/u/william303/>`__) + 0.17.4 (2021-04-07): - prevent (empty) comments from throwing assertion error (issue 351 reported by `William Kimball <https://sourceforge.net/u/william303/>`__) diff --git a/__init__.py b/__init__.py index ee2b544..ef4c8b4 100644 --- a/__init__.py +++ b/__init__.py @@ -5,8 +5,8 @@ if False: # MYPY _package_data = dict( full_package_name='ruamel.yaml', - version_info=(0, 17, 4), - __version__='0.17.4', + version_info=(0, 17, 5), + __version__='0.17.5', author='Anthon van der Neut', author_email='a.van.der.neut@ruamel.eu', description='ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order', # NOQA diff --git a/_doc/_static/pypi.svg b/_doc/_static/pypi.svg index d88372e..820debd 100644 --- a/_doc/_static/pypi.svg +++ b/_doc/_static/pypi.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="86" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="86" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#007ec6" d="M33 0h53v20H33z"/><path fill="url(#b)" d="M0 0h86v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="230">pypi</text><text x="175" y="140" transform="scale(.1)" textLength="230">pypi</text><text x="585" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">0.17.4</text><text x="585" y="140" transform="scale(.1)" textLength="430">0.17.4</text></g> </svg> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="86" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="86" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#007ec6" d="M33 0h53v20H33z"/><path fill="url(#b)" d="M0 0h86v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="230">pypi</text><text x="175" y="140" transform="scale(.1)" textLength="230">pypi</text><text x="585" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">0.17.5</text><text x="585" y="140" transform="scale(.1)" textLength="430">0.17.5</text></g> </svg> diff --git a/comments.py b/comments.py index f49c183..d429fe1 100644 --- a/comments.py +++ b/comments.py @@ -11,7 +11,7 @@ import copy from ruamel.yaml.compat import ordereddict # type: ignore -from ruamel.yaml.compat import MutableSliceableSequence, _F, nprintf +from ruamel.yaml.compat import MutableSliceableSequence, _F, nprintf # NOQA from ruamel.yaml.scalarstring import ScalarString from ruamel.yaml.anchor import Anchor @@ -24,22 +24,24 @@ if False: # MYPY __all__ = ['CommentedSeq', 'CommentedKeySeq', 'CommentedMap', 'CommentedOrderedMap', 'CommentedSet', 'comment_attrib', 'merge_attrib', - 'C_POST', 'C_PRE', 'C_SPLIT_ON_FIRST_BLANK', 'C_BLANK_LINE_PRESERVE_SPACE', + 'C_POST', 'C_PRE', 'C_SPLIT_ON_FIRST_BLANK', 'C_BLANK_LINE_PRESERVE_SPACE', ] # fmt: on # splitting of comments by the scanner # an EOLC (End-Of-Line Comment) is preceded by some token -# an FLC (Full Line Comment) is a comment not preceded by a token, i.e. # is first non-blank on line +# an FLC (Full Line Comment) is a comment not preceded by a token, i.e. # is +# the first non-blank on line # a BL is a blank line i.e. empty or spaces/tabs only # bits 0 and 1 are combined, you can choose only one C_POST = 0b00 -C_PRE = 0b01 -C_SPLIT_ON_FIRST_BLANK = 0b10 # as C_POST, but if blank line then C_PRE all lines before first - # blank goes to POST even if no following real FLC (first blank -> first of post) +C_PRE = 0b01 +C_SPLIT_ON_FIRST_BLANK = 0b10 # as C_POST, but if blank line then C_PRE all lines before +# first blank goes to POST even if no following real FLC +# (first blank -> first of post) # 0b11 -> reserved for future use -C_BLANK_LINE_PRESERVE_SPACE = 0b100 -# C_EOL_PRESERVE_SPACE2 = 0b1000 +C_BLANK_LINE_PRESERVE_SPACE = 0b100 +# C_EOL_PRESERVE_SPACE2 = 0b1000 class IDX: @@ -55,14 +57,15 @@ class IDX: def __str__(self): return str(self._idx) + cidx = IDX() # more or less in order of subjective expected likelyhood # the _POST and _PRE ones are lists themselves C_VALUE_EOL = C_ELEM_EOL = cidx() C_KEY_EOL = cidx() -C_KEY_PRE = C_ELEM_PRE = cidx() # not this is not value -C_VALUE_POST = C_ELEM_POST = cidx() # not this is not value +C_KEY_PRE = C_ELEM_PRE = cidx() # not this is not value +C_VALUE_POST = C_ELEM_POST = cidx() # not this is not value C_VALUE_PRE = cidx() C_KEY_POST = cidx() C_TAG_EOL = cidx() @@ -140,7 +143,6 @@ class Comment: it = '\n ' + it + ' ' return 'Comment(\n pre={},\n items={{{}}}{})'.format(self.pre, it, end) - @property def items(self): # type: () -> Any @@ -166,6 +166,7 @@ class Nprint: out = sys.stdout if self._file_name is None else open(self._file_name, mode) return out + nprint = Nprint() nprintf = Nprint('/var/tmp/ruamel.yaml.log') diff --git a/constructor.py b/constructor.py index 199129e..0a5db9b 100644 --- a/constructor.py +++ b/constructor.py @@ -1323,8 +1323,9 @@ class RoundTripConstructor(SafeConstructor): if node.comment: seqtyp._yaml_add_comment(node.comment[:2]) if len(node.comment) > 2: - # this happens e.g. if you have a sequence element that is a flow-style mapping - # and that has no EOL comment but a following commentline or empty line + # this happens e.g. if you have a sequence element that is a flow-style + # mapping and that has no EOL comment but a following commentline or + # empty line seqtyp.yaml_end_comment_extend(node.comment[2], clear=True) else: # NEWCMNT @@ -13,7 +13,7 @@ from ruamel.yaml.events import * # NOQA # fmt: off from ruamel.yaml.compat import _F, nprint, dbg, DBG_EVENT, \ - check_anchorname_char, nprintf + check_anchorname_char, nprintf # NOQA # fmt: on if False: # MYPY @@ -695,7 +695,8 @@ class Emitter: pass self.states.append(self.expect_block_mapping_simple_value) self.expect_node(mapping=True, simple_key=True) - if isinstance(self.event, AliasEvent): + # test on style for alias in !!set + if isinstance(self.event, AliasEvent) and not self.event.style == '?': self.stream.write(' ') else: self.write_indicator('?', True, indention=True) @@ -1562,7 +1563,7 @@ class Emitter: def write_literal(self, text, comment=None): # type: (Any, Any) -> None hints, _indent, _indicator = self.determine_block_hints(text) - #if comment is not None: + # if comment is not None: # try: # hints += comment[1][0] # except (TypeError, IndexError) as e: @@ -1570,12 +1571,12 @@ class Emitter: if not isinstance(comment, str): comment = '' self.write_indicator('|' + hints + comment, True) - #try: + # try: # nprintf('selfev', comment) # cmx = comment[1][0] # if cmx: # self.stream.write(cmx) - #except (TypeError, IndexError) as e: + # except (TypeError, IndexError) as e: # pass if _indicator == '+': self.open_ended = True @@ -32,7 +32,7 @@ class Event: if True: arguments = [] if hasattr(self, 'value'): - arguments.append(repr(getattr(self, 'value'))) + arguments.append(repr(self.value)) for key in ['anchor', 'tag', 'implicit', 'flow_style', 'style']: v = getattr(self, key, None) if v is not None: @@ -40,8 +40,14 @@ class Event: if self.comment not in [None, CommentCheck]: arguments.append('comment={!r}'.format(self.comment)) if SHOW_LINES: - arguments.append('({}:{}/{}:{})'.format(self.start_mark.line, self.start_mark.column, - self.end_mark.line, self.end_mark.column)) + arguments.append( + '({}:{}/{}:{})'.format( + self.start_mark.line, + self.start_mark.column, + self.end_mark.line, + self.end_mark.column, + ) + ) arguments = ', '.join(arguments) else: attributes = [ @@ -50,7 +56,7 @@ class Event: if hasattr(self, key) ] arguments = ', '.join( - [_F('{key!s}={attr!r}', key=key, attr=getattr(self, key)) for key in attributes] + [_F('{k!s}={attr!r}', k=key, attr=getattr(self, key)) for key in attributes] ) if self.comment not in [None, CommentCheck]: arguments += ', comment={!r}'.format(self.comment) @@ -141,7 +147,11 @@ class DocumentEndEvent(Event): class AliasEvent(NodeEvent): - __slots__ = () + __slots__ = 'style' + + def __init__(self, anchor, start_mark=None, end_mark=None, style=None, comment=None): + NodeEvent.__init__(self, anchor, start_mark, end_mark, comment) + self.style = style class ScalarEvent(NodeEvent): @@ -16,7 +16,7 @@ from ruamel.yaml.nodes import * # NOQA from ruamel.yaml.loader import BaseLoader, SafeLoader, Loader, RoundTripLoader # NOQA from ruamel.yaml.dumper import BaseDumper, SafeDumper, Dumper, RoundTripDumper # NOQA -from ruamel.yaml.compat import StringIO, BytesIO, with_metaclass, nprint, nprintf +from ruamel.yaml.compat import StringIO, BytesIO, with_metaclass, nprint, nprintf # NOQA from ruamel.yaml.resolver import VersionedResolver, Resolver # NOQA from ruamel.yaml.representer import ( BaseRepresenter, @@ -92,6 +92,7 @@ def xprintf(*args, **kw): return nprintf(*args, **kw) pass + class ParserError(MarkedYAMLError): pass @@ -834,8 +835,8 @@ class RoundTripParser(Parser): class RoundTripParserSC(RoundTripParser): """roundtrip is a safe loader, that wants to see the unmangled tag""" - - # some of the differences are based on the superclass testing if self.loader.comment_handling is not None + # some of the differences are based on the superclass testing + # if self.loader.comment_handling is not None def move_token_comment(self, token, nt=None, empty=False): token.move_new_comment(self.scanner.peek_token() if nt is None else nt, empty=empty) @@ -846,11 +847,11 @@ class RoundTripParserSC(RoundTripParser): return None if not comment[0]: return None - if comment[0][0] != line + 1: + if comment[0][0] != line + 1: nprintf('>>>dcxxx', comment, line, typ) assert comment[0][0] == line + 1 - #if comment[0] - line > 1: - # return + # if comment[0] - line > 1: + # return typ = self.loader.comment_handling & 0b11 # nprintf('>>>dca', comment, line, typ) if typ == C_POST: @@ -860,7 +861,7 @@ class RoundTripParserSC(RoundTripParser): comment[0] = None return c # nprintf('>>>dcb', comment[0]) - for idx, cmntidx in enumerate(comment[0]): + for cmntidx in comment[0]: # nprintf('>>>dcb', cmntidx) if isinstance(self.scanner.comments[cmntidx], BlankLineComment): break @@ -874,5 +875,3 @@ class RoundTripParserSC(RoundTripParser): comment[0] = comment[0][idx:] return c raise NotImplementedError # reserved - - diff --git a/representer.py b/representer.py index f3e3e43..4b78c65 100644 --- a/representer.py +++ b/representer.py @@ -837,13 +837,17 @@ class RoundTripRepresenter(SafeRepresenter): for ct in node.comment[1]: ct.reset() item_comments = comment.items - for v in item_comments.values(): - if v and v[1]: - for ct in v[1]: - ct.reset() - try: - node.comment.append(comment.end) - except AttributeError: + if self.dumper.comment_handling is None: + for v in item_comments.values(): + if v and v[1]: + for ct in v[1]: + ct.reset() + try: + node.comment.append(comment.end) + except AttributeError: + pass + else: + # NEWCMNT pass except AttributeError: item_comments = {} @@ -29,7 +29,7 @@ # import inspect -from ruamel.yaml.error import MarkedYAMLError, CommentMark +from ruamel.yaml.error import MarkedYAMLError, CommentMark # NOQA from ruamel.yaml.tokens import * # NOQA from ruamel.yaml.compat import _F, check_anchorname_char, nprint, nprintf # NOQA @@ -44,6 +44,7 @@ _THE_END = '\n\0\r\x85\u2028\u2029' _THE_END_SPACE_TAB = ' \n\0\t\r\x85\u2028\u2029' _SPACE_TAB = ' \t' + def xprintf(*args, **kw): return nprintf(*args, **kw) pass @@ -1606,7 +1607,8 @@ class Scanner: break token = ScalarToken("".join(chunks), True, start_mark, end_mark) - # getattr provides True so C type loader, which cannot handle comment, will not make CommentToken + # getattr provides True so C type loader, which cannot handle comment, + # will not make CommentToken if self.loader is not None: comment_handler = getattr(self.loader, 'comment_handling', False) if comment_handler is None: @@ -2002,16 +2004,17 @@ class RoundTripScanner(Scanner): return Scanner.scan_block_scalar(self, style, rt=rt) -# commenthandling 2021, differentiatiation not needed +# commenthandling 2021, differentiatiation not needed VALUECMNT = 0 KEYCMNT = 0 # 1 -#TAGCMNT = 2 -#ANCHORCMNT = 3 +# TAGCMNT = 2 +# ANCHORCMNT = 3 class CommentBase: __slots__ = ('value', 'line', 'column', 'used', 'function', 'fline', 'ufun', 'uline') + def __init__(self, value, line, column): self.value = value self.line = line @@ -2039,9 +2042,18 @@ class CommentBase: return _F('{value!r}', value=self.value) def info(self): - return _F('{name}{used} {line:2}:{column:<2} "{value:40s} {function}:{fline} {ufun}:{uline}', - name=self.name, line=self.line, column=self.column, value=self.value + '"', used=self.used, - function=self.function, fline=self.fline, ufun=self.ufun, uline=self.uline) + return _F( + '{name}{used} {line:2}:{column:<2} "{value:40s} {function}:{fline} {ufun}:{uline}', + name=self.name, + line=self.line, + column=self.column, + value=self.value + '"', + used=self.used, + function=self.function, + fline=self.fline, + ufun=self.ufun, + uline=self.uline, + ) class EOLComment(CommentBase): @@ -2071,7 +2083,7 @@ class ScannedComments: self.unused = [] def add_eol_comment(self, comment, column, line): - info = inspect.getframeinfo(inspect.stack()[1][0]) + # info = inspect.getframeinfo(inspect.stack()[1][0]) if comment.count('\n') == 1: assert comment[-1] == '\n' else: @@ -2081,7 +2093,7 @@ class ScannedComments: return retval def add_blank_line(self, comment, column, line): - info = inspect.getframeinfo(inspect.stack()[1][0]) + # info = inspect.getframeinfo(inspect.stack()[1][0]) assert comment.count('\n') == 1 and comment[-1] == '\n' assert line not in self.comments self.comments[line] = retval = BlankLineComment(comment[:-1], line, column) @@ -2089,9 +2101,9 @@ class ScannedComments: return retval def add_full_line_comment(self, comment, column, line): - info = inspect.getframeinfo(inspect.stack()[1][0]) + # info = inspect.getframeinfo(inspect.stack()[1][0]) assert comment.count('\n') == 1 and comment[-1] == '\n' - #if comment.startswith('# C12'): + # if comment.startswith('# C12'): # raise # this raises in line 2127 fro 330 self.comments[line] = retval = FullLineComment(comment[:-1], line, column) @@ -2102,20 +2114,28 @@ class ScannedComments: return self.comments[idx] def __str__(self): - return 'ParsedComments:\n ' + \ - '\n '.join((_F('{lineno:2} {x}', lineno=lineno, x=x.info()) for lineno, x in self.comments.items())) + '\n' + return ( + 'ParsedComments:\n ' + + '\n '.join( + ( + _F('{lineno:2} {x}', lineno=lineno, x=x.info()) + for lineno, x in self.comments.items() + ) + ) + + '\n' + ) def last(self): lineno, x = list(self.comments.items())[-1] - return _F('{lineno:2} {x}\n', lineno=lineno, x=x.info()) + return _F('{lineno:2} {x}\n', lineno=lineno, x=x.info()) def any_unprocessed(self): # ToDo: might want to differentiate based on lineno return len(self.unused) > 0 - #for lno, comment in reversed(self.comments.items()): + # for lno, comment in reversed(self.comments.items()): # if comment.used == ' ': # return True - #return False + # return False def unprocessed(self, use=False): while len(self.unused) > 0: @@ -2132,7 +2152,7 @@ class ScannedComments: xprintf('assign_pre', token_line, self.unused, info.function, info.lineno) gobbled = False while self.unused and self.unused[0] < token_line: - gobled = True + gobbled = True first = self.unused.pop(0) xprintf('assign_pre < ', first) self.comments[first].set_used() @@ -2147,13 +2167,21 @@ class ScannedComments: if not isinstance(self.comments[comment_line], EOLComment): return idx = 1 - while tokens[-idx].start_mark.line > comment_line or isinstance(tokens[-idx], ValueToken): + while tokens[-idx].start_mark.line > comment_line or isinstance( + tokens[-idx], ValueToken + ): idx += 1 xprintf('idx1', idx) - if len(tokens) > idx and isinstance(tokens[-idx], ScalarToken) and isinstance(tokens[-(idx+1)], ScalarToken): + if ( + len(tokens) > idx + and isinstance(tokens[-idx], ScalarToken) + and isinstance(tokens[-(idx + 1)], ScalarToken) + ): return try: - if isinstance(tokens[-idx], ScalarToken) and isinstance(tokens[-(idx+1)], KeyToken): + if isinstance(tokens[-idx], ScalarToken) and isinstance( + tokens[-(idx + 1)], KeyToken + ): try: eol_idx = self.unused.pop(0) self.comments[eol_idx].set_used() @@ -2166,7 +2194,9 @@ class ScannedComments: xprintf('IndexError1') pass try: - if isinstance(tokens[-idx], ScalarToken) and isinstance(tokens[-(idx+1)], (ValueToken, BlockEntryToken)): + if isinstance(tokens[-idx], ScalarToken) and isinstance( + tokens[-(idx + 1)], (ValueToken, BlockEntryToken) + ): try: eol_idx = self.unused.pop(0) self.comments[eol_idx].set_used() @@ -2180,7 +2210,9 @@ class ScannedComments: for t in tokens: xprintf('tt-', t) xprintf('not implemented EOL', type(tokens[-idx])) - import sys; sys.exit(0) + import sys + + sys.exit(0) def assign_post(self, token): token_line = token.start_mark.line @@ -2188,7 +2220,7 @@ class ScannedComments: xprintf('assign_post', token_line, self.unused, info.function, info.lineno) gobbled = False while self.unused and self.unused[0] < token_line: - gobled = True + gobbled = True first = self.unused.pop(0) xprintf('assign_post < ', first) self.comments[first].set_used() @@ -2196,16 +2228,22 @@ class ScannedComments: return gobbled def str_unprocessed(self): - return ''.join((_F(' {ind:2} {x}\n', ind=ind, x=x.info()) for ind, x in self.comments.items() if x.used == ' ')) + return ''.join( + ( + _F(' {ind:2} {x}\n', ind=ind, x=x.info()) + for ind, x in self.comments.items() + if x.used == ' ' + ) + ) class RoundTripScannerSC(Scanner): # RoundTripScanner Split Comments def __init__(self, *arg, **kw): super().__init__(*arg, **kw) assert self.loader is not None - # comments isinitialised on .need_more_tokens and persist on self.loader.parsed_comments - # - self.comments = None + # comments isinitialised on .need_more_tokens and persist on + # self.loader.parsed_comments + self.comments = None def get_token(self): # type: () -> Any @@ -2240,7 +2278,7 @@ class RoundTripScannerSC(Scanner): # RoundTripScanner Split Comments xprintf('-x--', len(self.tokens)) for t in self.tokens: xprintf(t) - #xprintf(self.comments.last()) + # xprintf(self.comments.last()) xprintf(self.comments.str_unprocessed()) self.comments.assign_pre(self.tokens[0]) self.comments.assign_eol(self.tokens) @@ -2254,7 +2292,6 @@ class RoundTripScannerSC(Scanner): # RoundTripScanner Split Comments start_mark = self.reader.get_mark() # xprintf('current_mark', start_mark.line, start_mark.column) found = False - idx = 0 while not found: while srp() == ' ': srf() @@ -2262,7 +2299,7 @@ class RoundTripScannerSC(Scanner): # RoundTripScanner Split Comments if ch == '#': comment_start_mark = self.reader.get_mark() comment = ch - srf() # skipt the '#' + srf() # skipt the '#' while ch not in _THE_END: ch = srp() if ch == '\0': # don't gobble the end-of-stream character @@ -2275,9 +2312,13 @@ class RoundTripScannerSC(Scanner): # RoundTripScanner Split Comments srf() # we have a comment if start_mark.column == 0: - self.comments.add_full_line_comment(comment, comment_start_mark.column, comment_start_mark.line) + self.comments.add_full_line_comment( + comment, comment_start_mark.column, comment_start_mark.line + ) else: - self.comments.add_eol_comment(comment, comment_start_mark.column, comment_start_mark.line) + self.comments.add_eol_comment( + comment, comment_start_mark.column, comment_start_mark.line + ) comment = "" # gather any blank lines or full line comments following the comment as well self.scan_empty_or_full_line_comments() @@ -2300,7 +2341,7 @@ class RoundTripScannerSC(Scanner): # RoundTripScanner Split Comments if srp() == '#': # empty line followed by indented real comment comment = comment.rsplit('\n', 1)[0] + '\n' - end_mark = self.reader.get_mark() + _ = self.reader.get_mark() # gobble end_mark return None else: found = True diff --git a/serializer.py b/serializer.py index 1a78829..cc2329d 100644 --- a/serializer.py +++ b/serializer.py @@ -154,7 +154,10 @@ class Serializer: # type: (Any, Any, Any) -> None alias = self.anchors[node] if node in self.serialized_nodes: - self.emitter.emit(AliasEvent(alias)) + node_style = getattr(node, 'style', None) + if node_style != '?': + node_style = None + self.emitter.emit(AliasEvent(alias, style=node_style)) else: self.serialized_nodes[node] = True self.resolver.descend_resolver(parent, index) @@ -1,6 +1,6 @@ # coding: utf-8 -from ruamel.yaml.compat import _F, nprintf +from ruamel.yaml.compat import _F, nprintf # NOQA if False: # MYPY from typing import Text, Any, Dict, Optional, List # NOQA @@ -23,10 +23,12 @@ class Token: # hasattr('self', key)] attributes = [key for key in self.__slots__ if not key.endswith('_mark')] attributes.sort() - #arguments = ', '.join( - # [_F('{key!s}={gattr!r})', key=key, gattr=getattr(self, key)) for key in attributes] - #) - arguments = [_F('{key!s}={gattr!r}', key=key, gattr=getattr(self, key)) for key in attributes] + # arguments = ', '.join( + # [_F('{key!s}={gattr!r})', key=key, gattr=getattr(self, key)) for key in attributes] + # ) + arguments = [ + _F('{key!s}={gattr!r}', key=key, gattr=getattr(self, key)) for key in attributes + ] if SHOW_LINES: try: arguments.append('line: ' + str(self.start_mark.line)) @@ -46,7 +48,7 @@ class Token: def column(self, pos): self.start_mark.column = pos - # old style ( <= 0.17) is a TWO element list with first being the EOL + # old style ( <= 0.17) is a TWO element list with first being the EOL # comment concatenated with following FLC/BLNK; and second being a list of FLC/BLNK # preceding the token # new style ( >= 0.17 ) is a THREE element list with the first being a list of @@ -62,8 +64,8 @@ class Token: if not hasattr(self, '_comment'): self._comment = [None, None] else: - assert len(self._comment) == 2 # make sure it is version 0 - #if isinstance(comment, CommentToken): + assert len(self._comment) == 2 # make sure it is version 0 + # if isinstance(comment, CommentToken): # if comment.value.startswith('# C09'): # raise self._comment[0] = comment @@ -74,7 +76,7 @@ class Token: if not hasattr(self, '_comment'): self._comment = [None, None] else: - assert len(self._comment) == 2 # make sure it is version 0 + assert len(self._comment) == 2 # make sure it is version 0 assert self._comment[1] is None self._comment[1] = comments return @@ -110,10 +112,9 @@ class Token: self._comment[2] = [] self._comment[2].append(comment) - - #def get_comment(self): - # # type: () -> Any - # return getattr(self, '_comment', None) + # def get_comment(self): + # # type: () -> Any + # return getattr(self, '_comment', None) @property def comment(self): @@ -347,7 +348,7 @@ class CommentToken(Token): def __init__(self, value, start_mark=None, end_mark=None, column=None): # type: (Any, Any, Any) -> None if start_mark is None: - assert columns is not None + assert column is not None self._column = column Token.__init__(self, start_mark, None) self._value = value |