summaryrefslogtreecommitdiff
path: root/comments.py
diff options
context:
space:
mode:
Diffstat (limited to 'comments.py')
-rw-r--r--comments.py137
1 files changed, 124 insertions, 13 deletions
diff --git a/comments.py b/comments.py
index 26587ce..c3d17b0 100644
--- a/comments.py
+++ b/comments.py
@@ -8,7 +8,7 @@ these are not really related, formatting could be factored out as
a separate base
"""
-from collections import MutableSet # type: ignore
+from collections import MutableSet, Sized, Set # type: ignore
from ruamel.yaml.compat import ordereddict, PY2
@@ -321,6 +321,87 @@ class CommentedSeq(list, CommentedBase):
return pre_comments
+class CommentedMapView(Sized):
+
+ __slots__ = '_mapping',
+
+ def __init__(self, mapping):
+ self._mapping = mapping
+
+ def __len__(self):
+ count = len(self._mapping)
+ done = [] # list of processed merge items, kept for masking
+ for merged in getattr(self._mapping, merge_attrib, []):
+ for x in merged[1]:
+ if self._mapping._unmerged_contains(x):
+ continue
+ for y in done:
+ if x in y:
+ break
+ else:
+ count += 1
+ done.append(merged[1])
+ return count
+
+ def __repr__(self):
+ return '{0.__class__.__name__}({0._mapping!r})'.format(self)
+
+
+class CommentedMapKeysView(CommentedMapView, Set):
+
+ __slots__ = ()
+
+ @classmethod
+ def _from_iterable(self, it):
+ return set(it)
+
+ def __contains__(self, key):
+ return key in self._mapping
+
+ def __iter__(self):
+ # yield from self._mapping # not in py27, pypy
+ for x in self._mapping:
+ yield x
+
+
+class CommentedMapItemsView(CommentedMapView, Set):
+
+ __slots__ = ()
+
+ @classmethod
+ def _from_iterable(self, it):
+ return set(it)
+
+ def __contains__(self, item):
+ key, value = item
+ try:
+ v = self._mapping[key]
+ except KeyError:
+ return False
+ else:
+ return v == value
+
+ def __iter__(self):
+ for key in self._mapping._keys():
+ yield (key, self._mapping[key])
+
+
+class CommentedMapValuesView(CommentedMapView):
+
+ __slots__ = ()
+
+ def __contains__(self, value):
+ for key in self._mapping:
+ if value == self._mapping[key]:
+ return True
+ return False
+
+ def __iter__(self):
+ print('xxy values_iter')
+ for key in self._mapping:
+ yield self._mapping[key]
+
+
class CommentedMap(ordereddict, CommentedBase):
__slots__ = [Comment.attrib, ]
@@ -425,6 +506,10 @@ class CommentedMap(ordereddict, CommentedBase):
return merged[1][key]
raise
+ def _unmerged_contains(self, key):
+ if ordereddict.__contains__(self, key):
+ return True
+
def __contains__(self, key):
if ordereddict.__contains__(self, key):
return True
@@ -444,6 +529,20 @@ class CommentedMap(ordereddict, CommentedBase):
for x in ordereddict.__iter__(self):
yield x, ordereddict.__getitem__(self, x)
+ def __delitem__(self, key):
+ found = True
+ for merged in getattr(self, merge_attrib, []):
+ try:
+ del merged[1][key]
+ found = True
+ except KeyError:
+ pass
+ try:
+ ordereddict.__delitem__(self, key)
+ except KeyError:
+ if not found:
+ raise
+
def __iter__(self):
for x in ordereddict.__iter__(self):
yield x
@@ -477,11 +576,15 @@ class CommentedMap(ordereddict, CommentedBase):
if PY2:
def keys(self):
return list(self._keys())
+
+ def iterkeys(self):
+ return self._keys()
+
+ def viewkeys(self):
+ return CommentedMapKeysView(self)
else:
- # def keys(self):
- # import collections
- # return collections.KeysView(self._keys())
- keys = _keys
+ def keys(self):
+ return CommentedMapKeysView(self)
def _values(self):
for x in ordereddict.__iter__(self):
@@ -501,11 +604,15 @@ class CommentedMap(ordereddict, CommentedBase):
if PY2:
def values(self):
return list(self._values())
+
+ def itervalues(self):
+ return self._values()
+
+ def viewvalues(self):
+ return CommentedMapValuesView(self)
else:
- # def values(self):
- # import collections
- # return collections.ValuesView(self)
- values = _values
+ def values(self):
+ return CommentedMapValuesView(self)
def _items(self):
for x in ordereddict.__iter__(self):
@@ -525,11 +632,15 @@ class CommentedMap(ordereddict, CommentedBase):
if PY2:
def items(self):
return list(self._items())
+
+ def iteritems(self):
+ return self._items()
+
+ def viewitems(self):
+ return CommentedMapItemsView(self)
else:
- # def items(self):
- # import collections
- # return collections.ItemsView(self._items())
- items = _items
+ def items(self):
+ return CommentedMapItemsView(self)
@property
def merge(self):