Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from abc import ABCMeta, abstractmethod
- def freeze(x):
- return Freezable.summon[type(x)].freeze(x)
- class FreezableSummoner(object):
- _not_found = object()
- def __getitem__(self, t):
- v = Freezable._registry.get(t, self._not_found)
- if v is self._not_found:
- raise TypeError('{} is not Freezable'.format(t))
- return v
- class FreezableRegistrar(object):
- _typ = None
- def __call__(self, x):
- if not self._typ:
- if not isinstance(x, type):
- raise TypeError
- res = FreezableRegistrar()
- res._typ = x
- return res
- if not callable(x):
- raise TypeError
- class Derived(Freezable):
- def freeze(self, v):
- return x(v)
- Derived.__name__ = 'Freezable[{}]'.format(self._typ)
- Freezable._registry[self._typ] = Derived()
- return x
- class Freezable(object):
- __metaclass__ = ABCMeta
- _registry = {}
- register = FreezableRegistrar()
- summon = FreezableSummoner()
- @abstractmethod
- def freeze(self, v):
- pass
- class FrozenDict(object):
- def __init__(self, underlying):
- self._underlying = underlying
- def get(self, k):
- return self._underlying.get(k)
- def items(self):
- return self._underlying.items()
- def keys(self):
- return self._underlying.keys()
- def values(self):
- return self._underlying.values()
- def __getitem__(self, k):
- return self._underlying[k]
- def __iter__(self):
- return iter(self._underlying)
- def __repr__(self):
- return 'frozen({})'.format(self._underlying)
- @Freezable.register(dict)
- def freezable_dict(d):
- return FrozenDict({freeze(k): freeze(v) for k, v in d.items()})
- Freezable.register(str)(lambda x: x)
Add Comment
Please, Sign In to add comment