From 334c46400c2334b3939c76ab7a7b5d9195b6d131 Mon Sep 17 00:00:00 2001 From: Anthon van der Neut Date: Tue, 4 Apr 2017 10:05:01 +0200 Subject: fix issue #109 and #110 issue 109: None not represented round-trippable at top level, reported by Andrea Censi issue 110: .replace() on a ScalarString subclass would return a string instead of an instance of that subclass, reported by sandres23 --- README.rst | 5 +++++ __init__.py | 4 ++-- _test/test_none.py | 42 ++++++++++++++++++++++++++++++++++++++++++ _test/test_string.py | 31 +++++++++++++++++++++++++++++++ representer.py | 6 ++++-- scalarstring.py | 3 +++ 6 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 _test/test_none.py diff --git a/README.rst b/README.rst index 560161e..b82244b 100644 --- a/README.rst +++ b/README.rst @@ -18,6 +18,11 @@ ChangeLog .. should insert NEXT: at the beginning of line for next key +NEXT: + - fix issue 109: None not dumping correctly at top level (reported by Andrea Censi) + - fix issue 110: .replace on Preserved/DoubleQuoted/SingleQuoted ScalarString + would give back "normal" string (reported by sandres23) + 0.14.4 (2017-03-31): - fix readme diff --git a/__init__.py b/__init__.py index b3fe1a0..3fdcb33 100644 --- a/__init__.py +++ b/__init__.py @@ -10,8 +10,8 @@ from typing import Dict, Any # NOQA _package_data = dict( full_package_name='ruamel.yaml', - version_info=(0, 14, 4), - __version__='0.14.4', + version_info=(0, 14, 5, 'dev'), + __version__='0.14.5.dev', 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/_test/test_none.py b/_test/test_none.py new file mode 100644 index 0000000..ad51109 --- /dev/null +++ b/_test/test_none.py @@ -0,0 +1,42 @@ +# coding: utf-8 + + +import pytest # NOQA +import ruamel.yaml # NOQA + + +class TestNone: + def test_dump00(self): + data = None + s = ruamel.yaml.round_trip_dump(data) + assert s == 'null\n...\n' + d = ruamel.yaml.round_trip_load(s) + assert d == data + + def test_dump01(self): + data = None + s = ruamel.yaml.round_trip_dump(data, explicit_end=True) + assert s == 'null\n...\n' + d = ruamel.yaml.round_trip_load(s) + assert d == data + + def test_dump02(self): + data = None + s = ruamel.yaml.round_trip_dump(data, explicit_end=False) + assert s == 'null\n...\n' + d = ruamel.yaml.round_trip_load(s) + assert d == data + + def test_dump03(self): + data = None + s = ruamel.yaml.round_trip_dump(data, explicit_start=True) + assert s == '---\n...\n' + d = ruamel.yaml.round_trip_load(s) + assert d == data + + def test_dump04(self): + data = None + s = ruamel.yaml.round_trip_dump(data, explicit_start=True, explicit_end=False) + assert s == '---\n...\n' + d = ruamel.yaml.round_trip_load(s) + assert d == data diff --git a/_test/test_string.py b/_test/test_string.py index 13474b5..6b3070f 100644 --- a/_test/test_string.py +++ b/_test/test_string.py @@ -17,6 +17,7 @@ and the chomping modifiers: import pytest import platform +import ruamel # from ruamel.yaml.compat import ordereddict from roundtrip import round_trip, dedent, round_trip_load, round_trip_dump # NOQA @@ -124,3 +125,33 @@ class TestQuotedScalarString: """, outp=""" a: abc """) + + +class TestReplace: + """inspired by issue 110 from sandres23""" + def test_replace_preserved_scalar_string(self): + s = dedent("""\ + foo: | + foo + foo + bar + foo + """) + data = round_trip_load(s, preserve_quotes=True) + so = data['foo'].replace('foo', 'bar', 2) + assert isinstance(so, ruamel.yaml.scalarstring.PreservedScalarString) + assert so == dedent(""" + bar + bar + bar + foo + """) + + def test_replace_double_quoted_scalar_string(self): + s = dedent("""\ + foo: "foo foo bar foo" + """) + data = round_trip_load(s, preserve_quotes=True) + so = data['foo'].replace('foo', 'bar', 2) + assert isinstance(so, ruamel.yaml.scalarstring.DoubleQuotedScalarString) + assert so == 'bar bar bar foo' diff --git a/representer.py b/representer.py index a64d825..5db1d98 100644 --- a/representer.py +++ b/representer.py @@ -644,8 +644,10 @@ class RoundTripRepresenter(SafeRepresenter): def represent_none(self, data): # type: (Any) -> Any - return self.represent_scalar(u'tag:yaml.org,2002:null', - u'') + if len(self.represented_objects) == 0 and not self.serializer.use_explicit_start: + # this will be open ended (although it is not yet) + return self.represent_scalar(u'tag:yaml.org,2002:null', u'null') + return self.represent_scalar(u'tag:yaml.org,2002:null', u'') def represent_preserved_scalarstring(self, data): # type: (Any) -> Any diff --git a/scalarstring.py b/scalarstring.py index b02ad1d..6689911 100644 --- a/scalarstring.py +++ b/scalarstring.py @@ -21,6 +21,9 @@ class ScalarString(text_type): # type: (Any, Any) -> Any return text_type.__new__(cls, *args, **kw) # type: ignore + def replace(self, old, new, maxreplace=-1): + return type(self)((text_type.replace(self, old, new, maxreplace))) + class PreservedScalarString(ScalarString): __slots__ = () -- cgit v1.2.1