test_itertoolz.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. import itertools
  2. from itertools import starmap
  3. from toolz.utils import raises
  4. from functools import partial
  5. from random import Random
  6. from pickle import dumps, loads
  7. from toolz.itertoolz import (remove, groupby, merge_sorted,
  8. concat, concatv, interleave, unique,
  9. isiterable, getter,
  10. mapcat, isdistinct, first, second,
  11. nth, take, tail, drop, interpose, get,
  12. rest, last, cons, frequencies,
  13. reduceby, iterate, accumulate,
  14. sliding_window, count, partition,
  15. partition_all, take_nth, pluck, join,
  16. diff, topk, peek, peekn, random_sample)
  17. from operator import add, mul
  18. # is comparison will fail between this and no_default
  19. no_default2 = loads(dumps('__no__default__'))
  20. def identity(x):
  21. return x
  22. def iseven(x):
  23. return x % 2 == 0
  24. def isodd(x):
  25. return x % 2 == 1
  26. def inc(x):
  27. return x + 1
  28. def double(x):
  29. return 2 * x
  30. def test_remove():
  31. r = remove(iseven, range(5))
  32. assert type(r) is not list
  33. assert list(r) == list(filter(isodd, range(5)))
  34. def test_groupby():
  35. assert groupby(iseven, [1, 2, 3, 4]) == {True: [2, 4], False: [1, 3]}
  36. def test_groupby_non_callable():
  37. assert groupby(0, [(1, 2), (1, 3), (2, 2), (2, 4)]) == \
  38. {1: [(1, 2), (1, 3)],
  39. 2: [(2, 2), (2, 4)]}
  40. assert groupby([0], [(1, 2), (1, 3), (2, 2), (2, 4)]) == \
  41. {(1,): [(1, 2), (1, 3)],
  42. (2,): [(2, 2), (2, 4)]}
  43. assert groupby([0, 0], [(1, 2), (1, 3), (2, 2), (2, 4)]) == \
  44. {(1, 1): [(1, 2), (1, 3)],
  45. (2, 2): [(2, 2), (2, 4)]}
  46. def test_merge_sorted():
  47. assert list(merge_sorted([1, 2, 3], [1, 2, 3])) == [1, 1, 2, 2, 3, 3]
  48. assert list(merge_sorted([1, 3, 5], [2, 4, 6])) == [1, 2, 3, 4, 5, 6]
  49. assert list(merge_sorted([1], [2, 4], [3], [])) == [1, 2, 3, 4]
  50. assert list(merge_sorted([5, 3, 1], [6, 4, 3], [],
  51. key=lambda x: -x)) == [6, 5, 4, 3, 3, 1]
  52. assert list(merge_sorted([2, 1, 3], [1, 2, 3],
  53. key=lambda x: x // 3)) == [2, 1, 1, 2, 3, 3]
  54. assert list(merge_sorted([2, 3], [1, 3],
  55. key=lambda x: x // 3)) == [2, 1, 3, 3]
  56. assert ''.join(merge_sorted('abc', 'abc', 'abc')) == 'aaabbbccc'
  57. assert ''.join(merge_sorted('abc', 'abc', 'abc', key=ord)) == 'aaabbbccc'
  58. assert ''.join(merge_sorted('cba', 'cba', 'cba',
  59. key=lambda x: -ord(x))) == 'cccbbbaaa'
  60. assert list(merge_sorted([1], [2, 3, 4], key=identity)) == [1, 2, 3, 4]
  61. data = [[(1, 2), (0, 4), (3, 6)], [(5, 3), (6, 5), (8, 8)],
  62. [(9, 1), (9, 8), (9, 9)]]
  63. assert list(merge_sorted(*data, key=lambda x: x[1])) == [
  64. (9, 1), (1, 2), (5, 3), (0, 4), (6, 5), (3, 6), (8, 8), (9, 8), (9, 9)]
  65. assert list(merge_sorted()) == []
  66. assert list(merge_sorted([1, 2, 3])) == [1, 2, 3]
  67. assert list(merge_sorted([1, 4, 5], [2, 3])) == [1, 2, 3, 4, 5]
  68. assert list(merge_sorted([1, 4, 5], [2, 3], key=identity)) == [
  69. 1, 2, 3, 4, 5]
  70. assert list(merge_sorted([1, 5], [2], [4, 7], [3, 6], key=identity)) == [
  71. 1, 2, 3, 4, 5, 6, 7]
  72. def test_interleave():
  73. assert ''.join(interleave(('ABC', '123'))) == 'A1B2C3'
  74. assert ''.join(interleave(('ABC', '1'))) == 'A1BC'
  75. def test_unique():
  76. assert tuple(unique((1, 2, 3))) == (1, 2, 3)
  77. assert tuple(unique((1, 2, 1, 3))) == (1, 2, 3)
  78. assert tuple(unique((1, 2, 3), key=iseven)) == (1, 2)
  79. def test_isiterable():
  80. # objects that have a __iter__() or __getitem__() method are iterable
  81. # https://docs.python.org/3/library/functions.html#iter
  82. class IterIterable:
  83. def __iter__(self):
  84. return iter(["a", "b", "c"])
  85. class GetItemIterable:
  86. def __getitem__(self, item):
  87. return ["a", "b", "c"][item]
  88. # "if a class sets __iter__() to None, the class is not iterable"
  89. # https://docs.python.org/3/reference/datamodel.html#special-method-names
  90. class NotIterable:
  91. __iter__ = None
  92. class NotIterableEvenWithGetItem:
  93. __iter__ = None
  94. def __getitem__(self, item):
  95. return ["a", "b", "c"][item]
  96. assert isiterable([1, 2, 3]) is True
  97. assert isiterable('abc') is True
  98. assert isiterable(IterIterable()) is True
  99. assert isiterable(GetItemIterable()) is True
  100. assert isiterable(5) is False
  101. assert isiterable(NotIterable()) is False
  102. assert isiterable(NotIterableEvenWithGetItem()) is False
  103. def test_isdistinct():
  104. assert isdistinct([1, 2, 3]) is True
  105. assert isdistinct([1, 2, 1]) is False
  106. assert isdistinct("Hello") is False
  107. assert isdistinct("World") is True
  108. assert isdistinct(iter([1, 2, 3])) is True
  109. assert isdistinct(iter([1, 2, 1])) is False
  110. def test_nth():
  111. assert nth(2, 'ABCDE') == 'C'
  112. assert nth(2, iter('ABCDE')) == 'C'
  113. assert nth(1, (3, 2, 1)) == 2
  114. assert nth(0, {'foo': 'bar'}) == 'foo'
  115. assert raises(StopIteration, lambda: nth(10, {10: 'foo'}))
  116. assert nth(-2, 'ABCDE') == 'D'
  117. assert raises(ValueError, lambda: nth(-2, iter('ABCDE')))
  118. def test_first():
  119. assert first('ABCDE') == 'A'
  120. assert first((3, 2, 1)) == 3
  121. assert isinstance(first({0: 'zero', 1: 'one'}), int)
  122. def test_second():
  123. assert second('ABCDE') == 'B'
  124. assert second((3, 2, 1)) == 2
  125. assert isinstance(second({0: 'zero', 1: 'one'}), int)
  126. def test_last():
  127. assert last('ABCDE') == 'E'
  128. assert last((3, 2, 1)) == 1
  129. assert isinstance(last({0: 'zero', 1: 'one'}), int)
  130. def test_rest():
  131. assert list(rest('ABCDE')) == list('BCDE')
  132. assert list(rest((3, 2, 1))) == list((2, 1))
  133. def test_take():
  134. assert list(take(3, 'ABCDE')) == list('ABC')
  135. assert list(take(2, (3, 2, 1))) == list((3, 2))
  136. def test_tail():
  137. assert list(tail(3, 'ABCDE')) == list('CDE')
  138. assert list(tail(3, iter('ABCDE'))) == list('CDE')
  139. assert list(tail(2, (3, 2, 1))) == list((2, 1))
  140. def test_drop():
  141. assert list(drop(3, 'ABCDE')) == list('DE')
  142. assert list(drop(1, (3, 2, 1))) == list((2, 1))
  143. def test_take_nth():
  144. assert list(take_nth(2, 'ABCDE')) == list('ACE')
  145. def test_get():
  146. assert get(1, 'ABCDE') == 'B'
  147. assert list(get([1, 3], 'ABCDE')) == list('BD')
  148. assert get('a', {'a': 1, 'b': 2, 'c': 3}) == 1
  149. assert get(['a', 'b'], {'a': 1, 'b': 2, 'c': 3}) == (1, 2)
  150. assert get('foo', {}, default='bar') == 'bar'
  151. assert get({}, [1, 2, 3], default='bar') == 'bar'
  152. assert get([0, 2], 'AB', 'C') == ('A', 'C')
  153. assert get([0], 'AB') == ('A',)
  154. assert get([], 'AB') == ()
  155. assert raises(IndexError, lambda: get(10, 'ABC'))
  156. assert raises(KeyError, lambda: get(10, {'a': 1}))
  157. assert raises(TypeError, lambda: get({}, [1, 2, 3]))
  158. assert raises(TypeError, lambda: get([1, 2, 3], 1, None))
  159. assert raises(KeyError, lambda: get('foo', {}, default=no_default2))
  160. def test_mapcat():
  161. assert (list(mapcat(identity, [[1, 2, 3], [4, 5, 6]])) ==
  162. [1, 2, 3, 4, 5, 6])
  163. assert (list(mapcat(reversed, [[3, 2, 1, 0], [6, 5, 4], [9, 8, 7]])) ==
  164. list(range(10)))
  165. inc = lambda i: i + 1
  166. assert ([4, 5, 6, 7, 8, 9] ==
  167. list(mapcat(partial(map, inc), [[3, 4, 5], [6, 7, 8]])))
  168. def test_cons():
  169. assert list(cons(1, [2, 3])) == [1, 2, 3]
  170. def test_concat():
  171. assert list(concat([[], [], []])) == []
  172. assert (list(take(5, concat([['a', 'b'], range(1000000000)]))) ==
  173. ['a', 'b', 0, 1, 2])
  174. def test_concatv():
  175. assert list(concatv([], [], [])) == []
  176. assert (list(take(5, concatv(['a', 'b'], range(1000000000)))) ==
  177. ['a', 'b', 0, 1, 2])
  178. def test_interpose():
  179. assert "a" == first(rest(interpose("a", range(1000000000))))
  180. assert "tXaXrXzXaXn" == "".join(interpose("X", "tarzan"))
  181. assert list(interpose(0, itertools.repeat(1, 4))) == [1, 0, 1, 0, 1, 0, 1]
  182. assert list(interpose('.', ['a', 'b', 'c'])) == ['a', '.', 'b', '.', 'c']
  183. def test_frequencies():
  184. assert (frequencies(["cat", "pig", "cat", "eel",
  185. "pig", "dog", "dog", "dog"]) ==
  186. {"cat": 2, "eel": 1, "pig": 2, "dog": 3})
  187. assert frequencies([]) == {}
  188. assert frequencies("onomatopoeia") == {"a": 2, "e": 1, "i": 1, "m": 1,
  189. "o": 4, "n": 1, "p": 1, "t": 1}
  190. def test_reduceby():
  191. data = [1, 2, 3, 4, 5]
  192. iseven = lambda x: x % 2 == 0
  193. assert reduceby(iseven, add, data, 0) == {False: 9, True: 6}
  194. assert reduceby(iseven, mul, data, 1) == {False: 15, True: 8}
  195. projects = [{'name': 'build roads', 'state': 'CA', 'cost': 1000000},
  196. {'name': 'fight crime', 'state': 'IL', 'cost': 100000},
  197. {'name': 'help farmers', 'state': 'IL', 'cost': 2000000},
  198. {'name': 'help farmers', 'state': 'CA', 'cost': 200000}]
  199. assert reduceby(lambda x: x['state'],
  200. lambda acc, x: acc + x['cost'],
  201. projects, 0) == {'CA': 1200000, 'IL': 2100000}
  202. assert reduceby('state',
  203. lambda acc, x: acc + x['cost'],
  204. projects, 0) == {'CA': 1200000, 'IL': 2100000}
  205. def test_reduce_by_init():
  206. assert reduceby(iseven, add, [1, 2, 3, 4]) == {True: 2 + 4, False: 1 + 3}
  207. assert reduceby(iseven, add, [1, 2, 3, 4], no_default2) == {True: 2 + 4,
  208. False: 1 + 3}
  209. def test_reduce_by_callable_default():
  210. def set_add(s, i):
  211. s.add(i)
  212. return s
  213. assert reduceby(iseven, set_add, [1, 2, 3, 4, 1, 2], set) == \
  214. {True: {2, 4}, False: {1, 3}}
  215. def test_iterate():
  216. assert list(itertools.islice(iterate(inc, 0), 0, 5)) == [0, 1, 2, 3, 4]
  217. assert list(take(4, iterate(double, 1))) == [1, 2, 4, 8]
  218. def test_accumulate():
  219. assert list(accumulate(add, [1, 2, 3, 4, 5])) == [1, 3, 6, 10, 15]
  220. assert list(accumulate(mul, [1, 2, 3, 4, 5])) == [1, 2, 6, 24, 120]
  221. assert list(accumulate(add, [1, 2, 3, 4, 5], -1)) == [-1, 0, 2, 5, 9, 14]
  222. def binop(a, b):
  223. raise AssertionError('binop should not be called')
  224. start = object()
  225. assert list(accumulate(binop, [], start)) == [start]
  226. assert list(accumulate(binop, [])) == []
  227. assert list(accumulate(add, [1, 2, 3], no_default2)) == [1, 3, 6]
  228. def test_accumulate_works_on_consumable_iterables():
  229. assert list(accumulate(add, iter((1, 2, 3)))) == [1, 3, 6]
  230. def test_sliding_window():
  231. assert list(sliding_window(2, [1, 2, 3, 4])) == [(1, 2), (2, 3), (3, 4)]
  232. assert list(sliding_window(3, [1, 2, 3, 4])) == [(1, 2, 3), (2, 3, 4)]
  233. def test_sliding_window_of_short_iterator():
  234. assert list(sliding_window(3, [1, 2])) == []
  235. assert list(sliding_window(7, [1, 2])) == []
  236. def test_partition():
  237. assert list(partition(2, [1, 2, 3, 4])) == [(1, 2), (3, 4)]
  238. assert list(partition(3, range(7))) == [(0, 1, 2), (3, 4, 5)]
  239. assert list(partition(3, range(4), pad=-1)) == [(0, 1, 2),
  240. (3, -1, -1)]
  241. assert list(partition(2, [])) == []
  242. def test_partition_all():
  243. assert list(partition_all(2, [1, 2, 3, 4])) == [(1, 2), (3, 4)]
  244. assert list(partition_all(3, range(5))) == [(0, 1, 2), (3, 4)]
  245. assert list(partition_all(2, [])) == []
  246. # Regression test: https://github.com/pytoolz/toolz/issues/387
  247. class NoCompare(object):
  248. def __eq__(self, other):
  249. if self.__class__ == other.__class__:
  250. return True
  251. raise ValueError()
  252. obj = NoCompare()
  253. result = [(obj, obj, obj, obj), (obj, obj, obj)]
  254. assert list(partition_all(4, [obj]*7)) == result
  255. assert list(partition_all(4, iter([obj]*7))) == result
  256. def test_count():
  257. assert count((1, 2, 3)) == 3
  258. assert count([]) == 0
  259. assert count(iter((1, 2, 3, 4))) == 4
  260. assert count('hello') == 5
  261. assert count(iter('hello')) == 5
  262. def test_pluck():
  263. assert list(pluck(0, [[0, 1], [2, 3], [4, 5]])) == [0, 2, 4]
  264. assert list(pluck([0, 1], [[0, 1, 2], [3, 4, 5]])) == [(0, 1), (3, 4)]
  265. assert list(pluck(1, [[0], [0, 1]], None)) == [None, 1]
  266. data = [{'id': 1, 'name': 'cheese'}, {'id': 2, 'name': 'pies', 'price': 1}]
  267. assert list(pluck('id', data)) == [1, 2]
  268. assert list(pluck('price', data, 0)) == [0, 1]
  269. assert list(pluck(['id', 'name'], data)) == [(1, 'cheese'), (2, 'pies')]
  270. assert list(pluck(['name'], data)) == [('cheese',), ('pies',)]
  271. assert list(pluck(['price', 'other'], data, 0)) == [(0, 0), (1, 0)]
  272. assert raises(IndexError, lambda: list(pluck(1, [[0]])))
  273. assert raises(KeyError, lambda: list(pluck('name', [{'id': 1}])))
  274. assert list(pluck(0, [[0, 1], [2, 3], [4, 5]], no_default2)) == [0, 2, 4]
  275. assert raises(IndexError, lambda: list(pluck(1, [[0]], no_default2)))
  276. def test_join():
  277. names = [(1, 'one'), (2, 'two'), (3, 'three')]
  278. fruit = [('apple', 1), ('orange', 1), ('banana', 2), ('coconut', 2)]
  279. def addpair(pair):
  280. return pair[0] + pair[1]
  281. result = set(starmap(add, join(first, names, second, fruit)))
  282. expected = {(1, 'one', 'apple', 1),
  283. (1, 'one', 'orange', 1),
  284. (2, 'two', 'banana', 2),
  285. (2, 'two', 'coconut', 2)}
  286. assert result == expected
  287. result = set(starmap(add, join(first, names, second, fruit,
  288. left_default=no_default2,
  289. right_default=no_default2)))
  290. assert result == expected
  291. def test_getter():
  292. assert getter(0)('Alice') == 'A'
  293. assert getter([0])('Alice') == ('A',)
  294. assert getter([])('Alice') == ()
  295. def test_key_as_getter():
  296. squares = [(i, i**2) for i in range(5)]
  297. pows = [(i, i**2, i**3) for i in range(5)]
  298. assert set(join(0, squares, 0, pows)) == set(join(lambda x: x[0], squares,
  299. lambda x: x[0], pows))
  300. get = lambda x: (x[0], x[1])
  301. assert set(join([0, 1], squares, [0, 1], pows)) == set(join(get, squares,
  302. get, pows))
  303. get = lambda x: (x[0],)
  304. assert set(join([0], squares, [0], pows)) == set(join(get, squares,
  305. get, pows))
  306. def test_join_double_repeats():
  307. names = [(1, 'one'), (2, 'two'), (3, 'three'), (1, 'uno'), (2, 'dos')]
  308. fruit = [('apple', 1), ('orange', 1), ('banana', 2), ('coconut', 2)]
  309. result = set(starmap(add, join(first, names, second, fruit)))
  310. expected = {(1, 'one', 'apple', 1),
  311. (1, 'one', 'orange', 1),
  312. (2, 'two', 'banana', 2),
  313. (2, 'two', 'coconut', 2),
  314. (1, 'uno', 'apple', 1),
  315. (1, 'uno', 'orange', 1),
  316. (2, 'dos', 'banana', 2),
  317. (2, 'dos', 'coconut', 2)}
  318. assert result == expected
  319. def test_join_missing_element():
  320. names = [(1, 'one'), (2, 'two'), (3, 'three')]
  321. fruit = [('apple', 5), ('orange', 1)]
  322. result = set(starmap(add, join(first, names, second, fruit)))
  323. expected = {(1, 'one', 'orange', 1)}
  324. assert result == expected
  325. def test_left_outer_join():
  326. result = set(join(identity, [1, 2], identity, [2, 3], left_default=None))
  327. expected = {(2, 2), (None, 3)}
  328. assert result == expected
  329. def test_right_outer_join():
  330. result = set(join(identity, [1, 2], identity, [2, 3], right_default=None))
  331. expected = {(2, 2), (1, None)}
  332. assert result == expected
  333. def test_outer_join():
  334. result = set(join(identity, [1, 2], identity, [2, 3],
  335. left_default=None, right_default=None))
  336. expected = {(2, 2), (1, None), (None, 3)}
  337. assert result == expected
  338. def test_diff():
  339. assert raises(TypeError, lambda: list(diff()))
  340. assert raises(TypeError, lambda: list(diff([1, 2])))
  341. assert raises(TypeError, lambda: list(diff([1, 2], 3)))
  342. assert list(diff([1, 2], (1, 2), iter([1, 2]))) == []
  343. assert list(diff([1, 2, 3], (1, 10, 3), iter([1, 2, 10]))) == [
  344. (2, 10, 2), (3, 3, 10)]
  345. assert list(diff([1, 2], [10])) == [(1, 10)]
  346. assert list(diff([1, 2], [10], default=None)) == [(1, 10), (2, None)]
  347. # non-variadic usage
  348. assert raises(TypeError, lambda: list(diff([])))
  349. assert raises(TypeError, lambda: list(diff([[]])))
  350. assert raises(TypeError, lambda: list(diff([[1, 2]])))
  351. assert raises(TypeError, lambda: list(diff([[1, 2], 3])))
  352. assert list(diff([(1, 2), (1, 3)])) == [(2, 3)]
  353. data1 = [{'cost': 1, 'currency': 'dollar'},
  354. {'cost': 2, 'currency': 'dollar'}]
  355. data2 = [{'cost': 100, 'currency': 'yen'},
  356. {'cost': 300, 'currency': 'yen'}]
  357. conversions = {'dollar': 1, 'yen': 0.01}
  358. def indollars(item):
  359. return conversions[item['currency']] * item['cost']
  360. list(diff(data1, data2, key=indollars)) == [
  361. ({'cost': 2, 'currency': 'dollar'}, {'cost': 300, 'currency': 'yen'})]
  362. def test_topk():
  363. assert topk(2, [4, 1, 5, 2]) == (5, 4)
  364. assert topk(2, [4, 1, 5, 2], key=lambda x: -x) == (1, 2)
  365. assert topk(2, iter([5, 1, 4, 2]), key=lambda x: -x) == (1, 2)
  366. assert topk(2, [{'a': 1, 'b': 10}, {'a': 2, 'b': 9},
  367. {'a': 10, 'b': 1}, {'a': 9, 'b': 2}], key='a') == \
  368. ({'a': 10, 'b': 1}, {'a': 9, 'b': 2})
  369. assert topk(2, [{'a': 1, 'b': 10}, {'a': 2, 'b': 9},
  370. {'a': 10, 'b': 1}, {'a': 9, 'b': 2}], key='b') == \
  371. ({'a': 1, 'b': 10}, {'a': 2, 'b': 9})
  372. assert topk(2, [(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)], 0) == \
  373. ((4, 0), (3, 1))
  374. def test_topk_is_stable():
  375. assert topk(4, [5, 9, 2, 1, 5, 3], key=lambda x: 1) == (5, 9, 2, 1)
  376. def test_peek():
  377. alist = ["Alice", "Bob", "Carol"]
  378. element, blist = peek(alist)
  379. assert element == alist[0]
  380. assert list(blist) == alist
  381. assert raises(StopIteration, lambda: peek([]))
  382. def test_peekn():
  383. alist = ("Alice", "Bob", "Carol")
  384. elements, blist = peekn(2, alist)
  385. assert elements == alist[:2]
  386. assert tuple(blist) == alist
  387. elements, blist = peekn(len(alist) * 4, alist)
  388. assert elements == alist
  389. assert tuple(blist) == alist
  390. def test_random_sample():
  391. alist = list(range(100))
  392. assert list(random_sample(prob=1, seq=alist, random_state=2016)) == alist
  393. mk_rsample = lambda rs=1: list(random_sample(prob=0.1,
  394. seq=alist,
  395. random_state=rs))
  396. rsample1 = mk_rsample()
  397. assert rsample1 == mk_rsample()
  398. rsample2 = mk_rsample(1984)
  399. randobj = Random(1984)
  400. assert rsample2 == mk_rsample(randobj)
  401. assert rsample1 != rsample2
  402. assert mk_rsample(hash(object)) == mk_rsample(hash(object))
  403. assert mk_rsample(hash(object)) != mk_rsample(hash(object()))
  404. assert mk_rsample(b"a") == mk_rsample(u"a")
  405. assert raises(TypeError, lambda: mk_rsample([]))