Example #1
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])
Example #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])
Example #3
0
    def test_weak_keyed_dict_setdefault(self):
        key, value1, value2 = C(), "value 1", "value 2"
        self.assertTrue(value1 is not value2,
                        "invalid test"
                        " -- value parameters must be distinct objects")
        weakdict = WeakKeyIdentityDict()
        o = weakdict.setdefault(key, value1)
        assert o is value1
        assert key in weakdict
        assert weakdict.get(key) is value1
        assert weakdict[key] is value1

        o = weakdict.setdefault(key, value2)
        assert o is value1
        assert key in weakdict
        assert weakdict.get(key) is value1
        assert weakdict[key] is value1
Example #4
0
    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]
        self.assertEqual(len(d), 0)
        self.assertEqual(count, 2)
Example #5
0
 def test_weak_keyed_dict_popitem(self):
     key1, value1, key2, value2 = C(), "value 1", C(), "value 2"
     weakdict = WeakKeyIdentityDict()
     weakdict[key1] = value1
     weakdict[key2] = value2
     self.assertTrue(len(weakdict) == 2)
     k, v = weakdict.popitem()
     self.assertTrue(len(weakdict) == 1)
     if k is key1:
         self.assertTrue(v is value1)
     else:
         self.assertTrue(v is value2)
     k, v = weakdict.popitem()
     self.assertTrue(len(weakdict) == 0)
     if k is key1:
         self.assertTrue(v is value1)
     else:
         self.assertTrue(v is value2)
Example #6
0
 def test_weak_keyed_dict_popitem(self):
     key1, value1, key2, value2 = C(), "value 1", C(), "value 2"
     weakdict = WeakKeyIdentityDict()
     weakdict[key1] = value1
     weakdict[key2] = value2
     self.assertTrue(len(weakdict) == 2)
     k, v = weakdict.popitem()
     self.assertTrue(len(weakdict) == 1)
     if k is key1:
         self.assertTrue(v is value1)
     else:
         self.assertTrue(v is value2)
     k, v = weakdict.popitem()
     self.assertTrue(len(weakdict) == 0)
     if k is key1:
         self.assertTrue(v is value1)
     else:
         self.assertTrue(v is value2)
Example #7
0
    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]
        self.assertEqual(len(d), 0)
        self.assertEqual(count, 2)
Example #8
0
    def test_weak_keyed_bad_delitem(self):
        d = WeakKeyIdentityDict()
        o = Object('1')
        # An attempt to delete an object that isn't there should raise
        # KeyError.  It didn't before 2.3.
        self.assertRaises(KeyError, d.__delitem__, o)
        self.assertRaises(KeyError, d.__getitem__, o)

        # If a key isn't of a weakly referencable type, __getitem__ and
        # __setitem__ raise TypeError.  __delitem__ should too.
        self.assertRaises(TypeError, d.__delitem__, 13)
        self.assertRaises(TypeError, d.__getitem__, 13)
        self.assertRaises(TypeError, d.__setitem__, 13, 13)
Example #9
0
def test():
    '''Test the basic workings of `WeakKeyIdentityDict`.'''
    wki_dict = WeakKeyIdentityDict()
    my_weakreffable_list = WeakreffableList([1, 2])
    wki_dict[my_weakreffable_list] = 7
    assert my_weakreffable_list in wki_dict
    assert wki_dict[my_weakreffable_list] == 7
    identical_weakreffable_list = WeakreffableList([1, 2])
    assert identical_weakreffable_list not in wki_dict
    nose.tools.assert_raises(KeyError,
                             lambda: wki_dict[identical_weakreffable_list])

    my_weakreffable_list.append(3)
    assert my_weakreffable_list in wki_dict
    assert wki_dict[my_weakreffable_list] == 7

    del wki_dict[my_weakreffable_list]
    assert my_weakreffable_list not in wki_dict
    nose.tools.assert_raises(KeyError, lambda: wki_dict[my_weakreffable_list])
Example #10
0
class ChangeTracker(object): 
    '''
    Tracks changes in objects that are registered with it.
    
    To register an object, use `.check_in(obj)`. It will return `True`. Every
    time `.check_in` will be called with the same object, it will return
    whether the object changed since the last time it was checked in.
    '''
    
    def __init__(self):
        self.library = WeakKeyIdentityDict()
        '''dictoid mapping from objects to their last pickle value.'''
        
        
    def check_in(self, thing):
        '''        
        Check in an object for change tracking.
        
        The first time you check in an object, it will return `True`. Every
        time `.check_in` will be called with the same object, it will return
        whether the object changed since the last time it was checked in.
        '''
        
        new_pickle = cPickle.dumps(thing, 2)
        
        if thing not in self.library:
            self.library[thing] = new_pickle
            return True
        
        # thing in self.library
        
        previous_pickle = self.library[thing]
        if previous_pickle == new_pickle:
            return False
        else:
            self.library[thing] = new_pickle
            return True
    
        
    def __contains__(self, thing):
        '''Return whether `thing` is tracked.'''
        return self.library.__contains__(thing)
Example #11
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)
Example #12
0
    def test_weak_keyed_dict_setdefault(self):
        key, value1, value2 = C(), "value 1", "value 2"
        self.assertTrue(
            value1 is not value2, "invalid test"
            " -- value parameters must be distinct objects")
        weakdict = WeakKeyIdentityDict()
        o = weakdict.setdefault(key, value1)
        assert o is value1
        assert key in weakdict
        assert weakdict.get(key) is value1
        assert weakdict[key] is value1

        o = weakdict.setdefault(key, value2)
        assert o is value1
        assert key in weakdict
        assert weakdict.get(key) is value1
        assert weakdict[key] is value1
Example #13
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)
Example #14
0
 def __init__(self):
     self.library = WeakKeyIdentityDict()
     '''dictoid mapping from objects to their last pickle value.'''
Example #15
0
 def make_weak_keyed_dict(self):
     dict_ = WeakKeyIdentityDict()
     objects = map(Object, range(self.COUNT))
     for o in objects:
         dict_[o] = o.arg
     return dict_, objects
Example #16
0
 def test_make_weak_keyed_dict_from_weak_keyed_dict(self):
     o = Object(3)
     dict1 = WeakKeyIdentityDict({o: 364})
     dict2 = WeakKeyIdentityDict(dict1)
     self.assertTrue(dict1[o] == 364)