3
3
#
4
4
# Also test that hash implementations are inherited as expected
5
5
6
+
import os
7
+
import sys
8
+
import struct
9
+
import datetime
6
10
import unittest
11
+
import subprocess
12
+
7
13
from test import test_support
8
14
from collections import Hashable
9
15
16
+
IS_64BIT = (struct.calcsize('l') == 8)
17
+
10
18
11
19
class HashEqualityTestCase(unittest.TestCase):
12
20
@@ -133,10 +141,100 @@ def test_hashes(self):
133
141
for obj in self.hashes_to_check:
134
142
self.assertEqual(hash(obj), _default_hash(obj))
135
143
144
+
class HashRandomizationTests(unittest.TestCase):
145
+
146
+
# Each subclass should define a field "repr_", containing the repr() of
147
+
# an object to be tested
148
+
149
+
def get_hash_command(self, repr_):
150
+
return 'print(hash(%s))' % repr_
151
+
152
+
def get_hash(self, repr_, seed=None):
153
+
env = os.environ.copy()
154
+
if seed is not None:
155
+
env['PYTHONHASHSEED'] = str(seed)
156
+
else:
157
+
env.pop('PYTHONHASHSEED', None)
158
+
cmd_line = [sys.executable, '-c', self.get_hash_command(repr_)]
159
+
p = subprocess.Popen(cmd_line, stdin=subprocess.PIPE,
160
+
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
161
+
env=env)
162
+
out, err = p.communicate()
163
+
out = test_support.strip_python_stderr(out)
164
+
return int(out.strip())
165
+
166
+
def test_randomized_hash(self):
167
+
# two runs should return different hashes
168
+
run1 = self.get_hash(self.repr_, seed='random')
169
+
run2 = self.get_hash(self.repr_, seed='random')
170
+
self.assertNotEqual(run1, run2)
171
+
172
+
class StringlikeHashRandomizationTests(HashRandomizationTests):
173
+
def test_null_hash(self):
174
+
# PYTHONHASHSEED=0 disables the randomized hash
175
+
if IS_64BIT:
176
+
known_hash_of_obj = 1453079729188098211
177
+
else:
178
+
known_hash_of_obj = -1600925533
179
+
180
+
# Randomization is disabled by default:
181
+
self.assertEqual(self.get_hash(self.repr_), known_hash_of_obj)
182
+
183
+
# It can also be disabled by setting the seed to 0:
184
+
self.assertEqual(self.get_hash(self.repr_, seed=0), known_hash_of_obj)
185
+
186
+
def test_fixed_hash(self):
187
+
# test a fixed seed for the randomized hash
188
+
# Note that all types share the same values:
189
+
if IS_64BIT:
190
+
h = -4410911502303878509
191
+
else:
192
+
h = -206076799
193
+
self.assertEqual(self.get_hash(self.repr_, seed=42), h)
194
+
195
+
class StrHashRandomizationTests(StringlikeHashRandomizationTests):
196
+
repr_ = repr('abc')
197
+
198
+
def test_empty_string(self):
199
+
self.assertEqual(hash(""), 0)
200
+
201
+
class UnicodeHashRandomizationTests(StringlikeHashRandomizationTests):
202
+
repr_ = repr(u'abc')
203
+
204
+
def test_empty_string(self):
205
+
self.assertEqual(hash(u""), 0)
206
+
207
+
class BufferHashRandomizationTests(StringlikeHashRandomizationTests):
208
+
repr_ = 'buffer("abc")'
209
+
210
+
def test_empty_string(self):
211
+
self.assertEqual(hash(buffer("")), 0)
212
+
213
+
class DatetimeTests(HashRandomizationTests):
214
+
def get_hash_command(self, repr_):
215
+
return 'import datetime; print(hash(%s))' % repr_
216
+
217
+
class DatetimeDateTests(DatetimeTests):
218
+
repr_ = repr(datetime.date(1066, 10, 14))
219
+
220
+
class DatetimeDatetimeTests(DatetimeTests):
221
+
repr_ = repr(datetime.datetime(1, 2, 3, 4, 5, 6, 7))
222
+
223
+
class DatetimeTimeTests(DatetimeTests):
224
+
repr_ = repr(datetime.time(0))
225
+
226
+
136
227
def test_main():
137
228
test_support.run_unittest(HashEqualityTestCase,
138
229
HashInheritanceTestCase,
139
-
HashBuiltinsTestCase)
230
+
HashBuiltinsTestCase,
231
+
StrHashRandomizationTests,
232
+
UnicodeHashRandomizationTests,
233
+
BufferHashRandomizationTests,
234
+
DatetimeDateTests,
235
+
DatetimeDatetimeTests,
236
+
DatetimeTimeTests)
237
+
140
238
141
239
142
240
if __name__ == "__main__":
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4