Also save what was merged in

This commit is contained in:
ZyX 2015-01-07 20:02:25 +03:00
parent ee78221af4
commit 7d6b9c5c51
3 changed files with 37 additions and 12 deletions

View File

@ -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])

View File

@ -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')

View File

@ -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]