• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / transaction / 16399678488

18 Sep 2024 07:25AM UTC coverage: 99.793% (+0.1%) from 99.696%
16399678488

push

github

dataflake
- vb [ci skip]

299 of 306 branches covered (97.71%)

Branch coverage included in aggregate %.

3083 of 3083 relevant lines covered (100.0%)

1.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/transaction/weakset.py
1
############################################################################
2
#
3
# Copyright (c) 2007 Zope Foundation and Contributors.
4
# All Rights Reserved.
5
#
6
# This software is subject to the provisions of the Zope Public License,
7
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
# FOR A PARTICULAR PURPOSE.
12
#
13
############################################################################
14

15
import weakref
1✔
16

17

18
# A simple implementation of weak sets, supplying just enough of Python's
19
# sets.Set interface for our needs.
20

21

22
class WeakSet:
1✔
23
    """A set of objects that doesn't keep its elements alive.
24

25
    The objects in the set must be weakly referencable.
26
    The objects need not be hashable, and need not support comparison.
27
    Two objects are considered to be the same iff their id()s are equal.
28

29
    When the only references to an object are weak references (including
30
    those from WeakSets), the object can be garbage-collected, and
31
    will vanish from any WeakSets it may be a member of at that time.
32
    """
33

34
    def __init__(self):
1✔
35
        # Map id(obj) to obj.  By using ids as keys, we avoid requiring
36
        # that the elements be hashable or comparable.
37
        self.data = weakref.WeakValueDictionary()
1✔
38

39
    def __len__(self):
1✔
40
        return len(self.data)
1✔
41

42
    def __contains__(self, obj):
1✔
43
        return id(obj) in self.data
1✔
44

45
    # Same as a Set, add obj to the collection.
46
    def add(self, obj):
1✔
47
        self.data[id(obj)] = obj
1✔
48

49
    # Same as a Set, remove obj from the collection, and raise
50
    # KeyError if obj not in the collection.
51
    def remove(self, obj):
1✔
52
        del self.data[id(obj)]
1✔
53

54
    def clear(self):
1✔
55
        self.data.clear()
1✔
56

57
    # f is a one-argument function.  Execute f(elt) for each elt in the
58
    # set.  f's return value is ignored.
59
    def map(self, f):
1✔
60
        for wr in self.as_weakref_list():
1✔
61
            elt = wr()
1✔
62
            if elt is not None:
1✔
63
                f(elt)
1✔
64

65
    # Return a list of weakrefs to all the objects in the collection.
66
    # Because a weak dict is used internally, iteration is dicey (the
67
    # underlying dict may change size during iteration, due to gc or
68
    # activity from other threads).  as_weakef_list() is safe.
69
    #
70
    # If we invoke self.data.values() instead, we get back a list of live
71
    # objects instead of weakrefs.  If gc occurs while this list is alive,
72
    # all the objects move to an older generation (because they're strongly
73
    # referenced by the list!).  They can't get collected then, until a
74
    # less frequent collection of the older generation.  Before then, if we
75
    # invoke self.data.values() again, they're still alive, and if gc occurs
76
    # while that list is alive they're all moved to yet an older generation.
77
    # And so on.  Stress tests showed that it was easy to get into a state
78
    # where a WeakSet grows without bounds, despite that almost all its
79
    # elements are actually trash.  By returning a list of weakrefs instead,
80
    # we avoid that, although the decision to use weakrefs is now very
81
    # visible to our clients.
82

83
    def as_weakref_list(self):
1✔
84
        # The docstring of WeakValueDictionary.valuerefs()
85
        # guarantees to return an actual list on all supported versions
86
        # of Python.
87
        return self.data.valuerefs()
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc