Also save what was merged in
This commit is contained in:
parent
ee78221af4
commit
7d6b9c5c51
|
@ -35,6 +35,7 @@ def mergedicts(d1, d2, remove=True):
|
||||||
|
|
||||||
First dictionary is modified in-place.
|
First dictionary is modified in-place.
|
||||||
'''
|
'''
|
||||||
|
_setmerged(d1, d2)
|
||||||
for k in d2:
|
for k in d2:
|
||||||
if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict):
|
if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict):
|
||||||
mergedicts(d1[k], d2[k], remove)
|
mergedicts(d1[k], d2[k], remove)
|
||||||
|
@ -58,6 +59,11 @@ def mergedefaults(d1, d2):
|
||||||
d1.setdefault(k, d2[k])
|
d1.setdefault(k, d2[k])
|
||||||
|
|
||||||
|
|
||||||
|
def _setmerged(d1, d2):
|
||||||
|
if hasattr(d1, 'setmerged'):
|
||||||
|
d1.setmerged(d2)
|
||||||
|
|
||||||
|
|
||||||
def mergedicts_copy(d1, d2):
|
def mergedicts_copy(d1, d2):
|
||||||
'''Recursively merge two dictionaries.
|
'''Recursively merge two dictionaries.
|
||||||
|
|
||||||
|
@ -65,6 +71,7 @@ def mergedicts_copy(d1, d2):
|
||||||
that first dictionary supports .copy() method.
|
that first dictionary supports .copy() method.
|
||||||
'''
|
'''
|
||||||
ret = d1.copy()
|
ret = d1.copy()
|
||||||
|
_setmerged(ret, d2)
|
||||||
for k in d2:
|
for k in d2:
|
||||||
if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict):
|
if k in d1 and isinstance(d1[k], dict) and isinstance(d2[k], dict):
|
||||||
ret[k] = mergedicts_copy(d1[k], d2[k])
|
ret[k] = mergedicts_copy(d1[k], d2[k])
|
||||||
|
|
|
@ -42,16 +42,17 @@ def strtrans(s):
|
||||||
|
|
||||||
|
|
||||||
class Mark:
|
class Mark:
|
||||||
def __init__(self, name, line, column, buffer, pointer, old_mark=None):
|
def __init__(self, name, line, column, buffer, pointer, old_mark=None, merged_marks=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.line = line
|
self.line = line
|
||||||
self.column = column
|
self.column = column
|
||||||
self.buffer = buffer
|
self.buffer = buffer
|
||||||
self.pointer = pointer
|
self.pointer = pointer
|
||||||
self.old_mark = old_mark
|
self.old_mark = old_mark
|
||||||
|
self.merged_marks = merged_marks or []
|
||||||
|
|
||||||
def copy(self):
|
def copy(self):
|
||||||
return Mark(self.name, self.line, self.column, self.buffer, self.pointer, self.old_mark)
|
return Mark(self.name, self.line, self.column, self.buffer, self.pointer, self.old_mark, self.merged_marks[:])
|
||||||
|
|
||||||
def get_snippet(self, indent=4, max_length=75):
|
def get_snippet(self, indent=4, max_length=75):
|
||||||
if self.buffer is None:
|
if self.buffer is None:
|
||||||
|
@ -100,21 +101,32 @@ class Mark:
|
||||||
break
|
break
|
||||||
self.old_mark = old_mark
|
self.old_mark = old_mark
|
||||||
|
|
||||||
def to_string(self, indent=0):
|
def set_merged_mark(self, merged_mark):
|
||||||
|
self.merged_marks.append(merged_mark)
|
||||||
|
|
||||||
|
def to_string(self, indent=0, head_text='in ', add_snippet=True):
|
||||||
mark = self
|
mark = self
|
||||||
where = ''
|
where = ''
|
||||||
processed_marks = set()
|
processed_marks = set()
|
||||||
while mark:
|
while mark:
|
||||||
indentstr = ' ' * indent
|
indentstr = ' ' * indent
|
||||||
snippet = mark.get_snippet(indent=(indent + 4))
|
where += ('%s %s"%s", line %d, column %d' % (
|
||||||
where += (indentstr + ' in "%s", line %d, column %d' % (
|
indentstr, head_text, mark.name, mark.line + 1, mark.column + 1))
|
||||||
mark.name, mark.line + 1, mark.column + 1))
|
if add_snippet:
|
||||||
if snippet:
|
snippet = mark.get_snippet(indent=(indent + 4))
|
||||||
where += ':\n' + snippet
|
if snippet:
|
||||||
processed_marks.add(id(mark))
|
where += ':\n' + snippet
|
||||||
if mark.old_mark:
|
if mark.merged_marks:
|
||||||
where += '\n' + indentstr + ' which replaced value\n'
|
where += '\n' + indentstr + ' with additionally merged\n'
|
||||||
indent += 4
|
where += mark.merged_marks[0].to_string(indent + 4, head_text='', add_snippet=False)
|
||||||
|
for mmark in mark.merged_marks[1:]:
|
||||||
|
where += '\n' + indentstr + ' and\n'
|
||||||
|
where += mmark.to_string(indent + 4, head_text='', add_snippet=False)
|
||||||
|
if add_snippet:
|
||||||
|
processed_marks.add(id(mark))
|
||||||
|
if mark.old_mark:
|
||||||
|
where += '\n' + indentstr + ' which replaced value\n'
|
||||||
|
indent += 4
|
||||||
mark = mark.old_mark
|
mark = mark.old_mark
|
||||||
if id(mark) in processed_marks:
|
if id(mark) in processed_marks:
|
||||||
raise ValueError('Trying to dump recursive mark')
|
raise ValueError('Trying to dump recursive mark')
|
||||||
|
|
|
@ -65,6 +65,12 @@ class MarkedDict(dict):
|
||||||
r.keydict = dict(((key, key) for key in r))
|
r.keydict = dict(((key, key) for key in r))
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
def setmerged(self, d):
|
||||||
|
try:
|
||||||
|
self.mark.set_merged_mark(d.mark)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
try:
|
try:
|
||||||
old_value = self[key]
|
old_value = self[key]
|
||||||
|
|
Loading…
Reference in New Issue