17db96d56Sopenharmony_ci# -*- coding: utf-8 -*-
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci"""
47db96d56Sopenharmony_ciTest suite for PEP 380 implementation
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ciadapted from original tests written by Greg Ewing
77db96d56Sopenharmony_cisee <http://www.cosc.canterbury.ac.nz/greg.ewing/python/yield-from/YieldFrom-Python3.1.2-rev5.zip>
87db96d56Sopenharmony_ci"""
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ciimport unittest
117db96d56Sopenharmony_ciimport inspect
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_cifrom test.support import captured_stderr, disable_gc, gc_collect
147db96d56Sopenharmony_cifrom test import support
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ciclass TestPEP380Operation(unittest.TestCase):
177db96d56Sopenharmony_ci    """
187db96d56Sopenharmony_ci    Test semantics.
197db96d56Sopenharmony_ci    """
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ci    def test_delegation_of_initial_next_to_subgenerator(self):
227db96d56Sopenharmony_ci        """
237db96d56Sopenharmony_ci        Test delegation of initial next() call to subgenerator
247db96d56Sopenharmony_ci        """
257db96d56Sopenharmony_ci        trace = []
267db96d56Sopenharmony_ci        def g1():
277db96d56Sopenharmony_ci            trace.append("Starting g1")
287db96d56Sopenharmony_ci            yield from g2()
297db96d56Sopenharmony_ci            trace.append("Finishing g1")
307db96d56Sopenharmony_ci        def g2():
317db96d56Sopenharmony_ci            trace.append("Starting g2")
327db96d56Sopenharmony_ci            yield 42
337db96d56Sopenharmony_ci            trace.append("Finishing g2")
347db96d56Sopenharmony_ci        for x in g1():
357db96d56Sopenharmony_ci            trace.append("Yielded %s" % (x,))
367db96d56Sopenharmony_ci        self.assertEqual(trace,[
377db96d56Sopenharmony_ci            "Starting g1",
387db96d56Sopenharmony_ci            "Starting g2",
397db96d56Sopenharmony_ci            "Yielded 42",
407db96d56Sopenharmony_ci            "Finishing g2",
417db96d56Sopenharmony_ci            "Finishing g1",
427db96d56Sopenharmony_ci        ])
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ci    def test_raising_exception_in_initial_next_call(self):
457db96d56Sopenharmony_ci        """
467db96d56Sopenharmony_ci        Test raising exception in initial next() call
477db96d56Sopenharmony_ci        """
487db96d56Sopenharmony_ci        trace = []
497db96d56Sopenharmony_ci        def g1():
507db96d56Sopenharmony_ci            try:
517db96d56Sopenharmony_ci                trace.append("Starting g1")
527db96d56Sopenharmony_ci                yield from g2()
537db96d56Sopenharmony_ci            finally:
547db96d56Sopenharmony_ci                trace.append("Finishing g1")
557db96d56Sopenharmony_ci        def g2():
567db96d56Sopenharmony_ci            try:
577db96d56Sopenharmony_ci                trace.append("Starting g2")
587db96d56Sopenharmony_ci                raise ValueError("spanish inquisition occurred")
597db96d56Sopenharmony_ci            finally:
607db96d56Sopenharmony_ci                trace.append("Finishing g2")
617db96d56Sopenharmony_ci        try:
627db96d56Sopenharmony_ci            for x in g1():
637db96d56Sopenharmony_ci                trace.append("Yielded %s" % (x,))
647db96d56Sopenharmony_ci        except ValueError as e:
657db96d56Sopenharmony_ci            self.assertEqual(e.args[0], "spanish inquisition occurred")
667db96d56Sopenharmony_ci        else:
677db96d56Sopenharmony_ci            self.fail("subgenerator failed to raise ValueError")
687db96d56Sopenharmony_ci        self.assertEqual(trace,[
697db96d56Sopenharmony_ci            "Starting g1",
707db96d56Sopenharmony_ci            "Starting g2",
717db96d56Sopenharmony_ci            "Finishing g2",
727db96d56Sopenharmony_ci            "Finishing g1",
737db96d56Sopenharmony_ci        ])
747db96d56Sopenharmony_ci
757db96d56Sopenharmony_ci    def test_delegation_of_next_call_to_subgenerator(self):
767db96d56Sopenharmony_ci        """
777db96d56Sopenharmony_ci        Test delegation of next() call to subgenerator
787db96d56Sopenharmony_ci        """
797db96d56Sopenharmony_ci        trace = []
807db96d56Sopenharmony_ci        def g1():
817db96d56Sopenharmony_ci            trace.append("Starting g1")
827db96d56Sopenharmony_ci            yield "g1 ham"
837db96d56Sopenharmony_ci            yield from g2()
847db96d56Sopenharmony_ci            yield "g1 eggs"
857db96d56Sopenharmony_ci            trace.append("Finishing g1")
867db96d56Sopenharmony_ci        def g2():
877db96d56Sopenharmony_ci            trace.append("Starting g2")
887db96d56Sopenharmony_ci            yield "g2 spam"
897db96d56Sopenharmony_ci            yield "g2 more spam"
907db96d56Sopenharmony_ci            trace.append("Finishing g2")
917db96d56Sopenharmony_ci        for x in g1():
927db96d56Sopenharmony_ci            trace.append("Yielded %s" % (x,))
937db96d56Sopenharmony_ci        self.assertEqual(trace,[
947db96d56Sopenharmony_ci            "Starting g1",
957db96d56Sopenharmony_ci            "Yielded g1 ham",
967db96d56Sopenharmony_ci            "Starting g2",
977db96d56Sopenharmony_ci            "Yielded g2 spam",
987db96d56Sopenharmony_ci            "Yielded g2 more spam",
997db96d56Sopenharmony_ci            "Finishing g2",
1007db96d56Sopenharmony_ci            "Yielded g1 eggs",
1017db96d56Sopenharmony_ci            "Finishing g1",
1027db96d56Sopenharmony_ci        ])
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci    def test_raising_exception_in_delegated_next_call(self):
1057db96d56Sopenharmony_ci        """
1067db96d56Sopenharmony_ci        Test raising exception in delegated next() call
1077db96d56Sopenharmony_ci        """
1087db96d56Sopenharmony_ci        trace = []
1097db96d56Sopenharmony_ci        def g1():
1107db96d56Sopenharmony_ci            try:
1117db96d56Sopenharmony_ci                trace.append("Starting g1")
1127db96d56Sopenharmony_ci                yield "g1 ham"
1137db96d56Sopenharmony_ci                yield from g2()
1147db96d56Sopenharmony_ci                yield "g1 eggs"
1157db96d56Sopenharmony_ci            finally:
1167db96d56Sopenharmony_ci                trace.append("Finishing g1")
1177db96d56Sopenharmony_ci        def g2():
1187db96d56Sopenharmony_ci            try:
1197db96d56Sopenharmony_ci                trace.append("Starting g2")
1207db96d56Sopenharmony_ci                yield "g2 spam"
1217db96d56Sopenharmony_ci                raise ValueError("hovercraft is full of eels")
1227db96d56Sopenharmony_ci                yield "g2 more spam"
1237db96d56Sopenharmony_ci            finally:
1247db96d56Sopenharmony_ci                trace.append("Finishing g2")
1257db96d56Sopenharmony_ci        try:
1267db96d56Sopenharmony_ci            for x in g1():
1277db96d56Sopenharmony_ci                trace.append("Yielded %s" % (x,))
1287db96d56Sopenharmony_ci        except ValueError as e:
1297db96d56Sopenharmony_ci            self.assertEqual(e.args[0], "hovercraft is full of eels")
1307db96d56Sopenharmony_ci        else:
1317db96d56Sopenharmony_ci            self.fail("subgenerator failed to raise ValueError")
1327db96d56Sopenharmony_ci        self.assertEqual(trace,[
1337db96d56Sopenharmony_ci            "Starting g1",
1347db96d56Sopenharmony_ci            "Yielded g1 ham",
1357db96d56Sopenharmony_ci            "Starting g2",
1367db96d56Sopenharmony_ci            "Yielded g2 spam",
1377db96d56Sopenharmony_ci            "Finishing g2",
1387db96d56Sopenharmony_ci            "Finishing g1",
1397db96d56Sopenharmony_ci        ])
1407db96d56Sopenharmony_ci
1417db96d56Sopenharmony_ci    def test_delegation_of_send(self):
1427db96d56Sopenharmony_ci        """
1437db96d56Sopenharmony_ci        Test delegation of send()
1447db96d56Sopenharmony_ci        """
1457db96d56Sopenharmony_ci        trace = []
1467db96d56Sopenharmony_ci        def g1():
1477db96d56Sopenharmony_ci            trace.append("Starting g1")
1487db96d56Sopenharmony_ci            x = yield "g1 ham"
1497db96d56Sopenharmony_ci            trace.append("g1 received %s" % (x,))
1507db96d56Sopenharmony_ci            yield from g2()
1517db96d56Sopenharmony_ci            x = yield "g1 eggs"
1527db96d56Sopenharmony_ci            trace.append("g1 received %s" % (x,))
1537db96d56Sopenharmony_ci            trace.append("Finishing g1")
1547db96d56Sopenharmony_ci        def g2():
1557db96d56Sopenharmony_ci            trace.append("Starting g2")
1567db96d56Sopenharmony_ci            x = yield "g2 spam"
1577db96d56Sopenharmony_ci            trace.append("g2 received %s" % (x,))
1587db96d56Sopenharmony_ci            x = yield "g2 more spam"
1597db96d56Sopenharmony_ci            trace.append("g2 received %s" % (x,))
1607db96d56Sopenharmony_ci            trace.append("Finishing g2")
1617db96d56Sopenharmony_ci        g = g1()
1627db96d56Sopenharmony_ci        y = next(g)
1637db96d56Sopenharmony_ci        x = 1
1647db96d56Sopenharmony_ci        try:
1657db96d56Sopenharmony_ci            while 1:
1667db96d56Sopenharmony_ci                y = g.send(x)
1677db96d56Sopenharmony_ci                trace.append("Yielded %s" % (y,))
1687db96d56Sopenharmony_ci                x += 1
1697db96d56Sopenharmony_ci        except StopIteration:
1707db96d56Sopenharmony_ci            pass
1717db96d56Sopenharmony_ci        self.assertEqual(trace,[
1727db96d56Sopenharmony_ci            "Starting g1",
1737db96d56Sopenharmony_ci            "g1 received 1",
1747db96d56Sopenharmony_ci            "Starting g2",
1757db96d56Sopenharmony_ci            "Yielded g2 spam",
1767db96d56Sopenharmony_ci            "g2 received 2",
1777db96d56Sopenharmony_ci            "Yielded g2 more spam",
1787db96d56Sopenharmony_ci            "g2 received 3",
1797db96d56Sopenharmony_ci            "Finishing g2",
1807db96d56Sopenharmony_ci            "Yielded g1 eggs",
1817db96d56Sopenharmony_ci            "g1 received 4",
1827db96d56Sopenharmony_ci            "Finishing g1",
1837db96d56Sopenharmony_ci        ])
1847db96d56Sopenharmony_ci
1857db96d56Sopenharmony_ci    def test_handling_exception_while_delegating_send(self):
1867db96d56Sopenharmony_ci        """
1877db96d56Sopenharmony_ci        Test handling exception while delegating 'send'
1887db96d56Sopenharmony_ci        """
1897db96d56Sopenharmony_ci        trace = []
1907db96d56Sopenharmony_ci        def g1():
1917db96d56Sopenharmony_ci            trace.append("Starting g1")
1927db96d56Sopenharmony_ci            x = yield "g1 ham"
1937db96d56Sopenharmony_ci            trace.append("g1 received %s" % (x,))
1947db96d56Sopenharmony_ci            yield from g2()
1957db96d56Sopenharmony_ci            x = yield "g1 eggs"
1967db96d56Sopenharmony_ci            trace.append("g1 received %s" % (x,))
1977db96d56Sopenharmony_ci            trace.append("Finishing g1")
1987db96d56Sopenharmony_ci        def g2():
1997db96d56Sopenharmony_ci            trace.append("Starting g2")
2007db96d56Sopenharmony_ci            x = yield "g2 spam"
2017db96d56Sopenharmony_ci            trace.append("g2 received %s" % (x,))
2027db96d56Sopenharmony_ci            raise ValueError("hovercraft is full of eels")
2037db96d56Sopenharmony_ci            x = yield "g2 more spam"
2047db96d56Sopenharmony_ci            trace.append("g2 received %s" % (x,))
2057db96d56Sopenharmony_ci            trace.append("Finishing g2")
2067db96d56Sopenharmony_ci        def run():
2077db96d56Sopenharmony_ci            g = g1()
2087db96d56Sopenharmony_ci            y = next(g)
2097db96d56Sopenharmony_ci            x = 1
2107db96d56Sopenharmony_ci            try:
2117db96d56Sopenharmony_ci                while 1:
2127db96d56Sopenharmony_ci                    y = g.send(x)
2137db96d56Sopenharmony_ci                    trace.append("Yielded %s" % (y,))
2147db96d56Sopenharmony_ci                    x += 1
2157db96d56Sopenharmony_ci            except StopIteration:
2167db96d56Sopenharmony_ci                trace.append("StopIteration")
2177db96d56Sopenharmony_ci        self.assertRaises(ValueError,run)
2187db96d56Sopenharmony_ci        self.assertEqual(trace,[
2197db96d56Sopenharmony_ci            "Starting g1",
2207db96d56Sopenharmony_ci            "g1 received 1",
2217db96d56Sopenharmony_ci            "Starting g2",
2227db96d56Sopenharmony_ci            "Yielded g2 spam",
2237db96d56Sopenharmony_ci            "g2 received 2",
2247db96d56Sopenharmony_ci        ])
2257db96d56Sopenharmony_ci
2267db96d56Sopenharmony_ci    def test_delegating_close(self):
2277db96d56Sopenharmony_ci        """
2287db96d56Sopenharmony_ci        Test delegating 'close'
2297db96d56Sopenharmony_ci        """
2307db96d56Sopenharmony_ci        trace = []
2317db96d56Sopenharmony_ci        def g1():
2327db96d56Sopenharmony_ci            try:
2337db96d56Sopenharmony_ci                trace.append("Starting g1")
2347db96d56Sopenharmony_ci                yield "g1 ham"
2357db96d56Sopenharmony_ci                yield from g2()
2367db96d56Sopenharmony_ci                yield "g1 eggs"
2377db96d56Sopenharmony_ci            finally:
2387db96d56Sopenharmony_ci                trace.append("Finishing g1")
2397db96d56Sopenharmony_ci        def g2():
2407db96d56Sopenharmony_ci            try:
2417db96d56Sopenharmony_ci                trace.append("Starting g2")
2427db96d56Sopenharmony_ci                yield "g2 spam"
2437db96d56Sopenharmony_ci                yield "g2 more spam"
2447db96d56Sopenharmony_ci            finally:
2457db96d56Sopenharmony_ci                trace.append("Finishing g2")
2467db96d56Sopenharmony_ci        g = g1()
2477db96d56Sopenharmony_ci        for i in range(2):
2487db96d56Sopenharmony_ci            x = next(g)
2497db96d56Sopenharmony_ci            trace.append("Yielded %s" % (x,))
2507db96d56Sopenharmony_ci        g.close()
2517db96d56Sopenharmony_ci        self.assertEqual(trace,[
2527db96d56Sopenharmony_ci            "Starting g1",
2537db96d56Sopenharmony_ci            "Yielded g1 ham",
2547db96d56Sopenharmony_ci            "Starting g2",
2557db96d56Sopenharmony_ci            "Yielded g2 spam",
2567db96d56Sopenharmony_ci            "Finishing g2",
2577db96d56Sopenharmony_ci            "Finishing g1"
2587db96d56Sopenharmony_ci        ])
2597db96d56Sopenharmony_ci
2607db96d56Sopenharmony_ci    def test_handing_exception_while_delegating_close(self):
2617db96d56Sopenharmony_ci        """
2627db96d56Sopenharmony_ci        Test handling exception while delegating 'close'
2637db96d56Sopenharmony_ci        """
2647db96d56Sopenharmony_ci        trace = []
2657db96d56Sopenharmony_ci        def g1():
2667db96d56Sopenharmony_ci            try:
2677db96d56Sopenharmony_ci                trace.append("Starting g1")
2687db96d56Sopenharmony_ci                yield "g1 ham"
2697db96d56Sopenharmony_ci                yield from g2()
2707db96d56Sopenharmony_ci                yield "g1 eggs"
2717db96d56Sopenharmony_ci            finally:
2727db96d56Sopenharmony_ci                trace.append("Finishing g1")
2737db96d56Sopenharmony_ci        def g2():
2747db96d56Sopenharmony_ci            try:
2757db96d56Sopenharmony_ci                trace.append("Starting g2")
2767db96d56Sopenharmony_ci                yield "g2 spam"
2777db96d56Sopenharmony_ci                yield "g2 more spam"
2787db96d56Sopenharmony_ci            finally:
2797db96d56Sopenharmony_ci                trace.append("Finishing g2")
2807db96d56Sopenharmony_ci                raise ValueError("nybbles have exploded with delight")
2817db96d56Sopenharmony_ci        try:
2827db96d56Sopenharmony_ci            g = g1()
2837db96d56Sopenharmony_ci            for i in range(2):
2847db96d56Sopenharmony_ci                x = next(g)
2857db96d56Sopenharmony_ci                trace.append("Yielded %s" % (x,))
2867db96d56Sopenharmony_ci            g.close()
2877db96d56Sopenharmony_ci        except ValueError as e:
2887db96d56Sopenharmony_ci            self.assertEqual(e.args[0], "nybbles have exploded with delight")
2897db96d56Sopenharmony_ci            self.assertIsInstance(e.__context__, GeneratorExit)
2907db96d56Sopenharmony_ci        else:
2917db96d56Sopenharmony_ci            self.fail("subgenerator failed to raise ValueError")
2927db96d56Sopenharmony_ci        self.assertEqual(trace,[
2937db96d56Sopenharmony_ci            "Starting g1",
2947db96d56Sopenharmony_ci            "Yielded g1 ham",
2957db96d56Sopenharmony_ci            "Starting g2",
2967db96d56Sopenharmony_ci            "Yielded g2 spam",
2977db96d56Sopenharmony_ci            "Finishing g2",
2987db96d56Sopenharmony_ci            "Finishing g1",
2997db96d56Sopenharmony_ci        ])
3007db96d56Sopenharmony_ci
3017db96d56Sopenharmony_ci    def test_delegating_throw(self):
3027db96d56Sopenharmony_ci        """
3037db96d56Sopenharmony_ci        Test delegating 'throw'
3047db96d56Sopenharmony_ci        """
3057db96d56Sopenharmony_ci        trace = []
3067db96d56Sopenharmony_ci        def g1():
3077db96d56Sopenharmony_ci            try:
3087db96d56Sopenharmony_ci                trace.append("Starting g1")
3097db96d56Sopenharmony_ci                yield "g1 ham"
3107db96d56Sopenharmony_ci                yield from g2()
3117db96d56Sopenharmony_ci                yield "g1 eggs"
3127db96d56Sopenharmony_ci            finally:
3137db96d56Sopenharmony_ci                trace.append("Finishing g1")
3147db96d56Sopenharmony_ci        def g2():
3157db96d56Sopenharmony_ci            try:
3167db96d56Sopenharmony_ci                trace.append("Starting g2")
3177db96d56Sopenharmony_ci                yield "g2 spam"
3187db96d56Sopenharmony_ci                yield "g2 more spam"
3197db96d56Sopenharmony_ci            finally:
3207db96d56Sopenharmony_ci                trace.append("Finishing g2")
3217db96d56Sopenharmony_ci        try:
3227db96d56Sopenharmony_ci            g = g1()
3237db96d56Sopenharmony_ci            for i in range(2):
3247db96d56Sopenharmony_ci                x = next(g)
3257db96d56Sopenharmony_ci                trace.append("Yielded %s" % (x,))
3267db96d56Sopenharmony_ci            e = ValueError("tomato ejected")
3277db96d56Sopenharmony_ci            g.throw(e)
3287db96d56Sopenharmony_ci        except ValueError as e:
3297db96d56Sopenharmony_ci            self.assertEqual(e.args[0], "tomato ejected")
3307db96d56Sopenharmony_ci        else:
3317db96d56Sopenharmony_ci            self.fail("subgenerator failed to raise ValueError")
3327db96d56Sopenharmony_ci        self.assertEqual(trace,[
3337db96d56Sopenharmony_ci            "Starting g1",
3347db96d56Sopenharmony_ci            "Yielded g1 ham",
3357db96d56Sopenharmony_ci            "Starting g2",
3367db96d56Sopenharmony_ci            "Yielded g2 spam",
3377db96d56Sopenharmony_ci            "Finishing g2",
3387db96d56Sopenharmony_ci            "Finishing g1",
3397db96d56Sopenharmony_ci        ])
3407db96d56Sopenharmony_ci
3417db96d56Sopenharmony_ci    def test_value_attribute_of_StopIteration_exception(self):
3427db96d56Sopenharmony_ci        """
3437db96d56Sopenharmony_ci        Test 'value' attribute of StopIteration exception
3447db96d56Sopenharmony_ci        """
3457db96d56Sopenharmony_ci        trace = []
3467db96d56Sopenharmony_ci        def pex(e):
3477db96d56Sopenharmony_ci            trace.append("%s: %s" % (e.__class__.__name__, e))
3487db96d56Sopenharmony_ci            trace.append("value = %s" % (e.value,))
3497db96d56Sopenharmony_ci        e = StopIteration()
3507db96d56Sopenharmony_ci        pex(e)
3517db96d56Sopenharmony_ci        e = StopIteration("spam")
3527db96d56Sopenharmony_ci        pex(e)
3537db96d56Sopenharmony_ci        e.value = "eggs"
3547db96d56Sopenharmony_ci        pex(e)
3557db96d56Sopenharmony_ci        self.assertEqual(trace,[
3567db96d56Sopenharmony_ci            "StopIteration: ",
3577db96d56Sopenharmony_ci            "value = None",
3587db96d56Sopenharmony_ci            "StopIteration: spam",
3597db96d56Sopenharmony_ci            "value = spam",
3607db96d56Sopenharmony_ci            "StopIteration: spam",
3617db96d56Sopenharmony_ci            "value = eggs",
3627db96d56Sopenharmony_ci        ])
3637db96d56Sopenharmony_ci
3647db96d56Sopenharmony_ci
3657db96d56Sopenharmony_ci    def test_exception_value_crash(self):
3667db96d56Sopenharmony_ci        # There used to be a refcount error when the return value
3677db96d56Sopenharmony_ci        # stored in the StopIteration has a refcount of 1.
3687db96d56Sopenharmony_ci        def g1():
3697db96d56Sopenharmony_ci            yield from g2()
3707db96d56Sopenharmony_ci        def g2():
3717db96d56Sopenharmony_ci            yield "g2"
3727db96d56Sopenharmony_ci            return [42]
3737db96d56Sopenharmony_ci        self.assertEqual(list(g1()), ["g2"])
3747db96d56Sopenharmony_ci
3757db96d56Sopenharmony_ci
3767db96d56Sopenharmony_ci    def test_generator_return_value(self):
3777db96d56Sopenharmony_ci        """
3787db96d56Sopenharmony_ci        Test generator return value
3797db96d56Sopenharmony_ci        """
3807db96d56Sopenharmony_ci        trace = []
3817db96d56Sopenharmony_ci        def g1():
3827db96d56Sopenharmony_ci            trace.append("Starting g1")
3837db96d56Sopenharmony_ci            yield "g1 ham"
3847db96d56Sopenharmony_ci            ret = yield from g2()
3857db96d56Sopenharmony_ci            trace.append("g2 returned %r" % (ret,))
3867db96d56Sopenharmony_ci            for v in 1, (2,), StopIteration(3):
3877db96d56Sopenharmony_ci                ret = yield from g2(v)
3887db96d56Sopenharmony_ci                trace.append("g2 returned %r" % (ret,))
3897db96d56Sopenharmony_ci            yield "g1 eggs"
3907db96d56Sopenharmony_ci            trace.append("Finishing g1")
3917db96d56Sopenharmony_ci        def g2(v = None):
3927db96d56Sopenharmony_ci            trace.append("Starting g2")
3937db96d56Sopenharmony_ci            yield "g2 spam"
3947db96d56Sopenharmony_ci            yield "g2 more spam"
3957db96d56Sopenharmony_ci            trace.append("Finishing g2")
3967db96d56Sopenharmony_ci            if v:
3977db96d56Sopenharmony_ci                return v
3987db96d56Sopenharmony_ci        for x in g1():
3997db96d56Sopenharmony_ci            trace.append("Yielded %s" % (x,))
4007db96d56Sopenharmony_ci        self.assertEqual(trace,[
4017db96d56Sopenharmony_ci            "Starting g1",
4027db96d56Sopenharmony_ci            "Yielded g1 ham",
4037db96d56Sopenharmony_ci            "Starting g2",
4047db96d56Sopenharmony_ci            "Yielded g2 spam",
4057db96d56Sopenharmony_ci            "Yielded g2 more spam",
4067db96d56Sopenharmony_ci            "Finishing g2",
4077db96d56Sopenharmony_ci            "g2 returned None",
4087db96d56Sopenharmony_ci            "Starting g2",
4097db96d56Sopenharmony_ci            "Yielded g2 spam",
4107db96d56Sopenharmony_ci            "Yielded g2 more spam",
4117db96d56Sopenharmony_ci            "Finishing g2",
4127db96d56Sopenharmony_ci            "g2 returned 1",
4137db96d56Sopenharmony_ci            "Starting g2",
4147db96d56Sopenharmony_ci            "Yielded g2 spam",
4157db96d56Sopenharmony_ci            "Yielded g2 more spam",
4167db96d56Sopenharmony_ci            "Finishing g2",
4177db96d56Sopenharmony_ci            "g2 returned (2,)",
4187db96d56Sopenharmony_ci            "Starting g2",
4197db96d56Sopenharmony_ci            "Yielded g2 spam",
4207db96d56Sopenharmony_ci            "Yielded g2 more spam",
4217db96d56Sopenharmony_ci            "Finishing g2",
4227db96d56Sopenharmony_ci            "g2 returned StopIteration(3)",
4237db96d56Sopenharmony_ci            "Yielded g1 eggs",
4247db96d56Sopenharmony_ci            "Finishing g1",
4257db96d56Sopenharmony_ci        ])
4267db96d56Sopenharmony_ci
4277db96d56Sopenharmony_ci    def test_delegation_of_next_to_non_generator(self):
4287db96d56Sopenharmony_ci        """
4297db96d56Sopenharmony_ci        Test delegation of next() to non-generator
4307db96d56Sopenharmony_ci        """
4317db96d56Sopenharmony_ci        trace = []
4327db96d56Sopenharmony_ci        def g():
4337db96d56Sopenharmony_ci            yield from range(3)
4347db96d56Sopenharmony_ci        for x in g():
4357db96d56Sopenharmony_ci            trace.append("Yielded %s" % (x,))
4367db96d56Sopenharmony_ci        self.assertEqual(trace,[
4377db96d56Sopenharmony_ci            "Yielded 0",
4387db96d56Sopenharmony_ci            "Yielded 1",
4397db96d56Sopenharmony_ci            "Yielded 2",
4407db96d56Sopenharmony_ci        ])
4417db96d56Sopenharmony_ci
4427db96d56Sopenharmony_ci
4437db96d56Sopenharmony_ci    def test_conversion_of_sendNone_to_next(self):
4447db96d56Sopenharmony_ci        """
4457db96d56Sopenharmony_ci        Test conversion of send(None) to next()
4467db96d56Sopenharmony_ci        """
4477db96d56Sopenharmony_ci        trace = []
4487db96d56Sopenharmony_ci        def g():
4497db96d56Sopenharmony_ci            yield from range(3)
4507db96d56Sopenharmony_ci        gi = g()
4517db96d56Sopenharmony_ci        for x in range(3):
4527db96d56Sopenharmony_ci            y = gi.send(None)
4537db96d56Sopenharmony_ci            trace.append("Yielded: %s" % (y,))
4547db96d56Sopenharmony_ci        self.assertEqual(trace,[
4557db96d56Sopenharmony_ci            "Yielded: 0",
4567db96d56Sopenharmony_ci            "Yielded: 1",
4577db96d56Sopenharmony_ci            "Yielded: 2",
4587db96d56Sopenharmony_ci        ])
4597db96d56Sopenharmony_ci
4607db96d56Sopenharmony_ci    def test_delegation_of_close_to_non_generator(self):
4617db96d56Sopenharmony_ci        """
4627db96d56Sopenharmony_ci        Test delegation of close() to non-generator
4637db96d56Sopenharmony_ci        """
4647db96d56Sopenharmony_ci        trace = []
4657db96d56Sopenharmony_ci        def g():
4667db96d56Sopenharmony_ci            try:
4677db96d56Sopenharmony_ci                trace.append("starting g")
4687db96d56Sopenharmony_ci                yield from range(3)
4697db96d56Sopenharmony_ci                trace.append("g should not be here")
4707db96d56Sopenharmony_ci            finally:
4717db96d56Sopenharmony_ci                trace.append("finishing g")
4727db96d56Sopenharmony_ci        gi = g()
4737db96d56Sopenharmony_ci        next(gi)
4747db96d56Sopenharmony_ci        with captured_stderr() as output:
4757db96d56Sopenharmony_ci            gi.close()
4767db96d56Sopenharmony_ci        self.assertEqual(output.getvalue(), '')
4777db96d56Sopenharmony_ci        self.assertEqual(trace,[
4787db96d56Sopenharmony_ci            "starting g",
4797db96d56Sopenharmony_ci            "finishing g",
4807db96d56Sopenharmony_ci        ])
4817db96d56Sopenharmony_ci
4827db96d56Sopenharmony_ci    def test_delegating_throw_to_non_generator(self):
4837db96d56Sopenharmony_ci        """
4847db96d56Sopenharmony_ci        Test delegating 'throw' to non-generator
4857db96d56Sopenharmony_ci        """
4867db96d56Sopenharmony_ci        trace = []
4877db96d56Sopenharmony_ci        def g():
4887db96d56Sopenharmony_ci            try:
4897db96d56Sopenharmony_ci                trace.append("Starting g")
4907db96d56Sopenharmony_ci                yield from range(10)
4917db96d56Sopenharmony_ci            finally:
4927db96d56Sopenharmony_ci                trace.append("Finishing g")
4937db96d56Sopenharmony_ci        try:
4947db96d56Sopenharmony_ci            gi = g()
4957db96d56Sopenharmony_ci            for i in range(5):
4967db96d56Sopenharmony_ci                x = next(gi)
4977db96d56Sopenharmony_ci                trace.append("Yielded %s" % (x,))
4987db96d56Sopenharmony_ci            e = ValueError("tomato ejected")
4997db96d56Sopenharmony_ci            gi.throw(e)
5007db96d56Sopenharmony_ci        except ValueError as e:
5017db96d56Sopenharmony_ci            self.assertEqual(e.args[0],"tomato ejected")
5027db96d56Sopenharmony_ci        else:
5037db96d56Sopenharmony_ci            self.fail("subgenerator failed to raise ValueError")
5047db96d56Sopenharmony_ci        self.assertEqual(trace,[
5057db96d56Sopenharmony_ci            "Starting g",
5067db96d56Sopenharmony_ci            "Yielded 0",
5077db96d56Sopenharmony_ci            "Yielded 1",
5087db96d56Sopenharmony_ci            "Yielded 2",
5097db96d56Sopenharmony_ci            "Yielded 3",
5107db96d56Sopenharmony_ci            "Yielded 4",
5117db96d56Sopenharmony_ci            "Finishing g",
5127db96d56Sopenharmony_ci        ])
5137db96d56Sopenharmony_ci
5147db96d56Sopenharmony_ci    def test_attempting_to_send_to_non_generator(self):
5157db96d56Sopenharmony_ci        """
5167db96d56Sopenharmony_ci        Test attempting to send to non-generator
5177db96d56Sopenharmony_ci        """
5187db96d56Sopenharmony_ci        trace = []
5197db96d56Sopenharmony_ci        def g():
5207db96d56Sopenharmony_ci            try:
5217db96d56Sopenharmony_ci                trace.append("starting g")
5227db96d56Sopenharmony_ci                yield from range(3)
5237db96d56Sopenharmony_ci                trace.append("g should not be here")
5247db96d56Sopenharmony_ci            finally:
5257db96d56Sopenharmony_ci                trace.append("finishing g")
5267db96d56Sopenharmony_ci        try:
5277db96d56Sopenharmony_ci            gi = g()
5287db96d56Sopenharmony_ci            next(gi)
5297db96d56Sopenharmony_ci            for x in range(3):
5307db96d56Sopenharmony_ci                y = gi.send(42)
5317db96d56Sopenharmony_ci                trace.append("Should not have yielded: %s" % (y,))
5327db96d56Sopenharmony_ci        except AttributeError as e:
5337db96d56Sopenharmony_ci            self.assertIn("send", e.args[0])
5347db96d56Sopenharmony_ci        else:
5357db96d56Sopenharmony_ci            self.fail("was able to send into non-generator")
5367db96d56Sopenharmony_ci        self.assertEqual(trace,[
5377db96d56Sopenharmony_ci            "starting g",
5387db96d56Sopenharmony_ci            "finishing g",
5397db96d56Sopenharmony_ci        ])
5407db96d56Sopenharmony_ci
5417db96d56Sopenharmony_ci    def test_broken_getattr_handling(self):
5427db96d56Sopenharmony_ci        """
5437db96d56Sopenharmony_ci        Test subiterator with a broken getattr implementation
5447db96d56Sopenharmony_ci        """
5457db96d56Sopenharmony_ci        class Broken:
5467db96d56Sopenharmony_ci            def __iter__(self):
5477db96d56Sopenharmony_ci                return self
5487db96d56Sopenharmony_ci            def __next__(self):
5497db96d56Sopenharmony_ci                return 1
5507db96d56Sopenharmony_ci            def __getattr__(self, attr):
5517db96d56Sopenharmony_ci                1/0
5527db96d56Sopenharmony_ci
5537db96d56Sopenharmony_ci        def g():
5547db96d56Sopenharmony_ci            yield from Broken()
5557db96d56Sopenharmony_ci
5567db96d56Sopenharmony_ci        with self.assertRaises(ZeroDivisionError):
5577db96d56Sopenharmony_ci            gi = g()
5587db96d56Sopenharmony_ci            self.assertEqual(next(gi), 1)
5597db96d56Sopenharmony_ci            gi.send(1)
5607db96d56Sopenharmony_ci
5617db96d56Sopenharmony_ci        with self.assertRaises(ZeroDivisionError):
5627db96d56Sopenharmony_ci            gi = g()
5637db96d56Sopenharmony_ci            self.assertEqual(next(gi), 1)
5647db96d56Sopenharmony_ci            gi.throw(AttributeError)
5657db96d56Sopenharmony_ci
5667db96d56Sopenharmony_ci        with support.catch_unraisable_exception() as cm:
5677db96d56Sopenharmony_ci            gi = g()
5687db96d56Sopenharmony_ci            self.assertEqual(next(gi), 1)
5697db96d56Sopenharmony_ci            gi.close()
5707db96d56Sopenharmony_ci
5717db96d56Sopenharmony_ci            self.assertEqual(ZeroDivisionError, cm.unraisable.exc_type)
5727db96d56Sopenharmony_ci
5737db96d56Sopenharmony_ci    def test_exception_in_initial_next_call(self):
5747db96d56Sopenharmony_ci        """
5757db96d56Sopenharmony_ci        Test exception in initial next() call
5767db96d56Sopenharmony_ci        """
5777db96d56Sopenharmony_ci        trace = []
5787db96d56Sopenharmony_ci        def g1():
5797db96d56Sopenharmony_ci            trace.append("g1 about to yield from g2")
5807db96d56Sopenharmony_ci            yield from g2()
5817db96d56Sopenharmony_ci            trace.append("g1 should not be here")
5827db96d56Sopenharmony_ci        def g2():
5837db96d56Sopenharmony_ci            yield 1/0
5847db96d56Sopenharmony_ci        def run():
5857db96d56Sopenharmony_ci            gi = g1()
5867db96d56Sopenharmony_ci            next(gi)
5877db96d56Sopenharmony_ci        self.assertRaises(ZeroDivisionError,run)
5887db96d56Sopenharmony_ci        self.assertEqual(trace,[
5897db96d56Sopenharmony_ci            "g1 about to yield from g2"
5907db96d56Sopenharmony_ci        ])
5917db96d56Sopenharmony_ci
5927db96d56Sopenharmony_ci    def test_attempted_yield_from_loop(self):
5937db96d56Sopenharmony_ci        """
5947db96d56Sopenharmony_ci        Test attempted yield-from loop
5957db96d56Sopenharmony_ci        """
5967db96d56Sopenharmony_ci        trace = []
5977db96d56Sopenharmony_ci        def g1():
5987db96d56Sopenharmony_ci            trace.append("g1: starting")
5997db96d56Sopenharmony_ci            yield "y1"
6007db96d56Sopenharmony_ci            trace.append("g1: about to yield from g2")
6017db96d56Sopenharmony_ci            yield from g2()
6027db96d56Sopenharmony_ci            trace.append("g1 should not be here")
6037db96d56Sopenharmony_ci
6047db96d56Sopenharmony_ci        def g2():
6057db96d56Sopenharmony_ci            trace.append("g2: starting")
6067db96d56Sopenharmony_ci            yield "y2"
6077db96d56Sopenharmony_ci            trace.append("g2: about to yield from g1")
6087db96d56Sopenharmony_ci            yield from gi
6097db96d56Sopenharmony_ci            trace.append("g2 should not be here")
6107db96d56Sopenharmony_ci        try:
6117db96d56Sopenharmony_ci            gi = g1()
6127db96d56Sopenharmony_ci            for y in gi:
6137db96d56Sopenharmony_ci                trace.append("Yielded: %s" % (y,))
6147db96d56Sopenharmony_ci        except ValueError as e:
6157db96d56Sopenharmony_ci            self.assertEqual(e.args[0],"generator already executing")
6167db96d56Sopenharmony_ci        else:
6177db96d56Sopenharmony_ci            self.fail("subgenerator didn't raise ValueError")
6187db96d56Sopenharmony_ci        self.assertEqual(trace,[
6197db96d56Sopenharmony_ci            "g1: starting",
6207db96d56Sopenharmony_ci            "Yielded: y1",
6217db96d56Sopenharmony_ci            "g1: about to yield from g2",
6227db96d56Sopenharmony_ci            "g2: starting",
6237db96d56Sopenharmony_ci            "Yielded: y2",
6247db96d56Sopenharmony_ci            "g2: about to yield from g1",
6257db96d56Sopenharmony_ci        ])
6267db96d56Sopenharmony_ci
6277db96d56Sopenharmony_ci    def test_returning_value_from_delegated_throw(self):
6287db96d56Sopenharmony_ci        """
6297db96d56Sopenharmony_ci        Test returning value from delegated 'throw'
6307db96d56Sopenharmony_ci        """
6317db96d56Sopenharmony_ci        trace = []
6327db96d56Sopenharmony_ci        def g1():
6337db96d56Sopenharmony_ci            try:
6347db96d56Sopenharmony_ci                trace.append("Starting g1")
6357db96d56Sopenharmony_ci                yield "g1 ham"
6367db96d56Sopenharmony_ci                yield from g2()
6377db96d56Sopenharmony_ci                yield "g1 eggs"
6387db96d56Sopenharmony_ci            finally:
6397db96d56Sopenharmony_ci                trace.append("Finishing g1")
6407db96d56Sopenharmony_ci        def g2():
6417db96d56Sopenharmony_ci            try:
6427db96d56Sopenharmony_ci                trace.append("Starting g2")
6437db96d56Sopenharmony_ci                yield "g2 spam"
6447db96d56Sopenharmony_ci                yield "g2 more spam"
6457db96d56Sopenharmony_ci            except LunchError:
6467db96d56Sopenharmony_ci                trace.append("Caught LunchError in g2")
6477db96d56Sopenharmony_ci                yield "g2 lunch saved"
6487db96d56Sopenharmony_ci                yield "g2 yet more spam"
6497db96d56Sopenharmony_ci        class LunchError(Exception):
6507db96d56Sopenharmony_ci            pass
6517db96d56Sopenharmony_ci        g = g1()
6527db96d56Sopenharmony_ci        for i in range(2):
6537db96d56Sopenharmony_ci            x = next(g)
6547db96d56Sopenharmony_ci            trace.append("Yielded %s" % (x,))
6557db96d56Sopenharmony_ci        e = LunchError("tomato ejected")
6567db96d56Sopenharmony_ci        g.throw(e)
6577db96d56Sopenharmony_ci        for x in g:
6587db96d56Sopenharmony_ci            trace.append("Yielded %s" % (x,))
6597db96d56Sopenharmony_ci        self.assertEqual(trace,[
6607db96d56Sopenharmony_ci            "Starting g1",
6617db96d56Sopenharmony_ci            "Yielded g1 ham",
6627db96d56Sopenharmony_ci            "Starting g2",
6637db96d56Sopenharmony_ci            "Yielded g2 spam",
6647db96d56Sopenharmony_ci            "Caught LunchError in g2",
6657db96d56Sopenharmony_ci            "Yielded g2 yet more spam",
6667db96d56Sopenharmony_ci            "Yielded g1 eggs",
6677db96d56Sopenharmony_ci            "Finishing g1",
6687db96d56Sopenharmony_ci        ])
6697db96d56Sopenharmony_ci
6707db96d56Sopenharmony_ci    def test_next_and_return_with_value(self):
6717db96d56Sopenharmony_ci        """
6727db96d56Sopenharmony_ci        Test next and return with value
6737db96d56Sopenharmony_ci        """
6747db96d56Sopenharmony_ci        trace = []
6757db96d56Sopenharmony_ci        def f(r):
6767db96d56Sopenharmony_ci            gi = g(r)
6777db96d56Sopenharmony_ci            next(gi)
6787db96d56Sopenharmony_ci            try:
6797db96d56Sopenharmony_ci                trace.append("f resuming g")
6807db96d56Sopenharmony_ci                next(gi)
6817db96d56Sopenharmony_ci                trace.append("f SHOULD NOT BE HERE")
6827db96d56Sopenharmony_ci            except StopIteration as e:
6837db96d56Sopenharmony_ci                trace.append("f caught %r" % (e,))
6847db96d56Sopenharmony_ci        def g(r):
6857db96d56Sopenharmony_ci            trace.append("g starting")
6867db96d56Sopenharmony_ci            yield
6877db96d56Sopenharmony_ci            trace.append("g returning %r" % (r,))
6887db96d56Sopenharmony_ci            return r
6897db96d56Sopenharmony_ci        f(None)
6907db96d56Sopenharmony_ci        f(1)
6917db96d56Sopenharmony_ci        f((2,))
6927db96d56Sopenharmony_ci        f(StopIteration(3))
6937db96d56Sopenharmony_ci        self.assertEqual(trace,[
6947db96d56Sopenharmony_ci            "g starting",
6957db96d56Sopenharmony_ci            "f resuming g",
6967db96d56Sopenharmony_ci            "g returning None",
6977db96d56Sopenharmony_ci            "f caught StopIteration()",
6987db96d56Sopenharmony_ci            "g starting",
6997db96d56Sopenharmony_ci            "f resuming g",
7007db96d56Sopenharmony_ci            "g returning 1",
7017db96d56Sopenharmony_ci            "f caught StopIteration(1)",
7027db96d56Sopenharmony_ci            "g starting",
7037db96d56Sopenharmony_ci            "f resuming g",
7047db96d56Sopenharmony_ci            "g returning (2,)",
7057db96d56Sopenharmony_ci            "f caught StopIteration((2,))",
7067db96d56Sopenharmony_ci            "g starting",
7077db96d56Sopenharmony_ci            "f resuming g",
7087db96d56Sopenharmony_ci            "g returning StopIteration(3)",
7097db96d56Sopenharmony_ci            "f caught StopIteration(StopIteration(3))",
7107db96d56Sopenharmony_ci        ])
7117db96d56Sopenharmony_ci
7127db96d56Sopenharmony_ci    def test_send_and_return_with_value(self):
7137db96d56Sopenharmony_ci        """
7147db96d56Sopenharmony_ci        Test send and return with value
7157db96d56Sopenharmony_ci        """
7167db96d56Sopenharmony_ci        trace = []
7177db96d56Sopenharmony_ci        def f(r):
7187db96d56Sopenharmony_ci            gi = g(r)
7197db96d56Sopenharmony_ci            next(gi)
7207db96d56Sopenharmony_ci            try:
7217db96d56Sopenharmony_ci                trace.append("f sending spam to g")
7227db96d56Sopenharmony_ci                gi.send("spam")
7237db96d56Sopenharmony_ci                trace.append("f SHOULD NOT BE HERE")
7247db96d56Sopenharmony_ci            except StopIteration as e:
7257db96d56Sopenharmony_ci                trace.append("f caught %r" % (e,))
7267db96d56Sopenharmony_ci        def g(r):
7277db96d56Sopenharmony_ci            trace.append("g starting")
7287db96d56Sopenharmony_ci            x = yield
7297db96d56Sopenharmony_ci            trace.append("g received %r" % (x,))
7307db96d56Sopenharmony_ci            trace.append("g returning %r" % (r,))
7317db96d56Sopenharmony_ci            return r
7327db96d56Sopenharmony_ci        f(None)
7337db96d56Sopenharmony_ci        f(1)
7347db96d56Sopenharmony_ci        f((2,))
7357db96d56Sopenharmony_ci        f(StopIteration(3))
7367db96d56Sopenharmony_ci        self.assertEqual(trace, [
7377db96d56Sopenharmony_ci            "g starting",
7387db96d56Sopenharmony_ci            "f sending spam to g",
7397db96d56Sopenharmony_ci            "g received 'spam'",
7407db96d56Sopenharmony_ci            "g returning None",
7417db96d56Sopenharmony_ci            "f caught StopIteration()",
7427db96d56Sopenharmony_ci            "g starting",
7437db96d56Sopenharmony_ci            "f sending spam to g",
7447db96d56Sopenharmony_ci            "g received 'spam'",
7457db96d56Sopenharmony_ci            "g returning 1",
7467db96d56Sopenharmony_ci            'f caught StopIteration(1)',
7477db96d56Sopenharmony_ci            'g starting',
7487db96d56Sopenharmony_ci            'f sending spam to g',
7497db96d56Sopenharmony_ci            "g received 'spam'",
7507db96d56Sopenharmony_ci            'g returning (2,)',
7517db96d56Sopenharmony_ci            'f caught StopIteration((2,))',
7527db96d56Sopenharmony_ci            'g starting',
7537db96d56Sopenharmony_ci            'f sending spam to g',
7547db96d56Sopenharmony_ci            "g received 'spam'",
7557db96d56Sopenharmony_ci            'g returning StopIteration(3)',
7567db96d56Sopenharmony_ci            'f caught StopIteration(StopIteration(3))'
7577db96d56Sopenharmony_ci        ])
7587db96d56Sopenharmony_ci
7597db96d56Sopenharmony_ci    def test_catching_exception_from_subgen_and_returning(self):
7607db96d56Sopenharmony_ci        """
7617db96d56Sopenharmony_ci        Test catching an exception thrown into a
7627db96d56Sopenharmony_ci        subgenerator and returning a value
7637db96d56Sopenharmony_ci        """
7647db96d56Sopenharmony_ci        def inner():
7657db96d56Sopenharmony_ci            try:
7667db96d56Sopenharmony_ci                yield 1
7677db96d56Sopenharmony_ci            except ValueError:
7687db96d56Sopenharmony_ci                trace.append("inner caught ValueError")
7697db96d56Sopenharmony_ci            return value
7707db96d56Sopenharmony_ci
7717db96d56Sopenharmony_ci        def outer():
7727db96d56Sopenharmony_ci            v = yield from inner()
7737db96d56Sopenharmony_ci            trace.append("inner returned %r to outer" % (v,))
7747db96d56Sopenharmony_ci            yield v
7757db96d56Sopenharmony_ci
7767db96d56Sopenharmony_ci        for value in 2, (2,), StopIteration(2):
7777db96d56Sopenharmony_ci            trace = []
7787db96d56Sopenharmony_ci            g = outer()
7797db96d56Sopenharmony_ci            trace.append(next(g))
7807db96d56Sopenharmony_ci            trace.append(repr(g.throw(ValueError)))
7817db96d56Sopenharmony_ci            self.assertEqual(trace, [
7827db96d56Sopenharmony_ci                1,
7837db96d56Sopenharmony_ci                "inner caught ValueError",
7847db96d56Sopenharmony_ci                "inner returned %r to outer" % (value,),
7857db96d56Sopenharmony_ci                repr(value),
7867db96d56Sopenharmony_ci            ])
7877db96d56Sopenharmony_ci
7887db96d56Sopenharmony_ci    def test_throwing_GeneratorExit_into_subgen_that_returns(self):
7897db96d56Sopenharmony_ci        """
7907db96d56Sopenharmony_ci        Test throwing GeneratorExit into a subgenerator that
7917db96d56Sopenharmony_ci        catches it and returns normally.
7927db96d56Sopenharmony_ci        """
7937db96d56Sopenharmony_ci        trace = []
7947db96d56Sopenharmony_ci        def f():
7957db96d56Sopenharmony_ci            try:
7967db96d56Sopenharmony_ci                trace.append("Enter f")
7977db96d56Sopenharmony_ci                yield
7987db96d56Sopenharmony_ci                trace.append("Exit f")
7997db96d56Sopenharmony_ci            except GeneratorExit:
8007db96d56Sopenharmony_ci                return
8017db96d56Sopenharmony_ci        def g():
8027db96d56Sopenharmony_ci            trace.append("Enter g")
8037db96d56Sopenharmony_ci            yield from f()
8047db96d56Sopenharmony_ci            trace.append("Exit g")
8057db96d56Sopenharmony_ci        try:
8067db96d56Sopenharmony_ci            gi = g()
8077db96d56Sopenharmony_ci            next(gi)
8087db96d56Sopenharmony_ci            gi.throw(GeneratorExit)
8097db96d56Sopenharmony_ci        except GeneratorExit:
8107db96d56Sopenharmony_ci            pass
8117db96d56Sopenharmony_ci        else:
8127db96d56Sopenharmony_ci            self.fail("subgenerator failed to raise GeneratorExit")
8137db96d56Sopenharmony_ci        self.assertEqual(trace,[
8147db96d56Sopenharmony_ci            "Enter g",
8157db96d56Sopenharmony_ci            "Enter f",
8167db96d56Sopenharmony_ci        ])
8177db96d56Sopenharmony_ci
8187db96d56Sopenharmony_ci    def test_throwing_GeneratorExit_into_subgenerator_that_yields(self):
8197db96d56Sopenharmony_ci        """
8207db96d56Sopenharmony_ci        Test throwing GeneratorExit into a subgenerator that
8217db96d56Sopenharmony_ci        catches it and yields.
8227db96d56Sopenharmony_ci        """
8237db96d56Sopenharmony_ci        trace = []
8247db96d56Sopenharmony_ci        def f():
8257db96d56Sopenharmony_ci            try:
8267db96d56Sopenharmony_ci                trace.append("Enter f")
8277db96d56Sopenharmony_ci                yield
8287db96d56Sopenharmony_ci                trace.append("Exit f")
8297db96d56Sopenharmony_ci            except GeneratorExit:
8307db96d56Sopenharmony_ci                yield
8317db96d56Sopenharmony_ci        def g():
8327db96d56Sopenharmony_ci            trace.append("Enter g")
8337db96d56Sopenharmony_ci            yield from f()
8347db96d56Sopenharmony_ci            trace.append("Exit g")
8357db96d56Sopenharmony_ci        try:
8367db96d56Sopenharmony_ci            gi = g()
8377db96d56Sopenharmony_ci            next(gi)
8387db96d56Sopenharmony_ci            gi.throw(GeneratorExit)
8397db96d56Sopenharmony_ci        except RuntimeError as e:
8407db96d56Sopenharmony_ci            self.assertEqual(e.args[0], "generator ignored GeneratorExit")
8417db96d56Sopenharmony_ci        else:
8427db96d56Sopenharmony_ci            self.fail("subgenerator failed to raise GeneratorExit")
8437db96d56Sopenharmony_ci        self.assertEqual(trace,[
8447db96d56Sopenharmony_ci            "Enter g",
8457db96d56Sopenharmony_ci            "Enter f",
8467db96d56Sopenharmony_ci        ])
8477db96d56Sopenharmony_ci
8487db96d56Sopenharmony_ci    def test_throwing_GeneratorExit_into_subgen_that_raises(self):
8497db96d56Sopenharmony_ci        """
8507db96d56Sopenharmony_ci        Test throwing GeneratorExit into a subgenerator that
8517db96d56Sopenharmony_ci        catches it and raises a different exception.
8527db96d56Sopenharmony_ci        """
8537db96d56Sopenharmony_ci        trace = []
8547db96d56Sopenharmony_ci        def f():
8557db96d56Sopenharmony_ci            try:
8567db96d56Sopenharmony_ci                trace.append("Enter f")
8577db96d56Sopenharmony_ci                yield
8587db96d56Sopenharmony_ci                trace.append("Exit f")
8597db96d56Sopenharmony_ci            except GeneratorExit:
8607db96d56Sopenharmony_ci                raise ValueError("Vorpal bunny encountered")
8617db96d56Sopenharmony_ci        def g():
8627db96d56Sopenharmony_ci            trace.append("Enter g")
8637db96d56Sopenharmony_ci            yield from f()
8647db96d56Sopenharmony_ci            trace.append("Exit g")
8657db96d56Sopenharmony_ci        try:
8667db96d56Sopenharmony_ci            gi = g()
8677db96d56Sopenharmony_ci            next(gi)
8687db96d56Sopenharmony_ci            gi.throw(GeneratorExit)
8697db96d56Sopenharmony_ci        except ValueError as e:
8707db96d56Sopenharmony_ci            self.assertEqual(e.args[0], "Vorpal bunny encountered")
8717db96d56Sopenharmony_ci            self.assertIsInstance(e.__context__, GeneratorExit)
8727db96d56Sopenharmony_ci        else:
8737db96d56Sopenharmony_ci            self.fail("subgenerator failed to raise ValueError")
8747db96d56Sopenharmony_ci        self.assertEqual(trace,[
8757db96d56Sopenharmony_ci            "Enter g",
8767db96d56Sopenharmony_ci            "Enter f",
8777db96d56Sopenharmony_ci        ])
8787db96d56Sopenharmony_ci
8797db96d56Sopenharmony_ci    def test_yield_from_empty(self):
8807db96d56Sopenharmony_ci        def g():
8817db96d56Sopenharmony_ci            yield from ()
8827db96d56Sopenharmony_ci        self.assertRaises(StopIteration, next, g())
8837db96d56Sopenharmony_ci
8847db96d56Sopenharmony_ci    def test_delegating_generators_claim_to_be_running(self):
8857db96d56Sopenharmony_ci        # Check with basic iteration
8867db96d56Sopenharmony_ci        def one():
8877db96d56Sopenharmony_ci            yield 0
8887db96d56Sopenharmony_ci            yield from two()
8897db96d56Sopenharmony_ci            yield 3
8907db96d56Sopenharmony_ci        def two():
8917db96d56Sopenharmony_ci            yield 1
8927db96d56Sopenharmony_ci            try:
8937db96d56Sopenharmony_ci                yield from g1
8947db96d56Sopenharmony_ci            except ValueError:
8957db96d56Sopenharmony_ci                pass
8967db96d56Sopenharmony_ci            yield 2
8977db96d56Sopenharmony_ci        g1 = one()
8987db96d56Sopenharmony_ci        self.assertEqual(list(g1), [0, 1, 2, 3])
8997db96d56Sopenharmony_ci        # Check with send
9007db96d56Sopenharmony_ci        g1 = one()
9017db96d56Sopenharmony_ci        res = [next(g1)]
9027db96d56Sopenharmony_ci        try:
9037db96d56Sopenharmony_ci            while True:
9047db96d56Sopenharmony_ci                res.append(g1.send(42))
9057db96d56Sopenharmony_ci        except StopIteration:
9067db96d56Sopenharmony_ci            pass
9077db96d56Sopenharmony_ci        self.assertEqual(res, [0, 1, 2, 3])
9087db96d56Sopenharmony_ci        # Check with throw
9097db96d56Sopenharmony_ci        class MyErr(Exception):
9107db96d56Sopenharmony_ci            pass
9117db96d56Sopenharmony_ci        def one():
9127db96d56Sopenharmony_ci            try:
9137db96d56Sopenharmony_ci                yield 0
9147db96d56Sopenharmony_ci            except MyErr:
9157db96d56Sopenharmony_ci                pass
9167db96d56Sopenharmony_ci            yield from two()
9177db96d56Sopenharmony_ci            try:
9187db96d56Sopenharmony_ci                yield 3
9197db96d56Sopenharmony_ci            except MyErr:
9207db96d56Sopenharmony_ci                pass
9217db96d56Sopenharmony_ci        def two():
9227db96d56Sopenharmony_ci            try:
9237db96d56Sopenharmony_ci                yield 1
9247db96d56Sopenharmony_ci            except MyErr:
9257db96d56Sopenharmony_ci                pass
9267db96d56Sopenharmony_ci            try:
9277db96d56Sopenharmony_ci                yield from g1
9287db96d56Sopenharmony_ci            except ValueError:
9297db96d56Sopenharmony_ci                pass
9307db96d56Sopenharmony_ci            try:
9317db96d56Sopenharmony_ci                yield 2
9327db96d56Sopenharmony_ci            except MyErr:
9337db96d56Sopenharmony_ci                pass
9347db96d56Sopenharmony_ci        g1 = one()
9357db96d56Sopenharmony_ci        res = [next(g1)]
9367db96d56Sopenharmony_ci        try:
9377db96d56Sopenharmony_ci            while True:
9387db96d56Sopenharmony_ci                res.append(g1.throw(MyErr))
9397db96d56Sopenharmony_ci        except StopIteration:
9407db96d56Sopenharmony_ci            pass
9417db96d56Sopenharmony_ci        except:
9427db96d56Sopenharmony_ci            self.assertEqual(res, [0, 1, 2, 3])
9437db96d56Sopenharmony_ci            raise
9447db96d56Sopenharmony_ci        # Check with close
9457db96d56Sopenharmony_ci        class MyIt(object):
9467db96d56Sopenharmony_ci            def __iter__(self):
9477db96d56Sopenharmony_ci                return self
9487db96d56Sopenharmony_ci            def __next__(self):
9497db96d56Sopenharmony_ci                return 42
9507db96d56Sopenharmony_ci            def close(self_):
9517db96d56Sopenharmony_ci                self.assertTrue(g1.gi_running)
9527db96d56Sopenharmony_ci                self.assertRaises(ValueError, next, g1)
9537db96d56Sopenharmony_ci        def one():
9547db96d56Sopenharmony_ci            yield from MyIt()
9557db96d56Sopenharmony_ci        g1 = one()
9567db96d56Sopenharmony_ci        next(g1)
9577db96d56Sopenharmony_ci        g1.close()
9587db96d56Sopenharmony_ci
9597db96d56Sopenharmony_ci    def test_delegator_is_visible_to_debugger(self):
9607db96d56Sopenharmony_ci        def call_stack():
9617db96d56Sopenharmony_ci            return [f[3] for f in inspect.stack()]
9627db96d56Sopenharmony_ci
9637db96d56Sopenharmony_ci        def gen():
9647db96d56Sopenharmony_ci            yield call_stack()
9657db96d56Sopenharmony_ci            yield call_stack()
9667db96d56Sopenharmony_ci            yield call_stack()
9677db96d56Sopenharmony_ci
9687db96d56Sopenharmony_ci        def spam(g):
9697db96d56Sopenharmony_ci            yield from g
9707db96d56Sopenharmony_ci
9717db96d56Sopenharmony_ci        def eggs(g):
9727db96d56Sopenharmony_ci            yield from g
9737db96d56Sopenharmony_ci
9747db96d56Sopenharmony_ci        for stack in spam(gen()):
9757db96d56Sopenharmony_ci            self.assertTrue('spam' in stack)
9767db96d56Sopenharmony_ci
9777db96d56Sopenharmony_ci        for stack in spam(eggs(gen())):
9787db96d56Sopenharmony_ci            self.assertTrue('spam' in stack and 'eggs' in stack)
9797db96d56Sopenharmony_ci
9807db96d56Sopenharmony_ci    def test_custom_iterator_return(self):
9817db96d56Sopenharmony_ci        # See issue #15568
9827db96d56Sopenharmony_ci        class MyIter:
9837db96d56Sopenharmony_ci            def __iter__(self):
9847db96d56Sopenharmony_ci                return self
9857db96d56Sopenharmony_ci            def __next__(self):
9867db96d56Sopenharmony_ci                raise StopIteration(42)
9877db96d56Sopenharmony_ci        def gen():
9887db96d56Sopenharmony_ci            nonlocal ret
9897db96d56Sopenharmony_ci            ret = yield from MyIter()
9907db96d56Sopenharmony_ci        ret = None
9917db96d56Sopenharmony_ci        list(gen())
9927db96d56Sopenharmony_ci        self.assertEqual(ret, 42)
9937db96d56Sopenharmony_ci
9947db96d56Sopenharmony_ci    def test_close_with_cleared_frame(self):
9957db96d56Sopenharmony_ci        # See issue #17669.
9967db96d56Sopenharmony_ci        #
9977db96d56Sopenharmony_ci        # Create a stack of generators: outer() delegating to inner()
9987db96d56Sopenharmony_ci        # delegating to innermost(). The key point is that the instance of
9997db96d56Sopenharmony_ci        # inner is created first: this ensures that its frame appears before
10007db96d56Sopenharmony_ci        # the instance of outer in the GC linked list.
10017db96d56Sopenharmony_ci        #
10027db96d56Sopenharmony_ci        # At the gc.collect call:
10037db96d56Sopenharmony_ci        #   - frame_clear is called on the inner_gen frame.
10047db96d56Sopenharmony_ci        #   - gen_dealloc is called on the outer_gen generator (the only
10057db96d56Sopenharmony_ci        #     reference is in the frame's locals).
10067db96d56Sopenharmony_ci        #   - gen_close is called on the outer_gen generator.
10077db96d56Sopenharmony_ci        #   - gen_close_iter is called to close the inner_gen generator, which
10087db96d56Sopenharmony_ci        #     in turn calls gen_close, and gen_yf.
10097db96d56Sopenharmony_ci        #
10107db96d56Sopenharmony_ci        # Previously, gen_yf would crash since inner_gen's frame had been
10117db96d56Sopenharmony_ci        # cleared (and in particular f_stacktop was NULL).
10127db96d56Sopenharmony_ci
10137db96d56Sopenharmony_ci        def innermost():
10147db96d56Sopenharmony_ci            yield
10157db96d56Sopenharmony_ci        def inner():
10167db96d56Sopenharmony_ci            outer_gen = yield
10177db96d56Sopenharmony_ci            yield from innermost()
10187db96d56Sopenharmony_ci        def outer():
10197db96d56Sopenharmony_ci            inner_gen = yield
10207db96d56Sopenharmony_ci            yield from inner_gen
10217db96d56Sopenharmony_ci
10227db96d56Sopenharmony_ci        with disable_gc():
10237db96d56Sopenharmony_ci            inner_gen = inner()
10247db96d56Sopenharmony_ci            outer_gen = outer()
10257db96d56Sopenharmony_ci            outer_gen.send(None)
10267db96d56Sopenharmony_ci            outer_gen.send(inner_gen)
10277db96d56Sopenharmony_ci            outer_gen.send(outer_gen)
10287db96d56Sopenharmony_ci
10297db96d56Sopenharmony_ci            del outer_gen
10307db96d56Sopenharmony_ci            del inner_gen
10317db96d56Sopenharmony_ci            gc_collect()
10327db96d56Sopenharmony_ci
10337db96d56Sopenharmony_ci    def test_send_tuple_with_custom_generator(self):
10347db96d56Sopenharmony_ci        # See issue #21209.
10357db96d56Sopenharmony_ci        class MyGen:
10367db96d56Sopenharmony_ci            def __iter__(self):
10377db96d56Sopenharmony_ci                return self
10387db96d56Sopenharmony_ci            def __next__(self):
10397db96d56Sopenharmony_ci                return 42
10407db96d56Sopenharmony_ci            def send(self, what):
10417db96d56Sopenharmony_ci                nonlocal v
10427db96d56Sopenharmony_ci                v = what
10437db96d56Sopenharmony_ci                return None
10447db96d56Sopenharmony_ci        def outer():
10457db96d56Sopenharmony_ci            v = yield from MyGen()
10467db96d56Sopenharmony_ci        g = outer()
10477db96d56Sopenharmony_ci        next(g)
10487db96d56Sopenharmony_ci        v = None
10497db96d56Sopenharmony_ci        g.send((1, 2, 3, 4))
10507db96d56Sopenharmony_ci        self.assertEqual(v, (1, 2, 3, 4))
10517db96d56Sopenharmony_ci
10527db96d56Sopenharmony_ci
10537db96d56Sopenharmony_ciif __name__ == '__main__':
10547db96d56Sopenharmony_ci    unittest.main()
1055