For updating a base dict with a fresh one, returning a list of
    3-tuples containing the key, previous value (base[key]) and the
    fresh value (fresh[key]) for all colliding changes (reassignment of
    identical values are omitted).
489727
def dict_update_overwrite_check(base, fresh):
    

    result = [
        (key, base[key], fresh[key])
        for key in set(base.keys()) & set(fresh.keys())
        if base[key] != fresh[key]
    ]
    base.update(fresh)
    return result
409005
def deep_merge(*dicts):
    
    result = {}
    for d in dicts:
        if not isinstance(d, dict):
            raise Exception('Can only deep_merge dicts, got {}'.format(d))
        for k, v in d.items():
            # Whenever the value is a dict, we deep_merge it. This ensures that
            # (a) we only ever merge dicts with dicts and (b) we always get a
            # deep(ish) copy of the dicts and are thus safe from accidental
            # mutations to shared state.
            if isinstance(v, dict):
                v = deep_merge(result.get(k, {}), v)
            result[k] = v
    return result
1370407
def _get_values(cls, diff_dict, type='new'):
        '''
        
        '''
        ret_dict = {}
        for p in diff_dict.keys():
            if type in diff_dict[p].keys():
                ret_dict.update({p: diff_dict[p][type]})
            else:
                ret_dict.update(
                    {p: cls._get_values(diff_dict[p], type=type)})
        return ret_dict
1097362
def recursive_update(_dict, _update):
    
    for k, v in _update.items():
        if isinstance(v, collections.Mapping):
            r = recursive_update(_dict.get(k, {}), v)
            _dict[k] = r
        else:
            _dict[k] = _update[k]
    return _dict
919107
def clean_dict_keys(d):
    
    new_d = {}
    for (k, v) in d.iteritems():
        new_d[str(k)] = v
    return new_d
866597
def _bin_update_items(self, items, replace_at_most_one,
                          replacements, leftovers):
        
        for key, value in items:
            # If there are existing items with key <key> that have yet to be
            # marked for replacement, mark that item's value to be replaced by
            # <value> by appending it to <replacements>.
            if key in self and key not in replacements:
                replacements[key] = [value]
            elif (key in self and not replace_at_most_one and
                  len(replacements[key]) < len(self.values(key))):
                replacements[key].append(value)
            else:
                if replace_at_most_one:
                    replacements[key] = [value]
                else:
                    leftovers.append((key, value))
128801
def dict_update(d, u):
    
    for k, v in six.iteritems(u):
        if isinstance(v, collections.Mapping):
            r = dict_update(d.get(k, {}), v)
            d[k] = r
        else:
            d[k] = u[k]
    return d
130248
def _get_changes(cls, diff_dict):
        '''
        
        '''
        changes_strings = []
        for p in sorted(diff_dict.keys()):
            if sorted(diff_dict[p].keys()) == ['new', 'old']:
                # Some string formatting
                old_value = diff_dict[p]['old']
                if diff_dict[p]['old'] == cls.NONE_VALUE:
                    old_value = 'nothing'
                elif isinstance(diff_dict[p]['old'], six.string_types):
                    old_value = '\'{0}\''.format(diff_dict[p]['old'])
                elif isinstance(diff_dict[p]['old'], list):
                    old_value = '\'{0}\''.format(
                        ', '.join(diff_dict[p]['old']))
                new_value = diff_dict[p]['new']
                if diff_dict[p]['new'] == cls.NONE_VALUE:
                    new_value = 'nothing'
                elif isinstance(diff_dict[p]['new'], six.string_types):
                    new_value = '\'{0}\''.format(diff_dict[p]['new'])
                elif isinstance(diff_dict[p]['new'], list):
                    new_value = '\'{0}\''.format(', '.join(diff_dict[p]['new']))
                changes_strings.append('{0} from {1} to {2}'.format(
                    p, old_value, new_value))
            else:
                sub_changes = cls._get_changes(diff_dict[p])
                if sub_changes:
                    changes_strings.append('{0}:'.format(p))
                    changes_strings.extend(['  {0}'.format(c)
                                           for c in sub_changes])
        return changes_strings
71043
def changes_str(self):
        ''''''
        changes = ''
        for item in self._get_recursive_difference(type='intersect'):
            if item.diffs:
                changes = ''.join([changes,
                                   # Tabulate comment deeper, show the key attribute and the value
                                   # Next line should be tabulated even deeper,
                                   #  every change should be tabulated 1 deeper
                                   '\tidentified by {0} {1}:\n\t{2}\n'.format(
                                       self._key,
                                       item.past_dict[self._key],
                                       item.changes_str.replace('\n', '\n\t'))])
        for item in self._get_recursive_difference(type='removed'):
            if item.past_dict:
                changes = ''.join([changes,
                                   # Tabulate comment deeper, show the key attribute and the value
                                   '\tidentified by {0} {1}:'
                                   '\n\twill be removed\n'.format(self._key,
                                                                  item.past_dict[self._key])])
        for item in self._get_recursive_difference(type='added'):
            if item.current_dict:
                changes = ''.join([changes,
                                   # Tabulate comment deeper, show the key attribute and the value
                                   '\tidentified by {0} {1}:'
                                   '\n\twill be added\n'.format(self._key,
                                                                item.current_dict[self._key])])
        return changes
187369
def _get_diffs(cls, dict1, dict2, ignore_missing_keys):
        '''
        
        '''
        ret_dict = {}
        for p in dict1.keys():
            if p not in dict2:
                ret_dict.update({p: {'new': dict1[p], 'old': cls.NONE_VALUE}})
            elif dict1[p] != dict2[p]:
                if isinstance(dict1[p], dict) and isinstance(dict2[p], dict):
                    sub_diff_dict = cls._get_diffs(dict1[p], dict2[p],
                                                   ignore_missing_keys)
                    if sub_diff_dict:
                        ret_dict.update({p: sub_diff_dict})
                else:
                    ret_dict.update({p: {'new': dict1[p], 'old': dict2[p]}})
        if not ignore_missing_keys:
            for p in dict2.keys():
                if p not in dict1.keys():
                    ret_dict.update({p: {'new': cls.NONE_VALUE,
                                         'old': dict2[p]}})
        return ret_dict
959585
def merge_dictionaries(current, new, only_defaults=False, template_special_case=False):
    '''
    

    '''
    changes = 0
    for key, value in new.items():
        if key not in current:
            if hasattr(global_settings, key):
                current[key] = getattr(global_settings, key)
                LOGGER.debug("Set %r to global default %r.", key, current[key])
            else:
                current[key] = copy.copy(value)
                LOGGER.debug("Set %r to %r.", key, current[key])
                changes += 1
                continue
        elif only_defaults:
            continue
        current_value = current[key]
        if hasattr(current_value, 'items'):
            changes += merge_dictionaries(current_value, value)
        elif isinstance(current_value, (list, tuple)):
            for element in value:
                if element not in current_value:
                    if template_special_case and key == 'TEMPLATES':
                        existing_matches = [
                            template for template in current_value if template['BACKEND'] == element['BACKEND']
                        ]
                        if existing_matches:
                            changes += merge_dictionaries(existing_matches[0], element)
                        else:
                            current[key] = list(current_value) + [element]
                            LOGGER.debug("Added %r to %r.", element, key)
                            changes += 1
                    else:
                        current[key] = list(current_value) + [element]
                        LOGGER.debug("Added %r to %r.", element, key)
                        changes += 1
        elif isinstance(current_value, Promise) or isinstance(value, Promise):
            # If we don't know what to do with it, replace it.
            if current_value is not value:
                current[key] = value
                LOGGER.debug("Set %r to %r.", key, current[key])
                changes += 1
        else:
            # If we don't know what to do with it, replace it.
            if current_value != value:
                current[key] = value
                LOGGER.debug("Set %r to %r.", key, current[key])
                changes += 1
    return changes
1260006
def _recursive_dict_update(dict_, other, **kwargs):
    
    overwrite = kwargs['overwrite']

    for key, other_value in iteritems(other):
        if key in dict_:
            value = dict_[key]
            if is_mapping(value) and is_mapping(other_value):
                _recursive_dict_update(value, other_value, overwrite=overwrite)
                continue
        if overwrite:
            dict_[key] = other_value
        else:
            dict_.setdefault(key, other_value)
344388
def changed(self):
        '''
        
        '''
        def _changed(diffs, prefix):
            keys = []
            for key in diffs.keys():
                if not isinstance(diffs[key], dict):
                    continue

                if isinstance(diffs[key], dict) and 'old' not in diffs[key]:
                    keys.extend(_changed(diffs[key],
                                       prefix='{0}{1}.'.format(prefix, key)))
                    continue
                if self.ignore_unset_values:
                    if 'old' in diffs[key] and 'new' in diffs[key] and \
                            diffs[key]['old'] != self.NONE_VALUE and \
                            diffs[key]['new'] != self.NONE_VALUE:
                        if isinstance(diffs[key]['new'], dict):
                            keys.extend(
                                _changed(diffs[key]['new'],
                                         prefix='{0}{1}.'.format(prefix, key)))
                        else:
                            keys.append('{0}{1}'.format(prefix, key))
                    elif isinstance(diffs[key], dict):
                        keys.extend(
                            _changed(diffs[key],
                                     prefix='{0}{1}.'.format(prefix, key)))
                else:
                    if 'old' in diffs[key] and 'new' in diffs[key]:
                        if isinstance(diffs[key]['new'], dict):
                            keys.extend(
                                _changed(diffs[key]['new'],
                                         prefix='{0}{1}.'.format(prefix, key)))
                        else:
                            keys.append('{0}{1}'.format(prefix, key))
                    elif isinstance(diffs[key], dict):
                        keys.extend(
                            _changed(diffs[key],
                                     prefix='{0}{1}.'.format(prefix, key)))

            return keys

        return sorted(_changed(self._diffs, prefix=''))
9973
def dict_filter_update(base, updates):
    # type: (dict, dict) -> None
    
    base.update((k, v) for k, v in updates.items() if v is not None)
1333664
def merge(d, *dicts):
    

    for d_update in dicts:
        if not isinstance(d, dict):
            raise TypeError("{0} is not a dict".format(d))

        dict_merge_pair(d, d_update)

    return d
1101032
def _flatten_dict(self, dict_):
        
        flattened_dict = {}
        for (key, value) in dict_.iteritems():
            if isinstance(value, dict):
                flattened_dict.update(self._flatten_dict(value))
            else:
                flattened_dict[key] = value
        return flattened_dict
1326669
def update(args):
    
    # Check specifying some new values
    if ((not args.__dict__.get('new_type') and
         not args.__dict__.get('new_content') and
         not args.__dict__.get('new_ttl') and
         not args.__dict__.get('new_priority'))):
        utils.error("Not update any values.")

    args.__dict__['search'] = (args.__dict__.get('name') + ',' +
                               args.__dict__.get('rtype') + ',' +
                               args.__dict__.get('content'))

    args.__dict__['raw_flag'] = True
    data = get(args)
    if len(data.get('records')) == 1:
        cur_ttl = data.get('records')[0].get('ttl')
        cur_priority = data.get('records')[0].get('priority')
    elif len(data.get('records')) > 1:
        utils.error("Match multiple records")
    else:
        utils.error("No match records")

    new_args = copy.copy(args)

    if new_args.__dict__.get('new_type'):
        new_args.__dict__['rtype'] = new_args.__dict__.get('new_type')

    if new_args.__dict__.get('new_content'):
        new_args.__dict__['content'] = new_args.__dict__.get('new_content')

    if new_args.__dict__.get('new_ttl'):
        new_args.__dict__['ttl'] = new_args.__dict__.get('new_ttl')
    else:
        new_args.__dict__['ttl'] = cur_ttl

    if new_args.__dict__.get('new_priority'):
        new_args.__dict__['priority'] = new_args.__dict__.get('new_priority')
    else:
        if cur_priority:
            new_args.__dict__['priority'] = cur_priority

    delete(args)
    create(new_args)