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:
parent
6442de916d
commit
0e2b05d487
189
pep-0205.txt
189
pep-0205.txt
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue