weakref.py revision a81dd6594067a9501f3ba65b7c05dd50accac5de
1"""Weak reference support for Python. 2 3This module is an implementation of PEP 205: 4 5http://www.python.org/dev/peps/pep-0205/ 6""" 7 8# Naming convention: Variables named "wr" are weak reference objects; 9# they are called this instead of "ref" to avoid name collisions with 10# the module-global ref() function imported from _weakref. 11 12from _weakref import ( 13 getweakrefcount, 14 getweakrefs, 15 ref, 16 proxy, 17 CallableProxyType, 18 ProxyType, 19 ReferenceType) 20 21from _weakrefset import WeakSet, _IterationGuard 22 23import collections # Import after _weakref to avoid circular import. 24import sys 25import itertools 26 27ProxyTypes = (ProxyType, CallableProxyType) 28 29__all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs", 30 "WeakKeyDictionary", "ReferenceType", "ProxyType", 31 "CallableProxyType", "ProxyTypes", "WeakValueDictionary", 32 "WeakSet", "WeakMethod", "finalize"] 33 34 35class WeakMethod(ref): 36 """ 37 A custom `weakref.ref` subclass which simulates a weak reference to 38 a bound method, working around the lifetime problem of bound methods. 39 """ 40 41 __slots__ = "_func_ref", "_meth_type", "_alive", "__weakref__" 42 43 def __new__(cls, meth, callback=None): 44 try: 45 obj = meth.__self__ 46 func = meth.__func__ 47 except AttributeError: 48 raise TypeError("argument should be a bound method, not {}" 49 .format(type(meth))) from None 50 def _cb(arg): 51 # The self-weakref trick is needed to avoid creating a reference 52 # cycle. 53 self = self_wr() 54 if self._alive: 55 self._alive = False 56 if callback is not None: 57 callback(self) 58 self = ref.__new__(cls, obj, _cb) 59 self._func_ref = ref(func, _cb) 60 self._meth_type = type(meth) 61 self._alive = True 62 self_wr = ref(self) 63 return self 64 65 def __call__(self): 66 obj = super().__call__() 67 func = self._func_ref() 68 if obj is None or func is None: 69 return None 70 return self._meth_type(func, obj) 71 72 def __eq__(self, other): 73 if isinstance(other, WeakMethod): 74 if not self._alive or not other._alive: 75 return self is other 76 return ref.__eq__(self, other) and self._func_ref == other._func_ref 77 return False 78 79 def __ne__(self, other): 80 if isinstance(other, WeakMethod): 81 if not self._alive or not other._alive: 82 return self is not other 83 return ref.__ne__(self, other) or self._func_ref != other._func_ref 84 return True 85 86 __hash__ = ref.__hash__ 87 88 89class WeakValueDictionary(collections.MutableMapping): 90 """Mapping class that references values weakly. 91 92 Entries in the dictionary will be discarded when no strong 93 reference to the value exists anymore 94 """ 95 # We inherit the constructor without worrying about the input 96 # dictionary; since it uses our .update() method, we get the right 97 # checks (if the other dictionary is a WeakValueDictionary, 98 # objects are unwrapped on the way out, and we always wrap on the 99 # way in). 100 101 def __init__(self, *args, **kw): 102 def remove(wr, selfref=ref(self)): 103 self = selfref() 104 if self is not None: 105 if self._iterating: 106 self._pending_removals.append(wr.key) 107 else: 108 del self.data[wr.key] 109 self._remove = remove 110 # A list of keys to be removed 111 self._pending_removals = [] 112 self._iterating = set() 113 self.data = d = {} 114 self.update(*args, **kw) 115 116 def _commit_removals(self): 117 l = self._pending_removals 118 d = self.data 119 # We shouldn't encounter any KeyError, because this method should 120 # always be called *before* mutating the dict. 121 while l: 122 del d[l.pop()] 123 124 def __getitem__(self, key): 125 o = self.data[key]() 126 if o is None: 127 raise KeyError(key) 128 else: 129 return o 130 131 def __delitem__(self, key): 132 if self._pending_removals: 133 self._commit_removals() 134 del self.data[key] 135 136 def __len__(self): 137 return len(self.data) - len(self._pending_removals) 138 139 def __contains__(self, key): 140 try: 141 o = self.data[key]() 142 except KeyError: 143 return False 144 return o is not None 145 146 def __repr__(self): 147 return "<WeakValueDictionary at %s>" % id(self) 148 149 def __setitem__(self, key, value): 150 if self._pending_removals: 151 self._commit_removals() 152 self.data[key] = KeyedRef(value, self._remove, key) 153 154 def copy(self): 155 new = WeakValueDictionary() 156 for key, wr in self.data.items(): 157 o = wr() 158 if o is not None: 159 new[key] = o 160 return new 161 162 __copy__ = copy 163 164 def __deepcopy__(self, memo): 165 from copy import deepcopy 166 new = self.__class__() 167 for key, wr in self.data.items(): 168 o = wr() 169 if o is not None: 170 new[deepcopy(key, memo)] = o 171 return new 172 173 def get(self, key, default=None): 174 try: 175 wr = self.data[key] 176 except KeyError: 177 return default 178 else: 179 o = wr() 180 if o is None: 181 # This should only happen 182 return default 183 else: 184 return o 185 186 def items(self): 187 with _IterationGuard(self): 188 for k, wr in self.data.items(): 189 v = wr() 190 if v is not None: 191 yield k, v 192 193 def keys(self): 194 with _IterationGuard(self): 195 for k, wr in self.data.items(): 196 if wr() is not None: 197 yield k 198 199 __iter__ = keys 200 201 def itervaluerefs(self): 202 """Return an iterator that yields the weak references to the values. 203 204 The references are not guaranteed to be 'live' at the time 205 they are used, so the result of calling the references needs 206 to be checked before being used. This can be used to avoid 207 creating references that will cause the garbage collector to 208 keep the values around longer than needed. 209 210 """ 211 with _IterationGuard(self): 212 yield from self.data.values() 213 214 def values(self): 215 with _IterationGuard(self): 216 for wr in self.data.values(): 217 obj = wr() 218 if obj is not None: 219 yield obj 220 221 def popitem(self): 222 if self._pending_removals: 223 self._commit_removals() 224 while True: 225 key, wr = self.data.popitem() 226 o = wr() 227 if o is not None: 228 return key, o 229 230 def pop(self, key, *args): 231 if self._pending_removals: 232 self._commit_removals() 233 try: 234 o = self.data.pop(key)() 235 except KeyError: 236 if args: 237 return args[0] 238 raise 239 if o is None: 240 raise KeyError(key) 241 else: 242 return o 243 244 def setdefault(self, key, default=None): 245 try: 246 wr = self.data[key] 247 except KeyError: 248 if self._pending_removals: 249 self._commit_removals() 250 self.data[key] = KeyedRef(default, self._remove, key) 251 return default 252 else: 253 return wr() 254 255 def update(self, dict=None, **kwargs): 256 if self._pending_removals: 257 self._commit_removals() 258 d = self.data 259 if dict is not None: 260 if not hasattr(dict, "items"): 261 dict = type({})(dict) 262 for key, o in dict.items(): 263 d[key] = KeyedRef(o, self._remove, key) 264 if len(kwargs): 265 self.update(kwargs) 266 267 def valuerefs(self): 268 """Return a list of weak references to the values. 269 270 The references are not guaranteed to be 'live' at the time 271 they are used, so the result of calling the references needs 272 to be checked before being used. This can be used to avoid 273 creating references that will cause the garbage collector to 274 keep the values around longer than needed. 275 276 """ 277 return list(self.data.values()) 278 279 280class KeyedRef(ref): 281 """Specialized reference that includes a key corresponding to the value. 282 283 This is used in the WeakValueDictionary to avoid having to create 284 a function object for each key stored in the mapping. A shared 285 callback object can use the 'key' attribute of a KeyedRef instead 286 of getting a reference to the key from an enclosing scope. 287 288 """ 289 290 __slots__ = "key", 291 292 def __new__(type, ob, callback, key): 293 self = ref.__new__(type, ob, callback) 294 self.key = key 295 return self 296 297 def __init__(self, ob, callback, key): 298 super().__init__(ob, callback) 299 300 301class WeakKeyDictionary(collections.MutableMapping): 302 """ Mapping class that references keys weakly. 303 304 Entries in the dictionary will be discarded when there is no 305 longer a strong reference to the key. This can be used to 306 associate additional data with an object owned by other parts of 307 an application without adding attributes to those objects. This 308 can be especially useful with objects that override attribute 309 accesses. 310 """ 311 312 def __init__(self, dict=None): 313 self.data = {} 314 def remove(k, selfref=ref(self)): 315 self = selfref() 316 if self is not None: 317 if self._iterating: 318 self._pending_removals.append(k) 319 else: 320 del self.data[k] 321 self._remove = remove 322 # A list of dead weakrefs (keys to be removed) 323 self._pending_removals = [] 324 self._iterating = set() 325 if dict is not None: 326 self.update(dict) 327 328 def _commit_removals(self): 329 # NOTE: We don't need to call this method before mutating the dict, 330 # because a dead weakref never compares equal to a live weakref, 331 # even if they happened to refer to equal objects. 332 # However, it means keys may already have been removed. 333 l = self._pending_removals 334 d = self.data 335 while l: 336 try: 337 del d[l.pop()] 338 except KeyError: 339 pass 340 341 def __delitem__(self, key): 342 del self.data[ref(key)] 343 344 def __getitem__(self, key): 345 return self.data[ref(key)] 346 347 def __len__(self): 348 return len(self.data) - len(self._pending_removals) 349 350 def __repr__(self): 351 return "<WeakKeyDictionary at %s>" % id(self) 352 353 def __setitem__(self, key, value): 354 self.data[ref(key, self._remove)] = value 355 356 def copy(self): 357 new = WeakKeyDictionary() 358 for key, value in self.data.items(): 359 o = key() 360 if o is not None: 361 new[o] = value 362 return new 363 364 __copy__ = copy 365 366 def __deepcopy__(self, memo): 367 from copy import deepcopy 368 new = self.__class__() 369 for key, value in self.data.items(): 370 o = key() 371 if o is not None: 372 new[o] = deepcopy(value, memo) 373 return new 374 375 def get(self, key, default=None): 376 return self.data.get(ref(key),default) 377 378 def __contains__(self, key): 379 try: 380 wr = ref(key) 381 except TypeError: 382 return False 383 return wr in self.data 384 385 def items(self): 386 with _IterationGuard(self): 387 for wr, value in self.data.items(): 388 key = wr() 389 if key is not None: 390 yield key, value 391 392 def keys(self): 393 with _IterationGuard(self): 394 for wr in self.data: 395 obj = wr() 396 if obj is not None: 397 yield obj 398 399 __iter__ = keys 400 401 def values(self): 402 with _IterationGuard(self): 403 for wr, value in self.data.items(): 404 if wr() is not None: 405 yield value 406 407 def keyrefs(self): 408 """Return a list of weak references to the keys. 409 410 The references are not guaranteed to be 'live' at the time 411 they are used, so the result of calling the references needs 412 to be checked before being used. This can be used to avoid 413 creating references that will cause the garbage collector to 414 keep the keys around longer than needed. 415 416 """ 417 return list(self.data) 418 419 def popitem(self): 420 while True: 421 key, value = self.data.popitem() 422 o = key() 423 if o is not None: 424 return o, value 425 426 def pop(self, key, *args): 427 return self.data.pop(ref(key), *args) 428 429 def setdefault(self, key, default=None): 430 return self.data.setdefault(ref(key, self._remove),default) 431 432 def update(self, dict=None, **kwargs): 433 d = self.data 434 if dict is not None: 435 if not hasattr(dict, "items"): 436 dict = type({})(dict) 437 for key, value in dict.items(): 438 d[ref(key, self._remove)] = value 439 if len(kwargs): 440 self.update(kwargs) 441 442 443class finalize: 444 """Class for finalization of weakrefable objects 445 446 finalize(obj, func, *args, **kwargs) returns a callable finalizer 447 object which will be called when obj is garbage collected. The 448 first time the finalizer is called it evaluates func(*arg, **kwargs) 449 and returns the result. After this the finalizer is dead, and 450 calling it just returns None. 451 452 When the program exits any remaining finalizers for which the 453 atexit attribute is true will be run in reverse order of creation. 454 By default atexit is true. 455 """ 456 457 # Finalizer objects don't have any state of their own. They are 458 # just used as keys to lookup _Info objects in the registry. This 459 # ensures that they cannot be part of a ref-cycle. 460 461 __slots__ = () 462 _registry = {} 463 _shutdown = False 464 _index_iter = itertools.count() 465 _dirty = False 466 _registered_with_atexit = False 467 468 class _Info: 469 __slots__ = ("weakref", "func", "args", "kwargs", "atexit", "index") 470 471 def __init__(self, obj, func, *args, **kwargs): 472 if not self._registered_with_atexit: 473 # We may register the exit function more than once because 474 # of a thread race, but that is harmless 475 import atexit 476 atexit.register(self._exitfunc) 477 finalize._registered_with_atexit = True 478 info = self._Info() 479 info.weakref = ref(obj, self) 480 info.func = func 481 info.args = args 482 info.kwargs = kwargs or None 483 info.atexit = True 484 info.index = next(self._index_iter) 485 self._registry[self] = info 486 finalize._dirty = True 487 488 def __call__(self, _=None): 489 """If alive then mark as dead and return func(*args, **kwargs); 490 otherwise return None""" 491 info = self._registry.pop(self, None) 492 if info and not self._shutdown: 493 return info.func(*info.args, **(info.kwargs or {})) 494 495 def detach(self): 496 """If alive then mark as dead and return (obj, func, args, kwargs); 497 otherwise return None""" 498 info = self._registry.get(self) 499 obj = info and info.weakref() 500 if obj is not None and self._registry.pop(self, None): 501 return (obj, info.func, info.args, info.kwargs or {}) 502 503 def peek(self): 504 """If alive then return (obj, func, args, kwargs); 505 otherwise return None""" 506 info = self._registry.get(self) 507 obj = info and info.weakref() 508 if obj is not None: 509 return (obj, info.func, info.args, info.kwargs or {}) 510 511 @property 512 def alive(self): 513 """Whether finalizer is alive""" 514 return self in self._registry 515 516 @property 517 def atexit(self): 518 """Whether finalizer should be called at exit""" 519 info = self._registry.get(self) 520 return bool(info) and info.atexit 521 522 @atexit.setter 523 def atexit(self, value): 524 info = self._registry.get(self) 525 if info: 526 info.atexit = bool(value) 527 528 def __repr__(self): 529 info = self._registry.get(self) 530 obj = info and info.weakref() 531 if obj is None: 532 return '<%s object at %#x; dead>' % (type(self).__name__, id(self)) 533 else: 534 return '<%s object at %#x; for %r at %#x>' % \ 535 (type(self).__name__, id(self), type(obj).__name__, id(obj)) 536 537 @classmethod 538 def _select_for_exit(cls): 539 # Return live finalizers marked for exit, oldest first 540 L = [(f,i) for (f,i) in cls._registry.items() if i.atexit] 541 L.sort(key=lambda item:item[1].index) 542 return [f for (f,i) in L] 543 544 @classmethod 545 def _exitfunc(cls): 546 # At shutdown invoke finalizers for which atexit is true. 547 # This is called once all other non-daemonic threads have been 548 # joined. 549 reenable_gc = False 550 try: 551 if cls._registry: 552 import gc 553 if gc.isenabled(): 554 reenable_gc = True 555 gc.disable() 556 pending = None 557 while True: 558 if pending is None or finalize._dirty: 559 pending = cls._select_for_exit() 560 finalize._dirty = False 561 if not pending: 562 break 563 f = pending.pop() 564 try: 565 # gc is disabled, so (assuming no daemonic 566 # threads) the following is the only line in 567 # this function which might trigger creation 568 # of a new finalizer 569 f() 570 except Exception: 571 sys.excepthook(*sys.exc_info()) 572 assert f not in cls._registry 573 finally: 574 # prevent any more finalizers from executing during shutdown 575 finalize._shutdown = True 576 if reenable_gc: 577 gc.enable() 578