Commit bd7f818c authored by Fred Drake's avatar Fred Drake

Weak*Dictionary: Added docstrings to the classes.

Weak*Dictionary.update():  No longer create a temporary list to hold the
    things that will be stuffed into the underlying dictionary.  This had
    been done so that if any of the objects used as the weakly-held value
    was not weakly-referencable, no updates would take place (TypeError
    would be raised).  With this change, TypeError will still be raised
    but a partial update could occur.  This is more like other .update()
    implementations.

Thoughout, use of the name "ref" as a local variable has been removed.  The
original use of the name occurred when the function to create a weak
reference was called "new"; the overloaded use of the name could be
confusing for someone reading the code.  "ref" used as a variable name
has been replaced with "wr" (for 'weak reference').
parent 1aec3a16
...@@ -5,6 +5,10 @@ This module is an implementation of PEP 205: ...@@ -5,6 +5,10 @@ This module is an implementation of PEP 205:
http://python.sourceforge.net/peps/pep-0205.html http://python.sourceforge.net/peps/pep-0205.html
""" """
# Naming convention: Variables named "wr" are weak reference objects;
# they are called this instead of "ref" to avoid name collisions with
# the module-global ref() function imported from _weakref.
import UserDict import UserDict
from _weakref import \ from _weakref import \
...@@ -23,8 +27,13 @@ __all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs", ...@@ -23,8 +27,13 @@ __all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
"WeakKeyDictionary", "ReferenceType", "ProxyType", "WeakKeyDictionary", "ReferenceType", "ProxyType",
"CallableProxyType", "ProxyTypes", "WeakValueDictionary"] "CallableProxyType", "ProxyTypes", "WeakValueDictionary"]
class WeakValueDictionary(UserDict.UserDict): class WeakValueDictionary(UserDict.UserDict):
"""Mapping class that references values weakly.
Entries in the dictionary will be discarded when no strong
reference to the value exists anymore
"""
# We inherit the constructor without worrying about the input # We inherit the constructor without worrying about the input
# dictionary; since it uses our .update() method, we get the right # dictionary; since it uses our .update() method, we get the right
# checks (if the other dictionary is a WeakValueDictionary, # checks (if the other dictionary is a WeakValueDictionary,
...@@ -48,19 +57,19 @@ class WeakValueDictionary(UserDict.UserDict): ...@@ -48,19 +57,19 @@ class WeakValueDictionary(UserDict.UserDict):
def copy(self): def copy(self):
new = WeakValueDictionary() new = WeakValueDictionary()
for key, ref in self.data.items(): for key, wr in self.data.items():
o = ref() o = wr()
if o is not None: if o is not None:
new[key] = o new[key] = o
return new return new
def get(self, key, default=None): def get(self, key, default=None):
try: try:
ref = self.data[key] wr = self.data[key]
except KeyError: except KeyError:
return default return default
else: else:
o = ref() o = wr()
if o is None: if o is None:
# This should only happen # This should only happen
return default return default
...@@ -69,51 +78,56 @@ class WeakValueDictionary(UserDict.UserDict): ...@@ -69,51 +78,56 @@ class WeakValueDictionary(UserDict.UserDict):
def items(self): def items(self):
L = [] L = []
for key, ref in self.data.items(): for key, wr in self.data.items():
o = ref() o = wr()
if o is not None: if o is not None:
L.append((key, o)) L.append((key, o))
return L return L
def popitem(self): def popitem(self):
while 1: while 1:
key, ref = self.data.popitem() key, wr = self.data.popitem()
o = ref() o = wr()
if o is not None: if o is not None:
return key, o return key, o
def setdefault(self, key, default): def setdefault(self, key, default):
try: try:
ref = self.data[key] wr = self.data[key]
except KeyError: except KeyError:
def remove(o, data=self.data, key=key): def remove(o, data=self.data, key=key):
del data[key] del data[key]
ref = ref(default, remove) self.data[key] = ref(default, remove)
self.data[key] = ref
return default return default
else: else:
return ref() return wr()
def update(self, dict): def update(self, dict):
d = self.data d = self.data
L = []
for key, o in dict.items(): for key, o in dict.items():
def remove(o, data=d, key=key): def remove(o, data=d, key=key):
del data[key] del data[key]
L.append((key, ref(o, remove))) d[key] = ref(o, remove)
for key, r in L:
d[key] = r
def values(self): def values(self):
L = [] L = []
for ref in self.data.values(): for wr in self.data.values():
o = ref() o = wr()
if o is not None: if o is not None:
L.append(o) L.append(o)
return L return L
class WeakKeyDictionary(UserDict.UserDict): class WeakKeyDictionary(UserDict.UserDict):
""" Mapping class that references keys weakly.
Entries in the dictionary will be discarded when there is no
longer a strong reference to the key. This can be used to
associate additional data with an object owned by other parts of
an application without adding attributes to those objects. This
can be especially useful with objects that override attribute
accesses.
"""
def __init__(self, dict=None): def __init__(self, dict=None):
self.data = {} self.data = {}
...@@ -155,8 +169,8 @@ class WeakKeyDictionary(UserDict.UserDict): ...@@ -155,8 +169,8 @@ class WeakKeyDictionary(UserDict.UserDict):
def keys(self): def keys(self):
L = [] L = []
for ref in self.data.keys(): for wr in self.data.keys():
o = ref() o = wr()
if o is not None: if o is not None:
L.append(o) L.append(o)
return L return L
...@@ -173,11 +187,9 @@ class WeakKeyDictionary(UserDict.UserDict): ...@@ -173,11 +187,9 @@ class WeakKeyDictionary(UserDict.UserDict):
def update(self, dict): def update(self, dict):
d = self.data d = self.data
L = []
for key, value in dict.items(): for key, value in dict.items():
L.append((ref(key, self._remove), value)) d[ref(key, self._remove)] = value
for key, r in L:
d[key] = r
# no longer needed # no longer needed
del UserDict del UserDict
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment