summaryrefslogtreecommitdiff
path: root/comments.py
diff options
context:
space:
mode:
Diffstat (limited to 'comments.py')
-rw-r--r--comments.py156
1 files changed, 61 insertions, 95 deletions
diff --git a/comments.py b/comments.py
index 9d51a29..9730f0a 100644
--- a/comments.py
+++ b/comments.py
@@ -637,12 +637,14 @@ class CommentedMapValuesView(CommentedMapView):
yield self._mapping[key]
-class CommentedMap(CommentedBase, MutableMapping):
- __slots__ = (Comment.attrib, '_od')
+class CommentedMap(MutableMapping, ordereddict, CommentedBase):
+ __slots__ = (Comment.attrib, '_ok', '_ref') # own keys
def __init__(self, *args, **kw):
# type: (Any, Any) -> None
- self._od = ordereddict(*args, **kw)
+ ordereddict.__init__(self, *args, **kw)
+ self._ok = set()
+ self._ref = []
def _yaml_add_comment(self, comment, key=NoComment, value=NoComment):
# type: (Any, Optional[Any], Optional[Any]) -> None
@@ -704,7 +706,8 @@ class CommentedMap(CommentedBase, MutableMapping):
def update(self, vals): # type: ignore
# type: (Any) -> None
try:
- self._od.update(vals)
+ ordereddict.update(self, vals)
+ self._ok.update(vals.keys())
except TypeError:
# probably a dict that is used
for x in vals:
@@ -715,7 +718,8 @@ class CommentedMap(CommentedBase, MutableMapping):
"""insert key value into given position
attach comment if provided
"""
- self._od.insert(pos, key, value)
+ ordereddict.insert(self, pos, key, value)
+ self._ok.add(key)
if comment is not None:
self.yaml_add_eol_comment(comment, key=key)
@@ -748,7 +752,7 @@ class CommentedMap(CommentedBase, MutableMapping):
def __getitem__(self, key):
# type: (Any) -> Any
try:
- return self._od.__getitem__(key)
+ return ordereddict.__getitem__(self, key)
except KeyError:
for merged in getattr(self, merge_attrib, []):
if key in merged[1]:
@@ -765,23 +769,18 @@ class CommentedMap(CommentedBase, MutableMapping):
and isinstance(self[key], ScalarString)
):
value = type(self[key])(value)
- self._od.__setitem__(key, value)
+ ordereddict.__setitem__(self, key, value)
+ self._ok.add(key)
def _unmerged_contains(self, key):
# type: (Any) -> Any
- if self._od.__contains__(key):
+ if key in self._ok:
return True
return None
def __contains__(self, key):
# type: (Any) -> bool
- if self._od.__contains__(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
- return False
+ return ordereddict.__contains__(self, key)
def get(self, key, default=None):
# type: (Any, Any) -> Any
@@ -792,77 +791,47 @@ class CommentedMap(CommentedBase, MutableMapping):
def __repr__(self):
# type: () -> Any
- if not hasattr(self, merge_attrib):
- return self._od.__repr__()
- return 'ordereddict(' + repr(list(self._items())) + ')'
+ return ordereddict.__repr__(self).replace('CommentedMap', 'ordereddict')
def non_merged_items(self):
# type: () -> Any
- for x in self._od.__iter__():
- yield x, self._od.__getitem__(x)
+ for x in ordereddict.__iter__(self):
+ if x in self._ok:
+ yield x, ordereddict.__getitem__(self, x)
def __delitem__(self, key):
# type: (Any) -> None
- found = True
- for merged in getattr(self, merge_attrib, []):
- try:
- del merged[1][key]
- found = True
- except KeyError:
- pass
- try:
- self._od.__delitem__(key)
- except KeyError:
- if not found:
- raise
+ # for merged in getattr(self, merge_attrib, []):
+ # if key in merged[1]:
+ # value = merged[1][key]
+ # break
+ # else:
+ # # not found in merged in stuff
+ # ordereddict.__delitem__(self, key)
+ # for referer in self._ref:
+ # referer.update_key_value(key)
+ # return
+ #
+ # ordereddict.__setitem__(self, key, value) # merge might have different value
+ # self._ok.discard(key)
+ self._ok.discard(key)
+ ordereddict.__delitem__(self, key)
+ for referer in self._ref:
+ referer.update_key_value(key)
def __iter__(self):
# type: () -> Any
- for x in self._od.__iter__():
+ for x in ordereddict.__iter__(self):
yield x
- done = [] # type: List[Any] # list of processed merge items, kept for masking
- for merged in getattr(self, merge_attrib, []):
- for x in merged[1]:
- if self._od.__contains__(x):
- continue
- for y in done:
- if x in y:
- break
- else:
- yield x
- done.append(merged[1])
def _keys(self):
# type: () -> Any
- for x in self._od.__iter__():
+ for x in ordereddict.__iter__(self):
yield x
- done = [] # type: List[Any] # list of processed merge items, kept for masking
- for merged in getattr(self, merge_attrib, []):
- for x in merged[1].keys():
- if self._od.__contains__(x):
- continue
- for y in done:
- if x in y:
- break
- else:
- yield x
- done.append(merged[1])
def __len__(self):
# type: () -> int
- count = self._od.__len__() # type: int
- done = [] # type: List[Any] # list of processed merge items, kept for masking
- for merged in getattr(self, merge_attrib, []):
- for x in merged[1]:
- if self._od.__contains__(x):
- continue
- for y in done:
- if x in y:
- break
- else:
- count += 1
- done.append(merged[1])
- return count
+ return ordereddict.__len__(self)
def __eq__(self, other):
# type: (Any) -> bool
@@ -892,19 +861,8 @@ class CommentedMap(CommentedBase, MutableMapping):
def _values(self):
# type: () -> Any
- for x in self._od.__iter__():
- yield self._od.__getitem__(x)
- done = [] # type: List[Any] # list of processed merge items, kept for masking
- for merged in getattr(self, merge_attrib, []):
- for x in merged[1]:
- if self._od.__contains__(x):
- continue
- for y in done:
- if x in y:
- break
- else:
- yield merged[1]._od.__getitem__(x)
- done.append(merged[1])
+ for x in ordereddict.__iter__(self):
+ yield ordereddict.__getitem__(self, x)
def values(self):
# type: () -> Any
@@ -926,19 +884,8 @@ class CommentedMap(CommentedBase, MutableMapping):
def _items(self):
# type: () -> Any
- for x in self._od.__iter__():
- yield x, self._od.__getitem__(x)
- done = [] # type: List[Any] # list of processed merge items, kept for masking
- for merged in getattr(self, merge_attrib, []):
- for x, v in merged[1].items():
- if self._od.__contains__(x):
- continue
- for y in done:
- if x in y:
- break
- else:
- yield x, v # self._od.__getitem__(merged[1], x)
- done.append(merged[1])
+ for x in ordereddict.__iter__(self):
+ yield x, ordereddict.__getitem__(self, x)
if PY2:
@@ -974,10 +921,29 @@ class CommentedMap(CommentedBase, MutableMapping):
x[k] = v
return x
+ def add_referent(self, cm):
+ if cm not in self._ref:
+ self._ref.append(cm)
+
def add_yaml_merge(self, value):
# type: (Any) -> None
+ for v in value:
+ v[1].add_referent(self)
+ for k, v in v[1].items():
+ if ordereddict.__contains__(self, k):
+ continue
+ ordereddict.__setitem__(self, k, v)
self.merge.extend(value)
+ def update_key_value(self, key):
+ if key in self._ok:
+ return
+ for v in self.merge:
+ if key in v[1]:
+ ordereddict.__setitem__(self, key, v[1][key])
+ return
+ ordereddict.__delitem__(self, key)
+
def __deepcopy__(self, memo):
# type: (Any) -> Any
res = self.__class__()