17db96d56Sopenharmony_ci# Test iterators. 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciimport sys 47db96d56Sopenharmony_ciimport unittest 57db96d56Sopenharmony_cifrom test.support import cpython_only 67db96d56Sopenharmony_cifrom test.support.os_helper import TESTFN, unlink 77db96d56Sopenharmony_cifrom test.support import check_free_after_iterating, ALWAYS_EQ, NEVER_EQ 87db96d56Sopenharmony_ciimport pickle 97db96d56Sopenharmony_ciimport collections.abc 107db96d56Sopenharmony_ciimport functools 117db96d56Sopenharmony_ciimport contextlib 127db96d56Sopenharmony_ciimport builtins 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci# Test result of triple loop (too big to inline) 157db96d56Sopenharmony_ciTRIPLETS = [(0, 0, 0), (0, 0, 1), (0, 0, 2), 167db96d56Sopenharmony_ci (0, 1, 0), (0, 1, 1), (0, 1, 2), 177db96d56Sopenharmony_ci (0, 2, 0), (0, 2, 1), (0, 2, 2), 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci (1, 0, 0), (1, 0, 1), (1, 0, 2), 207db96d56Sopenharmony_ci (1, 1, 0), (1, 1, 1), (1, 1, 2), 217db96d56Sopenharmony_ci (1, 2, 0), (1, 2, 1), (1, 2, 2), 227db96d56Sopenharmony_ci 237db96d56Sopenharmony_ci (2, 0, 0), (2, 0, 1), (2, 0, 2), 247db96d56Sopenharmony_ci (2, 1, 0), (2, 1, 1), (2, 1, 2), 257db96d56Sopenharmony_ci (2, 2, 0), (2, 2, 1), (2, 2, 2)] 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci# Helper classes 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_ciclass BasicIterClass: 307db96d56Sopenharmony_ci def __init__(self, n): 317db96d56Sopenharmony_ci self.n = n 327db96d56Sopenharmony_ci self.i = 0 337db96d56Sopenharmony_ci def __next__(self): 347db96d56Sopenharmony_ci res = self.i 357db96d56Sopenharmony_ci if res >= self.n: 367db96d56Sopenharmony_ci raise StopIteration 377db96d56Sopenharmony_ci self.i = res + 1 387db96d56Sopenharmony_ci return res 397db96d56Sopenharmony_ci def __iter__(self): 407db96d56Sopenharmony_ci return self 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ciclass IteratingSequenceClass: 437db96d56Sopenharmony_ci def __init__(self, n): 447db96d56Sopenharmony_ci self.n = n 457db96d56Sopenharmony_ci def __iter__(self): 467db96d56Sopenharmony_ci return BasicIterClass(self.n) 477db96d56Sopenharmony_ci 487db96d56Sopenharmony_ciclass IteratorProxyClass: 497db96d56Sopenharmony_ci def __init__(self, i): 507db96d56Sopenharmony_ci self.i = i 517db96d56Sopenharmony_ci def __next__(self): 527db96d56Sopenharmony_ci return next(self.i) 537db96d56Sopenharmony_ci def __iter__(self): 547db96d56Sopenharmony_ci return self 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_ciclass SequenceClass: 577db96d56Sopenharmony_ci def __init__(self, n): 587db96d56Sopenharmony_ci self.n = n 597db96d56Sopenharmony_ci def __getitem__(self, i): 607db96d56Sopenharmony_ci if 0 <= i < self.n: 617db96d56Sopenharmony_ci return i 627db96d56Sopenharmony_ci else: 637db96d56Sopenharmony_ci raise IndexError 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ciclass SequenceProxyClass: 667db96d56Sopenharmony_ci def __init__(self, s): 677db96d56Sopenharmony_ci self.s = s 687db96d56Sopenharmony_ci def __getitem__(self, i): 697db96d56Sopenharmony_ci return self.s[i] 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ciclass UnlimitedSequenceClass: 727db96d56Sopenharmony_ci def __getitem__(self, i): 737db96d56Sopenharmony_ci return i 747db96d56Sopenharmony_ci 757db96d56Sopenharmony_ciclass DefaultIterClass: 767db96d56Sopenharmony_ci pass 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_ciclass NoIterClass: 797db96d56Sopenharmony_ci def __getitem__(self, i): 807db96d56Sopenharmony_ci return i 817db96d56Sopenharmony_ci __iter__ = None 827db96d56Sopenharmony_ci 837db96d56Sopenharmony_ciclass BadIterableClass: 847db96d56Sopenharmony_ci def __iter__(self): 857db96d56Sopenharmony_ci raise ZeroDivisionError 867db96d56Sopenharmony_ci 877db96d56Sopenharmony_ciclass CallableIterClass: 887db96d56Sopenharmony_ci def __init__(self): 897db96d56Sopenharmony_ci self.i = 0 907db96d56Sopenharmony_ci def __call__(self): 917db96d56Sopenharmony_ci i = self.i 927db96d56Sopenharmony_ci self.i = i + 1 937db96d56Sopenharmony_ci if i > 100: 947db96d56Sopenharmony_ci raise IndexError # Emergency stop 957db96d56Sopenharmony_ci return i 967db96d56Sopenharmony_ci 977db96d56Sopenharmony_ciclass EmptyIterClass: 987db96d56Sopenharmony_ci def __len__(self): 997db96d56Sopenharmony_ci return 0 1007db96d56Sopenharmony_ci def __getitem__(self, i): 1017db96d56Sopenharmony_ci raise StopIteration 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_ci# Main test suite 1047db96d56Sopenharmony_ci 1057db96d56Sopenharmony_ciclass TestCase(unittest.TestCase): 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_ci # Helper to check that an iterator returns a given sequence 1087db96d56Sopenharmony_ci def check_iterator(self, it, seq, pickle=True): 1097db96d56Sopenharmony_ci if pickle: 1107db96d56Sopenharmony_ci self.check_pickle(it, seq) 1117db96d56Sopenharmony_ci res = [] 1127db96d56Sopenharmony_ci while 1: 1137db96d56Sopenharmony_ci try: 1147db96d56Sopenharmony_ci val = next(it) 1157db96d56Sopenharmony_ci except StopIteration: 1167db96d56Sopenharmony_ci break 1177db96d56Sopenharmony_ci res.append(val) 1187db96d56Sopenharmony_ci self.assertEqual(res, seq) 1197db96d56Sopenharmony_ci 1207db96d56Sopenharmony_ci # Helper to check that a for loop generates a given sequence 1217db96d56Sopenharmony_ci def check_for_loop(self, expr, seq, pickle=True): 1227db96d56Sopenharmony_ci if pickle: 1237db96d56Sopenharmony_ci self.check_pickle(iter(expr), seq) 1247db96d56Sopenharmony_ci res = [] 1257db96d56Sopenharmony_ci for val in expr: 1267db96d56Sopenharmony_ci res.append(val) 1277db96d56Sopenharmony_ci self.assertEqual(res, seq) 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_ci # Helper to check picklability 1307db96d56Sopenharmony_ci def check_pickle(self, itorg, seq): 1317db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 1327db96d56Sopenharmony_ci d = pickle.dumps(itorg, proto) 1337db96d56Sopenharmony_ci it = pickle.loads(d) 1347db96d56Sopenharmony_ci # Cannot assert type equality because dict iterators unpickle as list 1357db96d56Sopenharmony_ci # iterators. 1367db96d56Sopenharmony_ci # self.assertEqual(type(itorg), type(it)) 1377db96d56Sopenharmony_ci self.assertTrue(isinstance(it, collections.abc.Iterator)) 1387db96d56Sopenharmony_ci self.assertEqual(list(it), seq) 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_ci it = pickle.loads(d) 1417db96d56Sopenharmony_ci try: 1427db96d56Sopenharmony_ci next(it) 1437db96d56Sopenharmony_ci except StopIteration: 1447db96d56Sopenharmony_ci continue 1457db96d56Sopenharmony_ci d = pickle.dumps(it, proto) 1467db96d56Sopenharmony_ci it = pickle.loads(d) 1477db96d56Sopenharmony_ci self.assertEqual(list(it), seq[1:]) 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci # Test basic use of iter() function 1507db96d56Sopenharmony_ci def test_iter_basic(self): 1517db96d56Sopenharmony_ci self.check_iterator(iter(range(10)), list(range(10))) 1527db96d56Sopenharmony_ci 1537db96d56Sopenharmony_ci # Test that iter(iter(x)) is the same as iter(x) 1547db96d56Sopenharmony_ci def test_iter_idempotency(self): 1557db96d56Sopenharmony_ci seq = list(range(10)) 1567db96d56Sopenharmony_ci it = iter(seq) 1577db96d56Sopenharmony_ci it2 = iter(it) 1587db96d56Sopenharmony_ci self.assertTrue(it is it2) 1597db96d56Sopenharmony_ci 1607db96d56Sopenharmony_ci # Test that for loops over iterators work 1617db96d56Sopenharmony_ci def test_iter_for_loop(self): 1627db96d56Sopenharmony_ci self.check_for_loop(iter(range(10)), list(range(10))) 1637db96d56Sopenharmony_ci 1647db96d56Sopenharmony_ci # Test several independent iterators over the same list 1657db96d56Sopenharmony_ci def test_iter_independence(self): 1667db96d56Sopenharmony_ci seq = range(3) 1677db96d56Sopenharmony_ci res = [] 1687db96d56Sopenharmony_ci for i in iter(seq): 1697db96d56Sopenharmony_ci for j in iter(seq): 1707db96d56Sopenharmony_ci for k in iter(seq): 1717db96d56Sopenharmony_ci res.append((i, j, k)) 1727db96d56Sopenharmony_ci self.assertEqual(res, TRIPLETS) 1737db96d56Sopenharmony_ci 1747db96d56Sopenharmony_ci # Test triple list comprehension using iterators 1757db96d56Sopenharmony_ci def test_nested_comprehensions_iter(self): 1767db96d56Sopenharmony_ci seq = range(3) 1777db96d56Sopenharmony_ci res = [(i, j, k) 1787db96d56Sopenharmony_ci for i in iter(seq) for j in iter(seq) for k in iter(seq)] 1797db96d56Sopenharmony_ci self.assertEqual(res, TRIPLETS) 1807db96d56Sopenharmony_ci 1817db96d56Sopenharmony_ci # Test triple list comprehension without iterators 1827db96d56Sopenharmony_ci def test_nested_comprehensions_for(self): 1837db96d56Sopenharmony_ci seq = range(3) 1847db96d56Sopenharmony_ci res = [(i, j, k) for i in seq for j in seq for k in seq] 1857db96d56Sopenharmony_ci self.assertEqual(res, TRIPLETS) 1867db96d56Sopenharmony_ci 1877db96d56Sopenharmony_ci # Test a class with __iter__ in a for loop 1887db96d56Sopenharmony_ci def test_iter_class_for(self): 1897db96d56Sopenharmony_ci self.check_for_loop(IteratingSequenceClass(10), list(range(10))) 1907db96d56Sopenharmony_ci 1917db96d56Sopenharmony_ci # Test a class with __iter__ with explicit iter() 1927db96d56Sopenharmony_ci def test_iter_class_iter(self): 1937db96d56Sopenharmony_ci self.check_iterator(iter(IteratingSequenceClass(10)), list(range(10))) 1947db96d56Sopenharmony_ci 1957db96d56Sopenharmony_ci # Test for loop on a sequence class without __iter__ 1967db96d56Sopenharmony_ci def test_seq_class_for(self): 1977db96d56Sopenharmony_ci self.check_for_loop(SequenceClass(10), list(range(10))) 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_ci # Test iter() on a sequence class without __iter__ 2007db96d56Sopenharmony_ci def test_seq_class_iter(self): 2017db96d56Sopenharmony_ci self.check_iterator(iter(SequenceClass(10)), list(range(10))) 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci def test_mutating_seq_class_iter_pickle(self): 2047db96d56Sopenharmony_ci orig = SequenceClass(5) 2057db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 2067db96d56Sopenharmony_ci # initial iterator 2077db96d56Sopenharmony_ci itorig = iter(orig) 2087db96d56Sopenharmony_ci d = pickle.dumps((itorig, orig), proto) 2097db96d56Sopenharmony_ci it, seq = pickle.loads(d) 2107db96d56Sopenharmony_ci seq.n = 7 2117db96d56Sopenharmony_ci self.assertIs(type(it), type(itorig)) 2127db96d56Sopenharmony_ci self.assertEqual(list(it), list(range(7))) 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci # running iterator 2157db96d56Sopenharmony_ci next(itorig) 2167db96d56Sopenharmony_ci d = pickle.dumps((itorig, orig), proto) 2177db96d56Sopenharmony_ci it, seq = pickle.loads(d) 2187db96d56Sopenharmony_ci seq.n = 7 2197db96d56Sopenharmony_ci self.assertIs(type(it), type(itorig)) 2207db96d56Sopenharmony_ci self.assertEqual(list(it), list(range(1, 7))) 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ci # empty iterator 2237db96d56Sopenharmony_ci for i in range(1, 5): 2247db96d56Sopenharmony_ci next(itorig) 2257db96d56Sopenharmony_ci d = pickle.dumps((itorig, orig), proto) 2267db96d56Sopenharmony_ci it, seq = pickle.loads(d) 2277db96d56Sopenharmony_ci seq.n = 7 2287db96d56Sopenharmony_ci self.assertIs(type(it), type(itorig)) 2297db96d56Sopenharmony_ci self.assertEqual(list(it), list(range(5, 7))) 2307db96d56Sopenharmony_ci 2317db96d56Sopenharmony_ci # exhausted iterator 2327db96d56Sopenharmony_ci self.assertRaises(StopIteration, next, itorig) 2337db96d56Sopenharmony_ci d = pickle.dumps((itorig, orig), proto) 2347db96d56Sopenharmony_ci it, seq = pickle.loads(d) 2357db96d56Sopenharmony_ci seq.n = 7 2367db96d56Sopenharmony_ci self.assertTrue(isinstance(it, collections.abc.Iterator)) 2377db96d56Sopenharmony_ci self.assertEqual(list(it), []) 2387db96d56Sopenharmony_ci 2397db96d56Sopenharmony_ci def test_mutating_seq_class_exhausted_iter(self): 2407db96d56Sopenharmony_ci a = SequenceClass(5) 2417db96d56Sopenharmony_ci exhit = iter(a) 2427db96d56Sopenharmony_ci empit = iter(a) 2437db96d56Sopenharmony_ci for x in exhit: # exhaust the iterator 2447db96d56Sopenharmony_ci next(empit) # not exhausted 2457db96d56Sopenharmony_ci a.n = 7 2467db96d56Sopenharmony_ci self.assertEqual(list(exhit), []) 2477db96d56Sopenharmony_ci self.assertEqual(list(empit), [5, 6]) 2487db96d56Sopenharmony_ci self.assertEqual(list(a), [0, 1, 2, 3, 4, 5, 6]) 2497db96d56Sopenharmony_ci 2507db96d56Sopenharmony_ci def test_reduce_mutating_builtins_iter(self): 2517db96d56Sopenharmony_ci # This is a reproducer of issue #101765 2527db96d56Sopenharmony_ci # where iter `__reduce__` calls could lead to a segfault or SystemError 2537db96d56Sopenharmony_ci # depending on the order of C argument evaluation, which is undefined 2547db96d56Sopenharmony_ci 2557db96d56Sopenharmony_ci # Backup builtins 2567db96d56Sopenharmony_ci builtins_dict = builtins.__dict__ 2577db96d56Sopenharmony_ci orig = {"iter": iter, "reversed": reversed} 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci def run(builtin_name, item, sentinel=None): 2607db96d56Sopenharmony_ci it = iter(item) if sentinel is None else iter(item, sentinel) 2617db96d56Sopenharmony_ci 2627db96d56Sopenharmony_ci class CustomStr: 2637db96d56Sopenharmony_ci def __init__(self, name, iterator): 2647db96d56Sopenharmony_ci self.name = name 2657db96d56Sopenharmony_ci self.iterator = iterator 2667db96d56Sopenharmony_ci def __hash__(self): 2677db96d56Sopenharmony_ci return hash(self.name) 2687db96d56Sopenharmony_ci def __eq__(self, other): 2697db96d56Sopenharmony_ci # Here we exhaust our iterator, possibly changing 2707db96d56Sopenharmony_ci # its `it_seq` pointer to NULL 2717db96d56Sopenharmony_ci # The `__reduce__` call should correctly get 2727db96d56Sopenharmony_ci # the pointers after this call 2737db96d56Sopenharmony_ci list(self.iterator) 2747db96d56Sopenharmony_ci return other == self.name 2757db96d56Sopenharmony_ci 2767db96d56Sopenharmony_ci # del is required here 2777db96d56Sopenharmony_ci # to not prematurely call __eq__ from 2787db96d56Sopenharmony_ci # the hash collision with the old key 2797db96d56Sopenharmony_ci del builtins_dict[builtin_name] 2807db96d56Sopenharmony_ci builtins_dict[CustomStr(builtin_name, it)] = orig[builtin_name] 2817db96d56Sopenharmony_ci 2827db96d56Sopenharmony_ci return it.__reduce__() 2837db96d56Sopenharmony_ci 2847db96d56Sopenharmony_ci types = [ 2857db96d56Sopenharmony_ci (EmptyIterClass(),), 2867db96d56Sopenharmony_ci (bytes(8),), 2877db96d56Sopenharmony_ci (bytearray(8),), 2887db96d56Sopenharmony_ci ((1, 2, 3),), 2897db96d56Sopenharmony_ci (lambda: 0, 0), 2907db96d56Sopenharmony_ci (tuple[int],) # GenericAlias 2917db96d56Sopenharmony_ci ] 2927db96d56Sopenharmony_ci 2937db96d56Sopenharmony_ci try: 2947db96d56Sopenharmony_ci run_iter = functools.partial(run, "iter") 2957db96d56Sopenharmony_ci # The returned value of `__reduce__` should not only be valid 2967db96d56Sopenharmony_ci # but also *empty*, as `it` was exhausted during `__eq__` 2977db96d56Sopenharmony_ci # i.e "xyz" returns (iter, ("",)) 2987db96d56Sopenharmony_ci self.assertEqual(run_iter("xyz"), (orig["iter"], ("",))) 2997db96d56Sopenharmony_ci self.assertEqual(run_iter([1, 2, 3]), (orig["iter"], ([],))) 3007db96d56Sopenharmony_ci 3017db96d56Sopenharmony_ci # _PyEval_GetBuiltin is also called for `reversed` in a branch of 3027db96d56Sopenharmony_ci # listiter_reduce_general 3037db96d56Sopenharmony_ci self.assertEqual( 3047db96d56Sopenharmony_ci run("reversed", orig["reversed"](list(range(8)))), 3057db96d56Sopenharmony_ci (iter, ([],)) 3067db96d56Sopenharmony_ci ) 3077db96d56Sopenharmony_ci 3087db96d56Sopenharmony_ci for case in types: 3097db96d56Sopenharmony_ci self.assertEqual(run_iter(*case), (orig["iter"], ((),))) 3107db96d56Sopenharmony_ci finally: 3117db96d56Sopenharmony_ci # Restore original builtins 3127db96d56Sopenharmony_ci for key, func in orig.items(): 3137db96d56Sopenharmony_ci # need to suppress KeyErrors in case 3147db96d56Sopenharmony_ci # a failed test deletes the key without setting anything 3157db96d56Sopenharmony_ci with contextlib.suppress(KeyError): 3167db96d56Sopenharmony_ci # del is required here 3177db96d56Sopenharmony_ci # to not invoke our custom __eq__ from 3187db96d56Sopenharmony_ci # the hash collision with the old key 3197db96d56Sopenharmony_ci del builtins_dict[key] 3207db96d56Sopenharmony_ci builtins_dict[key] = func 3217db96d56Sopenharmony_ci 3227db96d56Sopenharmony_ci # Test a new_style class with __iter__ but no next() method 3237db96d56Sopenharmony_ci def test_new_style_iter_class(self): 3247db96d56Sopenharmony_ci class IterClass(object): 3257db96d56Sopenharmony_ci def __iter__(self): 3267db96d56Sopenharmony_ci return self 3277db96d56Sopenharmony_ci self.assertRaises(TypeError, iter, IterClass()) 3287db96d56Sopenharmony_ci 3297db96d56Sopenharmony_ci # Test two-argument iter() with callable instance 3307db96d56Sopenharmony_ci def test_iter_callable(self): 3317db96d56Sopenharmony_ci self.check_iterator(iter(CallableIterClass(), 10), list(range(10)), pickle=True) 3327db96d56Sopenharmony_ci 3337db96d56Sopenharmony_ci # Test two-argument iter() with function 3347db96d56Sopenharmony_ci def test_iter_function(self): 3357db96d56Sopenharmony_ci def spam(state=[0]): 3367db96d56Sopenharmony_ci i = state[0] 3377db96d56Sopenharmony_ci state[0] = i+1 3387db96d56Sopenharmony_ci return i 3397db96d56Sopenharmony_ci self.check_iterator(iter(spam, 10), list(range(10)), pickle=False) 3407db96d56Sopenharmony_ci 3417db96d56Sopenharmony_ci # Test two-argument iter() with function that raises StopIteration 3427db96d56Sopenharmony_ci def test_iter_function_stop(self): 3437db96d56Sopenharmony_ci def spam(state=[0]): 3447db96d56Sopenharmony_ci i = state[0] 3457db96d56Sopenharmony_ci if i == 10: 3467db96d56Sopenharmony_ci raise StopIteration 3477db96d56Sopenharmony_ci state[0] = i+1 3487db96d56Sopenharmony_ci return i 3497db96d56Sopenharmony_ci self.check_iterator(iter(spam, 20), list(range(10)), pickle=False) 3507db96d56Sopenharmony_ci 3517db96d56Sopenharmony_ci def test_iter_function_concealing_reentrant_exhaustion(self): 3527db96d56Sopenharmony_ci # gh-101892: Test two-argument iter() with a function that 3537db96d56Sopenharmony_ci # exhausts its associated iterator but forgets to either return 3547db96d56Sopenharmony_ci # a sentinel value or raise StopIteration. 3557db96d56Sopenharmony_ci HAS_MORE = 1 3567db96d56Sopenharmony_ci NO_MORE = 2 3577db96d56Sopenharmony_ci 3587db96d56Sopenharmony_ci def exhaust(iterator): 3597db96d56Sopenharmony_ci """Exhaust an iterator without raising StopIteration.""" 3607db96d56Sopenharmony_ci list(iterator) 3617db96d56Sopenharmony_ci 3627db96d56Sopenharmony_ci def spam(): 3637db96d56Sopenharmony_ci # Touching the iterator with exhaust() below will call 3647db96d56Sopenharmony_ci # spam() once again so protect against recursion. 3657db96d56Sopenharmony_ci if spam.is_recursive_call: 3667db96d56Sopenharmony_ci return NO_MORE 3677db96d56Sopenharmony_ci spam.is_recursive_call = True 3687db96d56Sopenharmony_ci exhaust(spam.iterator) 3697db96d56Sopenharmony_ci return HAS_MORE 3707db96d56Sopenharmony_ci 3717db96d56Sopenharmony_ci spam.is_recursive_call = False 3727db96d56Sopenharmony_ci spam.iterator = iter(spam, NO_MORE) 3737db96d56Sopenharmony_ci with self.assertRaises(StopIteration): 3747db96d56Sopenharmony_ci next(spam.iterator) 3757db96d56Sopenharmony_ci 3767db96d56Sopenharmony_ci # Test exception propagation through function iterator 3777db96d56Sopenharmony_ci def test_exception_function(self): 3787db96d56Sopenharmony_ci def spam(state=[0]): 3797db96d56Sopenharmony_ci i = state[0] 3807db96d56Sopenharmony_ci state[0] = i+1 3817db96d56Sopenharmony_ci if i == 10: 3827db96d56Sopenharmony_ci raise RuntimeError 3837db96d56Sopenharmony_ci return i 3847db96d56Sopenharmony_ci res = [] 3857db96d56Sopenharmony_ci try: 3867db96d56Sopenharmony_ci for x in iter(spam, 20): 3877db96d56Sopenharmony_ci res.append(x) 3887db96d56Sopenharmony_ci except RuntimeError: 3897db96d56Sopenharmony_ci self.assertEqual(res, list(range(10))) 3907db96d56Sopenharmony_ci else: 3917db96d56Sopenharmony_ci self.fail("should have raised RuntimeError") 3927db96d56Sopenharmony_ci 3937db96d56Sopenharmony_ci # Test exception propagation through sequence iterator 3947db96d56Sopenharmony_ci def test_exception_sequence(self): 3957db96d56Sopenharmony_ci class MySequenceClass(SequenceClass): 3967db96d56Sopenharmony_ci def __getitem__(self, i): 3977db96d56Sopenharmony_ci if i == 10: 3987db96d56Sopenharmony_ci raise RuntimeError 3997db96d56Sopenharmony_ci return SequenceClass.__getitem__(self, i) 4007db96d56Sopenharmony_ci res = [] 4017db96d56Sopenharmony_ci try: 4027db96d56Sopenharmony_ci for x in MySequenceClass(20): 4037db96d56Sopenharmony_ci res.append(x) 4047db96d56Sopenharmony_ci except RuntimeError: 4057db96d56Sopenharmony_ci self.assertEqual(res, list(range(10))) 4067db96d56Sopenharmony_ci else: 4077db96d56Sopenharmony_ci self.fail("should have raised RuntimeError") 4087db96d56Sopenharmony_ci 4097db96d56Sopenharmony_ci # Test for StopIteration from __getitem__ 4107db96d56Sopenharmony_ci def test_stop_sequence(self): 4117db96d56Sopenharmony_ci class MySequenceClass(SequenceClass): 4127db96d56Sopenharmony_ci def __getitem__(self, i): 4137db96d56Sopenharmony_ci if i == 10: 4147db96d56Sopenharmony_ci raise StopIteration 4157db96d56Sopenharmony_ci return SequenceClass.__getitem__(self, i) 4167db96d56Sopenharmony_ci self.check_for_loop(MySequenceClass(20), list(range(10)), pickle=False) 4177db96d56Sopenharmony_ci 4187db96d56Sopenharmony_ci # Test a big range 4197db96d56Sopenharmony_ci def test_iter_big_range(self): 4207db96d56Sopenharmony_ci self.check_for_loop(iter(range(10000)), list(range(10000))) 4217db96d56Sopenharmony_ci 4227db96d56Sopenharmony_ci # Test an empty list 4237db96d56Sopenharmony_ci def test_iter_empty(self): 4247db96d56Sopenharmony_ci self.check_for_loop(iter([]), []) 4257db96d56Sopenharmony_ci 4267db96d56Sopenharmony_ci # Test a tuple 4277db96d56Sopenharmony_ci def test_iter_tuple(self): 4287db96d56Sopenharmony_ci self.check_for_loop(iter((0,1,2,3,4,5,6,7,8,9)), list(range(10))) 4297db96d56Sopenharmony_ci 4307db96d56Sopenharmony_ci # Test a range 4317db96d56Sopenharmony_ci def test_iter_range(self): 4327db96d56Sopenharmony_ci self.check_for_loop(iter(range(10)), list(range(10))) 4337db96d56Sopenharmony_ci 4347db96d56Sopenharmony_ci # Test a string 4357db96d56Sopenharmony_ci def test_iter_string(self): 4367db96d56Sopenharmony_ci self.check_for_loop(iter("abcde"), ["a", "b", "c", "d", "e"]) 4377db96d56Sopenharmony_ci 4387db96d56Sopenharmony_ci # Test a directory 4397db96d56Sopenharmony_ci def test_iter_dict(self): 4407db96d56Sopenharmony_ci dict = {} 4417db96d56Sopenharmony_ci for i in range(10): 4427db96d56Sopenharmony_ci dict[i] = None 4437db96d56Sopenharmony_ci self.check_for_loop(dict, list(dict.keys())) 4447db96d56Sopenharmony_ci 4457db96d56Sopenharmony_ci # Test a file 4467db96d56Sopenharmony_ci def test_iter_file(self): 4477db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 4487db96d56Sopenharmony_ci try: 4497db96d56Sopenharmony_ci for i in range(5): 4507db96d56Sopenharmony_ci f.write("%d\n" % i) 4517db96d56Sopenharmony_ci finally: 4527db96d56Sopenharmony_ci f.close() 4537db96d56Sopenharmony_ci f = open(TESTFN, "r", encoding="utf-8") 4547db96d56Sopenharmony_ci try: 4557db96d56Sopenharmony_ci self.check_for_loop(f, ["0\n", "1\n", "2\n", "3\n", "4\n"], pickle=False) 4567db96d56Sopenharmony_ci self.check_for_loop(f, [], pickle=False) 4577db96d56Sopenharmony_ci finally: 4587db96d56Sopenharmony_ci f.close() 4597db96d56Sopenharmony_ci try: 4607db96d56Sopenharmony_ci unlink(TESTFN) 4617db96d56Sopenharmony_ci except OSError: 4627db96d56Sopenharmony_ci pass 4637db96d56Sopenharmony_ci 4647db96d56Sopenharmony_ci # Test list()'s use of iterators. 4657db96d56Sopenharmony_ci def test_builtin_list(self): 4667db96d56Sopenharmony_ci self.assertEqual(list(SequenceClass(5)), list(range(5))) 4677db96d56Sopenharmony_ci self.assertEqual(list(SequenceClass(0)), []) 4687db96d56Sopenharmony_ci self.assertEqual(list(()), []) 4697db96d56Sopenharmony_ci 4707db96d56Sopenharmony_ci d = {"one": 1, "two": 2, "three": 3} 4717db96d56Sopenharmony_ci self.assertEqual(list(d), list(d.keys())) 4727db96d56Sopenharmony_ci 4737db96d56Sopenharmony_ci self.assertRaises(TypeError, list, list) 4747db96d56Sopenharmony_ci self.assertRaises(TypeError, list, 42) 4757db96d56Sopenharmony_ci 4767db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 4777db96d56Sopenharmony_ci try: 4787db96d56Sopenharmony_ci for i in range(5): 4797db96d56Sopenharmony_ci f.write("%d\n" % i) 4807db96d56Sopenharmony_ci finally: 4817db96d56Sopenharmony_ci f.close() 4827db96d56Sopenharmony_ci f = open(TESTFN, "r", encoding="utf-8") 4837db96d56Sopenharmony_ci try: 4847db96d56Sopenharmony_ci self.assertEqual(list(f), ["0\n", "1\n", "2\n", "3\n", "4\n"]) 4857db96d56Sopenharmony_ci f.seek(0, 0) 4867db96d56Sopenharmony_ci self.assertEqual(list(f), 4877db96d56Sopenharmony_ci ["0\n", "1\n", "2\n", "3\n", "4\n"]) 4887db96d56Sopenharmony_ci finally: 4897db96d56Sopenharmony_ci f.close() 4907db96d56Sopenharmony_ci try: 4917db96d56Sopenharmony_ci unlink(TESTFN) 4927db96d56Sopenharmony_ci except OSError: 4937db96d56Sopenharmony_ci pass 4947db96d56Sopenharmony_ci 4957db96d56Sopenharmony_ci # Test tuples()'s use of iterators. 4967db96d56Sopenharmony_ci def test_builtin_tuple(self): 4977db96d56Sopenharmony_ci self.assertEqual(tuple(SequenceClass(5)), (0, 1, 2, 3, 4)) 4987db96d56Sopenharmony_ci self.assertEqual(tuple(SequenceClass(0)), ()) 4997db96d56Sopenharmony_ci self.assertEqual(tuple([]), ()) 5007db96d56Sopenharmony_ci self.assertEqual(tuple(()), ()) 5017db96d56Sopenharmony_ci self.assertEqual(tuple("abc"), ("a", "b", "c")) 5027db96d56Sopenharmony_ci 5037db96d56Sopenharmony_ci d = {"one": 1, "two": 2, "three": 3} 5047db96d56Sopenharmony_ci self.assertEqual(tuple(d), tuple(d.keys())) 5057db96d56Sopenharmony_ci 5067db96d56Sopenharmony_ci self.assertRaises(TypeError, tuple, list) 5077db96d56Sopenharmony_ci self.assertRaises(TypeError, tuple, 42) 5087db96d56Sopenharmony_ci 5097db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 5107db96d56Sopenharmony_ci try: 5117db96d56Sopenharmony_ci for i in range(5): 5127db96d56Sopenharmony_ci f.write("%d\n" % i) 5137db96d56Sopenharmony_ci finally: 5147db96d56Sopenharmony_ci f.close() 5157db96d56Sopenharmony_ci f = open(TESTFN, "r", encoding="utf-8") 5167db96d56Sopenharmony_ci try: 5177db96d56Sopenharmony_ci self.assertEqual(tuple(f), ("0\n", "1\n", "2\n", "3\n", "4\n")) 5187db96d56Sopenharmony_ci f.seek(0, 0) 5197db96d56Sopenharmony_ci self.assertEqual(tuple(f), 5207db96d56Sopenharmony_ci ("0\n", "1\n", "2\n", "3\n", "4\n")) 5217db96d56Sopenharmony_ci finally: 5227db96d56Sopenharmony_ci f.close() 5237db96d56Sopenharmony_ci try: 5247db96d56Sopenharmony_ci unlink(TESTFN) 5257db96d56Sopenharmony_ci except OSError: 5267db96d56Sopenharmony_ci pass 5277db96d56Sopenharmony_ci 5287db96d56Sopenharmony_ci # Test filter()'s use of iterators. 5297db96d56Sopenharmony_ci def test_builtin_filter(self): 5307db96d56Sopenharmony_ci self.assertEqual(list(filter(None, SequenceClass(5))), 5317db96d56Sopenharmony_ci list(range(1, 5))) 5327db96d56Sopenharmony_ci self.assertEqual(list(filter(None, SequenceClass(0))), []) 5337db96d56Sopenharmony_ci self.assertEqual(list(filter(None, ())), []) 5347db96d56Sopenharmony_ci self.assertEqual(list(filter(None, "abc")), ["a", "b", "c"]) 5357db96d56Sopenharmony_ci 5367db96d56Sopenharmony_ci d = {"one": 1, "two": 2, "three": 3} 5377db96d56Sopenharmony_ci self.assertEqual(list(filter(None, d)), list(d.keys())) 5387db96d56Sopenharmony_ci 5397db96d56Sopenharmony_ci self.assertRaises(TypeError, filter, None, list) 5407db96d56Sopenharmony_ci self.assertRaises(TypeError, filter, None, 42) 5417db96d56Sopenharmony_ci 5427db96d56Sopenharmony_ci class Boolean: 5437db96d56Sopenharmony_ci def __init__(self, truth): 5447db96d56Sopenharmony_ci self.truth = truth 5457db96d56Sopenharmony_ci def __bool__(self): 5467db96d56Sopenharmony_ci return self.truth 5477db96d56Sopenharmony_ci bTrue = Boolean(True) 5487db96d56Sopenharmony_ci bFalse = Boolean(False) 5497db96d56Sopenharmony_ci 5507db96d56Sopenharmony_ci class Seq: 5517db96d56Sopenharmony_ci def __init__(self, *args): 5527db96d56Sopenharmony_ci self.vals = args 5537db96d56Sopenharmony_ci def __iter__(self): 5547db96d56Sopenharmony_ci class SeqIter: 5557db96d56Sopenharmony_ci def __init__(self, vals): 5567db96d56Sopenharmony_ci self.vals = vals 5577db96d56Sopenharmony_ci self.i = 0 5587db96d56Sopenharmony_ci def __iter__(self): 5597db96d56Sopenharmony_ci return self 5607db96d56Sopenharmony_ci def __next__(self): 5617db96d56Sopenharmony_ci i = self.i 5627db96d56Sopenharmony_ci self.i = i + 1 5637db96d56Sopenharmony_ci if i < len(self.vals): 5647db96d56Sopenharmony_ci return self.vals[i] 5657db96d56Sopenharmony_ci else: 5667db96d56Sopenharmony_ci raise StopIteration 5677db96d56Sopenharmony_ci return SeqIter(self.vals) 5687db96d56Sopenharmony_ci 5697db96d56Sopenharmony_ci seq = Seq(*([bTrue, bFalse] * 25)) 5707db96d56Sopenharmony_ci self.assertEqual(list(filter(lambda x: not x, seq)), [bFalse]*25) 5717db96d56Sopenharmony_ci self.assertEqual(list(filter(lambda x: not x, iter(seq))), [bFalse]*25) 5727db96d56Sopenharmony_ci 5737db96d56Sopenharmony_ci # Test max() and min()'s use of iterators. 5747db96d56Sopenharmony_ci def test_builtin_max_min(self): 5757db96d56Sopenharmony_ci self.assertEqual(max(SequenceClass(5)), 4) 5767db96d56Sopenharmony_ci self.assertEqual(min(SequenceClass(5)), 0) 5777db96d56Sopenharmony_ci self.assertEqual(max(8, -1), 8) 5787db96d56Sopenharmony_ci self.assertEqual(min(8, -1), -1) 5797db96d56Sopenharmony_ci 5807db96d56Sopenharmony_ci d = {"one": 1, "two": 2, "three": 3} 5817db96d56Sopenharmony_ci self.assertEqual(max(d), "two") 5827db96d56Sopenharmony_ci self.assertEqual(min(d), "one") 5837db96d56Sopenharmony_ci self.assertEqual(max(d.values()), 3) 5847db96d56Sopenharmony_ci self.assertEqual(min(iter(d.values())), 1) 5857db96d56Sopenharmony_ci 5867db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 5877db96d56Sopenharmony_ci try: 5887db96d56Sopenharmony_ci f.write("medium line\n") 5897db96d56Sopenharmony_ci f.write("xtra large line\n") 5907db96d56Sopenharmony_ci f.write("itty-bitty line\n") 5917db96d56Sopenharmony_ci finally: 5927db96d56Sopenharmony_ci f.close() 5937db96d56Sopenharmony_ci f = open(TESTFN, "r", encoding="utf-8") 5947db96d56Sopenharmony_ci try: 5957db96d56Sopenharmony_ci self.assertEqual(min(f), "itty-bitty line\n") 5967db96d56Sopenharmony_ci f.seek(0, 0) 5977db96d56Sopenharmony_ci self.assertEqual(max(f), "xtra large line\n") 5987db96d56Sopenharmony_ci finally: 5997db96d56Sopenharmony_ci f.close() 6007db96d56Sopenharmony_ci try: 6017db96d56Sopenharmony_ci unlink(TESTFN) 6027db96d56Sopenharmony_ci except OSError: 6037db96d56Sopenharmony_ci pass 6047db96d56Sopenharmony_ci 6057db96d56Sopenharmony_ci # Test map()'s use of iterators. 6067db96d56Sopenharmony_ci def test_builtin_map(self): 6077db96d56Sopenharmony_ci self.assertEqual(list(map(lambda x: x+1, SequenceClass(5))), 6087db96d56Sopenharmony_ci list(range(1, 6))) 6097db96d56Sopenharmony_ci 6107db96d56Sopenharmony_ci d = {"one": 1, "two": 2, "three": 3} 6117db96d56Sopenharmony_ci self.assertEqual(list(map(lambda k, d=d: (k, d[k]), d)), 6127db96d56Sopenharmony_ci list(d.items())) 6137db96d56Sopenharmony_ci dkeys = list(d.keys()) 6147db96d56Sopenharmony_ci expected = [(i < len(d) and dkeys[i] or None, 6157db96d56Sopenharmony_ci i, 6167db96d56Sopenharmony_ci i < len(d) and dkeys[i] or None) 6177db96d56Sopenharmony_ci for i in range(3)] 6187db96d56Sopenharmony_ci 6197db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 6207db96d56Sopenharmony_ci try: 6217db96d56Sopenharmony_ci for i in range(10): 6227db96d56Sopenharmony_ci f.write("xy" * i + "\n") # line i has len 2*i+1 6237db96d56Sopenharmony_ci finally: 6247db96d56Sopenharmony_ci f.close() 6257db96d56Sopenharmony_ci f = open(TESTFN, "r", encoding="utf-8") 6267db96d56Sopenharmony_ci try: 6277db96d56Sopenharmony_ci self.assertEqual(list(map(len, f)), list(range(1, 21, 2))) 6287db96d56Sopenharmony_ci finally: 6297db96d56Sopenharmony_ci f.close() 6307db96d56Sopenharmony_ci try: 6317db96d56Sopenharmony_ci unlink(TESTFN) 6327db96d56Sopenharmony_ci except OSError: 6337db96d56Sopenharmony_ci pass 6347db96d56Sopenharmony_ci 6357db96d56Sopenharmony_ci # Test zip()'s use of iterators. 6367db96d56Sopenharmony_ci def test_builtin_zip(self): 6377db96d56Sopenharmony_ci self.assertEqual(list(zip()), []) 6387db96d56Sopenharmony_ci self.assertEqual(list(zip(*[])), []) 6397db96d56Sopenharmony_ci self.assertEqual(list(zip(*[(1, 2), 'ab'])), [(1, 'a'), (2, 'b')]) 6407db96d56Sopenharmony_ci 6417db96d56Sopenharmony_ci self.assertRaises(TypeError, zip, None) 6427db96d56Sopenharmony_ci self.assertRaises(TypeError, zip, range(10), 42) 6437db96d56Sopenharmony_ci self.assertRaises(TypeError, zip, range(10), zip) 6447db96d56Sopenharmony_ci 6457db96d56Sopenharmony_ci self.assertEqual(list(zip(IteratingSequenceClass(3))), 6467db96d56Sopenharmony_ci [(0,), (1,), (2,)]) 6477db96d56Sopenharmony_ci self.assertEqual(list(zip(SequenceClass(3))), 6487db96d56Sopenharmony_ci [(0,), (1,), (2,)]) 6497db96d56Sopenharmony_ci 6507db96d56Sopenharmony_ci d = {"one": 1, "two": 2, "three": 3} 6517db96d56Sopenharmony_ci self.assertEqual(list(d.items()), list(zip(d, d.values()))) 6527db96d56Sopenharmony_ci 6537db96d56Sopenharmony_ci # Generate all ints starting at constructor arg. 6547db96d56Sopenharmony_ci class IntsFrom: 6557db96d56Sopenharmony_ci def __init__(self, start): 6567db96d56Sopenharmony_ci self.i = start 6577db96d56Sopenharmony_ci 6587db96d56Sopenharmony_ci def __iter__(self): 6597db96d56Sopenharmony_ci return self 6607db96d56Sopenharmony_ci 6617db96d56Sopenharmony_ci def __next__(self): 6627db96d56Sopenharmony_ci i = self.i 6637db96d56Sopenharmony_ci self.i = i+1 6647db96d56Sopenharmony_ci return i 6657db96d56Sopenharmony_ci 6667db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 6677db96d56Sopenharmony_ci try: 6687db96d56Sopenharmony_ci f.write("a\n" "bbb\n" "cc\n") 6697db96d56Sopenharmony_ci finally: 6707db96d56Sopenharmony_ci f.close() 6717db96d56Sopenharmony_ci f = open(TESTFN, "r", encoding="utf-8") 6727db96d56Sopenharmony_ci try: 6737db96d56Sopenharmony_ci self.assertEqual(list(zip(IntsFrom(0), f, IntsFrom(-100))), 6747db96d56Sopenharmony_ci [(0, "a\n", -100), 6757db96d56Sopenharmony_ci (1, "bbb\n", -99), 6767db96d56Sopenharmony_ci (2, "cc\n", -98)]) 6777db96d56Sopenharmony_ci finally: 6787db96d56Sopenharmony_ci f.close() 6797db96d56Sopenharmony_ci try: 6807db96d56Sopenharmony_ci unlink(TESTFN) 6817db96d56Sopenharmony_ci except OSError: 6827db96d56Sopenharmony_ci pass 6837db96d56Sopenharmony_ci 6847db96d56Sopenharmony_ci self.assertEqual(list(zip(range(5))), [(i,) for i in range(5)]) 6857db96d56Sopenharmony_ci 6867db96d56Sopenharmony_ci # Classes that lie about their lengths. 6877db96d56Sopenharmony_ci class NoGuessLen5: 6887db96d56Sopenharmony_ci def __getitem__(self, i): 6897db96d56Sopenharmony_ci if i >= 5: 6907db96d56Sopenharmony_ci raise IndexError 6917db96d56Sopenharmony_ci return i 6927db96d56Sopenharmony_ci 6937db96d56Sopenharmony_ci class Guess3Len5(NoGuessLen5): 6947db96d56Sopenharmony_ci def __len__(self): 6957db96d56Sopenharmony_ci return 3 6967db96d56Sopenharmony_ci 6977db96d56Sopenharmony_ci class Guess30Len5(NoGuessLen5): 6987db96d56Sopenharmony_ci def __len__(self): 6997db96d56Sopenharmony_ci return 30 7007db96d56Sopenharmony_ci 7017db96d56Sopenharmony_ci def lzip(*args): 7027db96d56Sopenharmony_ci return list(zip(*args)) 7037db96d56Sopenharmony_ci 7047db96d56Sopenharmony_ci self.assertEqual(len(Guess3Len5()), 3) 7057db96d56Sopenharmony_ci self.assertEqual(len(Guess30Len5()), 30) 7067db96d56Sopenharmony_ci self.assertEqual(lzip(NoGuessLen5()), lzip(range(5))) 7077db96d56Sopenharmony_ci self.assertEqual(lzip(Guess3Len5()), lzip(range(5))) 7087db96d56Sopenharmony_ci self.assertEqual(lzip(Guess30Len5()), lzip(range(5))) 7097db96d56Sopenharmony_ci 7107db96d56Sopenharmony_ci expected = [(i, i) for i in range(5)] 7117db96d56Sopenharmony_ci for x in NoGuessLen5(), Guess3Len5(), Guess30Len5(): 7127db96d56Sopenharmony_ci for y in NoGuessLen5(), Guess3Len5(), Guess30Len5(): 7137db96d56Sopenharmony_ci self.assertEqual(lzip(x, y), expected) 7147db96d56Sopenharmony_ci 7157db96d56Sopenharmony_ci def test_unicode_join_endcase(self): 7167db96d56Sopenharmony_ci 7177db96d56Sopenharmony_ci # This class inserts a Unicode object into its argument's natural 7187db96d56Sopenharmony_ci # iteration, in the 3rd position. 7197db96d56Sopenharmony_ci class OhPhooey: 7207db96d56Sopenharmony_ci def __init__(self, seq): 7217db96d56Sopenharmony_ci self.it = iter(seq) 7227db96d56Sopenharmony_ci self.i = 0 7237db96d56Sopenharmony_ci 7247db96d56Sopenharmony_ci def __iter__(self): 7257db96d56Sopenharmony_ci return self 7267db96d56Sopenharmony_ci 7277db96d56Sopenharmony_ci def __next__(self): 7287db96d56Sopenharmony_ci i = self.i 7297db96d56Sopenharmony_ci self.i = i+1 7307db96d56Sopenharmony_ci if i == 2: 7317db96d56Sopenharmony_ci return "fooled you!" 7327db96d56Sopenharmony_ci return next(self.it) 7337db96d56Sopenharmony_ci 7347db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 7357db96d56Sopenharmony_ci try: 7367db96d56Sopenharmony_ci f.write("a\n" + "b\n" + "c\n") 7377db96d56Sopenharmony_ci finally: 7387db96d56Sopenharmony_ci f.close() 7397db96d56Sopenharmony_ci 7407db96d56Sopenharmony_ci f = open(TESTFN, "r", encoding="utf-8") 7417db96d56Sopenharmony_ci # Nasty: string.join(s) can't know whether unicode.join() is needed 7427db96d56Sopenharmony_ci # until it's seen all of s's elements. But in this case, f's 7437db96d56Sopenharmony_ci # iterator cannot be restarted. So what we're testing here is 7447db96d56Sopenharmony_ci # whether string.join() can manage to remember everything it's seen 7457db96d56Sopenharmony_ci # and pass that on to unicode.join(). 7467db96d56Sopenharmony_ci try: 7477db96d56Sopenharmony_ci got = " - ".join(OhPhooey(f)) 7487db96d56Sopenharmony_ci self.assertEqual(got, "a\n - b\n - fooled you! - c\n") 7497db96d56Sopenharmony_ci finally: 7507db96d56Sopenharmony_ci f.close() 7517db96d56Sopenharmony_ci try: 7527db96d56Sopenharmony_ci unlink(TESTFN) 7537db96d56Sopenharmony_ci except OSError: 7547db96d56Sopenharmony_ci pass 7557db96d56Sopenharmony_ci 7567db96d56Sopenharmony_ci # Test iterators with 'x in y' and 'x not in y'. 7577db96d56Sopenharmony_ci def test_in_and_not_in(self): 7587db96d56Sopenharmony_ci for sc5 in IteratingSequenceClass(5), SequenceClass(5): 7597db96d56Sopenharmony_ci for i in range(5): 7607db96d56Sopenharmony_ci self.assertIn(i, sc5) 7617db96d56Sopenharmony_ci for i in "abc", -1, 5, 42.42, (3, 4), [], {1: 1}, 3-12j, sc5: 7627db96d56Sopenharmony_ci self.assertNotIn(i, sc5) 7637db96d56Sopenharmony_ci 7647db96d56Sopenharmony_ci self.assertIn(ALWAYS_EQ, IteratorProxyClass(iter([1]))) 7657db96d56Sopenharmony_ci self.assertIn(ALWAYS_EQ, SequenceProxyClass([1])) 7667db96d56Sopenharmony_ci self.assertNotIn(ALWAYS_EQ, IteratorProxyClass(iter([NEVER_EQ]))) 7677db96d56Sopenharmony_ci self.assertNotIn(ALWAYS_EQ, SequenceProxyClass([NEVER_EQ])) 7687db96d56Sopenharmony_ci self.assertIn(NEVER_EQ, IteratorProxyClass(iter([ALWAYS_EQ]))) 7697db96d56Sopenharmony_ci self.assertIn(NEVER_EQ, SequenceProxyClass([ALWAYS_EQ])) 7707db96d56Sopenharmony_ci 7717db96d56Sopenharmony_ci self.assertRaises(TypeError, lambda: 3 in 12) 7727db96d56Sopenharmony_ci self.assertRaises(TypeError, lambda: 3 not in map) 7737db96d56Sopenharmony_ci self.assertRaises(ZeroDivisionError, lambda: 3 in BadIterableClass()) 7747db96d56Sopenharmony_ci 7757db96d56Sopenharmony_ci d = {"one": 1, "two": 2, "three": 3, 1j: 2j} 7767db96d56Sopenharmony_ci for k in d: 7777db96d56Sopenharmony_ci self.assertIn(k, d) 7787db96d56Sopenharmony_ci self.assertNotIn(k, d.values()) 7797db96d56Sopenharmony_ci for v in d.values(): 7807db96d56Sopenharmony_ci self.assertIn(v, d.values()) 7817db96d56Sopenharmony_ci self.assertNotIn(v, d) 7827db96d56Sopenharmony_ci for k, v in d.items(): 7837db96d56Sopenharmony_ci self.assertIn((k, v), d.items()) 7847db96d56Sopenharmony_ci self.assertNotIn((v, k), d.items()) 7857db96d56Sopenharmony_ci 7867db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 7877db96d56Sopenharmony_ci try: 7887db96d56Sopenharmony_ci f.write("a\n" "b\n" "c\n") 7897db96d56Sopenharmony_ci finally: 7907db96d56Sopenharmony_ci f.close() 7917db96d56Sopenharmony_ci f = open(TESTFN, "r", encoding="utf-8") 7927db96d56Sopenharmony_ci try: 7937db96d56Sopenharmony_ci for chunk in "abc": 7947db96d56Sopenharmony_ci f.seek(0, 0) 7957db96d56Sopenharmony_ci self.assertNotIn(chunk, f) 7967db96d56Sopenharmony_ci f.seek(0, 0) 7977db96d56Sopenharmony_ci self.assertIn((chunk + "\n"), f) 7987db96d56Sopenharmony_ci finally: 7997db96d56Sopenharmony_ci f.close() 8007db96d56Sopenharmony_ci try: 8017db96d56Sopenharmony_ci unlink(TESTFN) 8027db96d56Sopenharmony_ci except OSError: 8037db96d56Sopenharmony_ci pass 8047db96d56Sopenharmony_ci 8057db96d56Sopenharmony_ci # Test iterators with operator.countOf (PySequence_Count). 8067db96d56Sopenharmony_ci def test_countOf(self): 8077db96d56Sopenharmony_ci from operator import countOf 8087db96d56Sopenharmony_ci self.assertEqual(countOf([1,2,2,3,2,5], 2), 3) 8097db96d56Sopenharmony_ci self.assertEqual(countOf((1,2,2,3,2,5), 2), 3) 8107db96d56Sopenharmony_ci self.assertEqual(countOf("122325", "2"), 3) 8117db96d56Sopenharmony_ci self.assertEqual(countOf("122325", "6"), 0) 8127db96d56Sopenharmony_ci 8137db96d56Sopenharmony_ci self.assertRaises(TypeError, countOf, 42, 1) 8147db96d56Sopenharmony_ci self.assertRaises(TypeError, countOf, countOf, countOf) 8157db96d56Sopenharmony_ci 8167db96d56Sopenharmony_ci d = {"one": 3, "two": 3, "three": 3, 1j: 2j} 8177db96d56Sopenharmony_ci for k in d: 8187db96d56Sopenharmony_ci self.assertEqual(countOf(d, k), 1) 8197db96d56Sopenharmony_ci self.assertEqual(countOf(d.values(), 3), 3) 8207db96d56Sopenharmony_ci self.assertEqual(countOf(d.values(), 2j), 1) 8217db96d56Sopenharmony_ci self.assertEqual(countOf(d.values(), 1j), 0) 8227db96d56Sopenharmony_ci 8237db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 8247db96d56Sopenharmony_ci try: 8257db96d56Sopenharmony_ci f.write("a\n" "b\n" "c\n" "b\n") 8267db96d56Sopenharmony_ci finally: 8277db96d56Sopenharmony_ci f.close() 8287db96d56Sopenharmony_ci f = open(TESTFN, "r", encoding="utf-8") 8297db96d56Sopenharmony_ci try: 8307db96d56Sopenharmony_ci for letter, count in ("a", 1), ("b", 2), ("c", 1), ("d", 0): 8317db96d56Sopenharmony_ci f.seek(0, 0) 8327db96d56Sopenharmony_ci self.assertEqual(countOf(f, letter + "\n"), count) 8337db96d56Sopenharmony_ci finally: 8347db96d56Sopenharmony_ci f.close() 8357db96d56Sopenharmony_ci try: 8367db96d56Sopenharmony_ci unlink(TESTFN) 8377db96d56Sopenharmony_ci except OSError: 8387db96d56Sopenharmony_ci pass 8397db96d56Sopenharmony_ci 8407db96d56Sopenharmony_ci # Test iterators with operator.indexOf (PySequence_Index). 8417db96d56Sopenharmony_ci def test_indexOf(self): 8427db96d56Sopenharmony_ci from operator import indexOf 8437db96d56Sopenharmony_ci self.assertEqual(indexOf([1,2,2,3,2,5], 1), 0) 8447db96d56Sopenharmony_ci self.assertEqual(indexOf((1,2,2,3,2,5), 2), 1) 8457db96d56Sopenharmony_ci self.assertEqual(indexOf((1,2,2,3,2,5), 3), 3) 8467db96d56Sopenharmony_ci self.assertEqual(indexOf((1,2,2,3,2,5), 5), 5) 8477db96d56Sopenharmony_ci self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 0) 8487db96d56Sopenharmony_ci self.assertRaises(ValueError, indexOf, (1,2,2,3,2,5), 6) 8497db96d56Sopenharmony_ci 8507db96d56Sopenharmony_ci self.assertEqual(indexOf("122325", "2"), 1) 8517db96d56Sopenharmony_ci self.assertEqual(indexOf("122325", "5"), 5) 8527db96d56Sopenharmony_ci self.assertRaises(ValueError, indexOf, "122325", "6") 8537db96d56Sopenharmony_ci 8547db96d56Sopenharmony_ci self.assertRaises(TypeError, indexOf, 42, 1) 8557db96d56Sopenharmony_ci self.assertRaises(TypeError, indexOf, indexOf, indexOf) 8567db96d56Sopenharmony_ci self.assertRaises(ZeroDivisionError, indexOf, BadIterableClass(), 1) 8577db96d56Sopenharmony_ci 8587db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 8597db96d56Sopenharmony_ci try: 8607db96d56Sopenharmony_ci f.write("a\n" "b\n" "c\n" "d\n" "e\n") 8617db96d56Sopenharmony_ci finally: 8627db96d56Sopenharmony_ci f.close() 8637db96d56Sopenharmony_ci f = open(TESTFN, "r", encoding="utf-8") 8647db96d56Sopenharmony_ci try: 8657db96d56Sopenharmony_ci fiter = iter(f) 8667db96d56Sopenharmony_ci self.assertEqual(indexOf(fiter, "b\n"), 1) 8677db96d56Sopenharmony_ci self.assertEqual(indexOf(fiter, "d\n"), 1) 8687db96d56Sopenharmony_ci self.assertEqual(indexOf(fiter, "e\n"), 0) 8697db96d56Sopenharmony_ci self.assertRaises(ValueError, indexOf, fiter, "a\n") 8707db96d56Sopenharmony_ci finally: 8717db96d56Sopenharmony_ci f.close() 8727db96d56Sopenharmony_ci try: 8737db96d56Sopenharmony_ci unlink(TESTFN) 8747db96d56Sopenharmony_ci except OSError: 8757db96d56Sopenharmony_ci pass 8767db96d56Sopenharmony_ci 8777db96d56Sopenharmony_ci iclass = IteratingSequenceClass(3) 8787db96d56Sopenharmony_ci for i in range(3): 8797db96d56Sopenharmony_ci self.assertEqual(indexOf(iclass, i), i) 8807db96d56Sopenharmony_ci self.assertRaises(ValueError, indexOf, iclass, -1) 8817db96d56Sopenharmony_ci 8827db96d56Sopenharmony_ci # Test iterators with file.writelines(). 8837db96d56Sopenharmony_ci def test_writelines(self): 8847db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 8857db96d56Sopenharmony_ci 8867db96d56Sopenharmony_ci try: 8877db96d56Sopenharmony_ci self.assertRaises(TypeError, f.writelines, None) 8887db96d56Sopenharmony_ci self.assertRaises(TypeError, f.writelines, 42) 8897db96d56Sopenharmony_ci 8907db96d56Sopenharmony_ci f.writelines(["1\n", "2\n"]) 8917db96d56Sopenharmony_ci f.writelines(("3\n", "4\n")) 8927db96d56Sopenharmony_ci f.writelines({'5\n': None}) 8937db96d56Sopenharmony_ci f.writelines({}) 8947db96d56Sopenharmony_ci 8957db96d56Sopenharmony_ci # Try a big chunk too. 8967db96d56Sopenharmony_ci class Iterator: 8977db96d56Sopenharmony_ci def __init__(self, start, finish): 8987db96d56Sopenharmony_ci self.start = start 8997db96d56Sopenharmony_ci self.finish = finish 9007db96d56Sopenharmony_ci self.i = self.start 9017db96d56Sopenharmony_ci 9027db96d56Sopenharmony_ci def __next__(self): 9037db96d56Sopenharmony_ci if self.i >= self.finish: 9047db96d56Sopenharmony_ci raise StopIteration 9057db96d56Sopenharmony_ci result = str(self.i) + '\n' 9067db96d56Sopenharmony_ci self.i += 1 9077db96d56Sopenharmony_ci return result 9087db96d56Sopenharmony_ci 9097db96d56Sopenharmony_ci def __iter__(self): 9107db96d56Sopenharmony_ci return self 9117db96d56Sopenharmony_ci 9127db96d56Sopenharmony_ci class Whatever: 9137db96d56Sopenharmony_ci def __init__(self, start, finish): 9147db96d56Sopenharmony_ci self.start = start 9157db96d56Sopenharmony_ci self.finish = finish 9167db96d56Sopenharmony_ci 9177db96d56Sopenharmony_ci def __iter__(self): 9187db96d56Sopenharmony_ci return Iterator(self.start, self.finish) 9197db96d56Sopenharmony_ci 9207db96d56Sopenharmony_ci f.writelines(Whatever(6, 6+2000)) 9217db96d56Sopenharmony_ci f.close() 9227db96d56Sopenharmony_ci 9237db96d56Sopenharmony_ci f = open(TESTFN, encoding="utf-8") 9247db96d56Sopenharmony_ci expected = [str(i) + "\n" for i in range(1, 2006)] 9257db96d56Sopenharmony_ci self.assertEqual(list(f), expected) 9267db96d56Sopenharmony_ci 9277db96d56Sopenharmony_ci finally: 9287db96d56Sopenharmony_ci f.close() 9297db96d56Sopenharmony_ci try: 9307db96d56Sopenharmony_ci unlink(TESTFN) 9317db96d56Sopenharmony_ci except OSError: 9327db96d56Sopenharmony_ci pass 9337db96d56Sopenharmony_ci 9347db96d56Sopenharmony_ci 9357db96d56Sopenharmony_ci # Test iterators on RHS of unpacking assignments. 9367db96d56Sopenharmony_ci def test_unpack_iter(self): 9377db96d56Sopenharmony_ci a, b = 1, 2 9387db96d56Sopenharmony_ci self.assertEqual((a, b), (1, 2)) 9397db96d56Sopenharmony_ci 9407db96d56Sopenharmony_ci a, b, c = IteratingSequenceClass(3) 9417db96d56Sopenharmony_ci self.assertEqual((a, b, c), (0, 1, 2)) 9427db96d56Sopenharmony_ci 9437db96d56Sopenharmony_ci try: # too many values 9447db96d56Sopenharmony_ci a, b = IteratingSequenceClass(3) 9457db96d56Sopenharmony_ci except ValueError: 9467db96d56Sopenharmony_ci pass 9477db96d56Sopenharmony_ci else: 9487db96d56Sopenharmony_ci self.fail("should have raised ValueError") 9497db96d56Sopenharmony_ci 9507db96d56Sopenharmony_ci try: # not enough values 9517db96d56Sopenharmony_ci a, b, c = IteratingSequenceClass(2) 9527db96d56Sopenharmony_ci except ValueError: 9537db96d56Sopenharmony_ci pass 9547db96d56Sopenharmony_ci else: 9557db96d56Sopenharmony_ci self.fail("should have raised ValueError") 9567db96d56Sopenharmony_ci 9577db96d56Sopenharmony_ci try: # not iterable 9587db96d56Sopenharmony_ci a, b, c = len 9597db96d56Sopenharmony_ci except TypeError: 9607db96d56Sopenharmony_ci pass 9617db96d56Sopenharmony_ci else: 9627db96d56Sopenharmony_ci self.fail("should have raised TypeError") 9637db96d56Sopenharmony_ci 9647db96d56Sopenharmony_ci a, b, c = {1: 42, 2: 42, 3: 42}.values() 9657db96d56Sopenharmony_ci self.assertEqual((a, b, c), (42, 42, 42)) 9667db96d56Sopenharmony_ci 9677db96d56Sopenharmony_ci f = open(TESTFN, "w", encoding="utf-8") 9687db96d56Sopenharmony_ci lines = ("a\n", "bb\n", "ccc\n") 9697db96d56Sopenharmony_ci try: 9707db96d56Sopenharmony_ci for line in lines: 9717db96d56Sopenharmony_ci f.write(line) 9727db96d56Sopenharmony_ci finally: 9737db96d56Sopenharmony_ci f.close() 9747db96d56Sopenharmony_ci f = open(TESTFN, "r", encoding="utf-8") 9757db96d56Sopenharmony_ci try: 9767db96d56Sopenharmony_ci a, b, c = f 9777db96d56Sopenharmony_ci self.assertEqual((a, b, c), lines) 9787db96d56Sopenharmony_ci finally: 9797db96d56Sopenharmony_ci f.close() 9807db96d56Sopenharmony_ci try: 9817db96d56Sopenharmony_ci unlink(TESTFN) 9827db96d56Sopenharmony_ci except OSError: 9837db96d56Sopenharmony_ci pass 9847db96d56Sopenharmony_ci 9857db96d56Sopenharmony_ci (a, b), (c,) = IteratingSequenceClass(2), {42: 24} 9867db96d56Sopenharmony_ci self.assertEqual((a, b, c), (0, 1, 42)) 9877db96d56Sopenharmony_ci 9887db96d56Sopenharmony_ci 9897db96d56Sopenharmony_ci @cpython_only 9907db96d56Sopenharmony_ci def test_ref_counting_behavior(self): 9917db96d56Sopenharmony_ci class C(object): 9927db96d56Sopenharmony_ci count = 0 9937db96d56Sopenharmony_ci def __new__(cls): 9947db96d56Sopenharmony_ci cls.count += 1 9957db96d56Sopenharmony_ci return object.__new__(cls) 9967db96d56Sopenharmony_ci def __del__(self): 9977db96d56Sopenharmony_ci cls = self.__class__ 9987db96d56Sopenharmony_ci assert cls.count > 0 9997db96d56Sopenharmony_ci cls.count -= 1 10007db96d56Sopenharmony_ci x = C() 10017db96d56Sopenharmony_ci self.assertEqual(C.count, 1) 10027db96d56Sopenharmony_ci del x 10037db96d56Sopenharmony_ci self.assertEqual(C.count, 0) 10047db96d56Sopenharmony_ci l = [C(), C(), C()] 10057db96d56Sopenharmony_ci self.assertEqual(C.count, 3) 10067db96d56Sopenharmony_ci try: 10077db96d56Sopenharmony_ci a, b = iter(l) 10087db96d56Sopenharmony_ci except ValueError: 10097db96d56Sopenharmony_ci pass 10107db96d56Sopenharmony_ci del l 10117db96d56Sopenharmony_ci self.assertEqual(C.count, 0) 10127db96d56Sopenharmony_ci 10137db96d56Sopenharmony_ci 10147db96d56Sopenharmony_ci # Make sure StopIteration is a "sink state". 10157db96d56Sopenharmony_ci # This tests various things that weren't sink states in Python 2.2.1, 10167db96d56Sopenharmony_ci # plus various things that always were fine. 10177db96d56Sopenharmony_ci 10187db96d56Sopenharmony_ci def test_sinkstate_list(self): 10197db96d56Sopenharmony_ci # This used to fail 10207db96d56Sopenharmony_ci a = list(range(5)) 10217db96d56Sopenharmony_ci b = iter(a) 10227db96d56Sopenharmony_ci self.assertEqual(list(b), list(range(5))) 10237db96d56Sopenharmony_ci a.extend(range(5, 10)) 10247db96d56Sopenharmony_ci self.assertEqual(list(b), []) 10257db96d56Sopenharmony_ci 10267db96d56Sopenharmony_ci def test_sinkstate_tuple(self): 10277db96d56Sopenharmony_ci a = (0, 1, 2, 3, 4) 10287db96d56Sopenharmony_ci b = iter(a) 10297db96d56Sopenharmony_ci self.assertEqual(list(b), list(range(5))) 10307db96d56Sopenharmony_ci self.assertEqual(list(b), []) 10317db96d56Sopenharmony_ci 10327db96d56Sopenharmony_ci def test_sinkstate_string(self): 10337db96d56Sopenharmony_ci a = "abcde" 10347db96d56Sopenharmony_ci b = iter(a) 10357db96d56Sopenharmony_ci self.assertEqual(list(b), ['a', 'b', 'c', 'd', 'e']) 10367db96d56Sopenharmony_ci self.assertEqual(list(b), []) 10377db96d56Sopenharmony_ci 10387db96d56Sopenharmony_ci def test_sinkstate_sequence(self): 10397db96d56Sopenharmony_ci # This used to fail 10407db96d56Sopenharmony_ci a = SequenceClass(5) 10417db96d56Sopenharmony_ci b = iter(a) 10427db96d56Sopenharmony_ci self.assertEqual(list(b), list(range(5))) 10437db96d56Sopenharmony_ci a.n = 10 10447db96d56Sopenharmony_ci self.assertEqual(list(b), []) 10457db96d56Sopenharmony_ci 10467db96d56Sopenharmony_ci def test_sinkstate_callable(self): 10477db96d56Sopenharmony_ci # This used to fail 10487db96d56Sopenharmony_ci def spam(state=[0]): 10497db96d56Sopenharmony_ci i = state[0] 10507db96d56Sopenharmony_ci state[0] = i+1 10517db96d56Sopenharmony_ci if i == 10: 10527db96d56Sopenharmony_ci raise AssertionError("shouldn't have gotten this far") 10537db96d56Sopenharmony_ci return i 10547db96d56Sopenharmony_ci b = iter(spam, 5) 10557db96d56Sopenharmony_ci self.assertEqual(list(b), list(range(5))) 10567db96d56Sopenharmony_ci self.assertEqual(list(b), []) 10577db96d56Sopenharmony_ci 10587db96d56Sopenharmony_ci def test_sinkstate_dict(self): 10597db96d56Sopenharmony_ci # XXX For a more thorough test, see towards the end of: 10607db96d56Sopenharmony_ci # http://mail.python.org/pipermail/python-dev/2002-July/026512.html 10617db96d56Sopenharmony_ci a = {1:1, 2:2, 0:0, 4:4, 3:3} 10627db96d56Sopenharmony_ci for b in iter(a), a.keys(), a.items(), a.values(): 10637db96d56Sopenharmony_ci b = iter(a) 10647db96d56Sopenharmony_ci self.assertEqual(len(list(b)), 5) 10657db96d56Sopenharmony_ci self.assertEqual(list(b), []) 10667db96d56Sopenharmony_ci 10677db96d56Sopenharmony_ci def test_sinkstate_yield(self): 10687db96d56Sopenharmony_ci def gen(): 10697db96d56Sopenharmony_ci for i in range(5): 10707db96d56Sopenharmony_ci yield i 10717db96d56Sopenharmony_ci b = gen() 10727db96d56Sopenharmony_ci self.assertEqual(list(b), list(range(5))) 10737db96d56Sopenharmony_ci self.assertEqual(list(b), []) 10747db96d56Sopenharmony_ci 10757db96d56Sopenharmony_ci def test_sinkstate_range(self): 10767db96d56Sopenharmony_ci a = range(5) 10777db96d56Sopenharmony_ci b = iter(a) 10787db96d56Sopenharmony_ci self.assertEqual(list(b), list(range(5))) 10797db96d56Sopenharmony_ci self.assertEqual(list(b), []) 10807db96d56Sopenharmony_ci 10817db96d56Sopenharmony_ci def test_sinkstate_enumerate(self): 10827db96d56Sopenharmony_ci a = range(5) 10837db96d56Sopenharmony_ci e = enumerate(a) 10847db96d56Sopenharmony_ci b = iter(e) 10857db96d56Sopenharmony_ci self.assertEqual(list(b), list(zip(range(5), range(5)))) 10867db96d56Sopenharmony_ci self.assertEqual(list(b), []) 10877db96d56Sopenharmony_ci 10887db96d56Sopenharmony_ci def test_3720(self): 10897db96d56Sopenharmony_ci # Avoid a crash, when an iterator deletes its next() method. 10907db96d56Sopenharmony_ci class BadIterator(object): 10917db96d56Sopenharmony_ci def __iter__(self): 10927db96d56Sopenharmony_ci return self 10937db96d56Sopenharmony_ci def __next__(self): 10947db96d56Sopenharmony_ci del BadIterator.__next__ 10957db96d56Sopenharmony_ci return 1 10967db96d56Sopenharmony_ci 10977db96d56Sopenharmony_ci try: 10987db96d56Sopenharmony_ci for i in BadIterator() : 10997db96d56Sopenharmony_ci pass 11007db96d56Sopenharmony_ci except TypeError: 11017db96d56Sopenharmony_ci pass 11027db96d56Sopenharmony_ci 11037db96d56Sopenharmony_ci def test_extending_list_with_iterator_does_not_segfault(self): 11047db96d56Sopenharmony_ci # The code to extend a list with an iterator has a fair 11057db96d56Sopenharmony_ci # amount of nontrivial logic in terms of guessing how 11067db96d56Sopenharmony_ci # much memory to allocate in advance, "stealing" refs, 11077db96d56Sopenharmony_ci # and then shrinking at the end. This is a basic smoke 11087db96d56Sopenharmony_ci # test for that scenario. 11097db96d56Sopenharmony_ci def gen(): 11107db96d56Sopenharmony_ci for i in range(500): 11117db96d56Sopenharmony_ci yield i 11127db96d56Sopenharmony_ci lst = [0] * 500 11137db96d56Sopenharmony_ci for i in range(240): 11147db96d56Sopenharmony_ci lst.pop(0) 11157db96d56Sopenharmony_ci lst.extend(gen()) 11167db96d56Sopenharmony_ci self.assertEqual(len(lst), 760) 11177db96d56Sopenharmony_ci 11187db96d56Sopenharmony_ci @cpython_only 11197db96d56Sopenharmony_ci def test_iter_overflow(self): 11207db96d56Sopenharmony_ci # Test for the issue 22939 11217db96d56Sopenharmony_ci it = iter(UnlimitedSequenceClass()) 11227db96d56Sopenharmony_ci # Manually set `it_index` to PY_SSIZE_T_MAX-2 without a loop 11237db96d56Sopenharmony_ci it.__setstate__(sys.maxsize - 2) 11247db96d56Sopenharmony_ci self.assertEqual(next(it), sys.maxsize - 2) 11257db96d56Sopenharmony_ci self.assertEqual(next(it), sys.maxsize - 1) 11267db96d56Sopenharmony_ci with self.assertRaises(OverflowError): 11277db96d56Sopenharmony_ci next(it) 11287db96d56Sopenharmony_ci # Check that Overflow error is always raised 11297db96d56Sopenharmony_ci with self.assertRaises(OverflowError): 11307db96d56Sopenharmony_ci next(it) 11317db96d56Sopenharmony_ci 11327db96d56Sopenharmony_ci def test_iter_neg_setstate(self): 11337db96d56Sopenharmony_ci it = iter(UnlimitedSequenceClass()) 11347db96d56Sopenharmony_ci it.__setstate__(-42) 11357db96d56Sopenharmony_ci self.assertEqual(next(it), 0) 11367db96d56Sopenharmony_ci self.assertEqual(next(it), 1) 11377db96d56Sopenharmony_ci 11387db96d56Sopenharmony_ci def test_free_after_iterating(self): 11397db96d56Sopenharmony_ci check_free_after_iterating(self, iter, SequenceClass, (0,)) 11407db96d56Sopenharmony_ci 11417db96d56Sopenharmony_ci def test_error_iter(self): 11427db96d56Sopenharmony_ci for typ in (DefaultIterClass, NoIterClass): 11437db96d56Sopenharmony_ci self.assertRaises(TypeError, iter, typ()) 11447db96d56Sopenharmony_ci self.assertRaises(ZeroDivisionError, iter, BadIterableClass()) 11457db96d56Sopenharmony_ci 11467db96d56Sopenharmony_ci 11477db96d56Sopenharmony_ciif __name__ == "__main__": 11487db96d56Sopenharmony_ci unittest.main() 1149