From 17af0e7a084955b5c0bf4124bba87190ac16734d Mon Sep 17 00:00:00 2001 From: Anthon van der Neut Date: Wed, 27 Feb 2019 22:23:14 +0100 Subject: fix issue #280 namedtuple erorring in error generation on safe_dump *When this change indeed resolves your problem, please **Close** this issue*. *(You can do so using the WorkFlow pull-down (close to the top right of this page))* --- README.rst | 4 ++++ _test/test_issues.py | 14 ++++++++++++++ _test/test_z_data.py | 4 ++-- emitter.py | 10 +++++----- representer.py | 4 ++-- resolver.py | 8 ++++---- scanner.py | 14 +++++++------- setup.py | 6 +++++- 8 files changed, 43 insertions(+), 21 deletions(-) diff --git a/README.rst b/README.rst index 1fce9ca..6a8cf16 100644 --- a/README.rst +++ b/README.rst @@ -54,6 +54,10 @@ ChangeLog .. should insert NEXT: at the beginning of line for next key (with empty line) +NEXT: + - fix for safe dumping erroring in creation of representereror when dumping namedtuple + (reported and solution by `Jaakko Kantojärvi `__) + 0.15.88 (2019-02-12): - fix inclusing of python code from the subpackage data (containing extra tests, reported by `Florian Apolloner `__) diff --git a/_test/test_issues.py b/_test/test_issues.py index 721f3fe..d5913f6 100644 --- a/_test/test_issues.py +++ b/_test/test_issues.py @@ -560,8 +560,22 @@ class TestIssues: """ d = round_trip(inp) # NOQA + def test_issue_280(self): + from ruamel.yaml import YAML + from ruamel.yaml.representer import RepresenterError + from collections import namedtuple + from sys import stdout + T = namedtuple('T', ('a', 'b')) + t = T(1, 2) + yaml = YAML() + with pytest.raises(RepresenterError, match='cannot represent'): + yaml.dump({'t': t}, stdout) + # @pytest.mark.xfail(strict=True, reason='bla bla', raises=AssertionError) # def test_issue_ xxx(self): # inp = """ # """ # d = round_trip(inp) # NOQA + + + diff --git a/_test/test_z_data.py b/_test/test_z_data.py index 99810aa..f4e47cf 100644 --- a/_test/test_z_data.py +++ b/_test/test_z_data.py @@ -170,7 +170,7 @@ class TestYAMLData(object): yaml_version = d.get('yaml_version') if 'python' in d: if not check_python_version(d['python']): - pytest.skip("unsupported version") + pytest.skip('unsupported version') idx += 1 data = output = confirm = python = None for doc in docs[idx:]: @@ -230,7 +230,7 @@ def check_python_version(match, current=None): # assert m[0].isdigit() # assert m[-1].isdigit() m = [int(x) for x in m.split('.')] - current_len = current[:len(m)] + current_len = current[: len(m)] # print(m, current, current_len) if minimal: if current_len >= m: diff --git a/emitter.py b/emitter.py index 99fa6bd..690cbc5 100644 --- a/emitter.py +++ b/emitter.py @@ -321,11 +321,11 @@ class Emitter(object): self.write_stream_start() self.state = self.expect_first_document_start else: - raise EmitterError('expected StreamStartEvent, but got %s' % self.event) + raise EmitterError('expected StreamStartEvent, but got %s' % (self.event,)) def expect_nothing(self): # type: () -> None - raise EmitterError('expected nothing, but got %s' % self.event) + raise EmitterError('expected nothing, but got %s' % (self.event,)) # Document handlers. @@ -372,7 +372,7 @@ class Emitter(object): self.write_stream_end() self.state = self.expect_nothing else: - raise EmitterError('expected DocumentStartEvent, but got %s' % self.event) + raise EmitterError('expected DocumentStartEvent, but got %s' % (self.event,)) def expect_document_end(self): # type: () -> None @@ -384,7 +384,7 @@ class Emitter(object): self.flush_stream() self.state = self.expect_document_start else: - raise EmitterError('expected DocumentEndEvent, but got %s' % self.event) + raise EmitterError('expected DocumentEndEvent, but got %s' % (self.event,)) def expect_document_root(self): # type: () -> None @@ -448,7 +448,7 @@ class Emitter(object): else: self.expect_block_mapping() else: - raise EmitterError('expected NodeEvent, but got %s' % self.event) + raise EmitterError('expected NodeEvent, but got %s' % (self.event,)) def expect_alias(self): # type: () -> None diff --git a/representer.py b/representer.py index 859887c..946a909 100644 --- a/representer.py +++ b/representer.py @@ -389,7 +389,7 @@ class SafeRepresenter(BaseRepresenter): def represent_undefined(self, data): # type: (Any) -> None - raise RepresenterError('cannot represent an object: %s' % data) + raise RepresenterError('cannot represent an object: %s' % (data,)) SafeRepresenter.add_representer(type(None), SafeRepresenter.represent_none) @@ -573,7 +573,7 @@ class Representer(SafeRepresenter): elif hasattr(data, '__reduce__'): reduce = data.__reduce__() else: - raise RepresenterError('cannot represent object: %r' % data) + raise RepresenterError('cannot represent object: %r' % (data,)) reduce = (list(reduce) + [None] * 5)[:5] function, args, state, listitems, dictitems = reduce args = list(args) diff --git a/resolver.py b/resolver.py index 5da1fe3..cadca5b 100644 --- a/resolver.py +++ b/resolver.py @@ -186,7 +186,7 @@ class BaseResolver(object): node_check = element[0] index_check = True else: - raise ResolverError('Invalid path element: %s' % element) + raise ResolverError('Invalid path element: %s' % (element,)) else: node_check = None index_check = element @@ -201,9 +201,9 @@ class BaseResolver(object): and not isinstance(node_check, string_types) and node_check is not None ): - raise ResolverError('Invalid node checker: %s' % node_check) + raise ResolverError('Invalid node checker: %s' % (node_check,)) if not isinstance(index_check, (string_types, int)) and index_check is not None: - raise ResolverError('Invalid index checker: %s' % index_check) + raise ResolverError('Invalid index checker: %s' % (index_check,)) new_path.append((node_check, index_check)) if kind is str: kind = ScalarNode @@ -212,7 +212,7 @@ class BaseResolver(object): elif kind is dict: kind = MappingNode elif kind not in [ScalarNode, SequenceNode, MappingNode] and kind is not None: - raise ResolverError('Invalid node kind: %s' % kind) + raise ResolverError('Invalid node kind: %s' % (kind,)) cls.yaml_path_resolvers[tuple(new_path), kind] = tag def descend_resolver(self, current_node, current_index): diff --git a/scanner.py b/scanner.py index 1296160..1967a56 100644 --- a/scanner.py +++ b/scanner.py @@ -1065,7 +1065,7 @@ class Scanner(object): ch = srp(length) if not length: raise ScannerError( - 'while scanning an %s' % name, + 'while scanning an %s' % (name,), start_mark, 'expected alphabetic or numeric character, but found %r' % utf8(ch), self.reader.get_mark(), @@ -1077,7 +1077,7 @@ class Scanner(object): # assert ch1 == ch if ch not in '\0 \t\r\n\x85\u2028\u2029?:,[]{}%@`': raise ScannerError( - 'while scanning an %s' % name, + 'while scanning an %s' % (name,), start_mark, 'expected alphabetic or numeric character, but found %r' % utf8(ch), self.reader.get_mark(), @@ -1638,7 +1638,7 @@ class Scanner(object): ch = srp() if ch != '!': raise ScannerError( - 'while scanning a %s' % name, + 'while scanning a %s' % (name,), start_mark, "expected '!', but found %r" % utf8(ch), self.reader.get_mark(), @@ -1652,7 +1652,7 @@ class Scanner(object): if ch != '!': self.reader.forward(length) raise ScannerError( - 'while scanning a %s' % name, + 'while scanning a %s' % (name,), start_mark, "expected '!', but found %r" % utf8(ch), self.reader.get_mark(), @@ -1690,7 +1690,7 @@ class Scanner(object): length = 0 if not chunks: raise ScannerError( - 'while parsing a %s' % name, + 'while parsing a %s' % (name,), start_mark, 'expected URI, but found %r' % utf8(ch), self.reader.get_mark(), @@ -1709,7 +1709,7 @@ class Scanner(object): for k in range(2): if srp(k) not in '0123456789ABCDEFabcdef': raise ScannerError( - 'while scanning a %s' % name, + 'while scanning a %s' % (name,), start_mark, 'expected URI escape sequence of 2 hexdecimal numbers,' ' but found %r' % utf8(srp(k)), @@ -1726,7 +1726,7 @@ class Scanner(object): else: value = unicode(b"".join(code_bytes), 'utf-8') except UnicodeDecodeError as exc: - raise ScannerError('while scanning a %s' % name, start_mark, str(exc), mark) + raise ScannerError('while scanning a %s' % (name,), start_mark, str(exc), mark) return value def scan_line_break(self): diff --git a/setup.py b/setup.py index 70aee86..5b60dd1 100644 --- a/setup.py +++ b/setup.py @@ -424,9 +424,10 @@ class NameSpacePackager(object): def split(self): """split the full package name in list of compontents traditionally done by setuptools.find_packages. This routine skips any directories - with __init__.py that start with "_" or ".", or contain a + with __init__.py, for which the name starts with "_" or ".", or contain a setup.py/tox.ini (indicating a subpackage) """ + skip = [] if self._split is None: fpn = self.full_package_name.split('.') self._split = [] @@ -441,12 +442,15 @@ class NameSpacePackager(object): if os.path.exists(x): pd = _package_data(x) if pd.get('nested', False): + skip.append(d) continue self._split.append(self.full_package_name + '.' + d) if sys.version_info < (3,): self._split = [ (y.encode('utf-8') if isinstance(y, unicode) else y) for y in self._split ] + if skip: + print('skipping sub-packages:', ', '.join(skip)) return self._split @property -- cgit v1.2.1