diff options
Diffstat (limited to 'ptpython/entry_points/run_ptpython.py')
-rw-r--r-- | ptpython/entry_points/run_ptpython.py | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/ptpython/entry_points/run_ptpython.py b/ptpython/entry_points/run_ptpython.py index 0b3dbdb..1d4a532 100644 --- a/ptpython/entry_points/run_ptpython.py +++ b/ptpython/entry_points/run_ptpython.py @@ -9,6 +9,7 @@ optional arguments: -h, --help show this help message and exit --vi Enable Vi key bindings -i, --interactive Start interactive shell after executing this file. + --asyncio Run an asyncio event loop to support top-level "await". --light-bg Run on a light background (use dark colors for text). --dark-bg Run on a dark background (use light colors for text). --config-file CONFIG_FILE @@ -21,21 +22,24 @@ environment variables: PTPYTHON_CONFIG_HOME: a configuration directory to use PYTHONSTARTUP: file executed on interactive startup (no default) """ +from __future__ import annotations + import argparse +import asyncio import os import pathlib import sys from textwrap import dedent -from typing import Tuple +from typing import IO import appdirs from prompt_toolkit.formatted_text import HTML from prompt_toolkit.shortcuts import print_formatted_text -from ptpython.repl import embed, enable_deprecation_warnings, run_config +from ptpython.repl import PythonRepl, embed, enable_deprecation_warnings, run_config try: - from importlib import metadata + from importlib import metadata # type: ignore except ImportError: import importlib_metadata as metadata # type: ignore @@ -44,7 +48,7 @@ __all__ = ["create_parser", "get_config_and_history_file", "run"] class _Parser(argparse.ArgumentParser): - def print_help(self): + def print_help(self, file: IO[str] | None = None) -> None: super().print_help() print( dedent( @@ -67,15 +71,20 @@ def create_parser() -> _Parser: help="Start interactive shell after executing this file.", ) parser.add_argument( + "--asyncio", + action="store_true", + help='Run an asyncio event loop to support top-level "await".', + ) + parser.add_argument( "--light-bg", action="store_true", help="Run on a light background (use dark colors for text).", - ), + ) parser.add_argument( "--dark-bg", action="store_true", help="Run on a dark background (use light colors for text).", - ), + ) parser.add_argument( "--config-file", type=str, help="Location of configuration file." ) @@ -84,13 +93,13 @@ def create_parser() -> _Parser: "-V", "--version", action="version", - version=metadata.version("ptpython"), # type: ignore + version=metadata.version("ptpython"), ) parser.add_argument("args", nargs="*", help="Script and arguments") return parser -def get_config_and_history_file(namespace: argparse.Namespace) -> Tuple[str, str]: +def get_config_and_history_file(namespace: argparse.Namespace) -> tuple[str, str]: """ Check which config/history files to use, ensure that the directories for these files exist, and return the config and history path. @@ -179,16 +188,18 @@ def run() -> None: path = a.args[0] with open(path, "rb") as f: code = compile(f.read(), path, "exec") - # NOTE: We have to pass an empty dictionary as namespace. Omitting - # this argument causes imports to not be found. See issue #326. - exec(code, {}) + # NOTE: We have to pass a dict as namespace. Omitting this argument + # causes imports to not be found. See issue #326. + # However, an empty dict sets __name__ to 'builtins', which + # breaks `if __name__ == '__main__'` checks. See issue #444. + exec(code, {"__name__": "__main__", "__file__": path}) # Run interactive shell. else: enable_deprecation_warnings() # Apply config file - def configure(repl) -> None: + def configure(repl: PythonRepl) -> None: if os.path.exists(config_file): run_config(repl, config_file) @@ -202,7 +213,7 @@ def run() -> None: import __main__ - embed( + embed_result = embed( # type: ignore vi_mode=a.vi, history_filename=history_file, configure=configure, @@ -210,8 +221,14 @@ def run() -> None: globals=__main__.__dict__, startup_paths=startup_paths, title="Python REPL (ptpython)", + return_asyncio_coroutine=a.asyncio, ) + if a.asyncio: + print("Starting ptpython asyncio REPL") + print('Use "await" directly instead of "asyncio.run()".') + asyncio.run(embed_result) + if __name__ == "__main__": run() |