"""Weak reference support for Python.
This module is an implementation of PEP 205:
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.
from exceptions
import ReferenceError
ProxyTypes
= (ProxyType
, CallableProxyType
)
__all__
= ["ref", "proxy", "getweakrefcount", "getweakrefs",
"WeakKeyDictionary", "ReferenceType", "ProxyType",
"CallableProxyType", "ProxyTypes", "WeakValueDictionary"]
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
# dictionary; since it uses our .update() method, we get the right
# checks (if the other dictionary is a WeakValueDictionary,
# objects are unwrapped on the way out, and we always wrap on the
def __init__(self
, *args
, **kw
):
def remove(wr
, selfref
=ref(self
)):
UserDict
.UserDict
.__init
__(self
, *args
, **kw
)
def __getitem__(self
, key
):
def __contains__(self
, key
):
return "<WeakValueDictionary at %s>" % id(self
)
def __setitem__(self
, key
, value
):
self
.data
[key
] = KeyedRef(value
, self
._remove
, key
)
new
= WeakValueDictionary()
for key
, wr
in self
.data
.items():
def get(self
, key
, default
=None):
# This should only happen
for key
, wr
in self
.data
.items():
for wr
in self
.data
.itervalues():
return self
.data
.iterkeys()
return self
.data
.iterkeys()
for wr
in self
.data
.itervalues():
key
, wr
= self
.data
.popitem()
def pop(self
, key
, *args
):
def setdefault(self
, key
, default
=None):
self
.data
[key
] = KeyedRef(default
, self
._remove
, key
)
def update(self
, dict=None, **kwargs
):
if not hasattr(dict, "items"):
for key
, o
in dict.items():
d
[key
] = KeyedRef(o
, self
._remove
, key
)
for wr
in self
.data
.values():
"""Specialized reference that includes a key corresponding to the value.
This is used in the WeakValueDictionary to avoid having to create
a function object for each key stored in the mapping. A shared
callback object can use the 'key' attribute of a KeyedRef instead
of getting a reference to the key from an enclosing scope.
def __new__(type, ob
, callback
, key
):
self
= ref
.__new
__(type, ob
, callback
)
def __init__(self
, ob
, callback
, key
):
super(KeyedRef
, self
).__init
__(ob
, callback
)
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
def __init__(self
, dict=None):
def remove(k
, selfref
=ref(self
)):
if dict is not None: self
.update(dict)
def __delitem__(self
, key
):
def __getitem__(self
, key
):
return self
.data
[ref(key
)]
return "<WeakKeyDictionary at %s>" % id(self
)
def __setitem__(self
, key
, value
):
self
.data
[ref(key
, self
._remove
)] = value
new
= WeakKeyDictionary()
for key
, value
in self
.data
.items():
def get(self
, key
, default
=None):
return self
.data
.get(ref(key
),default
)
def __contains__(self
, key
):
for key
, value
in self
.data
.items():
for wr
, value
in self
.data
.iteritems():
for wr
in self
.data
.iterkeys():
return self
.data
.itervalues()
for wr
in self
.data
.keys():
key
, value
= self
.data
.popitem()
def pop(self
, key
, *args
):
return self
.data
.pop(ref(key
), *args
)
def setdefault(self
, key
, default
=None):
return self
.data
.setdefault(ref(key
, self
._remove
),default
)
def update(self
, dict=None, **kwargs
):
if not hasattr(dict, "items"):
for key
, value
in dict.items():
d
[ref(key
, self
._remove
)] = value