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