def test_weak_keyed_delitem(self):
     d = WeakKeyIdentityDict()
     o1 = Object('1')
     o2 = Object('2')
     d[o1] = 'something'
     d[o2] = 'something'
     self.assertTrue(len(d) == 2)
     del d[o1]
     self.assertTrue(len(d) == 1)
     self.assertTrue(list(d.keys()) == [o2])
Beispiel #2
0
 def test_weak_keyed_delitem(self):
     d = WeakKeyIdentityDict()
     o1 = Object('1')
     o2 = Object('2')
     d[o1] = 'something'
     d[o2] = 'something'
     self.assertTrue(len(d) == 2)
     del d[o1]
     self.assertTrue(len(d) == 1)
     self.assertTrue(d.keys() == [o2])
 def test_weak_keyed_delitem(self):
     d = WeakKeyIdentityDict()
     o1 = Object("1")
     o2 = Object("2")
     d[o1] = "something"
     d[o2] = "something"
     self.assertTrue(len(d) == 2)
     del d[o1]
     self.assertTrue(len(d) == 1)
     self.assertTrue(list(d.keys()) == [o2])
    def test_weak_keyed_cascading_deletes(self):
        # SF bug 742860.  For some reason, before 2.3 __delitem__ iterated
        # over the keys via self.data.iterkeys().  If things vanished from
        # the dict during this (or got added), that caused a RuntimeError.

        d = WeakKeyIdentityDict()
        mutate = False

        class C(object):
            def __init__(self, i):
                self.value = i

            def __hash__(self):
                return hash(self.value)

            def __eq__(self, other):
                if mutate:
                    # Side effect that mutates the dict, by removing the
                    # last strong reference to a key.
                    del objs[-1]
                return self.value == other.value

        objs = [C(i) for i in range(4)]
        for o in objs:
            d[o] = o.value
        del o  # now the only strong references to keys are in objs
        # Find the order in which iterkeys sees the keys.
        objs = d.keys()
        # Reverse it, so that the iteration implementation of __delitem__
        # has to keep looping to find the first object we delete.
        objs.reverse()

        # Turn on mutation in C.__eq__.  The first time thru the loop,
        # under the iterkeys() business the first comparison will delete
        # the last item iterkeys() would see, and that causes a
        #     RuntimeError: dictionary changed size during iteration
        # when the iterkeys() loop goes around to try comparing the next
        # key.  After this was fixed, it just deletes the last object *our*
        # "for o in obj" loop would have gotten to.
        mutate = True
        count = 0
        for o in objs:
            count += 1
            del d[o]
        gc_tools.collect()
        self.assertEqual(len(d), 0)
        self.assertEqual(count, 2)
    def test_weak_keyed_cascading_deletes(self):
        # SF bug 742860.  For some reason, before 2.3 __delitem__ iterated
        # over the keys via self.data.iterkeys().  If things vanished from
        # the dict during this (or got added), that caused a RuntimeError.

        d = WeakKeyIdentityDict()
        mutate = False

        class C(object):
            def __init__(self, i):
                self.value = i

            def __hash__(self):
                return hash(self.value)

            def __eq__(self, other):
                if mutate:
                    # Side effect that mutates the dict, by removing the
                    # last strong reference to a key.
                    del objs[-1]
                return self.value == other.value

        objs = [C(i) for i in range(4)]
        for o in objs:
            d[o] = o.value
        del o  # now the only strong references to keys are in objs
        # Find the order in which iterkeys sees the keys.
        objs = list(d.keys())
        # Reverse it, so that the iteration implementation of __delitem__
        # has to keep looping to find the first object we delete.
        objs.reverse()

        # Turn on mutation in C.__eq__.  The first time thru the loop,
        # under the iterkeys() business the first comparison will delete
        # the last item iterkeys() would see, and that causes a
        #     RuntimeError: dictionary changed size during iteration
        # when the iterkeys() loop goes around to try comparing the next
        # key.  After this was fixed, it just deletes the last object *our*
        # "for o in obj" loop would have gotten to.
        mutate = True
        count = 0
        for o in objs:
            count += 1
            del d[o]
        gc_tools.collect()
        self.assertEqual(len(d), 0)
        self.assertEqual(count, 2)
Beispiel #6
0
 def test_update(self):
     #
     #  This exercises d.update(), len(d), d.keys(), in d,
     #  d.get(), d[].
     #
     dict_ = {C(): 1, C(): 2, C(): 3}
     weakdict = WeakKeyIdentityDict()
     weakdict.update(dict_)
     self.assertEqual(len(weakdict), len(dict_))
     for k in weakdict.keys():
         assert k in dict_
         v = dict_.get(k)
         assert v is weakdict[k]
         assert v is weakdict.get(k)
     for k in dict_.keys():
         assert k in weakdict
         v = dict_[k]
         assert v is weakdict[k]
         assert v is weakdict.get(k)
 def test_update(self):
     #
     #  This exercises d.update(), len(d), d.keys(), in d,
     #  d.get(), d[].
     #
     dict_ = {C(): 1, C(): 2, C(): 3}
     weakdict = WeakKeyIdentityDict()
     weakdict.update(dict_)
     self.assertEqual(len(weakdict), len(dict_))
     for k in list(weakdict.keys()):
         assert k in dict_
         v = dict_.get(k)
         assert v is weakdict[k]
         assert v is weakdict.get(k)
     for k in list(dict_.keys()):
         assert k in weakdict
         v = dict_[k]
         assert v is weakdict[k]
         assert v is weakdict.get(k)