17db96d56Sopenharmony_ciimport ast
27db96d56Sopenharmony_ciimport asyncio
37db96d56Sopenharmony_ciimport code
47db96d56Sopenharmony_ciimport concurrent.futures
57db96d56Sopenharmony_ciimport inspect
67db96d56Sopenharmony_ciimport sys
77db96d56Sopenharmony_ciimport threading
87db96d56Sopenharmony_ciimport types
97db96d56Sopenharmony_ciimport warnings
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_cifrom . import futures
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_ciclass AsyncIOInteractiveConsole(code.InteractiveConsole):
157db96d56Sopenharmony_ci
167db96d56Sopenharmony_ci    def __init__(self, locals, loop):
177db96d56Sopenharmony_ci        super().__init__(locals)
187db96d56Sopenharmony_ci        self.compile.compiler.flags |= ast.PyCF_ALLOW_TOP_LEVEL_AWAIT
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci        self.loop = loop
217db96d56Sopenharmony_ci
227db96d56Sopenharmony_ci    def runcode(self, code):
237db96d56Sopenharmony_ci        future = concurrent.futures.Future()
247db96d56Sopenharmony_ci
257db96d56Sopenharmony_ci        def callback():
267db96d56Sopenharmony_ci            global repl_future
277db96d56Sopenharmony_ci            global repl_future_interrupted
287db96d56Sopenharmony_ci
297db96d56Sopenharmony_ci            repl_future = None
307db96d56Sopenharmony_ci            repl_future_interrupted = False
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci            func = types.FunctionType(code, self.locals)
337db96d56Sopenharmony_ci            try:
347db96d56Sopenharmony_ci                coro = func()
357db96d56Sopenharmony_ci            except SystemExit:
367db96d56Sopenharmony_ci                raise
377db96d56Sopenharmony_ci            except KeyboardInterrupt as ex:
387db96d56Sopenharmony_ci                repl_future_interrupted = True
397db96d56Sopenharmony_ci                future.set_exception(ex)
407db96d56Sopenharmony_ci                return
417db96d56Sopenharmony_ci            except BaseException as ex:
427db96d56Sopenharmony_ci                future.set_exception(ex)
437db96d56Sopenharmony_ci                return
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_ci            if not inspect.iscoroutine(coro):
467db96d56Sopenharmony_ci                future.set_result(coro)
477db96d56Sopenharmony_ci                return
487db96d56Sopenharmony_ci
497db96d56Sopenharmony_ci            try:
507db96d56Sopenharmony_ci                repl_future = self.loop.create_task(coro)
517db96d56Sopenharmony_ci                futures._chain_future(repl_future, future)
527db96d56Sopenharmony_ci            except BaseException as exc:
537db96d56Sopenharmony_ci                future.set_exception(exc)
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci        loop.call_soon_threadsafe(callback)
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci        try:
587db96d56Sopenharmony_ci            return future.result()
597db96d56Sopenharmony_ci        except SystemExit:
607db96d56Sopenharmony_ci            raise
617db96d56Sopenharmony_ci        except BaseException:
627db96d56Sopenharmony_ci            if repl_future_interrupted:
637db96d56Sopenharmony_ci                self.write("\nKeyboardInterrupt\n")
647db96d56Sopenharmony_ci            else:
657db96d56Sopenharmony_ci                self.showtraceback()
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_ciclass REPLThread(threading.Thread):
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci    def run(self):
717db96d56Sopenharmony_ci        try:
727db96d56Sopenharmony_ci            banner = (
737db96d56Sopenharmony_ci                f'asyncio REPL {sys.version} on {sys.platform}\n'
747db96d56Sopenharmony_ci                f'Use "await" directly instead of "asyncio.run()".\n'
757db96d56Sopenharmony_ci                f'Type "help", "copyright", "credits" or "license" '
767db96d56Sopenharmony_ci                f'for more information.\n'
777db96d56Sopenharmony_ci                f'{getattr(sys, "ps1", ">>> ")}import asyncio'
787db96d56Sopenharmony_ci            )
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ci            console.interact(
817db96d56Sopenharmony_ci                banner=banner,
827db96d56Sopenharmony_ci                exitmsg='exiting asyncio REPL...')
837db96d56Sopenharmony_ci        finally:
847db96d56Sopenharmony_ci            warnings.filterwarnings(
857db96d56Sopenharmony_ci                'ignore',
867db96d56Sopenharmony_ci                message=r'^coroutine .* was never awaited$',
877db96d56Sopenharmony_ci                category=RuntimeWarning)
887db96d56Sopenharmony_ci
897db96d56Sopenharmony_ci            loop.call_soon_threadsafe(loop.stop)
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ciif __name__ == '__main__':
937db96d56Sopenharmony_ci    loop = asyncio.new_event_loop()
947db96d56Sopenharmony_ci    asyncio.set_event_loop(loop)
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_ci    repl_locals = {'asyncio': asyncio}
977db96d56Sopenharmony_ci    for key in {'__name__', '__package__',
987db96d56Sopenharmony_ci                '__loader__', '__spec__',
997db96d56Sopenharmony_ci                '__builtins__', '__file__'}:
1007db96d56Sopenharmony_ci        repl_locals[key] = locals()[key]
1017db96d56Sopenharmony_ci
1027db96d56Sopenharmony_ci    console = AsyncIOInteractiveConsole(repl_locals, loop)
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci    repl_future = None
1057db96d56Sopenharmony_ci    repl_future_interrupted = False
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci    try:
1087db96d56Sopenharmony_ci        import readline  # NoQA
1097db96d56Sopenharmony_ci    except ImportError:
1107db96d56Sopenharmony_ci        pass
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ci    repl_thread = REPLThread()
1137db96d56Sopenharmony_ci    repl_thread.daemon = True
1147db96d56Sopenharmony_ci    repl_thread.start()
1157db96d56Sopenharmony_ci
1167db96d56Sopenharmony_ci    while True:
1177db96d56Sopenharmony_ci        try:
1187db96d56Sopenharmony_ci            loop.run_forever()
1197db96d56Sopenharmony_ci        except KeyboardInterrupt:
1207db96d56Sopenharmony_ci            if repl_future and not repl_future.done():
1217db96d56Sopenharmony_ci                repl_future.cancel()
1227db96d56Sopenharmony_ci                repl_future_interrupted = True
1237db96d56Sopenharmony_ci            continue
1247db96d56Sopenharmony_ci        else:
1257db96d56Sopenharmony_ci            break
126