"""Finalization with weakrefs
This is designed for avoiding __del__.
"""
import sys
import traceback
import weakref
__author__ = "Benjamin Peterson <benjamin@python.org>"
class OwnerRef(weakref.ref):
"""A simple weakref.ref subclass, so attributes can be added."""
pass
def _run_finalizer(ref):
"""Internal weakref callback to run finalizers"""
del _finalize_refs[id(ref)]
finalizer = ref.finalizer
item = ref.item
try:
finalizer(item)
except Exception:
print("Exception running {}:".format(finalizer), file=sys.stderr)
traceback.print_exc()
_finalize_refs = {}
def track_for_finalization(owner, item, finalizer):
"""Register an object for finalization.
``owner`` is the the object which is responsible for ``item``.
``finalizer`` will be called with ``item`` as its only argument when
``owner`` is destroyed by the garbage collector.
"""
ref = OwnerRef(owner, _run_finalizer)
ref.item = item
ref.finalizer = finalizer
_finalize_refs[id(ref)] = ref
Diff to Previous Revision
--- revision 2 2010-05-23 22:03:43
+++ revision 3 2011-07-02 18:42:08
@@ -16,18 +16,19 @@
pass
-def _run_finalizers(ref):
+def _run_finalizer(ref):
"""Internal weakref callback to run finalizers"""
- errors = []
- for item, callback in ref.to_finalize:
- try:
- callback(item)
- except Exception:
- errors.append((callback, sys.exc_info()))
- for callback, error in errors:
- print("Exception running {}:".format(callback), file=sys.stderr)
- traceback.print_exception(*error)
- del errors # Clear cycles from sys.exc_info()
+ del _finalize_refs[id(ref)]
+ finalizer = ref.finalizer
+ item = ref.item
+ try:
+ finalizer(item)
+ except Exception:
+ print("Exception running {}:".format(finalizer), file=sys.stderr)
+ traceback.print_exc()
+
+
+_finalize_refs = {}
def track_for_finalization(owner, item, finalizer):
@@ -37,9 +38,7 @@
``finalizer`` will be called with ``item`` as its only argument when
``owner`` is destroyed by the garbage collector.
"""
- try:
- ref = owner._owner_ref
- except AttributeError:
- ref = owner._owner_ref = OwnerRef(owner, _run_finalizers)
- ref.to_finalize = []
- ref.to_finalize.append((item, finalizer))
+ ref = OwnerRef(owner, _run_finalizer)
+ ref.item = item
+ ref.finalizer = finalizer
+ _finalize_refs[id(ref)] = ref