17db96d56Sopenharmony_ci"""Unittests for heapq.""" 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciimport random 47db96d56Sopenharmony_ciimport unittest 57db96d56Sopenharmony_ciimport doctest 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_cifrom test import support 87db96d56Sopenharmony_cifrom test.support import import_helper 97db96d56Sopenharmony_cifrom unittest import TestCase, skipUnless 107db96d56Sopenharmony_cifrom operator import itemgetter 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_cipy_heapq = import_helper.import_fresh_module('heapq', blocked=['_heapq']) 137db96d56Sopenharmony_cic_heapq = import_helper.import_fresh_module('heapq', fresh=['_heapq']) 147db96d56Sopenharmony_ci 157db96d56Sopenharmony_ci# _heapq.nlargest/nsmallest are saved in heapq._nlargest/_smallest when 167db96d56Sopenharmony_ci# _heapq is imported, so check them there 177db96d56Sopenharmony_cifunc_names = ['heapify', 'heappop', 'heappush', 'heappushpop', 'heapreplace', 187db96d56Sopenharmony_ci '_heappop_max', '_heapreplace_max', '_heapify_max'] 197db96d56Sopenharmony_ci 207db96d56Sopenharmony_ciclass TestModules(TestCase): 217db96d56Sopenharmony_ci def test_py_functions(self): 227db96d56Sopenharmony_ci for fname in func_names: 237db96d56Sopenharmony_ci self.assertEqual(getattr(py_heapq, fname).__module__, 'heapq') 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci @skipUnless(c_heapq, 'requires _heapq') 267db96d56Sopenharmony_ci def test_c_functions(self): 277db96d56Sopenharmony_ci for fname in func_names: 287db96d56Sopenharmony_ci self.assertEqual(getattr(c_heapq, fname).__module__, '_heapq') 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_cidef load_tests(loader, tests, ignore): 327db96d56Sopenharmony_ci # The 'merge' function has examples in its docstring which we should test 337db96d56Sopenharmony_ci # with 'doctest'. 347db96d56Sopenharmony_ci # 357db96d56Sopenharmony_ci # However, doctest can't easily find all docstrings in the module (loading 367db96d56Sopenharmony_ci # it through import_fresh_module seems to confuse it), so we specifically 377db96d56Sopenharmony_ci # create a finder which returns the doctests from the merge method. 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci class HeapqMergeDocTestFinder: 407db96d56Sopenharmony_ci def find(self, *args, **kwargs): 417db96d56Sopenharmony_ci dtf = doctest.DocTestFinder() 427db96d56Sopenharmony_ci return dtf.find(py_heapq.merge) 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci tests.addTests(doctest.DocTestSuite(py_heapq, 457db96d56Sopenharmony_ci test_finder=HeapqMergeDocTestFinder())) 467db96d56Sopenharmony_ci return tests 477db96d56Sopenharmony_ci 487db96d56Sopenharmony_ciclass TestHeap: 497db96d56Sopenharmony_ci 507db96d56Sopenharmony_ci def test_push_pop(self): 517db96d56Sopenharmony_ci # 1) Push 256 random numbers and pop them off, verifying all's OK. 527db96d56Sopenharmony_ci heap = [] 537db96d56Sopenharmony_ci data = [] 547db96d56Sopenharmony_ci self.check_invariant(heap) 557db96d56Sopenharmony_ci for i in range(256): 567db96d56Sopenharmony_ci item = random.random() 577db96d56Sopenharmony_ci data.append(item) 587db96d56Sopenharmony_ci self.module.heappush(heap, item) 597db96d56Sopenharmony_ci self.check_invariant(heap) 607db96d56Sopenharmony_ci results = [] 617db96d56Sopenharmony_ci while heap: 627db96d56Sopenharmony_ci item = self.module.heappop(heap) 637db96d56Sopenharmony_ci self.check_invariant(heap) 647db96d56Sopenharmony_ci results.append(item) 657db96d56Sopenharmony_ci data_sorted = data[:] 667db96d56Sopenharmony_ci data_sorted.sort() 677db96d56Sopenharmony_ci self.assertEqual(data_sorted, results) 687db96d56Sopenharmony_ci # 2) Check that the invariant holds for a sorted array 697db96d56Sopenharmony_ci self.check_invariant(results) 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci self.assertRaises(TypeError, self.module.heappush, []) 727db96d56Sopenharmony_ci try: 737db96d56Sopenharmony_ci self.assertRaises(TypeError, self.module.heappush, None, None) 747db96d56Sopenharmony_ci self.assertRaises(TypeError, self.module.heappop, None) 757db96d56Sopenharmony_ci except AttributeError: 767db96d56Sopenharmony_ci pass 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_ci def check_invariant(self, heap): 797db96d56Sopenharmony_ci # Check the heap invariant. 807db96d56Sopenharmony_ci for pos, item in enumerate(heap): 817db96d56Sopenharmony_ci if pos: # pos 0 has no parent 827db96d56Sopenharmony_ci parentpos = (pos-1) >> 1 837db96d56Sopenharmony_ci self.assertTrue(heap[parentpos] <= item) 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci def test_heapify(self): 867db96d56Sopenharmony_ci for size in list(range(30)) + [20000]: 877db96d56Sopenharmony_ci heap = [random.random() for dummy in range(size)] 887db96d56Sopenharmony_ci self.module.heapify(heap) 897db96d56Sopenharmony_ci self.check_invariant(heap) 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_ci self.assertRaises(TypeError, self.module.heapify, None) 927db96d56Sopenharmony_ci 937db96d56Sopenharmony_ci def test_naive_nbest(self): 947db96d56Sopenharmony_ci data = [random.randrange(2000) for i in range(1000)] 957db96d56Sopenharmony_ci heap = [] 967db96d56Sopenharmony_ci for item in data: 977db96d56Sopenharmony_ci self.module.heappush(heap, item) 987db96d56Sopenharmony_ci if len(heap) > 10: 997db96d56Sopenharmony_ci self.module.heappop(heap) 1007db96d56Sopenharmony_ci heap.sort() 1017db96d56Sopenharmony_ci self.assertEqual(heap, sorted(data)[-10:]) 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci def heapiter(self, heap): 1047db96d56Sopenharmony_ci # An iterator returning a heap's elements, smallest-first. 1057db96d56Sopenharmony_ci try: 1067db96d56Sopenharmony_ci while 1: 1077db96d56Sopenharmony_ci yield self.module.heappop(heap) 1087db96d56Sopenharmony_ci except IndexError: 1097db96d56Sopenharmony_ci pass 1107db96d56Sopenharmony_ci 1117db96d56Sopenharmony_ci def test_nbest(self): 1127db96d56Sopenharmony_ci # Less-naive "N-best" algorithm, much faster (if len(data) is big 1137db96d56Sopenharmony_ci # enough <wink>) than sorting all of data. However, if we had a max 1147db96d56Sopenharmony_ci # heap instead of a min heap, it could go faster still via 1157db96d56Sopenharmony_ci # heapify'ing all of data (linear time), then doing 10 heappops 1167db96d56Sopenharmony_ci # (10 log-time steps). 1177db96d56Sopenharmony_ci data = [random.randrange(2000) for i in range(1000)] 1187db96d56Sopenharmony_ci heap = data[:10] 1197db96d56Sopenharmony_ci self.module.heapify(heap) 1207db96d56Sopenharmony_ci for item in data[10:]: 1217db96d56Sopenharmony_ci if item > heap[0]: # this gets rarer the longer we run 1227db96d56Sopenharmony_ci self.module.heapreplace(heap, item) 1237db96d56Sopenharmony_ci self.assertEqual(list(self.heapiter(heap)), sorted(data)[-10:]) 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_ci self.assertRaises(TypeError, self.module.heapreplace, None) 1267db96d56Sopenharmony_ci self.assertRaises(TypeError, self.module.heapreplace, None, None) 1277db96d56Sopenharmony_ci self.assertRaises(IndexError, self.module.heapreplace, [], None) 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_ci def test_nbest_with_pushpop(self): 1307db96d56Sopenharmony_ci data = [random.randrange(2000) for i in range(1000)] 1317db96d56Sopenharmony_ci heap = data[:10] 1327db96d56Sopenharmony_ci self.module.heapify(heap) 1337db96d56Sopenharmony_ci for item in data[10:]: 1347db96d56Sopenharmony_ci self.module.heappushpop(heap, item) 1357db96d56Sopenharmony_ci self.assertEqual(list(self.heapiter(heap)), sorted(data)[-10:]) 1367db96d56Sopenharmony_ci self.assertEqual(self.module.heappushpop([], 'x'), 'x') 1377db96d56Sopenharmony_ci 1387db96d56Sopenharmony_ci def test_heappushpop(self): 1397db96d56Sopenharmony_ci h = [] 1407db96d56Sopenharmony_ci x = self.module.heappushpop(h, 10) 1417db96d56Sopenharmony_ci self.assertEqual((h, x), ([], 10)) 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ci h = [10] 1447db96d56Sopenharmony_ci x = self.module.heappushpop(h, 10.0) 1457db96d56Sopenharmony_ci self.assertEqual((h, x), ([10], 10.0)) 1467db96d56Sopenharmony_ci self.assertEqual(type(h[0]), int) 1477db96d56Sopenharmony_ci self.assertEqual(type(x), float) 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci h = [10] 1507db96d56Sopenharmony_ci x = self.module.heappushpop(h, 9) 1517db96d56Sopenharmony_ci self.assertEqual((h, x), ([10], 9)) 1527db96d56Sopenharmony_ci 1537db96d56Sopenharmony_ci h = [10] 1547db96d56Sopenharmony_ci x = self.module.heappushpop(h, 11) 1557db96d56Sopenharmony_ci self.assertEqual((h, x), ([11], 10)) 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_ci def test_heappop_max(self): 1587db96d56Sopenharmony_ci # _heapop_max has an optimization for one-item lists which isn't 1597db96d56Sopenharmony_ci # covered in other tests, so test that case explicitly here 1607db96d56Sopenharmony_ci h = [3, 2] 1617db96d56Sopenharmony_ci self.assertEqual(self.module._heappop_max(h), 3) 1627db96d56Sopenharmony_ci self.assertEqual(self.module._heappop_max(h), 2) 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ci def test_heapsort(self): 1657db96d56Sopenharmony_ci # Exercise everything with repeated heapsort checks 1667db96d56Sopenharmony_ci for trial in range(100): 1677db96d56Sopenharmony_ci size = random.randrange(50) 1687db96d56Sopenharmony_ci data = [random.randrange(25) for i in range(size)] 1697db96d56Sopenharmony_ci if trial & 1: # Half of the time, use heapify 1707db96d56Sopenharmony_ci heap = data[:] 1717db96d56Sopenharmony_ci self.module.heapify(heap) 1727db96d56Sopenharmony_ci else: # The rest of the time, use heappush 1737db96d56Sopenharmony_ci heap = [] 1747db96d56Sopenharmony_ci for item in data: 1757db96d56Sopenharmony_ci self.module.heappush(heap, item) 1767db96d56Sopenharmony_ci heap_sorted = [self.module.heappop(heap) for i in range(size)] 1777db96d56Sopenharmony_ci self.assertEqual(heap_sorted, sorted(data)) 1787db96d56Sopenharmony_ci 1797db96d56Sopenharmony_ci def test_merge(self): 1807db96d56Sopenharmony_ci inputs = [] 1817db96d56Sopenharmony_ci for i in range(random.randrange(25)): 1827db96d56Sopenharmony_ci row = [] 1837db96d56Sopenharmony_ci for j in range(random.randrange(100)): 1847db96d56Sopenharmony_ci tup = random.choice('ABC'), random.randrange(-500, 500) 1857db96d56Sopenharmony_ci row.append(tup) 1867db96d56Sopenharmony_ci inputs.append(row) 1877db96d56Sopenharmony_ci 1887db96d56Sopenharmony_ci for key in [None, itemgetter(0), itemgetter(1), itemgetter(1, 0)]: 1897db96d56Sopenharmony_ci for reverse in [False, True]: 1907db96d56Sopenharmony_ci seqs = [] 1917db96d56Sopenharmony_ci for seq in inputs: 1927db96d56Sopenharmony_ci seqs.append(sorted(seq, key=key, reverse=reverse)) 1937db96d56Sopenharmony_ci self.assertEqual(sorted(chain(*inputs), key=key, reverse=reverse), 1947db96d56Sopenharmony_ci list(self.module.merge(*seqs, key=key, reverse=reverse))) 1957db96d56Sopenharmony_ci self.assertEqual(list(self.module.merge()), []) 1967db96d56Sopenharmony_ci 1977db96d56Sopenharmony_ci def test_empty_merges(self): 1987db96d56Sopenharmony_ci # Merging two empty lists (with or without a key) should produce 1997db96d56Sopenharmony_ci # another empty list. 2007db96d56Sopenharmony_ci self.assertEqual(list(self.module.merge([], [])), []) 2017db96d56Sopenharmony_ci self.assertEqual(list(self.module.merge([], [], key=lambda: 6)), []) 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci def test_merge_does_not_suppress_index_error(self): 2047db96d56Sopenharmony_ci # Issue 19018: Heapq.merge suppresses IndexError from user generator 2057db96d56Sopenharmony_ci def iterable(): 2067db96d56Sopenharmony_ci s = list(range(10)) 2077db96d56Sopenharmony_ci for i in range(20): 2087db96d56Sopenharmony_ci yield s[i] # IndexError when i > 10 2097db96d56Sopenharmony_ci with self.assertRaises(IndexError): 2107db96d56Sopenharmony_ci list(self.module.merge(iterable(), iterable())) 2117db96d56Sopenharmony_ci 2127db96d56Sopenharmony_ci def test_merge_stability(self): 2137db96d56Sopenharmony_ci class Int(int): 2147db96d56Sopenharmony_ci pass 2157db96d56Sopenharmony_ci inputs = [[], [], [], []] 2167db96d56Sopenharmony_ci for i in range(20000): 2177db96d56Sopenharmony_ci stream = random.randrange(4) 2187db96d56Sopenharmony_ci x = random.randrange(500) 2197db96d56Sopenharmony_ci obj = Int(x) 2207db96d56Sopenharmony_ci obj.pair = (x, stream) 2217db96d56Sopenharmony_ci inputs[stream].append(obj) 2227db96d56Sopenharmony_ci for stream in inputs: 2237db96d56Sopenharmony_ci stream.sort() 2247db96d56Sopenharmony_ci result = [i.pair for i in self.module.merge(*inputs)] 2257db96d56Sopenharmony_ci self.assertEqual(result, sorted(result)) 2267db96d56Sopenharmony_ci 2277db96d56Sopenharmony_ci def test_nsmallest(self): 2287db96d56Sopenharmony_ci data = [(random.randrange(2000), i) for i in range(1000)] 2297db96d56Sopenharmony_ci for f in (None, lambda x: x[0] * 547 % 2000): 2307db96d56Sopenharmony_ci for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100): 2317db96d56Sopenharmony_ci self.assertEqual(list(self.module.nsmallest(n, data)), 2327db96d56Sopenharmony_ci sorted(data)[:n]) 2337db96d56Sopenharmony_ci self.assertEqual(list(self.module.nsmallest(n, data, key=f)), 2347db96d56Sopenharmony_ci sorted(data, key=f)[:n]) 2357db96d56Sopenharmony_ci 2367db96d56Sopenharmony_ci def test_nlargest(self): 2377db96d56Sopenharmony_ci data = [(random.randrange(2000), i) for i in range(1000)] 2387db96d56Sopenharmony_ci for f in (None, lambda x: x[0] * 547 % 2000): 2397db96d56Sopenharmony_ci for n in (0, 1, 2, 10, 100, 400, 999, 1000, 1100): 2407db96d56Sopenharmony_ci self.assertEqual(list(self.module.nlargest(n, data)), 2417db96d56Sopenharmony_ci sorted(data, reverse=True)[:n]) 2427db96d56Sopenharmony_ci self.assertEqual(list(self.module.nlargest(n, data, key=f)), 2437db96d56Sopenharmony_ci sorted(data, key=f, reverse=True)[:n]) 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_ci def test_comparison_operator(self): 2467db96d56Sopenharmony_ci # Issue 3051: Make sure heapq works with both __lt__ 2477db96d56Sopenharmony_ci # For python 3.0, __le__ alone is not enough 2487db96d56Sopenharmony_ci def hsort(data, comp): 2497db96d56Sopenharmony_ci data = [comp(x) for x in data] 2507db96d56Sopenharmony_ci self.module.heapify(data) 2517db96d56Sopenharmony_ci return [self.module.heappop(data).x for i in range(len(data))] 2527db96d56Sopenharmony_ci class LT: 2537db96d56Sopenharmony_ci def __init__(self, x): 2547db96d56Sopenharmony_ci self.x = x 2557db96d56Sopenharmony_ci def __lt__(self, other): 2567db96d56Sopenharmony_ci return self.x > other.x 2577db96d56Sopenharmony_ci class LE: 2587db96d56Sopenharmony_ci def __init__(self, x): 2597db96d56Sopenharmony_ci self.x = x 2607db96d56Sopenharmony_ci def __le__(self, other): 2617db96d56Sopenharmony_ci return self.x >= other.x 2627db96d56Sopenharmony_ci data = [random.random() for i in range(100)] 2637db96d56Sopenharmony_ci target = sorted(data, reverse=True) 2647db96d56Sopenharmony_ci self.assertEqual(hsort(data, LT), target) 2657db96d56Sopenharmony_ci self.assertRaises(TypeError, data, LE) 2667db96d56Sopenharmony_ci 2677db96d56Sopenharmony_ci 2687db96d56Sopenharmony_ciclass TestHeapPython(TestHeap, TestCase): 2697db96d56Sopenharmony_ci module = py_heapq 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ci 2727db96d56Sopenharmony_ci@skipUnless(c_heapq, 'requires _heapq') 2737db96d56Sopenharmony_ciclass TestHeapC(TestHeap, TestCase): 2747db96d56Sopenharmony_ci module = c_heapq 2757db96d56Sopenharmony_ci 2767db96d56Sopenharmony_ci 2777db96d56Sopenharmony_ci#============================================================================== 2787db96d56Sopenharmony_ci 2797db96d56Sopenharmony_ciclass LenOnly: 2807db96d56Sopenharmony_ci "Dummy sequence class defining __len__ but not __getitem__." 2817db96d56Sopenharmony_ci def __len__(self): 2827db96d56Sopenharmony_ci return 10 2837db96d56Sopenharmony_ci 2847db96d56Sopenharmony_ciclass CmpErr: 2857db96d56Sopenharmony_ci "Dummy element that always raises an error during comparison" 2867db96d56Sopenharmony_ci def __eq__(self, other): 2877db96d56Sopenharmony_ci raise ZeroDivisionError 2887db96d56Sopenharmony_ci __ne__ = __lt__ = __le__ = __gt__ = __ge__ = __eq__ 2897db96d56Sopenharmony_ci 2907db96d56Sopenharmony_cidef R(seqn): 2917db96d56Sopenharmony_ci 'Regular generator' 2927db96d56Sopenharmony_ci for i in seqn: 2937db96d56Sopenharmony_ci yield i 2947db96d56Sopenharmony_ci 2957db96d56Sopenharmony_ciclass G: 2967db96d56Sopenharmony_ci 'Sequence using __getitem__' 2977db96d56Sopenharmony_ci def __init__(self, seqn): 2987db96d56Sopenharmony_ci self.seqn = seqn 2997db96d56Sopenharmony_ci def __getitem__(self, i): 3007db96d56Sopenharmony_ci return self.seqn[i] 3017db96d56Sopenharmony_ci 3027db96d56Sopenharmony_ciclass I: 3037db96d56Sopenharmony_ci 'Sequence using iterator protocol' 3047db96d56Sopenharmony_ci def __init__(self, seqn): 3057db96d56Sopenharmony_ci self.seqn = seqn 3067db96d56Sopenharmony_ci self.i = 0 3077db96d56Sopenharmony_ci def __iter__(self): 3087db96d56Sopenharmony_ci return self 3097db96d56Sopenharmony_ci def __next__(self): 3107db96d56Sopenharmony_ci if self.i >= len(self.seqn): raise StopIteration 3117db96d56Sopenharmony_ci v = self.seqn[self.i] 3127db96d56Sopenharmony_ci self.i += 1 3137db96d56Sopenharmony_ci return v 3147db96d56Sopenharmony_ci 3157db96d56Sopenharmony_ciclass Ig: 3167db96d56Sopenharmony_ci 'Sequence using iterator protocol defined with a generator' 3177db96d56Sopenharmony_ci def __init__(self, seqn): 3187db96d56Sopenharmony_ci self.seqn = seqn 3197db96d56Sopenharmony_ci self.i = 0 3207db96d56Sopenharmony_ci def __iter__(self): 3217db96d56Sopenharmony_ci for val in self.seqn: 3227db96d56Sopenharmony_ci yield val 3237db96d56Sopenharmony_ci 3247db96d56Sopenharmony_ciclass X: 3257db96d56Sopenharmony_ci 'Missing __getitem__ and __iter__' 3267db96d56Sopenharmony_ci def __init__(self, seqn): 3277db96d56Sopenharmony_ci self.seqn = seqn 3287db96d56Sopenharmony_ci self.i = 0 3297db96d56Sopenharmony_ci def __next__(self): 3307db96d56Sopenharmony_ci if self.i >= len(self.seqn): raise StopIteration 3317db96d56Sopenharmony_ci v = self.seqn[self.i] 3327db96d56Sopenharmony_ci self.i += 1 3337db96d56Sopenharmony_ci return v 3347db96d56Sopenharmony_ci 3357db96d56Sopenharmony_ciclass N: 3367db96d56Sopenharmony_ci 'Iterator missing __next__()' 3377db96d56Sopenharmony_ci def __init__(self, seqn): 3387db96d56Sopenharmony_ci self.seqn = seqn 3397db96d56Sopenharmony_ci self.i = 0 3407db96d56Sopenharmony_ci def __iter__(self): 3417db96d56Sopenharmony_ci return self 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_ciclass E: 3447db96d56Sopenharmony_ci 'Test propagation of exceptions' 3457db96d56Sopenharmony_ci def __init__(self, seqn): 3467db96d56Sopenharmony_ci self.seqn = seqn 3477db96d56Sopenharmony_ci self.i = 0 3487db96d56Sopenharmony_ci def __iter__(self): 3497db96d56Sopenharmony_ci return self 3507db96d56Sopenharmony_ci def __next__(self): 3517db96d56Sopenharmony_ci 3 // 0 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ciclass S: 3547db96d56Sopenharmony_ci 'Test immediate stop' 3557db96d56Sopenharmony_ci def __init__(self, seqn): 3567db96d56Sopenharmony_ci pass 3577db96d56Sopenharmony_ci def __iter__(self): 3587db96d56Sopenharmony_ci return self 3597db96d56Sopenharmony_ci def __next__(self): 3607db96d56Sopenharmony_ci raise StopIteration 3617db96d56Sopenharmony_ci 3627db96d56Sopenharmony_cifrom itertools import chain 3637db96d56Sopenharmony_cidef L(seqn): 3647db96d56Sopenharmony_ci 'Test multiple tiers of iterators' 3657db96d56Sopenharmony_ci return chain(map(lambda x:x, R(Ig(G(seqn))))) 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_ci 3687db96d56Sopenharmony_ciclass SideEffectLT: 3697db96d56Sopenharmony_ci def __init__(self, value, heap): 3707db96d56Sopenharmony_ci self.value = value 3717db96d56Sopenharmony_ci self.heap = heap 3727db96d56Sopenharmony_ci 3737db96d56Sopenharmony_ci def __lt__(self, other): 3747db96d56Sopenharmony_ci self.heap[:] = [] 3757db96d56Sopenharmony_ci return self.value < other.value 3767db96d56Sopenharmony_ci 3777db96d56Sopenharmony_ci 3787db96d56Sopenharmony_ciclass TestErrorHandling: 3797db96d56Sopenharmony_ci 3807db96d56Sopenharmony_ci def test_non_sequence(self): 3817db96d56Sopenharmony_ci for f in (self.module.heapify, self.module.heappop): 3827db96d56Sopenharmony_ci self.assertRaises((TypeError, AttributeError), f, 10) 3837db96d56Sopenharmony_ci for f in (self.module.heappush, self.module.heapreplace, 3847db96d56Sopenharmony_ci self.module.nlargest, self.module.nsmallest): 3857db96d56Sopenharmony_ci self.assertRaises((TypeError, AttributeError), f, 10, 10) 3867db96d56Sopenharmony_ci 3877db96d56Sopenharmony_ci def test_len_only(self): 3887db96d56Sopenharmony_ci for f in (self.module.heapify, self.module.heappop): 3897db96d56Sopenharmony_ci self.assertRaises((TypeError, AttributeError), f, LenOnly()) 3907db96d56Sopenharmony_ci for f in (self.module.heappush, self.module.heapreplace): 3917db96d56Sopenharmony_ci self.assertRaises((TypeError, AttributeError), f, LenOnly(), 10) 3927db96d56Sopenharmony_ci for f in (self.module.nlargest, self.module.nsmallest): 3937db96d56Sopenharmony_ci self.assertRaises(TypeError, f, 2, LenOnly()) 3947db96d56Sopenharmony_ci 3957db96d56Sopenharmony_ci def test_cmp_err(self): 3967db96d56Sopenharmony_ci seq = [CmpErr(), CmpErr(), CmpErr()] 3977db96d56Sopenharmony_ci for f in (self.module.heapify, self.module.heappop): 3987db96d56Sopenharmony_ci self.assertRaises(ZeroDivisionError, f, seq) 3997db96d56Sopenharmony_ci for f in (self.module.heappush, self.module.heapreplace): 4007db96d56Sopenharmony_ci self.assertRaises(ZeroDivisionError, f, seq, 10) 4017db96d56Sopenharmony_ci for f in (self.module.nlargest, self.module.nsmallest): 4027db96d56Sopenharmony_ci self.assertRaises(ZeroDivisionError, f, 2, seq) 4037db96d56Sopenharmony_ci 4047db96d56Sopenharmony_ci def test_arg_parsing(self): 4057db96d56Sopenharmony_ci for f in (self.module.heapify, self.module.heappop, 4067db96d56Sopenharmony_ci self.module.heappush, self.module.heapreplace, 4077db96d56Sopenharmony_ci self.module.nlargest, self.module.nsmallest): 4087db96d56Sopenharmony_ci self.assertRaises((TypeError, AttributeError), f, 10) 4097db96d56Sopenharmony_ci 4107db96d56Sopenharmony_ci def test_iterable_args(self): 4117db96d56Sopenharmony_ci for f in (self.module.nlargest, self.module.nsmallest): 4127db96d56Sopenharmony_ci for s in ("123", "", range(1000), (1, 1.2), range(2000,2200,5)): 4137db96d56Sopenharmony_ci for g in (G, I, Ig, L, R): 4147db96d56Sopenharmony_ci self.assertEqual(list(f(2, g(s))), list(f(2,s))) 4157db96d56Sopenharmony_ci self.assertEqual(list(f(2, S(s))), []) 4167db96d56Sopenharmony_ci self.assertRaises(TypeError, f, 2, X(s)) 4177db96d56Sopenharmony_ci self.assertRaises(TypeError, f, 2, N(s)) 4187db96d56Sopenharmony_ci self.assertRaises(ZeroDivisionError, f, 2, E(s)) 4197db96d56Sopenharmony_ci 4207db96d56Sopenharmony_ci # Issue #17278: the heap may change size while it's being walked. 4217db96d56Sopenharmony_ci 4227db96d56Sopenharmony_ci def test_heappush_mutating_heap(self): 4237db96d56Sopenharmony_ci heap = [] 4247db96d56Sopenharmony_ci heap.extend(SideEffectLT(i, heap) for i in range(200)) 4257db96d56Sopenharmony_ci # Python version raises IndexError, C version RuntimeError 4267db96d56Sopenharmony_ci with self.assertRaises((IndexError, RuntimeError)): 4277db96d56Sopenharmony_ci self.module.heappush(heap, SideEffectLT(5, heap)) 4287db96d56Sopenharmony_ci 4297db96d56Sopenharmony_ci def test_heappop_mutating_heap(self): 4307db96d56Sopenharmony_ci heap = [] 4317db96d56Sopenharmony_ci heap.extend(SideEffectLT(i, heap) for i in range(200)) 4327db96d56Sopenharmony_ci # Python version raises IndexError, C version RuntimeError 4337db96d56Sopenharmony_ci with self.assertRaises((IndexError, RuntimeError)): 4347db96d56Sopenharmony_ci self.module.heappop(heap) 4357db96d56Sopenharmony_ci 4367db96d56Sopenharmony_ci def test_comparison_operator_modifiying_heap(self): 4377db96d56Sopenharmony_ci # See bpo-39421: Strong references need to be taken 4387db96d56Sopenharmony_ci # when comparing objects as they can alter the heap 4397db96d56Sopenharmony_ci class EvilClass(int): 4407db96d56Sopenharmony_ci def __lt__(self, o): 4417db96d56Sopenharmony_ci heap.clear() 4427db96d56Sopenharmony_ci return NotImplemented 4437db96d56Sopenharmony_ci 4447db96d56Sopenharmony_ci heap = [] 4457db96d56Sopenharmony_ci self.module.heappush(heap, EvilClass(0)) 4467db96d56Sopenharmony_ci self.assertRaises(IndexError, self.module.heappushpop, heap, 1) 4477db96d56Sopenharmony_ci 4487db96d56Sopenharmony_ci def test_comparison_operator_modifiying_heap_two_heaps(self): 4497db96d56Sopenharmony_ci 4507db96d56Sopenharmony_ci class h(int): 4517db96d56Sopenharmony_ci def __lt__(self, o): 4527db96d56Sopenharmony_ci list2.clear() 4537db96d56Sopenharmony_ci return NotImplemented 4547db96d56Sopenharmony_ci 4557db96d56Sopenharmony_ci class g(int): 4567db96d56Sopenharmony_ci def __lt__(self, o): 4577db96d56Sopenharmony_ci list1.clear() 4587db96d56Sopenharmony_ci return NotImplemented 4597db96d56Sopenharmony_ci 4607db96d56Sopenharmony_ci list1, list2 = [], [] 4617db96d56Sopenharmony_ci 4627db96d56Sopenharmony_ci self.module.heappush(list1, h(0)) 4637db96d56Sopenharmony_ci self.module.heappush(list2, g(0)) 4647db96d56Sopenharmony_ci 4657db96d56Sopenharmony_ci self.assertRaises((IndexError, RuntimeError), self.module.heappush, list1, g(1)) 4667db96d56Sopenharmony_ci self.assertRaises((IndexError, RuntimeError), self.module.heappush, list2, h(1)) 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_ciclass TestErrorHandlingPython(TestErrorHandling, TestCase): 4697db96d56Sopenharmony_ci module = py_heapq 4707db96d56Sopenharmony_ci 4717db96d56Sopenharmony_ci@skipUnless(c_heapq, 'requires _heapq') 4727db96d56Sopenharmony_ciclass TestErrorHandlingC(TestErrorHandling, TestCase): 4737db96d56Sopenharmony_ci module = c_heapq 4747db96d56Sopenharmony_ci 4757db96d56Sopenharmony_ci 4767db96d56Sopenharmony_ciif __name__ == "__main__": 4777db96d56Sopenharmony_ci unittest.main() 478