Mapping class that references keys weakly. Entries in the dictionary will be discarded when there is no longer a strong reference to the key. This can be used to associate additional data with an object owned by other parts of an application without adding attributes to those objec
| 296 | |
| 297 | |
| 298 | class WeakKeyDictionary(_collections_abc.MutableMapping): |
| 299 | """ Mapping class that references keys weakly. |
| 300 | |
| 301 | Entries in the dictionary will be discarded when there is no |
| 302 | longer a strong reference to the key. This can be used to |
| 303 | associate additional data with an object owned by other parts of |
| 304 | an application without adding attributes to those objects. This |
| 305 | can be especially useful with objects that override attribute |
| 306 | accesses. |
| 307 | """ |
| 308 | |
| 309 | def __init__(self, dict=None): |
| 310 | self.data = {} |
| 311 | def remove(k, selfref=ref(self)): |
| 312 | self = selfref() |
| 313 | if self is not None: |
| 314 | try: |
| 315 | del self.data[k] |
| 316 | except KeyError: |
| 317 | pass |
| 318 | self._remove = remove |
| 319 | if dict is not None: |
| 320 | self.update(dict) |
| 321 | |
| 322 | def __delitem__(self, key): |
| 323 | del self.data[ref(key)] |
| 324 | |
| 325 | def __getitem__(self, key): |
| 326 | return self.data[ref(key)] |
| 327 | |
| 328 | def __len__(self): |
| 329 | return len(self.data) |
| 330 | |
| 331 | def __repr__(self): |
| 332 | return "<%s at %#x>" % (self.__class__.__name__, id(self)) |
| 333 | |
| 334 | def __setitem__(self, key, value): |
| 335 | self.data[ref(key, self._remove)] = value |
| 336 | |
| 337 | def copy(self): |
| 338 | new = WeakKeyDictionary() |
| 339 | for key, value in self.data.copy().items(): |
| 340 | o = key() |
| 341 | if o is not None: |
| 342 | new[o] = value |
| 343 | return new |
| 344 | |
| 345 | __copy__ = copy |
| 346 | |
| 347 | def __deepcopy__(self, memo): |
| 348 | from copy import deepcopy |
| 349 | new = self.__class__() |
| 350 | for key, value in self.data.copy().items(): |
| 351 | o = key() |
| 352 | if o is not None: |
| 353 | new[o] = deepcopy(value, memo) |
| 354 | return new |
| 355 |
no outgoing calls
no test coverage detected
searching dependent graphs…