Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions Lib/test/test_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
from test.support import import_helper, get_c_recursion_limit


class CustomHash:
def __init__(self, hash):
self.hash = hash
def __hash__(self):
return self.hash
def __repr__(self):
return f'<CustomHash {self.hash} at {id(self):#x}>'


class DictTest(unittest.TestCase):

def test_invalid_keyword_arguments(self):
Expand Down Expand Up @@ -1701,6 +1710,29 @@ class MyClass: pass
d[MyStr("attr1")] = 2
self.assertIsInstance(list(d)[0], MyStr)

def test_hash_collision_remove_add(self):
self.maxDiff = None
# There should be enough space, so all elements with unique hash
# will be placed in corresponding cells without collision.
n = 64
items = [(CustomHash(h), h) for h in range(n)]
# Keys with hash collision.
a = CustomHash(n)
b = CustomHash(n)
items += [(a, 'a'), (b, 'b')]
d = dict(items)
self.assertEqual(len(d), len(items), d)
del d[a]
# "a" has been replaced with a dummy.
del items[n]
self.assertEqual(len(d), len(items), d)
self.assertEqual(d, dict(items))
d[b] = 'c'
# "b" should not replace the dummy.
items[n] = (b, 'c')
self.assertEqual(len(d), len(items), d)
self.assertEqual(d, dict(items))


class CAPITest(unittest.TestCase):

Expand Down
40 changes: 40 additions & 0 deletions Lib/test/test_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ def check_pass_thru():
raise PassThru
yield 1

class CustomHash:
def __init__(self, hash):
self.hash = hash
def __hash__(self):
return self.hash
def __repr__(self):
return f'<CustomHash {self.hash} at {id(self):#x}>'

class BadCmp:
def __hash__(self):
return 1
Expand Down Expand Up @@ -635,6 +643,38 @@ def __le__(self, some_set):
myset >= myobj
self.assertTrue(myobj.le_called)

def test_set_membership(self):
myfrozenset = frozenset(range(3))
myset = {myfrozenset, "abc", 1}
self.assertIn(set(range(3)), myset)
self.assertNotIn(set(range(1)), myset)
myset.discard(set(range(3)))
self.assertEqual(myset, {"abc", 1})
self.assertRaises(KeyError, myset.remove, set(range(1)))
self.assertRaises(KeyError, myset.remove, set(range(3)))

def test_hash_collision_remove_add(self):
self.maxDiff = None
# There should be enough space, so all elements with unique hash
# will be placed in corresponding cells without collision.
n = 64
elems = [CustomHash(h) for h in range(n)]
# Elements with hash collision.
a = CustomHash(n)
b = CustomHash(n)
elems += [a, b]
s = self.thetype(elems)
self.assertEqual(len(s), len(elems), s)
s.remove(a)
# "a" has been replaced with a dummy.
del elems[n]
self.assertEqual(len(s), len(elems), s)
self.assertEqual(s, set(elems))
s.add(b)
# "b" should not replace the dummy.
self.assertEqual(len(s), len(elems), s)
self.assertEqual(s, set(elems))


class SetSubclass(set):
pass
Expand Down