import unittest from immutables.map import map_hash, map_mask, Map as PyMap from tests.test_map import HashKey none_hash = map_hash(None) assert(none_hash != 1) assert((none_hash >> 32) == 0) not_collision = 0xffffffff & (~none_hash) mask = 0x7ffffffff none_collisions = [none_hash & (mask >> shift) for shift in reversed(range(0, 32, 5))] assert(len(none_collisions) == 7) none_collisions = [h | (not_collision & (mask << shift)) for shift, h in zip(range(5, 37, 5), none_collisions)] class NoneCollision(HashKey): def __init__(self, name, level): if name is None: raise ValueError("Can't have a NoneCollision with a None value") super().__init__(none_collisions[level], name) def __eq__(self, other): if other is None: return False return super().__eq__(other) __hash__ = HashKey.__hash__ class BaseNoneTest: Map = None def test_none_collisions(self): collisions = [NoneCollision('a', level) for level in range(7)] indices = [map_mask(none_hash, shift) for shift in range(0, 32, 5)] for i, c in enumerate(collisions[:-1], 1): self.assertNotEqual(c, None) c_hash = map_hash(c) self.assertNotEqual(c_hash, none_hash) for j, idx in enumerate(indices[:i]): self.assertEqual(map_mask(c_hash, j*5), idx) for j, idx in enumerate(indices[i:], i): self.assertNotEqual(map_mask(c_hash, j*5), idx) c = collisions[-1] self.assertNotEqual(c, None) c_hash = map_hash(c) self.assertEqual(c_hash, none_hash) for i, idx in enumerate(indices): self.assertEqual(map_mask(c_hash, i*5), idx) def test_none_as_key(self): m = self.Map({None: 1}) self.assertEqual(len(m), 1) self.assertTrue(None in m) self.assertEqual(m[None], 1) self.assertTrue(repr(m).startswith('