Rev 4769: A bit more error checking in _is_equal. in http://bazaar.launchpad.net/~jameinel/bzr/2.1-simple-set
John Arbash Meinel
john at arbash-meinel.com
Mon Oct 12 15:58:55 BST 2009
At http://bazaar.launchpad.net/~jameinel/bzr/2.1-simple-set
------------------------------------------------------------
revno: 4769
revision-id: john at arbash-meinel.com-20091012145850-9363u41ovkaz7nka
parent: john at arbash-meinel.com-20091009170327-ezw4vx4su1msq3ap
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.1-simple-set
timestamp: Mon 2009-10-12 09:58:50 -0500
message:
A bit more error checking in _is_equal.
Includes test cases that cover some bad-behavior in classes.
-------------- next part --------------
=== modified file 'bzrlib/_simple_set_pyx.pyx'
--- a/bzrlib/_simple_set_pyx.pyx 2009-10-09 16:49:45 +0000
+++ b/bzrlib/_simple_set_pyx.pyx 2009-10-12 14:58:50 +0000
@@ -59,6 +59,10 @@
if this == other:
return 1
other_hash = Py_TYPE(other).tp_hash(other)
+ if other_hash == -1:
+ # Even though other successfully hashed in the past, it seems to have
+ # changed its mind, and failed this time, so propogate the failure.
+ return -1
if other_hash != this_hash:
return 0
@@ -426,7 +430,6 @@
cdef size_t i, perturb
cdef Py_ssize_t mask
cdef long key_hash
- cdef long this_hash
cdef PyObject **table, **slot, *cur, **free_slot, *py_key
key_hash = hash(key)
=== modified file 'bzrlib/tests/test__simple_set.py'
--- a/bzrlib/tests/test__simple_set.py 2009-10-09 17:03:27 +0000
+++ b/bzrlib/tests/test__simple_set.py 2009-10-12 14:58:50 +0000
@@ -48,6 +48,27 @@
return NotImplemented
return other.hash == self.hash
+
+class _BadSecondHash(_Hashable):
+
+ def __init__(self, the_hash):
+ _Hashable.__init__(self, the_hash)
+ self._first = True
+
+ def __hash__(self):
+ if self._first:
+ self._first = False
+ return self.hash
+ else:
+ raise ValueError('I can only be hashed once.')
+
+
+class _BadCompare(_Hashable):
+
+ def __eq__(self, other):
+ raise RuntimeError('I refuse to play nice')
+
+
# Even though this is an extension, we don't permute the tests for a python
# version. As the plain python version is just a dict or set
@@ -258,6 +279,23 @@
self.assertFillState(1, 1, 0x7ff, obj)
self.assertEqual((591, '<null>'), obj._test_lookup(k2))
+ def test_second_hash_failure(self):
+ obj = self.module.SimpleSet()
+ k1 = _BadSecondHash(200)
+ k2 = _Hashable(200)
+ # Should only call hash() one time
+ obj.add(k1)
+ self.assertFalse(k1._first)
+ self.assertRaises(ValueError, obj.add, k2)
+
+ def test_richcompare_failure(self):
+ obj = self.module.SimpleSet()
+ k1 = _Hashable(200)
+ k2 = _BadCompare(200)
+ obj.add(k1)
+ # Tries to compare with k1, fails
+ self.assertRaises(RuntimeError, obj.add, k2)
+
def test_add_and_remove_lots_of_items(self):
obj = self.module.SimpleSet()
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'
More information about the bazaar-commits
mailing list