diff options
author | Richard Oudkerk <shibturn@gmail.com> | 2013-05-05 21:12:34 (GMT) |
---|---|---|
committer | Richard Oudkerk <shibturn@gmail.com> | 2013-05-05 21:12:34 (GMT) |
commit | 39b17c513ae7b9baecdc8292876683647186fee4 (patch) | |
tree | 62d11ed77e5a5b70b729d56627adcfed01fabeba /Lib/weakref.py | |
parent | f3593026ded99404c2c8f6c6fbf4c20197c9830a (diff) | |
download | cpython-39b17c513ae7b9baecdc8292876683647186fee4.zip cpython-39b17c513ae7b9baecdc8292876683647186fee4.tar.gz cpython-39b17c513ae7b9baecdc8292876683647186fee4.tar.bz2 |
Backout 2e446e87ac5b; it breaks the unix buildbots.
Diffstat (limited to 'Lib/weakref.py')
-rw-r--r-- | Lib/weakref.py | 137 |
1 files changed, 1 insertions, 136 deletions
diff --git a/Lib/weakref.py b/Lib/weakref.py index 7a17d17..8f9c107 100644 --- a/Lib/weakref.py +++ b/Lib/weakref.py @@ -21,16 +21,13 @@ from _weakref import ( from _weakrefset import WeakSet, _IterationGuard import collections # Import after _weakref to avoid circular import. -import sys -import atexit -import itertools ProxyTypes = (ProxyType, CallableProxyType) __all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs", "WeakKeyDictionary", "ReferenceType", "ProxyType", "CallableProxyType", "ProxyTypes", "WeakValueDictionary", - "WeakSet", "WeakMethod", "finalize"] + "WeakSet", "WeakMethod"] class WeakMethod(ref): @@ -439,135 +436,3 @@ class WeakKeyDictionary(collections.MutableMapping): d[ref(key, self._remove)] = value if len(kwargs): self.update(kwargs) - - -class finalize: - """Class for finalization of weakrefable objects - - finalize(obj, func, *args, **kwargs) returns a callable finalizer - object which will be called when obj is garbage collected. The - first time the finalizer is called it evaluates func(*arg, **kwargs) - and returns the result. After this the finalizer is dead, and - calling it just returns None. - - When the program exits any remaining finalizers for which the - atexit attribute is true will be run in reverse order of creation. - By default atexit is true. - """ - - # Finalizer objects don't have any state of their own. They are - # just used as keys to lookup _Info objects in the registry. This - # ensures that they cannot be part of a ref-cycle. - - __slots__ = () - _registry = {} - _shutdown = False - _index_iter = itertools.count() - _dirty = False - - class _Info: - __slots__ = ("weakref", "func", "args", "kwargs", "atexit", "index") - - def __init__(self, obj, func, *args, **kwargs): - info = self._Info() - info.weakref = ref(obj, self) - info.func = func - info.args = args - info.kwargs = kwargs or None - info.atexit = True - info.index = next(self._index_iter) - self._registry[self] = info - finalize._dirty = True - - def __call__(self, _=None): - """If alive then mark as dead and return func(*args, **kwargs); - otherwise return None""" - info = self._registry.pop(self, None) - if info and not self._shutdown: - return info.func(*info.args, **(info.kwargs or {})) - - def detach(self): - """If alive then mark as dead and return (obj, func, args, kwargs); - otherwise return None""" - info = self._registry.get(self) - obj = info and info.weakref() - if obj is not None and self._registry.pop(self, None): - return (obj, info.func, info.args, info.kwargs or {}) - - def peek(self): - """If alive then return (obj, func, args, kwargs); - otherwise return None""" - info = self._registry.get(self) - obj = info and info.weakref() - if obj is not None: - return (obj, info.func, info.args, info.kwargs or {}) - - @property - def alive(self): - """Whether finalizer is alive""" - return self in self._registry - - @property - def atexit(self): - """Whether finalizer should be called at exit""" - info = self._registry.get(self) - return bool(info) and info.atexit - - @atexit.setter - def atexit(self, value): - info = self._registry.get(self) - if info: - info.atexit = bool(value) - - def __repr__(self): - info = self._registry.get(self) - obj = info and info.weakref() - if obj is None: - return '<%s object at %#x; dead>' % (type(self).__name__, id(self)) - else: - return '<%s object at %#x; for %r at %#x>' % \ - (type(self).__name__, id(self), type(obj).__name__, id(obj)) - - @classmethod - def _select_for_exit(cls): - # Return live finalizers marked for exit, oldest first - L = [(f,i) for (f,i) in cls._registry.items() if i.atexit] - L.sort(key=lambda item:item[1].index) - return [f for (f,i) in L] - - @classmethod - def _exitfunc(cls): - # At shutdown invoke finalizers for which atexit is true. - # This is called once all other non-daemonic threads have been - # joined. - reenable_gc = False - try: - if cls._registry: - import gc - if gc.isenabled(): - reenable_gc = True - gc.disable() - pending = None - while True: - if pending is None or finalize._dirty: - pending = cls._select_for_exit() - finalize._dirty = False - if not pending: - break - f = pending.pop() - try: - # gc is disabled, so (assuming no daemonic - # threads) the following is the only line in - # this function which might trigger creation - # of a new finalizer - f() - except Exception: - sys.excepthook(*sys.exc_info()) - assert f not in cls._registry - finally: - # prevent any more finalizers from executing during shutdown - finalize._shutdown = True - if reenable_gc: - gc.enable() - -atexit.register(finalize._exitfunc) |