diff options
Diffstat (limited to 'pym/portage/cache/mappings.py')
-rw-r--r-- | pym/portage/cache/mappings.py | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/pym/portage/cache/mappings.py b/pym/portage/cache/mappings.py index 9aa5a21e2..7c347a4f9 100644 --- a/pym/portage/cache/mappings.py +++ b/pym/portage/cache/mappings.py @@ -4,6 +4,7 @@ # $Id$ import UserDict +import weakref class ProtectedDict(UserDict.DictMixin): """ @@ -101,3 +102,128 @@ class LazyLoad(UserDict.DictMixin): self.pull = None return key in self.d +_slot_dict_classes = weakref.WeakValueDictionary() + +def slot_dict_class(keys): + if isinstance(keys, frozenset): + keys_set = keys + else: + keys_set = frozenset(keys) + v = _slot_dict_classes.get(keys_set) + if v is None: + + class SlotDict(object): + + _keys = keys_set + __slots__ = ("__weakref__",) + tuple("_val_" + k for k in _keys) + + def __iter__(self): + for k, v in self.iteritems(): + yield k + + def __len__(self): + l = 0 + for i in self.iteritems(): + l += 1 + return l + + def keys(self): + return list(self) + + def iteritems(self): + for k in self._keys: + try: + yield (k, getattr(self, "_val_" + k)) + except AttributeError: + pass + + def items(self): + return list(self.iteritems()) + + def itervalues(self): + for k, v in self.itervalues(): + yield v + + def values(self): + return list(self.itervalues()) + + def __delitem__(self, k): + try: + delattr(self, "_val_" + k) + except AttributeError: + raise KeyError(k) + + def __setitem__(self, k, v): + setattr(self, "_val_" + k, v) + + def setdefault(self, key, default=None): + try: + return self[key] + except KeyError: + self[key] = default + return default + + def update(self, d): + i = getattr(d, "iteritems", None) + if i is None: + i = d + else: + i = i() + for k, v in i: + self[k] = v + + def __getitem__(self, k): + try: + return getattr(self, "_val_" + k) + except AttributeError: + raise KeyError(k) + + def get(self, key, default=None): + try: + return self[key] + except KeyError: + return default + + def __contains__(self, k): + return hasattr(self, "_val_" + k) + + def has_key(self, k): + return k in self + + def pop(self, key, *args): + if len(args) > 1: + raise TypeError( + "pop expected at most 2 arguments, got " + \ + repr(1 + len(args))) + try: + value = self[key] + except KeyError: + if args: + return args[0] + raise + del self[key] + return value + + def popitem(self): + try: + k, v = self.iteritems().next() + except StopIteration: + raise KeyError, 'container is empty' + del self[k] + return (k, v) + + def copy(self): + c = self.__class__() + c.update(self) + return c + + def clear(self): + for k in self._keys: + try: + delattr(self, "_val_" + k) + except AttributError: + pass + + v = SlotDict + _slot_dict_classes[keys_set] = v + return v |