blob: 4c0b26e15abd64321f245d826a3f830483d0c7fb [file] [log] [blame]
Fred Drake41deb1e2001-02-01 05:27:45 +00001"""Weak reference support for Python.
2
3This module is an implementation of PEP 205:
4
Christian Heimes81ee3ef2008-05-04 22:42:01 +00005http://www.python.org/dev/peps/pep-0205/
Fred Drake41deb1e2001-02-01 05:27:45 +00006"""
7
Fred Drakebd7f8182001-04-19 16:26:06 +00008# Naming convention: Variables named "wr" are weak reference objects;
9# they are called this instead of "ref" to avoid name collisions with
10# the module-global ref() function imported from _weakref.
11
Andrew M. Kuchling33ad28b2004-08-31 11:38:12 +000012from _weakref import (
13 getweakrefcount,
14 getweakrefs,
15 ref,
16 proxy,
17 CallableProxyType,
18 ProxyType,
19 ReferenceType)
Fred Drake41deb1e2001-02-01 05:27:45 +000020
Antoine Pitrouc1baa602010-01-08 17:54:23 +000021from _weakrefset import WeakSet, _IterationGuard
Fred Drakee0292422001-10-05 21:54:09 +000022
Brett Cannon663fffa2009-03-25 23:31:22 +000023import collections # Import after _weakref to avoid circular import.
Richard Oudkerk7a3dae052013-05-05 23:05:00 +010024import sys
25import itertools
26import atexit
Brett Cannon663fffa2009-03-25 23:31:22 +000027
Fred Drake41deb1e2001-02-01 05:27:45 +000028ProxyTypes = (ProxyType, CallableProxyType)
29
Fred Drake9a9d2192001-04-10 19:11:23 +000030__all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
Gregory P. Smith7d10c2b2008-08-18 03:41:46 +000031 "WeakKeyDictionary", "ReferenceType", "ProxyType",
Raymond Hettinger93fa6082008-02-05 00:20:01 +000032 "CallableProxyType", "ProxyTypes", "WeakValueDictionary",
Richard Oudkerk7a3dae052013-05-05 23:05:00 +010033 "WeakSet", "WeakMethod", "finalize"]
Antoine Pitrouc3afba12012-11-17 18:57:38 +010034
35
36class WeakMethod(ref):
37 """
38 A custom `weakref.ref` subclass which simulates a weak reference to
39 a bound method, working around the lifetime problem of bound methods.
40 """
41
42 __slots__ = "_func_ref", "_meth_type", "_alive", "__weakref__"
43
44 def __new__(cls, meth, callback=None):
45 try:
46 obj = meth.__self__
47 func = meth.__func__
48 except AttributeError:
49 raise TypeError("argument should be a bound method, not {}"
50 .format(type(meth))) from None
51 def _cb(arg):
52 # The self-weakref trick is needed to avoid creating a reference
53 # cycle.
54 self = self_wr()
55 if self._alive:
56 self._alive = False
57 if callback is not None:
58 callback(self)
59 self = ref.__new__(cls, obj, _cb)
60 self._func_ref = ref(func, _cb)
61 self._meth_type = type(meth)
62 self._alive = True
63 self_wr = ref(self)
64 return self
65
66 def __call__(self):
67 obj = super().__call__()
68 func = self._func_ref()
69 if obj is None or func is None:
70 return None
71 return self._meth_type(func, obj)
72
73 def __eq__(self, other):
74 if isinstance(other, WeakMethod):
75 if not self._alive or not other._alive:
76 return self is other
77 return ref.__eq__(self, other) and self._func_ref == other._func_ref
78 return False
79
80 def __ne__(self, other):
81 if isinstance(other, WeakMethod):
82 if not self._alive or not other._alive:
83 return self is not other
84 return ref.__ne__(self, other) or self._func_ref != other._func_ref
85 return True
86
87 __hash__ = ref.__hash__
Fred Drake41deb1e2001-02-01 05:27:45 +000088
Fred Drake41deb1e2001-02-01 05:27:45 +000089
Raymond Hettinger7ac60952008-02-05 01:15:57 +000090class WeakValueDictionary(collections.MutableMapping):
Fred Drakebd7f8182001-04-19 16:26:06 +000091 """Mapping class that references values weakly.
92
93 Entries in the dictionary will be discarded when no strong
94 reference to the value exists anymore
95 """
Fred Drake41deb1e2001-02-01 05:27:45 +000096 # We inherit the constructor without worrying about the input
97 # dictionary; since it uses our .update() method, we get the right
Fred Drake9d2c85d2001-03-01 03:06:03 +000098 # checks (if the other dictionary is a WeakValueDictionary,
99 # objects are unwrapped on the way out, and we always wrap on the
100 # way in).
Fred Drake41deb1e2001-02-01 05:27:45 +0000101
Fred Drake0a4dd392004-07-02 18:57:45 +0000102 def __init__(self, *args, **kw):
Fred Drake0a4dd392004-07-02 18:57:45 +0000103 def remove(wr, selfref=ref(self)):
104 self = selfref()
105 if self is not None:
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000106 if self._iterating:
107 self._pending_removals.append(wr.key)
108 else:
109 del self.data[wr.key]
Fred Drake0a4dd392004-07-02 18:57:45 +0000110 self._remove = remove
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000111 # A list of keys to be removed
112 self._pending_removals = []
113 self._iterating = set()
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000114 self.data = d = {}
Antoine Pitrouc06de472009-05-30 21:04:26 +0000115 self.update(*args, **kw)
Fred Drake0a4dd392004-07-02 18:57:45 +0000116
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000117 def _commit_removals(self):
118 l = self._pending_removals
119 d = self.data
120 # We shouldn't encounter any KeyError, because this method should
121 # always be called *before* mutating the dict.
122 while l:
123 del d[l.pop()]
124
Fred Drake41deb1e2001-02-01 05:27:45 +0000125 def __getitem__(self, key):
Fred Drake4fd06e02001-08-03 04:11:27 +0000126 o = self.data[key]()
Fred Drake41deb1e2001-02-01 05:27:45 +0000127 if o is None:
Collin Winterce36ad82007-08-30 01:19:48 +0000128 raise KeyError(key)
Fred Drake41deb1e2001-02-01 05:27:45 +0000129 else:
130 return o
131
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000132 def __delitem__(self, key):
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000133 if self._pending_removals:
134 self._commit_removals()
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000135 del self.data[key]
136
137 def __len__(self):
Antoine Pitroubbe2f602012-03-01 16:26:35 +0100138 return len(self.data) - len(self._pending_removals)
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000139
Raymond Hettinger61146792004-08-19 21:32:06 +0000140 def __contains__(self, key):
141 try:
142 o = self.data[key]()
143 except KeyError:
144 return False
145 return o is not None
146
Fred Drake41deb1e2001-02-01 05:27:45 +0000147 def __repr__(self):
Fred Drake9d2c85d2001-03-01 03:06:03 +0000148 return "<WeakValueDictionary at %s>" % id(self)
Fred Drake41deb1e2001-02-01 05:27:45 +0000149
150 def __setitem__(self, key, value):
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000151 if self._pending_removals:
152 self._commit_removals()
Fred Drake0a4dd392004-07-02 18:57:45 +0000153 self.data[key] = KeyedRef(value, self._remove, key)
Fred Drake41deb1e2001-02-01 05:27:45 +0000154
155 def copy(self):
Fred Drake9d2c85d2001-03-01 03:06:03 +0000156 new = WeakValueDictionary()
Fred Drakebd7f8182001-04-19 16:26:06 +0000157 for key, wr in self.data.items():
158 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +0000159 if o is not None:
160 new[key] = o
Fred Drake9d2c85d2001-03-01 03:06:03 +0000161 return new
Fred Drake41deb1e2001-02-01 05:27:45 +0000162
Antoine Pitrou6e610062009-05-15 17:04:50 +0000163 __copy__ = copy
164
165 def __deepcopy__(self, memo):
166 from copy import deepcopy
167 new = self.__class__()
168 for key, wr in self.data.items():
169 o = wr()
170 if o is not None:
171 new[deepcopy(key, memo)] = o
172 return new
173
Fred Drake1d9e4b72001-04-16 17:34:48 +0000174 def get(self, key, default=None):
Fred Drake41deb1e2001-02-01 05:27:45 +0000175 try:
Fred Drakebd7f8182001-04-19 16:26:06 +0000176 wr = self.data[key]
Fred Drake41deb1e2001-02-01 05:27:45 +0000177 except KeyError:
178 return default
179 else:
Fred Drakebd7f8182001-04-19 16:26:06 +0000180 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +0000181 if o is None:
182 # This should only happen
183 return default
184 else:
185 return o
186
187 def items(self):
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000188 with _IterationGuard(self):
189 for k, wr in self.data.items():
190 v = wr()
191 if v is not None:
192 yield k, v
Fred Drake101209d2001-05-02 05:43:09 +0000193
Barry Warsawecaab832008-09-04 01:42:51 +0000194 def keys(self):
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000195 with _IterationGuard(self):
196 for k, wr in self.data.items():
197 if wr() is not None:
198 yield k
Raymond Hettinger61146792004-08-19 21:32:06 +0000199
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000200 __iter__ = keys
Fred Drake101209d2001-05-02 05:43:09 +0000201
Thomas Wouters477c8d52006-05-27 19:21:47 +0000202 def itervaluerefs(self):
203 """Return an iterator that yields the weak references to the values.
204
205 The references are not guaranteed to be 'live' at the time
206 they are used, so the result of calling the references needs
207 to be checked before being used. This can be used to avoid
208 creating references that will cause the garbage collector to
209 keep the values around longer than needed.
210
211 """
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000212 with _IterationGuard(self):
Philip Jenvey4993cc02012-10-01 12:53:43 -0700213 yield from self.data.values()
Thomas Wouters477c8d52006-05-27 19:21:47 +0000214
Barry Warsawecaab832008-09-04 01:42:51 +0000215 def values(self):
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000216 with _IterationGuard(self):
217 for wr in self.data.values():
218 obj = wr()
219 if obj is not None:
220 yield obj
Fred Drake101209d2001-05-02 05:43:09 +0000221
Fred Drake41deb1e2001-02-01 05:27:45 +0000222 def popitem(self):
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000223 if self._pending_removals:
224 self._commit_removals()
Georg Brandlbd87d082010-12-03 07:49:09 +0000225 while True:
Fred Drakebd7f8182001-04-19 16:26:06 +0000226 key, wr = self.data.popitem()
227 o = wr()
Fred Drake41deb1e2001-02-01 05:27:45 +0000228 if o is not None:
229 return key, o
230
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000231 def pop(self, key, *args):
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000232 if self._pending_removals:
233 self._commit_removals()
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000234 try:
235 o = self.data.pop(key)()
236 except KeyError:
237 if args:
238 return args[0]
239 raise
240 if o is None:
Collin Winterce36ad82007-08-30 01:19:48 +0000241 raise KeyError(key)
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000242 else:
243 return o
244
Walter Dörwald80ce6dd2004-05-27 18:16:25 +0000245 def setdefault(self, key, default=None):
Fred Drake41deb1e2001-02-01 05:27:45 +0000246 try:
Fred Drakebd7f8182001-04-19 16:26:06 +0000247 wr = self.data[key]
Fred Drake41deb1e2001-02-01 05:27:45 +0000248 except KeyError:
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000249 if self._pending_removals:
250 self._commit_removals()
Fred Drake0a4dd392004-07-02 18:57:45 +0000251 self.data[key] = KeyedRef(default, self._remove, key)
Fred Drake41deb1e2001-02-01 05:27:45 +0000252 return default
253 else:
Fred Drakebd7f8182001-04-19 16:26:06 +0000254 return wr()
Fred Drake41deb1e2001-02-01 05:27:45 +0000255
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000256 def update(self, dict=None, **kwargs):
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000257 if self._pending_removals:
258 self._commit_removals()
Fred Drake41deb1e2001-02-01 05:27:45 +0000259 d = self.data
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000260 if dict is not None:
261 if not hasattr(dict, "items"):
262 dict = type({})(dict)
263 for key, o in dict.items():
Fred Drake0a4dd392004-07-02 18:57:45 +0000264 d[key] = KeyedRef(o, self._remove, key)
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000265 if len(kwargs):
266 self.update(kwargs)
Fred Drake41deb1e2001-02-01 05:27:45 +0000267
Thomas Wouters477c8d52006-05-27 19:21:47 +0000268 def valuerefs(self):
269 """Return a list of weak references to the values.
270
271 The references are not guaranteed to be 'live' at the time
272 they are used, so the result of calling the references needs
273 to be checked before being used. This can be used to avoid
274 creating references that will cause the garbage collector to
275 keep the values around longer than needed.
276
277 """
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000278 return list(self.data.values())
Thomas Wouters477c8d52006-05-27 19:21:47 +0000279
Fred Drake0a4dd392004-07-02 18:57:45 +0000280
281class KeyedRef(ref):
282 """Specialized reference that includes a key corresponding to the value.
283
284 This is used in the WeakValueDictionary to avoid having to create
285 a function object for each key stored in the mapping. A shared
286 callback object can use the 'key' attribute of a KeyedRef instead
287 of getting a reference to the key from an enclosing scope.
288
289 """
290
291 __slots__ = "key",
292
293 def __new__(type, ob, callback, key):
294 self = ref.__new__(type, ob, callback)
295 self.key = key
296 return self
297
298 def __init__(self, ob, callback, key):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000299 super().__init__(ob, callback)
Fred Drake746fe0f2001-09-28 19:01:26 +0000300
Fred Drake41deb1e2001-02-01 05:27:45 +0000301
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000302class WeakKeyDictionary(collections.MutableMapping):
Fred Drakebd7f8182001-04-19 16:26:06 +0000303 """ Mapping class that references keys weakly.
304
305 Entries in the dictionary will be discarded when there is no
306 longer a strong reference to the key. This can be used to
307 associate additional data with an object owned by other parts of
308 an application without adding attributes to those objects. This
309 can be especially useful with objects that override attribute
310 accesses.
311 """
Martin v. Löwis5e163332001-02-27 18:36:56 +0000312
313 def __init__(self, dict=None):
314 self.data = {}
Fred Drake746fe0f2001-09-28 19:01:26 +0000315 def remove(k, selfref=ref(self)):
316 self = selfref()
317 if self is not None:
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000318 if self._iterating:
319 self._pending_removals.append(k)
320 else:
321 del self.data[k]
Martin v. Löwis5e163332001-02-27 18:36:56 +0000322 self._remove = remove
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000323 # A list of dead weakrefs (keys to be removed)
324 self._pending_removals = []
325 self._iterating = set()
326 if dict is not None:
327 self.update(dict)
328
329 def _commit_removals(self):
330 # NOTE: We don't need to call this method before mutating the dict,
331 # because a dead weakref never compares equal to a live weakref,
332 # even if they happened to refer to equal objects.
333 # However, it means keys may already have been removed.
334 l = self._pending_removals
335 d = self.data
336 while l:
337 try:
338 del d[l.pop()]
339 except KeyError:
340 pass
Martin v. Löwis5e163332001-02-27 18:36:56 +0000341
Fred Drakeb663a2c2001-09-06 14:51:01 +0000342 def __delitem__(self, key):
Tim Peters886128f2003-05-25 01:45:11 +0000343 del self.data[ref(key)]
Fred Drakeb663a2c2001-09-06 14:51:01 +0000344
Martin v. Löwis5e163332001-02-27 18:36:56 +0000345 def __getitem__(self, key):
346 return self.data[ref(key)]
347
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000348 def __len__(self):
Antoine Pitroubbe2f602012-03-01 16:26:35 +0100349 return len(self.data) - len(self._pending_removals)
Raymond Hettinger7ac60952008-02-05 01:15:57 +0000350
Martin v. Löwis5e163332001-02-27 18:36:56 +0000351 def __repr__(self):
352 return "<WeakKeyDictionary at %s>" % id(self)
353
354 def __setitem__(self, key, value):
355 self.data[ref(key, self._remove)] = value
356
357 def copy(self):
358 new = WeakKeyDictionary()
359 for key, value in self.data.items():
360 o = key()
361 if o is not None:
362 new[o] = value
Fred Drake9d2c85d2001-03-01 03:06:03 +0000363 return new
Martin v. Löwis5e163332001-02-27 18:36:56 +0000364
Antoine Pitrou6e610062009-05-15 17:04:50 +0000365 __copy__ = copy
366
367 def __deepcopy__(self, memo):
368 from copy import deepcopy
369 new = self.__class__()
370 for key, value in self.data.items():
371 o = key()
372 if o is not None:
373 new[o] = deepcopy(value, memo)
374 return new
375
Fred Drake1d9e4b72001-04-16 17:34:48 +0000376 def get(self, key, default=None):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000377 return self.data.get(ref(key),default)
378
Raymond Hettinger54f02222002-06-01 14:18:47 +0000379 def __contains__(self, key):
380 try:
381 wr = ref(key)
382 except TypeError:
Georg Brandlbd87d082010-12-03 07:49:09 +0000383 return False
Raymond Hettinger54f02222002-06-01 14:18:47 +0000384 return wr in self.data
Tim Petersc411dba2002-07-16 21:35:23 +0000385
Martin v. Löwis5e163332001-02-27 18:36:56 +0000386 def items(self):
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000387 with _IterationGuard(self):
388 for wr, value in self.data.items():
389 key = wr()
390 if key is not None:
391 yield key, value
Thomas Wouters477c8d52006-05-27 19:21:47 +0000392
Barry Warsawecaab832008-09-04 01:42:51 +0000393 def keys(self):
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000394 with _IterationGuard(self):
395 for wr in self.data:
396 obj = wr()
397 if obj is not None:
398 yield obj
Raymond Hettinger61146792004-08-19 21:32:06 +0000399
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000400 __iter__ = keys
Fred Drake101209d2001-05-02 05:43:09 +0000401
Barry Warsawecaab832008-09-04 01:42:51 +0000402 def values(self):
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000403 with _IterationGuard(self):
404 for wr, value in self.data.items():
405 if wr() is not None:
406 yield value
Fred Drake101209d2001-05-02 05:43:09 +0000407
Thomas Wouters477c8d52006-05-27 19:21:47 +0000408 def keyrefs(self):
409 """Return a list of weak references to the keys.
410
411 The references are not guaranteed to be 'live' at the time
412 they are used, so the result of calling the references needs
413 to be checked before being used. This can be used to avoid
414 creating references that will cause the garbage collector to
415 keep the keys around longer than needed.
416
417 """
Antoine Pitrouc1baa602010-01-08 17:54:23 +0000418 return list(self.data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000419
Martin v. Löwis5e163332001-02-27 18:36:56 +0000420 def popitem(self):
Georg Brandlbd87d082010-12-03 07:49:09 +0000421 while True:
Martin v. Löwis5e163332001-02-27 18:36:56 +0000422 key, value = self.data.popitem()
423 o = key()
424 if o is not None:
425 return o, value
426
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000427 def pop(self, key, *args):
428 return self.data.pop(ref(key), *args)
429
Walter Dörwald80ce6dd2004-05-27 18:16:25 +0000430 def setdefault(self, key, default=None):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000431 return self.data.setdefault(ref(key, self._remove),default)
432
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000433 def update(self, dict=None, **kwargs):
Martin v. Löwis5e163332001-02-27 18:36:56 +0000434 d = self.data
Raymond Hettinger31017ae2004-03-04 08:25:44 +0000435 if dict is not None:
436 if not hasattr(dict, "items"):
437 dict = type({})(dict)
438 for key, value in dict.items():
439 d[ref(key, self._remove)] = value
440 if len(kwargs):
441 self.update(kwargs)
Richard Oudkerk7a3dae052013-05-05 23:05:00 +0100442
443
444class finalize:
445 """Class for finalization of weakrefable objects
446
447 finalize(obj, func, *args, **kwargs) returns a callable finalizer
448 object which will be called when obj is garbage collected. The
449 first time the finalizer is called it evaluates func(*arg, **kwargs)
450 and returns the result. After this the finalizer is dead, and
451 calling it just returns None.
452
453 When the program exits any remaining finalizers for which the
454 atexit attribute is true will be run in reverse order of creation.
455 By default atexit is true.
456 """
457
458 # Finalizer objects don't have any state of their own. They are
459 # just used as keys to lookup _Info objects in the registry. This
460 # ensures that they cannot be part of a ref-cycle.
461
462 __slots__ = ()
463 _registry = {}
464 _shutdown = False
465 _index_iter = itertools.count()
466 _dirty = False
467
468 class _Info:
469 __slots__ = ("weakref", "func", "args", "kwargs", "atexit", "index")
470
471 def __init__(self, obj, func, *args, **kwargs):
472 info = self._Info()
473 info.weakref = ref(obj, self)
474 info.func = func
475 info.args = args
476 info.kwargs = kwargs or None
477 info.atexit = True
478 info.index = next(self._index_iter)
479 self._registry[self] = info
480 finalize._dirty = True
481
482 def __call__(self, _=None):
483 """If alive then mark as dead and return func(*args, **kwargs);
484 otherwise return None"""
485 info = self._registry.pop(self, None)
486 if info and not self._shutdown:
487 return info.func(*info.args, **(info.kwargs or {}))
488
489 def detach(self):
490 """If alive then mark as dead and return (obj, func, args, kwargs);
491 otherwise return None"""
492 info = self._registry.get(self)
493 obj = info and info.weakref()
494 if obj is not None and self._registry.pop(self, None):
495 return (obj, info.func, info.args, info.kwargs or {})
496
497 def peek(self):
498 """If alive then return (obj, func, args, kwargs);
499 otherwise return None"""
500 info = self._registry.get(self)
501 obj = info and info.weakref()
502 if obj is not None:
503 return (obj, info.func, info.args, info.kwargs or {})
504
505 @property
506 def alive(self):
507 """Whether finalizer is alive"""
508 return self in self._registry
509
510 @property
511 def atexit(self):
512 """Whether finalizer should be called at exit"""
513 info = self._registry.get(self)
514 return bool(info) and info.atexit
515
516 @atexit.setter
517 def atexit(self, value):
518 info = self._registry.get(self)
519 if info:
520 info.atexit = bool(value)
521
522 def __repr__(self):
523 info = self._registry.get(self)
524 obj = info and info.weakref()
525 if obj is None:
526 return '<%s object at %#x; dead>' % (type(self).__name__, id(self))
527 else:
528 return '<%s object at %#x; for %r at %#x>' % \
529 (type(self).__name__, id(self), type(obj).__name__, id(obj))
530
531 @classmethod
532 def _select_for_exit(cls):
533 # Return live finalizers marked for exit, oldest first
534 L = [(f,i) for (f,i) in cls._registry.items() if i.atexit]
535 L.sort(key=lambda item:item[1].index)
536 return [f for (f,i) in L]
537
538 @classmethod
539 def _exitfunc(cls):
540 # At shutdown invoke finalizers for which atexit is true.
541 # This is called once all other non-daemonic threads have been
542 # joined.
543 reenable_gc = False
544 try:
545 if cls._registry:
546 import gc
547 if gc.isenabled():
548 reenable_gc = True
549 gc.disable()
550 pending = None
551 while True:
552 if pending is None or finalize._dirty:
553 pending = cls._select_for_exit()
554 finalize._dirty = False
555 if not pending:
556 break
557 f = pending.pop()
558 try:
559 # gc is disabled, so (assuming no daemonic
560 # threads) the following is the only line in
561 # this function which might trigger creation
562 # of a new finalizer
563 f()
564 except Exception:
565 sys.excepthook(*sys.exc_info())
566 assert f not in cls._registry
567 finally:
568 # prevent any more finalizers from executing during shutdown
569 finalize._shutdown = True
570 if reenable_gc:
571 gc.enable()
572
573atexit.register(finalize._exitfunc)