Ejemplo n.º 1
0
class DictDiff(object):
    """A wrapper around json_diff's dict comparisons.

    :param dict1: The first dict.  Can be a :class:`GitDict <GitDict>`.
    :type dict1: dict
    :param dict2: The second dict.  Can be a :class:`GitDict <GitDict>`.
    :type dict2: dict
    """

    def __init__(self, dict1, dict2):
        self._diff = Comparator().compare_dicts(dict1, dict2)

    @property
    def removed(self):
        """A dict of removed keys and their values.
        """
        return self._diff.get('_remove', {})

    @property
    def updated(self):
        """A dict of updated keys and their values.
        """
        return self._diff.get('_update', {})

    @property
    def appended(self):
        """A dict of appended keys and their values.
        """
        return self._diff.get('_append', {})

    def conflict(self, other):
        """Determine whether this :class:`DictDiff <DictDiff>`s conflicts with
        another.

        :param other: The diff to compare.
        :type other: :class:`DictDiff <DictDiff>`

        :return: the conflicts
        :rtype: :class:`DictConflict <DictConflict>`
        """
        conflicts = {}
        for other_mod_type, other_mods in other._diff.items():
            for self_mod_type, self_mods in self._diff.items():
                for other_mod_key, other_mod_value in other_mods.items():
                    if other_mod_key in self_mods:
                        self_mod_value = self_mods[other_mod_key]
                        # if the mod type is the same, it's OK if the actual
                        # modification was the same.
                        if other_mod_type == self_mod_type:
                            if other_mod_value == self_mods[other_mod_key]:
                                pass
                            else:
                                conflicts[other_mod_key] = {
                                    'other': { other_mod_type: other_mod_value },
                                    'self' : { self_mod_type: self_mod_value }
                                }
                        # if the mod type was not the same, it's a conflict no
                        # matter what
                        else:
                            conflicts[other_mod_key] = {
                                'other': { other_mod_type: other_mod_value },
                                'self' : { self_mod_type: self_mod_value }
                            }
        return conflicts if len(conflicts) else None