annotate Lib/weakref.py @ 87690:66c1c9f32567 default tip

Add use_weakref option to functools.lru_cache The use_weakref option makes lru_cache create weak references to the function arguments when creating the cache key, which prevents them from staying in the memory forever even after all other references to them are gone. This is a proof of concept for http://bugs.python.org/issue19859
author Radomir Dopieralski <devel@sheep.art.pl>
date Tue, 03 Dec 2013 16:02:48 +0100
parents d6ad9d7468f7
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
1 """Weak reference support for Python.
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
2
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
3 This module is an implementation of PEP 205:
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
4
46664
031dfe455585 Merged revisions 62425-62429,62434-62436,62441,62444,62446-62448,62450-62455,62463,62465-62466,62469,62474,62476-62478,62480,62485,62492,62497-62498,62500,62507,62513-62514,62516,62521,62531,62535,62545-62546,62548-62551,62553-62559,62569,62574,62577,62593,62595,62604-62606,62608,62616,62626-62627,62636,62638,62644-62645,62647-62648,62651-62653,62656,62661,62663,62680,62686-62687,62696,62699-62703,62711 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 45284
diff changeset
5 http://www.python.org/dev/peps/pep-0205/
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
6 """
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
7
17591
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
8 # Naming convention: Variables named "wr" are weak reference objects;
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
9 # they are called this instead of "ref" to avoid name collisions with
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
10 # the module-global ref() function imported from _weakref.
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
11
33356
e56192e9fd7e Use multi-line import
Andrew M. Kuchling <amk@amk.ca>
parents: 33197
diff changeset
12 from _weakref import (
e56192e9fd7e Use multi-line import
Andrew M. Kuchling <amk@amk.ca>
parents: 33197
diff changeset
13 getweakrefcount,
e56192e9fd7e Use multi-line import
Andrew M. Kuchling <amk@amk.ca>
parents: 33197
diff changeset
14 getweakrefs,
e56192e9fd7e Use multi-line import
Andrew M. Kuchling <amk@amk.ca>
parents: 33197
diff changeset
15 ref,
e56192e9fd7e Use multi-line import
Andrew M. Kuchling <amk@amk.ca>
parents: 33197
diff changeset
16 proxy,
e56192e9fd7e Use multi-line import
Andrew M. Kuchling <amk@amk.ca>
parents: 33197
diff changeset
17 CallableProxyType,
e56192e9fd7e Use multi-line import
Andrew M. Kuchling <amk@amk.ca>
parents: 33197
diff changeset
18 ProxyType,
e56192e9fd7e Use multi-line import
Andrew M. Kuchling <amk@amk.ca>
parents: 33197
diff changeset
19 ReferenceType)
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
20
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
21 from _weakrefset import WeakSet, _IterationGuard
20281
380d4b4ee602 ReferenceError is now built-in, so pick it up from the right place.
Fred Drake <fdrake@acm.org>
parents: 20155
diff changeset
22
52338
8b5a80f53317 Fix a circular import dependency.
Brett Cannon <bcannon@gmail.com>
parents: 49001
diff changeset
23 import collections # Import after _weakref to avoid circular import.
83631
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
24 import sys
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
25 import itertools
52338
8b5a80f53317 Fix a circular import dependency.
Brett Cannon <bcannon@gmail.com>
parents: 49001
diff changeset
26
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
27 ProxyTypes = (ProxyType, CallableProxyType)
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
28
17386
bbcc9837312e mapping(): Remove this function since it does not add anything to the API.
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
29 __all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
48739
3195bd6b6dd7 ReferenceError is undefined. causes test___all__.py to fail. remove it from __all__
Gregory P. Smith <greg@mad-scientist.com>
parents: 48733
diff changeset
30 "WeakKeyDictionary", "ReferenceType", "ProxyType",
45159
e6069b24031e Moved WeakSet into a bootstap module use by abc.py.
Raymond Hettinger <python@rcn.com>
parents: 43644
diff changeset
31 "CallableProxyType", "ProxyTypes", "WeakValueDictionary",
83631
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
32 "WeakSet", "WeakMethod", "finalize"]
80476
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
33
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
34
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
35 class WeakMethod(ref):
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
36 """
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
37 A custom `weakref.ref` subclass which simulates a weak reference to
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
38 a bound method, working around the lifetime problem of bound methods.
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
39 """
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
40
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
41 __slots__ = "_func_ref", "_meth_type", "_alive", "__weakref__"
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
42
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
43 def __new__(cls, meth, callback=None):
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
44 try:
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
45 obj = meth.__self__
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
46 func = meth.__func__
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
47 except AttributeError:
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
48 raise TypeError("argument should be a bound method, not {}"
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
49 .format(type(meth))) from None
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
50 def _cb(arg):
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
51 # The self-weakref trick is needed to avoid creating a reference
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
52 # cycle.
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
53 self = self_wr()
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
54 if self._alive:
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
55 self._alive = False
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
56 if callback is not None:
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
57 callback(self)
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
58 self = ref.__new__(cls, obj, _cb)
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
59 self._func_ref = ref(func, _cb)
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
60 self._meth_type = type(meth)
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
61 self._alive = True
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
62 self_wr = ref(self)
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
63 return self
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
64
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
65 def __call__(self):
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
66 obj = super().__call__()
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
67 func = self._func_ref()
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
68 if obj is None or func is None:
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
69 return None
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
70 return self._meth_type(func, obj)
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
71
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
72 def __eq__(self, other):
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
73 if isinstance(other, WeakMethod):
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
74 if not self._alive or not other._alive:
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
75 return self is other
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
76 return ref.__eq__(self, other) and self._func_ref == other._func_ref
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
77 return False
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
78
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
79 def __ne__(self, other):
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
80 if isinstance(other, WeakMethod):
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
81 if not self._alive or not other._alive:
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
82 return self is not other
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
83 return ref.__ne__(self, other) or self._func_ref != other._func_ref
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
84 return True
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
85
27c20650aeab Issue #14631: Add a new :class:`weakref.WeakMethod` to simulate weak references to bound methods.
Antoine Pitrou <solipsis@pitrou.net>
parents: 79378
diff changeset
86 __hash__ = ref.__hash__
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
87
17591
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
88
45161
bdf7486893ba Decouple weakref containers from UserDict
Raymond Hettinger <python@rcn.com>
parents: 45159
diff changeset
89 class WeakValueDictionary(collections.MutableMapping):
17591
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
90 """Mapping class that references values weakly.
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
91
17591
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
92 Entries in the dictionary will be discarded when no strong
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
93 reference to the value exists anymore
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
94 """
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
95 # We inherit the constructor without worrying about the input
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
96 # dictionary; since it uses our .update() method, we get the right
16884
1ce751fa67d8 Change WeakDictionary to WeakValueDictionary in a couple more places.
Fred Drake <fdrake@acm.org>
parents: 16794
diff changeset
97 # checks (if the other dictionary is a WeakValueDictionary,
1ce751fa67d8 Change WeakDictionary to WeakValueDictionary in a couple more places.
Fred Drake <fdrake@acm.org>
parents: 16794
diff changeset
98 # objects are unwrapped on the way out, and we always wrap on the
1ce751fa67d8 Change WeakDictionary to WeakValueDictionary in a couple more places.
Fred Drake <fdrake@acm.org>
parents: 16794
diff changeset
99 # way in).
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
100
32472
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
101 def __init__(self, *args, **kw):
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
102 def remove(wr, selfref=ref(self)):
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
103 self = selfref()
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
104 if self is not None:
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
105 if self._iterating:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
106 self._pending_removals.append(wr.key)
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
107 else:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
108 del self.data[wr.key]
32472
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
109 self._remove = remove
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
110 # A list of keys to be removed
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
111 self._pending_removals = []
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
112 self._iterating = set()
45161
bdf7486893ba Decouple weakref containers from UserDict
Raymond Hettinger <python@rcn.com>
parents: 45159
diff changeset
113 self.data = d = {}
54456
49485f98a308 Issue #6149: Fix initialization of WeakValueDictionary objects from non-empty parameters.
Antoine Pitrou <solipsis@pitrou.net>
parents: 54100
diff changeset
114 self.update(*args, **kw)
32472
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
115
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
116 def _commit_removals(self):
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
117 l = self._pending_removals
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
118 d = self.data
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
119 # We shouldn't encounter any KeyError, because this method should
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
120 # always be called *before* mutating the dict.
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
121 while l:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
122 del d[l.pop()]
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
123
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
124 def __getitem__(self, key):
18952
e90a658a58d4 Make sure that WeakValueDictionary[] raises KeyError instead of TypeError
Fred Drake <fdrake@acm.org>
parents: 17650
diff changeset
125 o = self.data[key]()
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
126 if o is None:
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 42084
diff changeset
127 raise KeyError(key)
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
128 else:
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
129 return o
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
130
45161
bdf7486893ba Decouple weakref containers from UserDict
Raymond Hettinger <python@rcn.com>
parents: 45159
diff changeset
131 def __delitem__(self, key):
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
132 if self._pending_removals:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
133 self._commit_removals()
45161
bdf7486893ba Decouple weakref containers from UserDict
Raymond Hettinger <python@rcn.com>
parents: 45159
diff changeset
134 del self.data[key]
bdf7486893ba Decouple weakref containers from UserDict
Raymond Hettinger <python@rcn.com>
parents: 45159
diff changeset
135
bdf7486893ba Decouple weakref containers from UserDict
Raymond Hettinger <python@rcn.com>
parents: 45159
diff changeset
136 def __len__(self):
75356
1cd0688ff004 Issue #14159: Fix the len() of weak containers (WeakSet, WeakKeyDictionary, WeakValueDictionary) to return a better approximation when some objects are dead or dying.
Antoine Pitrou <solipsis@pitrou.net>
parents: 66629
diff changeset
137 return len(self.data) - len(self._pending_removals)
45161
bdf7486893ba Decouple weakref containers from UserDict
Raymond Hettinger <python@rcn.com>
parents: 45159
diff changeset
138
33197
7da9201bc8b5 SF bug #1012315: weakref.WeakValueDictionary should override .has_key()
Raymond Hettinger <python@rcn.com>
parents: 33117
diff changeset
139 def __contains__(self, key):
7da9201bc8b5 SF bug #1012315: weakref.WeakValueDictionary should override .has_key()
Raymond Hettinger <python@rcn.com>
parents: 33117
diff changeset
140 try:
7da9201bc8b5 SF bug #1012315: weakref.WeakValueDictionary should override .has_key()
Raymond Hettinger <python@rcn.com>
parents: 33117
diff changeset
141 o = self.data[key]()
7da9201bc8b5 SF bug #1012315: weakref.WeakValueDictionary should override .has_key()
Raymond Hettinger <python@rcn.com>
parents: 33117
diff changeset
142 except KeyError:
7da9201bc8b5 SF bug #1012315: weakref.WeakValueDictionary should override .has_key()
Raymond Hettinger <python@rcn.com>
parents: 33117
diff changeset
143 return False
7da9201bc8b5 SF bug #1012315: weakref.WeakValueDictionary should override .has_key()
Raymond Hettinger <python@rcn.com>
parents: 33117
diff changeset
144 return o is not None
7da9201bc8b5 SF bug #1012315: weakref.WeakValueDictionary should override .has_key()
Raymond Hettinger <python@rcn.com>
parents: 33117
diff changeset
145
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
146 def __repr__(self):
16884
1ce751fa67d8 Change WeakDictionary to WeakValueDictionary in a couple more places.
Fred Drake <fdrake@acm.org>
parents: 16794
diff changeset
147 return "<WeakValueDictionary at %s>" % id(self)
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
148
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
149 def __setitem__(self, key, value):
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
150 if self._pending_removals:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
151 self._commit_removals()
32472
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
152 self.data[key] = KeyedRef(value, self._remove, key)
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
153
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
154 def copy(self):
16884
1ce751fa67d8 Change WeakDictionary to WeakValueDictionary in a couple more places.
Fred Drake <fdrake@acm.org>
parents: 16794
diff changeset
155 new = WeakValueDictionary()
17591
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
156 for key, wr in self.data.items():
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
157 o = wr()
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
158 if o is not None:
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
159 new[key] = o
16884
1ce751fa67d8 Change WeakDictionary to WeakValueDictionary in a couple more places.
Fred Drake <fdrake@acm.org>
parents: 16794
diff changeset
160 return new
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
161
54100
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
162 __copy__ = copy
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
163
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
164 def __deepcopy__(self, memo):
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
165 from copy import deepcopy
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
166 new = self.__class__()
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
167 for key, wr in self.data.items():
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
168 o = wr()
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
169 if o is not None:
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
170 new[deepcopy(key, memo)] = o
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
171 return new
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
172
17546
da5eab33147b Weak*Dictionary.update(): Fix calls to [].append() to only have one
Fred Drake <fdrake@acm.org>
parents: 17386
diff changeset
173 def get(self, key, default=None):
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
174 try:
17591
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
175 wr = self.data[key]
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
176 except KeyError:
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
177 return default
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
178 else:
17591
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
179 o = wr()
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
180 if o is None:
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
181 # This should only happen
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
182 return default
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
183 else:
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
184 return o
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
185
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
186 def items(self):
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
187 with _IterationGuard(self):
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
188 for k, wr in self.data.items():
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
189 v = wr()
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
190 if v is not None:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
191 yield k, v
17650
7a367ad43f35 Added iterator support to the Weak*Dictionary classes.
Fred Drake <fdrake@acm.org>
parents: 17591
diff changeset
192
49001
5b7845ef4efd Committing the patch in issue 2965, so that weakref dicts have a closer
Barry Warsaw <barry@python.org>
parents: 48739
diff changeset
193 def keys(self):
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
194 with _IterationGuard(self):
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
195 for k, wr in self.data.items():
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
196 if wr() is not None:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
197 yield k
33197
7da9201bc8b5 SF bug #1012315: weakref.WeakValueDictionary should override .has_key()
Raymond Hettinger <python@rcn.com>
parents: 33117
diff changeset
198
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
199 __iter__ = keys
17650
7a367ad43f35 Added iterator support to the Weak*Dictionary classes.
Fred Drake <fdrake@acm.org>
parents: 17591
diff changeset
200
38079
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
201 def itervaluerefs(self):
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
202 """Return an iterator that yields the weak references to the values.
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
203
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
204 The references are not guaranteed to be 'live' at the time
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
205 they are used, so the result of calling the references needs
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
206 to be checked before being used. This can be used to avoid
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
207 creating references that will cause the garbage collector to
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
208 keep the values around longer than needed.
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
209
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
210 """
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
211 with _IterationGuard(self):
79378
fb90e2ff95b7 utilize yield from
Philip Jenvey <pjenvey@underboss.org>
parents: 75356
diff changeset
212 yield from self.data.values()
38079
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
213
49001
5b7845ef4efd Committing the patch in issue 2965, so that weakref dicts have a closer
Barry Warsaw <barry@python.org>
parents: 48739
diff changeset
214 def values(self):
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
215 with _IterationGuard(self):
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
216 for wr in self.data.values():
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
217 obj = wr()
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
218 if obj is not None:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
219 yield obj
17650
7a367ad43f35 Added iterator support to the Weak*Dictionary classes.
Fred Drake <fdrake@acm.org>
parents: 17591
diff changeset
220
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
221 def popitem(self):
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
222 if self._pending_removals:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
223 self._commit_removals()
66629
a0cf64a5291e Use booleans.
Georg Brandl <georg@python.org>
parents: 58194
diff changeset
224 while True:
17591
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
225 key, wr = self.data.popitem()
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
226 o = wr()
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
227 if o is not None:
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
228 return key, o
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
229
28240
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
230 def pop(self, key, *args):
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
231 if self._pending_removals:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
232 self._commit_removals()
28240
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
233 try:
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
234 o = self.data.pop(key)()
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
235 except KeyError:
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
236 if args:
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
237 return args[0]
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
238 raise
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
239 if o is None:
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 42084
diff changeset
240 raise KeyError(key)
28240
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
241 else:
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
242 return o
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
243
32155
efb84ed7377d The default argument in dict.setdefault() defaults to None.
Walter Dörwald <walter@livinglogic.de>
parents: 31616
diff changeset
244 def setdefault(self, key, default=None):
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
245 try:
17591
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
246 wr = self.data[key]
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
247 except KeyError:
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
248 if self._pending_removals:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
249 self._commit_removals()
32472
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
250 self.data[key] = KeyedRef(default, self._remove, key)
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
251 return default
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
252 else:
17591
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
253 return wr()
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
254
31616
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
255 def update(self, dict=None, **kwargs):
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
256 if self._pending_removals:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
257 self._commit_removals()
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
258 d = self.data
31616
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
259 if dict is not None:
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
260 if not hasattr(dict, "items"):
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
261 dict = type({})(dict)
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
262 for key, o in dict.items():
32472
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
263 d[key] = KeyedRef(o, self._remove, key)
31616
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
264 if len(kwargs):
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
265 self.update(kwargs)
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
266
38079
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
267 def valuerefs(self):
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
268 """Return a list of weak references to the values.
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
269
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
270 The references are not guaranteed to be 'live' at the time
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
271 they are used, so the result of calling the references needs
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
272 to be checked before being used. This can be used to avoid
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
273 creating references that will cause the garbage collector to
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
274 keep the values around longer than needed.
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
275
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
276 """
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
277 return list(self.data.values())
38079
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
278
32472
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
279
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
280 class KeyedRef(ref):
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
281 """Specialized reference that includes a key corresponding to the value.
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
282
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
283 This is used in the WeakValueDictionary to avoid having to create
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
284 a function object for each key stored in the mapping. A shared
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
285 callback object can use the 'key' attribute of a KeyedRef instead
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
286 of getting a reference to the key from an enclosing scope.
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
287
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
288 """
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
289
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
290 __slots__ = "key",
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
291
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
292 def __new__(type, ob, callback, key):
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
293 self = ref.__new__(type, ob, callback)
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
294 self.key = key
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
295 return self
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
296
4383db77b19a Make weak references subclassable:
Fred Drake <fdrake@acm.org>
parents: 32155
diff changeset
297 def __init__(self, ob, callback, key):
42084
229c28cb9afb Merged revisions 55817-55961 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 40949
diff changeset
298 super().__init__(ob, callback)
20155
bbb353d31e25 Clean up circular references in the Weak*Dictionary classes; this avoids
Fred Drake <fdrake@acm.org>
parents: 19763
diff changeset
299
16385
1fb6672b20ef PEP 205, Weak References -- initial checkin.
Fred Drake <fdrake@acm.org>
parents:
diff changeset
300
45161
bdf7486893ba Decouple weakref containers from UserDict
Raymond Hettinger <python@rcn.com>
parents: 45159
diff changeset
301 class WeakKeyDictionary(collections.MutableMapping):
17591
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
302 """ Mapping class that references keys weakly.
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
303
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
304 Entries in the dictionary will be discarded when there is no
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
305 longer a strong reference to the key. This can be used to
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
306 associate additional data with an object owned by other parts of
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
307 an application without adding attributes to those objects. This
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
308 can be especially useful with objects that override attribute
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
309 accesses.
44a3ac59c268 Weak*Dictionary: Added docstrings to the classes.
Fred Drake <fdrake@acm.org>
parents: 17546
diff changeset
310 """
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
311
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
312 def __init__(self, dict=None):
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
313 self.data = {}
20155
bbb353d31e25 Clean up circular references in the Weak*Dictionary classes; this avoids
Fred Drake <fdrake@acm.org>
parents: 19763
diff changeset
314 def remove(k, selfref=ref(self)):
bbb353d31e25 Clean up circular references in the Weak*Dictionary classes; this avoids
Fred Drake <fdrake@acm.org>
parents: 19763
diff changeset
315 self = selfref()
bbb353d31e25 Clean up circular references in the Weak*Dictionary classes; this avoids
Fred Drake <fdrake@acm.org>
parents: 19763
diff changeset
316 if self is not None:
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
317 if self._iterating:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
318 self._pending_removals.append(k)
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
319 else:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
320 del self.data[k]
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
321 self._remove = remove
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
322 # A list of dead weakrefs (keys to be removed)
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
323 self._pending_removals = []
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
324 self._iterating = set()
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
325 if dict is not None:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
326 self.update(dict)
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
327
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
328 def _commit_removals(self):
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
329 # NOTE: We don't need to call this method before mutating the dict,
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
330 # because a dead weakref never compares equal to a live weakref,
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
331 # even if they happened to refer to equal objects.
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
332 # However, it means keys may already have been removed.
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
333 l = self._pending_removals
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
334 d = self.data
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
335 while l:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
336 try:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
337 del d[l.pop()]
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
338 except KeyError:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
339 pass
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
340
19763
94d0f2eea047 Add __delitem__() support for WeakKeyDictionary.
Fred Drake <fdrake@acm.org>
parents: 18952
diff changeset
341 def __delitem__(self, key):
29257
dea38116c373 SF 742860: WeakKeyDictionary __delitem__ uses iterkeys
Tim Peters <tim.peters@gmail.com>
parents: 28240
diff changeset
342 del self.data[ref(key)]
19763
94d0f2eea047 Add __delitem__() support for WeakKeyDictionary.
Fred Drake <fdrake@acm.org>
parents: 18952
diff changeset
343
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
344 def __getitem__(self, key):
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
345 return self.data[ref(key)]
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
346
45161
bdf7486893ba Decouple weakref containers from UserDict
Raymond Hettinger <python@rcn.com>
parents: 45159
diff changeset
347 def __len__(self):
75356
1cd0688ff004 Issue #14159: Fix the len() of weak containers (WeakSet, WeakKeyDictionary, WeakValueDictionary) to return a better approximation when some objects are dead or dying.
Antoine Pitrou <solipsis@pitrou.net>
parents: 66629
diff changeset
348 return len(self.data) - len(self._pending_removals)
45161
bdf7486893ba Decouple weakref containers from UserDict
Raymond Hettinger <python@rcn.com>
parents: 45159
diff changeset
349
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
350 def __repr__(self):
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
351 return "<WeakKeyDictionary at %s>" % id(self)
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
352
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
353 def __setitem__(self, key, value):
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
354 self.data[ref(key, self._remove)] = value
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
355
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
356 def copy(self):
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
357 new = WeakKeyDictionary()
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
358 for key, value in self.data.items():
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
359 o = key()
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
360 if o is not None:
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
361 new[o] = value
16884
1ce751fa67d8 Change WeakDictionary to WeakValueDictionary in a couple more places.
Fred Drake <fdrake@acm.org>
parents: 16794
diff changeset
362 return new
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
363
54100
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
364 __copy__ = copy
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
365
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
366 def __deepcopy__(self, memo):
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
367 from copy import deepcopy
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
368 new = self.__class__()
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
369 for key, value in self.data.items():
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
370 o = key()
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
371 if o is not None:
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
372 new[o] = deepcopy(value, memo)
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
373 return new
85fb4c229a9c Merged revisions 72669 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 52338
diff changeset
374
17546
da5eab33147b Weak*Dictionary.update(): Fix calls to [].append() to only have one
Fred Drake <fdrake@acm.org>
parents: 17386
diff changeset
375 def get(self, key, default=None):
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
376 return self.data.get(ref(key),default)
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
377
23620
a1de0bab5475 SF 563203. Replaced 'has_key()' with 'in'.
Raymond Hettinger <python@rcn.com>
parents: 20902
diff changeset
378 def __contains__(self, key):
a1de0bab5475 SF 563203. Replaced 'has_key()' with 'in'.
Raymond Hettinger <python@rcn.com>
parents: 20902
diff changeset
379 try:
a1de0bab5475 SF 563203. Replaced 'has_key()' with 'in'.
Raymond Hettinger <python@rcn.com>
parents: 20902
diff changeset
380 wr = ref(key)
a1de0bab5475 SF 563203. Replaced 'has_key()' with 'in'.
Raymond Hettinger <python@rcn.com>
parents: 20902
diff changeset
381 except TypeError:
66629
a0cf64a5291e Use booleans.
Georg Brandl <georg@python.org>
parents: 58194
diff changeset
382 return False
23620
a1de0bab5475 SF 563203. Replaced 'has_key()' with 'in'.
Raymond Hettinger <python@rcn.com>
parents: 20902
diff changeset
383 return wr in self.data
24263
e6033254df21 Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 23764
diff changeset
384
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
385 def items(self):
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
386 with _IterationGuard(self):
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
387 for wr, value in self.data.items():
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
388 key = wr()
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
389 if key is not None:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
390 yield key, value
38079
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
391
49001
5b7845ef4efd Committing the patch in issue 2965, so that weakref dicts have a closer
Barry Warsaw <barry@python.org>
parents: 48739
diff changeset
392 def keys(self):
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
393 with _IterationGuard(self):
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
394 for wr in self.data:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
395 obj = wr()
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
396 if obj is not None:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
397 yield obj
33197
7da9201bc8b5 SF bug #1012315: weakref.WeakValueDictionary should override .has_key()
Raymond Hettinger <python@rcn.com>
parents: 33117
diff changeset
398
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
399 __iter__ = keys
17650
7a367ad43f35 Added iterator support to the Weak*Dictionary classes.
Fred Drake <fdrake@acm.org>
parents: 17591
diff changeset
400
49001
5b7845ef4efd Committing the patch in issue 2965, so that weakref dicts have a closer
Barry Warsaw <barry@python.org>
parents: 48739
diff changeset
401 def values(self):
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
402 with _IterationGuard(self):
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
403 for wr, value in self.data.items():
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
404 if wr() is not None:
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
405 yield value
17650
7a367ad43f35 Added iterator support to the Weak*Dictionary classes.
Fred Drake <fdrake@acm.org>
parents: 17591
diff changeset
406
38079
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
407 def keyrefs(self):
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
408 """Return a list of weak references to the keys.
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
409
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
410 The references are not guaranteed to be 'live' at the time
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
411 they are used, so the result of calling the references needs
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
412 to be checked before being used. This can be used to avoid
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
413 creating references that will cause the garbage collector to
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
414 keep the keys around longer than needed.
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
415
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
416 """
58194
84caac71d79b Issue #7105: Make WeakKeyDictionary and WeakValueDictionary robust against
Antoine Pitrou <solipsis@pitrou.net>
parents: 54456
diff changeset
417 return list(self.data)
38079
728c16f16267 SF #1479988: add methods to allow access to weakrefs for the
Fred Drake <fdrake@acm.org>
parents: 35018
diff changeset
418
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
419 def popitem(self):
66629
a0cf64a5291e Use booleans.
Georg Brandl <georg@python.org>
parents: 58194
diff changeset
420 while True:
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
421 key, value = self.data.popitem()
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
422 o = key()
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
423 if o is not None:
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
424 return o, value
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
425
28240
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
426 def pop(self, key, *args):
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
427 return self.data.pop(ref(key), *args)
ea70032a24b1 SF patch #667730: More DictMixin
Raymond Hettinger <python@rcn.com>
parents: 24263
diff changeset
428
32155
efb84ed7377d The default argument in dict.setdefault() defaults to None.
Walter Dörwald <walter@livinglogic.de>
parents: 31616
diff changeset
429 def setdefault(self, key, default=None):
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
430 return self.data.setdefault(ref(key, self._remove),default)
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
431
31616
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
432 def update(self, dict=None, **kwargs):
16794
29aa832b8787 Patch #403985: Add support for weak-keyed dictionaries
Martin v. Löwis <martin@v.loewis.de>
parents: 16424
diff changeset
433 d = self.data
31616
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
434 if dict is not None:
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
435 if not hasattr(dict, "items"):
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
436 dict = type({})(dict)
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
437 for key, value in dict.items():
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
438 d[ref(key, self._remove)] = value
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
439 if len(kwargs):
5b3898d9ba59 SF #904720: dict.update should take a 2-tuple sequence like dict.__init_
Raymond Hettinger <python@rcn.com>
parents: 29257
diff changeset
440 self.update(kwargs)
83631
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
441
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
442
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
443 class finalize:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
444 """Class for finalization of weakrefable objects
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
445
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
446 finalize(obj, func, *args, **kwargs) returns a callable finalizer
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
447 object which will be called when obj is garbage collected. The
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
448 first time the finalizer is called it evaluates func(*arg, **kwargs)
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
449 and returns the result. After this the finalizer is dead, and
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
450 calling it just returns None.
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
451
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
452 When the program exits any remaining finalizers for which the
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
453 atexit attribute is true will be run in reverse order of creation.
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
454 By default atexit is true.
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
455 """
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
456
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
457 # Finalizer objects don't have any state of their own. They are
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
458 # just used as keys to lookup _Info objects in the registry. This
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
459 # ensures that they cannot be part of a ref-cycle.
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
460
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
461 __slots__ = ()
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
462 _registry = {}
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
463 _shutdown = False
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
464 _index_iter = itertools.count()
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
465 _dirty = False
84057
d6ad9d7468f7 Issue #15528: Delay importing atexit until weakref.finalize() used.
Richard Oudkerk <shibturn@gmail.com>
parents: 83631
diff changeset
466 _registered_with_atexit = False
83631
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
467
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
468 class _Info:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
469 __slots__ = ("weakref", "func", "args", "kwargs", "atexit", "index")
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
470
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
471 def __init__(self, obj, func, *args, **kwargs):
84057
d6ad9d7468f7 Issue #15528: Delay importing atexit until weakref.finalize() used.
Richard Oudkerk <shibturn@gmail.com>
parents: 83631
diff changeset
472 if not self._registered_with_atexit:
d6ad9d7468f7 Issue #15528: Delay importing atexit until weakref.finalize() used.
Richard Oudkerk <shibturn@gmail.com>
parents: 83631
diff changeset
473 # We may register the exit function more than once because
d6ad9d7468f7 Issue #15528: Delay importing atexit until weakref.finalize() used.
Richard Oudkerk <shibturn@gmail.com>
parents: 83631
diff changeset
474 # of a thread race, but that is harmless
d6ad9d7468f7 Issue #15528: Delay importing atexit until weakref.finalize() used.
Richard Oudkerk <shibturn@gmail.com>
parents: 83631
diff changeset
475 import atexit
d6ad9d7468f7 Issue #15528: Delay importing atexit until weakref.finalize() used.
Richard Oudkerk <shibturn@gmail.com>
parents: 83631
diff changeset
476 atexit.register(self._exitfunc)
d6ad9d7468f7 Issue #15528: Delay importing atexit until weakref.finalize() used.
Richard Oudkerk <shibturn@gmail.com>
parents: 83631
diff changeset
477 finalize._registered_with_atexit = True
83631
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
478 info = self._Info()
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
479 info.weakref = ref(obj, self)
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
480 info.func = func
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
481 info.args = args
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
482 info.kwargs = kwargs or None
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
483 info.atexit = True
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
484 info.index = next(self._index_iter)
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
485 self._registry[self] = info
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
486 finalize._dirty = True
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
487
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
488 def __call__(self, _=None):
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
489 """If alive then mark as dead and return func(*args, **kwargs);
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
490 otherwise return None"""
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
491 info = self._registry.pop(self, None)
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
492 if info and not self._shutdown:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
493 return info.func(*info.args, **(info.kwargs or {}))
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
494
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
495 def detach(self):
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
496 """If alive then mark as dead and return (obj, func, args, kwargs);
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
497 otherwise return None"""
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
498 info = self._registry.get(self)
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
499 obj = info and info.weakref()
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
500 if obj is not None and self._registry.pop(self, None):
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
501 return (obj, info.func, info.args, info.kwargs or {})
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
502
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
503 def peek(self):
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
504 """If alive then return (obj, func, args, kwargs);
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
505 otherwise return None"""
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
506 info = self._registry.get(self)
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
507 obj = info and info.weakref()
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
508 if obj is not None:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
509 return (obj, info.func, info.args, info.kwargs or {})
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
510
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
511 @property
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
512 def alive(self):
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
513 """Whether finalizer is alive"""
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
514 return self in self._registry
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
515
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
516 @property
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
517 def atexit(self):
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
518 """Whether finalizer should be called at exit"""
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
519 info = self._registry.get(self)
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
520 return bool(info) and info.atexit
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
521
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
522 @atexit.setter
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
523 def atexit(self, value):
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
524 info = self._registry.get(self)
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
525 if info:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
526 info.atexit = bool(value)
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
527
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
528 def __repr__(self):
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
529 info = self._registry.get(self)
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
530 obj = info and info.weakref()
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
531 if obj is None:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
532 return '<%s object at %#x; dead>' % (type(self).__name__, id(self))
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
533 else:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
534 return '<%s object at %#x; for %r at %#x>' % \
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
535 (type(self).__name__, id(self), type(obj).__name__, id(obj))
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
536
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
537 @classmethod
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
538 def _select_for_exit(cls):
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
539 # Return live finalizers marked for exit, oldest first
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
540 L = [(f,i) for (f,i) in cls._registry.items() if i.atexit]
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
541 L.sort(key=lambda item:item[1].index)
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
542 return [f for (f,i) in L]
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
543
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
544 @classmethod
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
545 def _exitfunc(cls):
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
546 # At shutdown invoke finalizers for which atexit is true.
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
547 # This is called once all other non-daemonic threads have been
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
548 # joined.
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
549 reenable_gc = False
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
550 try:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
551 if cls._registry:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
552 import gc
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
553 if gc.isenabled():
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
554 reenable_gc = True
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
555 gc.disable()
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
556 pending = None
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
557 while True:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
558 if pending is None or finalize._dirty:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
559 pending = cls._select_for_exit()
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
560 finalize._dirty = False
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
561 if not pending:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
562 break
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
563 f = pending.pop()
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
564 try:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
565 # gc is disabled, so (assuming no daemonic
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
566 # threads) the following is the only line in
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
567 # this function which might trigger creation
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
568 # of a new finalizer
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
569 f()
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
570 except Exception:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
571 sys.excepthook(*sys.exc_info())
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
572 assert f not in cls._registry
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
573 finally:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
574 # prevent any more finalizers from executing during shutdown
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
575 finalize._shutdown = True
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
576 if reenable_gc:
186cf551dae5 Issue #15528: Add weakref.finalize to support finalization using
Richard Oudkerk <shibturn@gmail.com>
parents: 83629
diff changeset
577 gc.enable()