Source code for curry.utility.shared

from copy import copy
import collections, sys

[docs] class Shared(object): ''' Manages an object with copy-on-write semantics. To access the contained object for reading or writing, use the ``read`` and ``write`` methods, resp. If the object has multiple references, then writing will trigger a copy. ''' def __init__(self, ty, obj=None): self.ty = ty if obj is None: self.obj = ty() assert self.unique else: self.obj = obj def __copy__(self): return Shared(self.ty, self.obj) # sharing copy @property def read(self): return self.obj @property def write(self): if not self.unique: self.obj = self.ty(self.obj) # copy for write assert self.unique return self.obj @property def refcnt(self): return sys.getrefcount(self.obj) - 1 @property def unique(self): return self.refcnt == 1 def __str__(self): return str(self.read) def __repr__(self): return str(self) return 'Shared(refcnt=%s, %s)' % (self.refcnt, self.obj) # Read-only container methods, for convenience. def __contains__(self, key): return key in self.obj def __len__(self): return len(self.obj) def __getitem__(self, key): return self.obj[key] def __iter__(self): return iter(self.obj)
[docs] class DefaultDict(collections.defaultdict): '''Like defaultdict but recursively copies values.''' def __copy__(self): return DefaultDict(self.default_factory, {k: copy(v) for k,v in self.items()}) copy = __copy__
[docs] def compose(typefunction, ty): ''' Composes a type function and type. The type function is a type, such as Shared or DefaultDict, that takes another type as its only argument. The returned object has object-copy semantics. ''' def factory(obj=None): if obj is None: return typefunction(ty) else: return copy(obj) return factory