[Python-Dev] Quick-and-dirty weak references

Jack Jansen jack@oratrix.nl
Fri, 13 Aug 1999 23:48:12 +0200


This week again I was bitten by the fact that Python doesn't have any
form of weak references, and while I was toying with some ideas I came 
up with the following quick-and-dirty scheme that I thought I'd bounce 
off this list. I might even volunteer to implement it, if people agree 
it is worth it:-)

We add a new builtin function (or a module with that function)
weak(). This returns a weak reference to the object passed as a
parameter. A weak object has one method: strong(), which returns the
corresponding real object or raises an exception if the object doesn't 
exist anymore. For convenience we could add a method exists() that
returns true if the real object still exists.

Now comes the bit that I'm unsure about: to implement this I need to
add a pointer to every object. This pointer is either NULL or points
to the corresponding weak objectt (so for every object there is either no
weak reference object or exactly one). But, for the price of 4 bytes extra
in every object we get the nicety that there is little cpu-overhead:
refcounting macros work identical to the way they do now, the only
thing to take care of is that during object deallocation we have to
zero the weak pointer. (actually: we could make do with a single bit
in every object, with the bit meaning "this object has an associated
weak object". We could then use a global dictionary indexed by object
address to find the weak object)

From here on life is easy: the weak object is a normal refcounted
object with a pointer to the real object as its only data. weak()
creates the weak object if it doesn't exist and returns the existing
(and INCREFfed) weak object if it does. Strong() checks that
self->object->weak == self and returns self->object (INCREFfed) if it
is. This works on all platforms that I'm aware of, but it could break
if there are any (Python) platforms that can have objects at VM
addresses that are later, when the object has been free()d, become
invalid addresses. And even then a vmaddrvalid() function, only needed 
in the strong() method, could solve this.

The weak object isn't transparent, because you have to call strong()
before you can do anything with it, but this is an advantage (says he, 
aspiring to a career in politics or sales:-): with a transparent weak
object the object could disappear at unexpected moments and with this
scheme it can't, because when you have the object itself in hand you
have a refcount too.
--
Jack Jansen             | ++++ stop the execution of Mumia Abu-Jamal ++++
Jack.Jansen@oratrix.com | ++++ if you agree copy these lines to your sig ++++
www.oratrix.nl/~jack    | see http://www.xs4all.nl/~tank/spg-l/sigaction.htm