1import errno 2import os 3import sys 4 5 6CAN_USE_PYREPL: bool 7FAIL_REASON: str 8try: 9 if sys.platform == "win32" and sys.getwindowsversion().build < 10586: 10 raise RuntimeError("Windows 10 TH2 or later required") 11 if not os.isatty(sys.stdin.fileno()): 12 raise OSError(errno.ENOTTY, "tty required", "stdin") 13 from .simple_interact import check 14 if err := check(): 15 raise RuntimeError(err) 16except Exception as e: 17 CAN_USE_PYREPL = False 18 FAIL_REASON = f"warning: can't use pyrepl: {e}" 19else: 20 CAN_USE_PYREPL = True 21 FAIL_REASON = "" 22 23 24def interactive_console(mainmodule=None, quiet=False, pythonstartup=False): 25 if not CAN_USE_PYREPL: 26 if not os.getenv('PYTHON_BASIC_REPL') and FAIL_REASON: 27 from .trace import trace 28 trace(FAIL_REASON) 29 print(FAIL_REASON, file=sys.stderr) 30 return sys._baserepl() 31 32 if mainmodule: 33 namespace = mainmodule.__dict__ 34 else: 35 import __main__ 36 namespace = __main__.__dict__ 37 namespace.pop("__pyrepl_interactive_console", None) 38 39 # sys._baserepl() above does this internally, we do it here 40 startup_path = os.getenv("PYTHONSTARTUP") 41 if pythonstartup and startup_path: 42 sys.audit("cpython.run_startup", startup_path) 43 44 import tokenize 45 with tokenize.open(startup_path) as f: 46 startup_code = compile(f.read(), startup_path, "exec") 47 exec(startup_code, namespace) 48 49 # set sys.{ps1,ps2} just before invoking the interactive interpreter. This 50 # mimics what CPython does in pythonrun.c 51 if not hasattr(sys, "ps1"): 52 sys.ps1 = ">>> " 53 if not hasattr(sys, "ps2"): 54 sys.ps2 = "... " 55 56 from .console import InteractiveColoredConsole 57 from .simple_interact import run_multiline_interactive_console 58 console = InteractiveColoredConsole(namespace, filename="<stdin>") 59 run_multiline_interactive_console(console) 60