feat: Sync code.py + test_code_module.py from CPython v3.13.1 by ntvinh2005 · Pull Request #6181 · RustPython/RustPython
import builtins import sys import traceback from codeop import CommandCompiler, compile_command
__all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact", "compile_command"]
class InteractiveInterpreter: """Base class for InteractiveConsole.
The optional 'locals' argument specifies the dictionary in which code will be executed; it defaults to a newly created dictionary with key "__name__" set to "__console__" and key "__doc__" set to None. The optional 'locals' argument specifies a mapping to use as the namespace in which code will be executed; it defaults to a newly created dictionary with key "__name__" set to "__console__" and key "__doc__" set to None.
""" if locals is None:
if code is None:
def showsyntaxerror(self, filename=None): def showsyntaxerror(self, filename=None, **kwargs): """Display the syntax error that just occurred.
This doesn't display a stack trace because there isn't one.
""" type, value, tb = sys.exc_info() sys.last_exc = value sys.last_type = type sys.last_value = value sys.last_traceback = tb if filename and type is SyntaxError: # Work hard to stuff the correct filename in the exception try: msg, (dummy_filename, lineno, offset, line) = value.args except ValueError: # Not the format we expect; leave it alone pass else: # Stuff in the right filename value = SyntaxError(msg, (filename, lineno, offset, line)) sys.last_exc = sys.last_value = value if sys.excepthook is sys.__excepthook__: lines = traceback.format_exception_only(type, value) self.write(''.join(lines)) else: # If someone has set sys.excepthook, we let that take precedence # over self.write sys.excepthook(type, value, tb) try: typ, value, tb = sys.exc_info() if filename and issubclass(typ, SyntaxError): value.filename = filename source = kwargs.pop('source', "") self._showtraceback(typ, value, None, source) finally: typ = value = tb = None
def showtraceback(self): """Display the exception that just occurred.
""" sys.last_type, sys.last_value, last_tb = ei = sys.exc_info() sys.last_traceback = last_tb sys.last_exc = ei[1] try: lines = traceback.format_exception(ei[0], ei[1], last_tb.tb_next) if sys.excepthook is sys.__excepthook__: self.write(''.join(lines)) else: # If someone has set sys.excepthook, we let that take precedence # over self.write sys.excepthook(ei[0], ei[1], last_tb) typ, value, tb = sys.exc_info() self._showtraceback(typ, value, tb.tb_next, '') finally: last_tb = ei = None typ = value = tb = None
def _showtraceback(self, typ, value, tb, source): sys.last_type = typ sys.last_traceback = tb value = value.with_traceback(tb) # Set the line of text that the exception refers to lines = source.splitlines() if (source and typ is SyntaxError and not value.text and value.lineno is not None and len(lines) >= value.lineno): value.text = lines[value.lineno - 1] sys.last_exc = sys.last_value = value = value.with_traceback(tb) if sys.excepthook is sys.__excepthook__: self._excepthook(typ, value, tb) else: # If someone has set sys.excepthook, we let that take precedence # over self.write try: sys.excepthook(typ, value, tb) except SystemExit: raise except BaseException as e: e.__context__ = None e = e.with_traceback(e.__traceback__.tb_next) print('Error in sys.excepthook:', file=sys.stderr) sys.__excepthook__(type(e), e, e.__traceback__) print(file=sys.stderr) print('Original exception was:', file=sys.stderr) sys.__excepthook__(typ, value, tb)
def _excepthook(self, typ, value, tb): # This method is being overwritten in # _pyrepl.console.InteractiveColoredConsole lines = traceback.format_exception(typ, value, tb) self.write(''.join(lines))
def write(self, data): """Write a string.
"""
def __init__(self, locals=None, filename="<console>"): def __init__(self, locals=None, filename="<console>", *, local_exit=False): """Constructor.
The optional locals argument will be passed to the
def resetbuffer(self):
# When the user uses exit() or quit() in their interactive shell # they probably just want to exit the created shell, not the whole # process. exit and quit in builtins closes sys.stdin which makes # it super difficult to restore # # When self.local_exit is True, we overwrite the builtins so # exit() and quit() only raises SystemExit and we can catch that # to only exit the interactive shell
_exit = None _quit = None
if self.local_exit: if hasattr(builtins, "exit"): _exit = builtins.exit builtins.exit = Quitter("exit")
if hasattr(builtins, "quit"): _quit = builtins.quit builtins.quit = Quitter("quit")
try: while True: try: line = self.raw_input(prompt) except EOFError: self.write("\n") break else: more = self.push(line) except KeyboardInterrupt: self.write("\nKeyboardInterrupt\n") self.resetbuffer() more = 0 if exitmsg is None: self.write('now exiting %s...\n' % self.__class__.__name__) elif exitmsg != '': self.write('%s\n' % exitmsg)
def push(self, line): if more: prompt = sys.ps2 else: prompt = sys.ps1 try: line = self.raw_input(prompt) except EOFError: self.write("\n") break else: more = self.push(line) except KeyboardInterrupt: self.write("\nKeyboardInterrupt\n") self.resetbuffer() more = 0 except SystemExit as e: if self.local_exit: self.write("\n") break else: raise e finally: # restore exit and quit in builtins if they were modified if _exit is not None: builtins.exit = _exit
if _quit is not None: builtins.quit = _quit
if exitmsg is None: self.write('now exiting %s...\n' % self.__class__.__name__) elif exitmsg != '': self.write('%s\n' % exitmsg)
def push(self, line, filename=None, _symbol="single"): """Push a line to the interpreter.
The line should not have a trailing newline; it may have
class Quitter: def __init__(self, name): self.name = name if sys.platform == "win32": self.eof = 'Ctrl-Z plus Return' else: self.eof = 'Ctrl-D (i.e. EOF)'
def __repr__(self): return f'Use {self.name} or {self.eof} to exit'
def __call__(self, code=None): raise SystemExit(code)
def interact(banner=None, readfunc=None, local=None, exitmsg=None): def interact(banner=None, readfunc=None, local=None, exitmsg=None, local_exit=False): """Closely emulate the interactive Python interpreter.
This is a backwards compatible interface to the InteractiveConsole
""" console = InteractiveConsole(local) console = InteractiveConsole(local, local_exit=local_exit) if readfunc is not None: console.raw_input = readfunc else:
parser = argparse.ArgumentParser() parser.add_argument('-q', action='store_true', help="don't print version and copyright messages") help="don't print version and copyright messages") args = parser.parse_args() if args.q or sys.flags.quiet: banner = ''