blob: e280889182545fab84e05a1108b191a1a1a3166e [file] [log] [blame]
martin f. krafftf37f0682013-06-14 16:36:20 +02001#
2# -*- coding: utf-8 -*-
3#
4# This file is part of reclass (http://github.com/madduck/reclass)
5#
6# Copyright © 2007–13 martin f. krafft <madduck@madduck.net>
7# Released under the terms of the Artistic Licence 2.0
8#
9from base import BaseDictMerger
10
11class DictRecursivePolicyUpdate(BaseDictMerger):
12
13 def __init__(self, policy=None):
14 super(DictRecursivePolicyUpdate, self).__init__()
15 if policy is None:
martin f. krafftae0a3922013-06-16 12:46:05 +020016 first = lambda first, second: first
17 second = lambda first, second: second
18
19 policy = {(dict,dict) : self.merge,
20 (list,list) : lambda x,y: x+y,
21 (dict,list) : lambda x,y: self.merge(x, dict(y)),
22 (dict,type(None)) : first,
23 (list,type(None)) : first,
24 None : second
martin f. krafftf37f0682013-06-14 16:36:20 +020025 }
26 self._policy = policy
27
28 def merge(self, first, second):
martin f. kraffta95eaa32013-06-16 11:56:41 +020029 if second is None:
30 return first
31
martin f. krafftf37f0682013-06-14 16:36:20 +020032 ret = first.copy()
33 for k,v in second.iteritems():
34 if k in ret:
martin f. krafftae0a3922013-06-16 12:46:05 +020035 lookup = (type(ret[k]), type(v))
36 pfn = self._policy.get(lookup, self._policy.get(None))
martin f. krafftf37f0682013-06-14 16:36:20 +020037 ret[k] = pfn(ret[k], v)
38 else:
39 ret[k] = v
40 return ret