1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
|
from .strategy.list import ListStrategies
from .strategy.dict import DictStrategies
from .strategy.type_conflict import TypeConflictStrategies
from .strategy.fallback import FallbackStrategies
class Merger(object):
"""
:param type_strategies, List[Tuple]: a list of (Type, Strategy) pairs
that should be used against incoming types. For example: (dict, "override").
"""
PROVIDED_TYPE_STRATEGIES = {
list: ListStrategies,
dict: DictStrategies
}
def __init__(self,
type_strategies,
fallback_strategies,
type_conflict_strategies):
self._fallback_strategy = FallbackStrategies(fallback_strategies)
expanded_type_strategies = []
for typ, strategy in type_strategies:
if typ in self.PROVIDED_TYPE_STRATEGIES:
strategy = self.PROVIDED_TYPE_STRATEGIES[typ](strategy)
expanded_type_strategies.append((typ, strategy))
self._type_strategies = expanded_type_strategies
self._type_conflict_strategy = TypeConflictStrategies(
type_conflict_strategies
)
def merge(self, base, nxt):
return self.value_strategy([], base, nxt)
def type_conflict_strategy(self, *args):
return self._type_conflict_strategy(self, *args)
def value_strategy(self, path, base, nxt):
if not (isinstance(base, type(nxt)) or isinstance(nxt, type(base))):
return self.type_conflict_strategy(path, base, nxt)
for typ, strategy in self._type_strategies:
if isinstance(nxt, typ):
return strategy(self, path, base, nxt)
return self._fallback_strategy(self, path, base, nxt)
|