Substantially updated; now includes a description of the proposed API and

rough outline of how the implementation should work.

Hopefully will be ready for broad posting sometime tomorrow.
This commit is contained in:
Fred Drake 2001-01-10 05:36:31 +00:00
parent 6442de916d
commit 0e2b05d487
1 changed files with 136 additions and 53 deletions

View File

@ -49,10 +49,142 @@ Motivation
Circular references
- DOMs require a huge amount of circular (to parent & document
nodes), but most of these aren't useful. Using weak
references allows applications to hold onto less of the tree
without a lot of difficulty. This might be especially
useful in the context of something like xml.dom.pulldom.
nodes), but these could be eliminated using a weak
dictionary mapping from each node to it's parent. This
might be especially useful in the context of something like
xml.dom.pulldom, allowing the .unlink() operation to become
a no-op.
This proposal is divided into the following sections:
- Proposed Solution
- Implementation Strategy
- Possible Applications
- Previous Weak Reference Work in Python
- Weak References in Java
The full text of one early proposal is included as an appendix
since it does not appear to be available on the net.
Proposed Solution
Weak references should be able to point to any Python object that
may have substantial memory size (directly or indirectly), or hold
references to external resources (database connections, open
files, etc.).
A new module, weakref, will contain two new functions used to
create weak references. weakref.new() will create a "weak
reference object" and optionally attach a callback which will be
called when the object is about to be finalized.
weakref.mapping() will create a "weak dictionary".
A weak reference object will allow access to the referenced object
if it hasn't been collected, allows application code to either
"clear" the weak reference and the associated callback, and to
determine if the object still exists in memory. These operations
are accessed via the .get(), .clear(), and .islive() methods. If
the object has been collected, .get() will return None and
islive() will return false; calling .clear() will produce the same
result, and is allowed to occur repeatedly. Weak references are
not hashable.
A weak dictionary maps arbitrary keys to values, but does not own
a reference to the values. When the values are finalized, the
(key, value) pairs for which it is a value are removed from all
the mappings containing such pairs. These mapping objects provide
an additional method, .setitem(), which accepts a key, value, and
optional callback which will be called when the object is removed
from the mapping. If the object is removed from the mapping by
deleting the entry by key or calling the mapping's .clear()
method, the callback is not called (since the object is not about
to be finalized), and will be unregistered from the object. Like
dictionaries, weak dictionaries are not hashable.
The callbacks registered with weak reference objects or in weak
dictionaries must accept a single parameter, which will be the
weak-ly referenced object itself. The object can be resurrected
by creating some other reference to the object in the callback, in
which case the weak reference generating the callback will still
be cleared but no weak references remaining to the object will be
cleared.
Implementation Strategy
The implementation of weak references will include a list of
reference containers that must be cleared for each weakly-
referencable object. If the reference is from a weak dictionary,
the dictionary entry is cleared first. Then, any associated
callback is called with the object passed as a parameter. If the
callback generates additional references, no further callbacks are
called and the object is resurrected. Once all callbacks have
been called and the object has not been resurrected, it is
finalized and deallocated.
Many built-in types will participate in the weak-reference
management, and any extension type can elect to do so. The type
structure will contain an additional field which provides an
offset into the instance structure which contains a list of weak
reference structures. If the value of the field is <= 0, the
object does not participate. In this case, weakref.new(),
<weakdict>.setitem(), .setdefault(), and item assignment will
raise TypeError. If the value of the field is > 0, a new weak
reference can be generated and added to the list.
This approach is taken to allow arbitrary extension types to
participate, without taking a memory hit for numbers or other
small types.
XXX -- Need to determine the exact list of standard types which
should support weak references. This should include instances and
dictionaries. Whether it should include strings, buffers, lists,
files, or sockets is debatable.
Possible Applications
PyGTK+ bindings?
Tkinter -- could avoid circular references by using weak
references from widgets to their parents. Objects won't be
discarded any sooner in the typical case, but there won't be so
much dependence on the programmer calling .destroy() before
releasing a reference. This would mostly benefit long-running
applications.
DOM trees.
Previous Weak Reference Work in Python
Dianne Hackborn has proposed something called "virtual references".
'vref' objects are very similar to java.lang.ref.WeakReference
objects, except there is no equivalent to the invalidation
queues. Implementing a "weak dictionary" would be just as
difficult as using only weak references (without the invalidation
queue) in Java. Information on this has disappeared from the Web,
but is included below as an Appendix.
Marc-André Lemburg's mx.Proxy package:
http://www.lemburg.com/files/python/mxProxy.html
The weakdict module by Dieter Maurer is implemented in C and
Python. It appears that the Web pages have not been updated since
Python 1.5.2a, so I'm not yet sure if the implementation is
compatible with Python 2.0.
http://www.handshake.de/~dieter/weakdict.html
PyWeakReference by Alex Shindich:
http://sourceforge.net/projects/pyweakreference/
Eric Tiedemann has a weak dictionary implementation:
http://www.hyperreal.org/~est/python/weak/
Weak References in Java
@ -101,55 +233,6 @@ Weak References in Java
associated with an invalidation queue.
Previous Weak Reference Work in Python
Dianne Hackborn has proposed something called "virtual references".
'vref' objects are very similar to java.lang.ref.WeakReference
objects, except there is no equivalent to the invalidation
queues. Implementing a "weak dictionary" would be just as
difficult as using only weak references (without the invalidation
queue) in Java. Information on this has disappeared from the Web,
but is included below as an Appendix.
Marc-André Lemburg's mx.Proxy package:
http://www.lemburg.com/files/python/mxProxy.html
The weakdict module by Dieter Maurer is implemented in C and
Python. It appears that the Web pages have not been updated since
Python 1.5.2a, so I'm not yet sure if the implementation is
compatible with Python 2.0.
http://www.handshake.de/~dieter/weakdict.html
PyWeakReference by Alex Shindich:
http://sourceforge.net/projects/pyweakreference/
Eric Tiedemann has a weak dictionary implementation:
http://www.hyperreal.org/~est/python/weak/
Possible Applications
PyGTK+ bindings?
Tkinter -- could avoid circular references by using weak
references from widgets to their parents. Objects won't be
discarded any sooner in the typical case, but there won't be so
much dependence on the programmer calling .destroy() before
releasing a reference. This would mostly benefit long-running
applications.
DOM trees?
Proposed Implementation
XXX -- Not yet.
Appendix -- Dianne Hackborn's vref proposal (1995)
[This has been indented and paragraphs reflowed, but there have be