| OLD | NEW |
| 1 # test the invariant that | 1 # test the invariant that |
| 2 # iff a==b then hash(a)==hash(b) | 2 # iff a==b then hash(a)==hash(b) |
| 3 # | 3 # |
| 4 # Also test that hash implementations are inherited as expected | 4 # Also test that hash implementations are inherited as expected |
| 5 | 5 |
| 6 import struct |
| 6 import unittest | 7 import unittest |
| 7 from test import support | 8 from test import support |
| 9 from test.script_helper import assert_python_ok |
| 8 from collections import Hashable | 10 from collections import Hashable |
| 11 |
| 12 IS_64BIT = (struct.calcsize('l') == 8) |
| 9 | 13 |
| 10 | 14 |
| 11 class HashEqualityTestCase(unittest.TestCase): | 15 class HashEqualityTestCase(unittest.TestCase): |
| 12 | 16 |
| 13 def same_hash(self, *objlist): | 17 def same_hash(self, *objlist): |
| 14 # Hash each object given and fail if | 18 # Hash each object given and fail if |
| 15 # the hash values are not all the same. | 19 # the hash values are not all the same. |
| 16 hashed = list(map(hash, objlist)) | 20 hashed = list(map(hash, objlist)) |
| 17 for h in hashed[1:]: | 21 for h in hashed[1:]: |
| 18 if h != hashed[0]: | 22 if h != hashed[0]: |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 hashes_to_check = [range(10), | 114 hashes_to_check = [range(10), |
| 111 enumerate(range(10)), | 115 enumerate(range(10)), |
| 112 iter(DefaultIterSeq()), | 116 iter(DefaultIterSeq()), |
| 113 iter(lambda: 0, 0), | 117 iter(lambda: 0, 0), |
| 114 ] | 118 ] |
| 115 | 119 |
| 116 def test_hashes(self): | 120 def test_hashes(self): |
| 117 _default_hash = object.__hash__ | 121 _default_hash = object.__hash__ |
| 118 for obj in self.hashes_to_check: | 122 for obj in self.hashes_to_check: |
| 119 self.assertEqual(hash(obj), _default_hash(obj)) | 123 self.assertEqual(hash(obj), _default_hash(obj)) |
| 124 |
| 125 class RandomizationTestCase(unittest.TestCase): |
| 126 |
| 127 # Examples of the various types having randomized hash: |
| 128 test_reprs = [repr('abc'), repr(b'abc')] |
| 129 |
| 130 def get_hash(self, repr_, randomization=None, seed=None): |
| 131 env = {} |
| 132 if randomization is not None: |
| 133 env['PYTHONHASHRANDOMIZATION'] = str(randomization) |
| 134 if seed is not None: |
| 135 env['PYTHONHASHSEED'] = str(seed) |
| 136 out = assert_python_ok( |
| 137 '-c', 'print(hash(%s))' % repr_, |
| 138 **env) |
| 139 stdout = out[1].strip() |
| 140 return int(stdout) |
| 141 |
| 142 def test_empty_string(self): |
| 143 self.assertEqual(hash(""), 0) |
| 144 self.assertEqual(hash(b""), 0) |
| 145 |
| 146 def test_null_hash(self): |
| 147 # PYTHONHASHSEED=0 disables the randomized hash |
| 148 if IS_64BIT: |
| 149 known_hash_of_obj = 1453079729188098211 |
| 150 else: |
| 151 known_hash_of_obj = -1600925533 |
| 152 for repr_ in self.test_reprs: |
| 153 # Randomization is disabled by default: |
| 154 self.assertEqual(self.get_hash(repr_), known_hash_of_obj) |
| 155 |
| 156 # If enabled, it can still be disabled by setting the seed to 0: |
| 157 self.assertEqual(self.get_hash(repr_, randomization=1, seed=0), |
| 158 known_hash_of_obj) |
| 159 |
| 160 def test_fixed_hash(self): |
| 161 # test a fixed seed for the randomized hash |
| 162 # Note that all types share the same values: |
| 163 if IS_64BIT: |
| 164 h = -4410911502303878509 |
| 165 else: |
| 166 h = -206076799 |
| 167 for repr_ in self.test_reprs: |
| 168 self.assertEqual(self.get_hash(repr_, randomization=1, seed=42), |
| 169 h) |
| 170 |
| 171 def test_randomized_hash(self): |
| 172 # two runs should return different hashes |
| 173 for repr_ in self.test_reprs: |
| 174 run1 = self.get_hash(repr_, randomization=1) |
| 175 run2 = self.get_hash(repr_, randomization=1) |
| 176 self.assertNotEqual(run1, run2) |
| 177 |
| 120 | 178 |
| 121 def test_main(): | 179 def test_main(): |
| 122 support.run_unittest(HashEqualityTestCase, | 180 support.run_unittest(HashEqualityTestCase, |
| 123 HashInheritanceTestCase, | 181 HashInheritanceTestCase, |
| 124 HashBuiltinsTestCase) | 182 HashBuiltinsTestCase, |
| 183 RandomizationTestCase) |
| 125 | 184 |
| 126 | 185 |
| 127 if __name__ == "__main__": | 186 if __name__ == "__main__": |
| 128 test_main() | 187 test_main() |
| OLD | NEW |