diff options
author | Anthon van der Neut <anthon@mnt.org> | 2016-08-17 23:20:49 +0200 |
---|---|---|
committer | Anthon van der Neut <anthon@mnt.org> | 2016-08-17 23:20:49 +0200 |
commit | f21343115c0b7f2849766f741bbe64e6c170a556 (patch) | |
tree | 9d6acdd6db9a3f8cb0ebead98d1233a5da1607cc /comments.py | |
parent | d8b794cccf8054a73ae61b6128e342b23b390e1d (diff) | |
download | ruamel.yaml-f21343115c0b7f2849766f741bbe64e6c170a556.tar.gz |
added .keys(), items(), values(), corrected __contains__
There was a huge problem with 3.4 and 3.3 as the OrderedDict
does not define a __contains__ and the implementation based on
the one by Ngo would not work with merge keys defining keys
that later were in the main dict (which should override).
Fix was to add the merge key info at the point the dict
has been completely created, thus restricting __contains__
automatically to the dict itself (and not test subkeys)
Diffstat (limited to 'comments.py')
-rw-r--r-- | comments.py | 96 |
1 files changed, 94 insertions, 2 deletions
diff --git a/comments.py b/comments.py index 07e2e9b..26587ce 100644 --- a/comments.py +++ b/comments.py @@ -10,7 +10,7 @@ a separate base from collections import MutableSet # type: ignore -from ruamel.yaml.compat import ordereddict +from ruamel.yaml.compat import ordereddict, PY2 __all__ = ["CommentedSeq", "CommentedMap", "CommentedOrderedMap", "CommentedSet", 'comment_attrib', 'merge_attrib'] @@ -24,7 +24,7 @@ tag_attrib = '_yaml_tag' class Comment(object): - # sys.getsize tested the Comment objects, __slots__ make them bigger + # sys.getsize tested the Comment objects, __slots__ makes them bigger # and adding self.end did not matter attrib = comment_attrib @@ -428,6 +428,7 @@ class CommentedMap(ordereddict, CommentedBase): def __contains__(self, key): if ordereddict.__contains__(self, key): return True + # this will only work once the mapping/dict is built to completion for merged in getattr(self, merge_attrib, []): if key in merged[1]: return True @@ -439,6 +440,97 @@ class CommentedMap(ordereddict, CommentedBase): except: return default + def non_merged_items(self): + for x in ordereddict.__iter__(self): + yield x, ordereddict.__getitem__(self, x) + + def __iter__(self): + for x in ordereddict.__iter__(self): + yield x + done = [] # list of processed merge items, kept for masking + for merged in getattr(self, merge_attrib, []): + for x in merged[1]: + if ordereddict.__contains__(self, x): + continue + for y in done: + if x in y: + break + else: + yield x + done.append(merged[1]) + + def _keys(self): + for x in ordereddict.__iter__(self): + yield x + done = [] # list of processed merge items, kept for masking + for merged in getattr(self, merge_attrib, []): + for x in merged[1]: + if ordereddict.__contains__(self, x): + continue + for y in done: + if x in y: + break + else: + yield x + done.append(merged[1]) + + if PY2: + def keys(self): + return list(self._keys()) + else: + # def keys(self): + # import collections + # return collections.KeysView(self._keys()) + keys = _keys + + def _values(self): + for x in ordereddict.__iter__(self): + yield ordereddict.__getitem__(self, x) + done = [] # list of processed merge items, kept for masking + for merged in getattr(self, merge_attrib, []): + for x in merged[1]: + if ordereddict.__contains__(self, x): + continue + for y in done: + if x in y: + break + else: + yield ordereddict.__getitem__(merged[1], x) + done.append(merged[1]) + + if PY2: + def values(self): + return list(self._values()) + else: + # def values(self): + # import collections + # return collections.ValuesView(self) + values = _values + + def _items(self): + for x in ordereddict.__iter__(self): + yield x, ordereddict.__getitem__(self, x) + done = [] # list of processed merge items, kept for masking + for merged in getattr(self, merge_attrib, []): + for x in merged[1]: + if ordereddict.__contains__(self, x): + continue + for y in done: + if x in y: + break + else: + yield x, ordereddict.__getitem__(merged[1], x) + done.append(merged[1]) + + if PY2: + def items(self): + return list(self._items()) + else: + # def items(self): + # import collections + # return collections.ItemsView(self._items()) + items = _items + @property def merge(self): if not hasattr(self, merge_attrib): |