From 5a5b603289bfd9b9e1bcd57618cf8694bd0ec2aa Mon Sep 17 00:00:00 2001 From: Anthon van der Neut Date: Wed, 9 Jun 2021 15:29:00 +0200 Subject: fix for issue 387 tagged objects that have a templated (idNNN) anchor, did get the anchor added explicitly, resulting potentially in double anchors --- CHANGES | 5 +++++ README.rst | 11 ++++++++--- __init__.py | 4 ++-- _doc/_static/pypi.svg | 2 +- comments.py | 10 +++++----- constructor.py | 19 ++++++++++++++----- reader.py | 2 +- representer.py | 2 +- scalarbool.py | 4 ++-- scalarfloat.py | 20 ++++++++++---------- scalarint.py | 8 ++++---- scalarstring.py | 8 ++++---- timestamp.py | 2 +- 13 files changed, 58 insertions(+), 39 deletions(-) diff --git a/CHANGES b/CHANGES index 9d06489..f893731 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +[0, 17, 8]: 2021-06-09 + - fix for issue 387 where templated anchors on tagged object did get set + resulting in potential id reuse. (reported by `Artem Ploujnikov + `__) + [0, 17, 7]: 2021-05-31 - issue 385 also affected other deprecated loaders (reported via email by Oren Watson) diff --git a/README.rst b/README.rst index 0974570..6ca30d4 100644 --- a/README.rst +++ b/README.rst @@ -4,8 +4,8 @@ ruamel.yaml ``ruamel.yaml`` is a YAML 1.2 loader/dumper package for Python. -:version: 0.17.7 -:updated: 2021-05-31 +:version: 0.17.8 +:updated: 2021-06-09 :documentation: http://yaml.readthedocs.io :repository: https://sourceforge.net/projects/ruamel-yaml/ :pypi: https://pypi.org/project/ruamel.yaml/ @@ -65,6 +65,11 @@ ChangeLog .. should insert NEXT: at the beginning of line for next key (with empty line) +0.17.8 (2021-06-09): + - fix for issue 387 where templated anchors on tagged object did get set + resulting in potential id reuse. (reported by `Artem Ploujnikov + `__) + 0.17.7 (2021-05-31): - issue 385 also affected other deprecated loaders (reported via email by Oren Watson) @@ -76,7 +81,7 @@ ChangeLog (reported by `Mike Gouline `__) - wasted a few hours getting rid of mypy warnings/errors -0.17.5: +0.17.5 (2021-05-30): - fix for issue 384 !!set with aliased entry resulting in broken YAML on rt reported by `William Kimball `__) diff --git a/__init__.py b/__init__.py index 85ec3de..45526be 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, 7), - __version__='0.17.7', + version_info=(0, 17, 8), + __version__='0.17.8', 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 d3c3527..0f34486 100644 --- a/_doc/_static/pypi.svg +++ b/_doc/_static/pypi.svg @@ -1 +1 @@ - pypipypi0.17.70.17.7 + pypipypi0.17.80.17.8 diff --git a/comments.py b/comments.py index 3df5f34..1e117e7 100644 --- a/comments.py +++ b/comments.py @@ -10,7 +10,7 @@ import sys import copy -from ruamel.yaml.compat import ordereddict # type: ignore +from ruamel.yaml.compat import ordereddict from ruamel.yaml.compat import MutableSliceableSequence, _F, nprintf # NOQA from ruamel.yaml.scalarstring import ScalarString from ruamel.yaml.anchor import Anchor @@ -118,7 +118,7 @@ class Comment: else: end = "" try: - ln = max([len(str(k)) for k in self._items]) + 1 # type: ignore + ln = max([len(str(k)) for k in self._items]) + 1 except ValueError: ln = '' # type: ignore it = ' '.join( @@ -137,7 +137,7 @@ class Comment: else: end = "" try: - ln = max([len(str(k)) for k in self._items]) + 1 # type: ignore + ln = max([len(str(k)) for k in self._items]) + 1 except ValueError: ln = '' # type: ignore it = ' '.join( @@ -632,7 +632,7 @@ class CommentedSeq(MutableSliceableSequence, list, CommentedBase): # type: igno # type: (Any) -> Any return list.__add__(self, other) - def sort(self, key=None, reverse=False): # type: ignore + def sort(self, key=None, reverse=False): # type: (Any, bool) -> None if key is None: tmp_lst = sorted(zip(self, range(len(self))), reverse=reverse) @@ -784,7 +784,7 @@ class CommentedMapValuesView(CommentedMapView): yield self._mapping[key] -class CommentedMap(ordereddict, CommentedBase): # type: ignore +class CommentedMap(ordereddict, CommentedBase): __slots__ = (Comment.attrib, '_ok', '_ref') def __init__(self, *args, **kw): diff --git a/constructor.py b/constructor.py index 53a3d41..7392855 100644 --- a/constructor.py +++ b/constructor.py @@ -7,7 +7,7 @@ import re import sys import types import warnings -from collections.abc import Hashable, MutableSequence, MutableMapping # type: ignore +from collections.abc import Hashable, MutableSequence, MutableMapping # fmt: off from ruamel.yaml.error import (MarkedYAMLError, MarkedYAMLFutureWarning, @@ -16,7 +16,7 @@ from ruamel.yaml.nodes import * # NOQA from ruamel.yaml.nodes import (SequenceNode, MappingNode, ScalarNode) from ruamel.yaml.compat import (_F, builtins_module, # NOQA nprint, nprintf, version_tnf) -from ruamel.yaml.compat import ordereddict # type: ignore +from ruamel.yaml.compat import ordereddict from ruamel.yaml.comments import * # NOQA from ruamel.yaml.comments import (CommentedMap, CommentedOrderedMap, CommentedSet, @@ -1725,7 +1725,10 @@ class RoundTripConstructor(SafeConstructor): data.yaml_set_tag(node.tag) yield data if node.anchor: - data.yaml_set_anchor(node.anchor) + from ruamel.yaml.serializer import templated_id + + if not templated_id(node.anchor): + data.yaml_set_anchor(node.anchor) self.construct_mapping(node, data) return elif isinstance(node, ScalarNode): @@ -1735,7 +1738,10 @@ class RoundTripConstructor(SafeConstructor): data2.yaml_set_tag(node.tag) yield data2 if node.anchor: - data2.yaml_set_anchor(node.anchor, always_dump=True) + from ruamel.yaml.serializer import templated_id + + if not templated_id(node.anchor): + data2.yaml_set_anchor(node.anchor, always_dump=True) return elif isinstance(node, SequenceNode): data3 = CommentedSeq() @@ -1747,7 +1753,10 @@ class RoundTripConstructor(SafeConstructor): data3.yaml_set_tag(node.tag) yield data3 if node.anchor: - data3.yaml_set_anchor(node.anchor) + from ruamel.yaml.serializer import templated_id + + if not templated_id(node.anchor): + data3.yaml_set_anchor(node.anchor) data3.extend(self.construct_sequence(node)) return except: # NOQA diff --git a/reader.py b/reader.py index a78a878..bceb790 100644 --- a/reader.py +++ b/reader.py @@ -118,7 +118,7 @@ class Reader: if isinstance(val, str): self.name = '' self.check_printable(val) - self.buffer = val + '\0' # type: ignore + self.buffer = val + '\0' elif isinstance(val, bytes): self.name = '' self.raw_buffer = val diff --git a/representer.py b/representer.py index d419f50..a27f457 100644 --- a/representer.py +++ b/representer.py @@ -2,7 +2,7 @@ from ruamel.yaml.error import * # NOQA from ruamel.yaml.nodes import * # NOQA -from ruamel.yaml.compat import ordereddict # type: ignore +from ruamel.yaml.compat import ordereddict from ruamel.yaml.compat import _F, nprint, nprintf # NOQA from ruamel.yaml.scalarstring import ( LiteralScalarString, diff --git a/scalarbool.py b/scalarbool.py index 3862464..60242b4 100644 --- a/scalarbool.py +++ b/scalarbool.py @@ -20,8 +20,8 @@ __all__ = ['ScalarBoolean'] class ScalarBoolean(int): def __new__(cls, *args, **kw): # type: (Any, Any, Any) -> Any - anchor = kw.pop('anchor', None) # type: ignore - b = int.__new__(cls, *args, **kw) # type: ignore + anchor = kw.pop('anchor', None) + b = int.__new__(cls, *args, **kw) if anchor is not None: b.yaml_set_anchor(anchor, always_dump=True) return b diff --git a/scalarfloat.py b/scalarfloat.py index 9d41879..b9f8bdf 100644 --- a/scalarfloat.py +++ b/scalarfloat.py @@ -12,16 +12,16 @@ __all__ = ['ScalarFloat', 'ExponentialFloat', 'ExponentialCapsFloat'] class ScalarFloat(float): def __new__(cls, *args, **kw): # type: (Any, Any, Any) -> Any - width = kw.pop('width', None) # type: ignore - prec = kw.pop('prec', None) # type: ignore - m_sign = kw.pop('m_sign', None) # type: ignore - m_lead0 = kw.pop('m_lead0', 0) # type: ignore - exp = kw.pop('exp', None) # type: ignore - e_width = kw.pop('e_width', None) # type: ignore - e_sign = kw.pop('e_sign', None) # type: ignore - underscore = kw.pop('underscore', None) # type: ignore - anchor = kw.pop('anchor', None) # type: ignore - v = float.__new__(cls, *args, **kw) # type: ignore + width = kw.pop('width', None) + prec = kw.pop('prec', None) + m_sign = kw.pop('m_sign', None) + m_lead0 = kw.pop('m_lead0', 0) + exp = kw.pop('exp', None) + e_width = kw.pop('e_width', None) + e_sign = kw.pop('e_sign', None) + underscore = kw.pop('underscore', None) + anchor = kw.pop('anchor', None) + v = float.__new__(cls, *args, **kw) v._width = width v._prec = prec v._m_sign = m_sign diff --git a/scalarint.py b/scalarint.py index 3923206..1572b0f 100644 --- a/scalarint.py +++ b/scalarint.py @@ -11,10 +11,10 @@ __all__ = ['ScalarInt', 'BinaryInt', 'OctalInt', 'HexInt', 'HexCapsInt', 'Decima class ScalarInt(int): def __new__(cls, *args, **kw): # type: (Any, Any, Any) -> Any - width = kw.pop('width', None) # type: ignore - underscore = kw.pop('underscore', None) # type: ignore - anchor = kw.pop('anchor', None) # type: ignore - v = int.__new__(cls, *args, **kw) # type: ignore + width = kw.pop('width', None) + underscore = kw.pop('underscore', None) + anchor = kw.pop('anchor', None) + v = int.__new__(cls, *args, **kw) v._width = width v._underscore = underscore if anchor is not None: diff --git a/scalarstring.py b/scalarstring.py index f5fb6a2..7538ab7 100644 --- a/scalarstring.py +++ b/scalarstring.py @@ -23,8 +23,8 @@ class ScalarString(str): def __new__(cls, *args, **kw): # type: (Any, Any) -> Any - anchor = kw.pop('anchor', None) # type: ignore - ret_val = str.__new__(cls, *args, **kw) # type: ignore + anchor = kw.pop('anchor', None) + ret_val = str.__new__(cls, *args, **kw) if anchor is not None: ret_val.yaml_set_anchor(anchor, always_dump=True) return ret_val @@ -126,7 +126,7 @@ def walk_tree(base, map=None): map[':'] = SingleQuotedScalarString walk_tree(data, map=map) """ - from collections.abc import MutableMapping, MutableSequence # type: ignore + from collections.abc import MutableMapping, MutableSequence if map is None: map = {'\n': preserve_literal} @@ -145,7 +145,7 @@ def walk_tree(base, map=None): for idx, elem in enumerate(base): if isinstance(elem, str): for ch in map: - if ch in elem: # type: ignore + if ch in elem: base[idx] = map[ch](elem) break else: diff --git a/timestamp.py b/timestamp.py index e338c30..58eef04 100644 --- a/timestamp.py +++ b/timestamp.py @@ -17,7 +17,7 @@ class TimeStamp(datetime.datetime): def __new__(cls, *args, **kw): # datetime is immutable # type: (Any, Any) -> Any - return datetime.datetime.__new__(cls, *args, **kw) # type: ignore + return datetime.datetime.__new__(cls, *args, **kw) def __deepcopy__(self, memo): # type: (Any) -> Any -- cgit v1.2.1