|
12 | 12 | from test.support import import_helper |
13 | 13 |
|
14 | 14 |
|
| 15 | +class CustomHash: |
| 16 | + def __init__(self, hash): |
| 17 | + self.hash = hash |
| 18 | + def __hash__(self): |
| 19 | + return self.hash |
| 20 | + def __repr__(self): |
| 21 | + return f'<CustomHash {self.hash} at {id(self):#x}>' |
| 22 | + |
| 23 | + |
15 | 24 | class DictTest(unittest.TestCase): |
16 | 25 |
|
17 | 26 | def test_invalid_keyword_arguments(self): |
@@ -1648,6 +1657,29 @@ class MyClass: pass |
1648 | 1657 | d[MyStr("attr1")] = 2 |
1649 | 1658 | self.assertIsInstance(list(d)[0], MyStr) |
1650 | 1659 |
|
| 1660 | + def test_hash_collision_remove_add(self): |
| 1661 | + self.maxDiff = None |
| 1662 | + # There should be enough space, so all elements with unique hash |
| 1663 | + # will be placed in corresponding cells without collision. |
| 1664 | + n = 64 |
| 1665 | + items = [(CustomHash(h), h) for h in range(n)] |
| 1666 | + # Keys with hash collision. |
| 1667 | + a = CustomHash(n) |
| 1668 | + b = CustomHash(n) |
| 1669 | + items += [(a, 'a'), (b, 'b')] |
| 1670 | + d = dict(items) |
| 1671 | + self.assertEqual(len(d), len(items), d) |
| 1672 | + del d[a] |
| 1673 | + # "a" has been replaced with a dummy. |
| 1674 | + del items[n] |
| 1675 | + self.assertEqual(len(d), len(items), d) |
| 1676 | + self.assertEqual(d, dict(items)) |
| 1677 | + d[b] = 'c' |
| 1678 | + # "b" should not replace the dummy. |
| 1679 | + items[n] = (b, 'c') |
| 1680 | + self.assertEqual(len(d), len(items), d) |
| 1681 | + self.assertEqual(d, dict(items)) |
| 1682 | + |
1651 | 1683 |
|
1652 | 1684 | class CAPITest(unittest.TestCase): |
1653 | 1685 |
|
|
0 commit comments