Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import collections.abc as cabc
- import weakref
- class WeakKeyIDDictionary(cabc.MutableMapping):
- def __init__(self): # TODO: Allow passing parameters here
- self._ids = weakref.WeakValueDictionary() # from id(key) to key
- self._values = {} # from id(key) to value
- def _remove_dead_refs(self):
- """Remove items from self._values which are not in self._ids.
- Return true if the dictionary changed.
- """
- strong_ids = list(self._ids.values()) # hold strong references to
- # keep the dictionary stable
- dead_identifiers = self._values.keys() - self._ids.keys()
- for identifier in dead_identifiers:
- del self._values[identifier]
- return bool(dead_identifiers)
- def __getattr__(self, key):
- # We have a strong reference to key, so it won't vanish.
- # Calling _remove_dead_refs() would not affect the correctness of this
- # method.
- identifier = id(key)
- return self._values[identifier]
- def __setattr__(self, key, value):
- # We have a strong reference to key, so again it won't vanish.
- identifier = id(key)
- self._ids[identifier] = key
- self._values[identifier] = value
- def __delattr__(self, key):
- # Strong reference, won't vanish.
- del self._ids[identifier]
- del self._values[identifier]
- def __iter__(self):
- for identifier, key in self._ids.items():
- # Have a strong ref to key
- # And the dictionary isn't allowed to change during iteration
- # anyway
- yield key
- def __len__(self):
- return len(self._ids)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement