diff options
Diffstat (limited to 'cmd2/cmd2.py')
-rw-r--r-- | cmd2/cmd2.py | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py index cbb79323..c690aef9 100644 --- a/cmd2/cmd2.py +++ b/cmd2/cmd2.py @@ -2957,14 +2957,13 @@ class Cmd(cmd.Cmd): self.perror(err, traceback_war=False) self._last_result = CommandResult('', err) return False - self._in_py = True - # noinspection PyBroadException try: + self._in_py = True + # Support the run command even if called prior to invoking an interactive interpreter - def run(filename: str): + def py_run(filename: str): """Run a Python script file in the interactive console. - :param filename: filename of *.py script file to run """ expanded_filename = os.path.expanduser(filename) @@ -2979,9 +2978,16 @@ class Cmd(cmd.Cmd): error_msg = "Error opening script file '{}': {}".format(expanded_filename, ex) self.perror(error_msg, traceback_war=False) + def py_quit(): + """Function callable from the interactive Python console to exit that environment""" + raise EmbeddedConsoleExit + + # Set up Python environment bridge = PyscriptBridge(self) - self.pystate['run'] = run self.pystate[self.pyscript_name] = bridge + self.pystate['run'] = py_run + self.pystate['quit'] = py_quit + self.pystate['exit'] = py_quit if self.locals_in_py: self.pystate['self'] = self @@ -3002,18 +3008,16 @@ class Cmd(cmd.Cmd): # Set cmd_echo to True so PyscriptBridge statements like: py app('help') # run at the command line will print their output. bridge.cmd_echo = True - interp.runcode(full_command) + + # noinspection PyBroadException + try: + interp.runcode(full_command) + except BaseException: + # We don't care about any exception that happened in the interactive console + pass # If there are no args, then we will open an interactive Python console else: - # noinspection PyShadowingBuiltins - def quit(): - """Function callable from the interactive Python console to exit that environment""" - raise EmbeddedConsoleExit - - self.pystate['quit'] = quit - self.pystate['exit'] = quit - # Set up readline for Python console if rl_type != RlType.NONE: # Save cmd2 history @@ -3072,10 +3076,12 @@ class Cmd(cmd.Cmd): 'Run Python code from external script files with: run("script.py")' .format(self.pyscript_name)) + # noinspection PyBroadException try: interp.interact(banner="Python {} on {}\n{}\n\n{}\n". format(sys.version, sys.platform, cprt, instructions)) - except EmbeddedConsoleExit: + except BaseException: + # We don't care about any exception that happened in the interactive console pass finally: @@ -3109,10 +3115,12 @@ class Cmd(cmd.Cmd): else: sys.modules['readline'] = saved_readline - except Exception: + except KeyboardInterrupt: pass + finally: self._in_py = False + return self._should_quit pyscript_parser = ACArgumentParser() @@ -3123,21 +3131,30 @@ class Cmd(cmd.Cmd): ACTION_ARG_CHOICES, ('path_complete',)) @with_argparser(pyscript_parser) - def do_pyscript(self, args: argparse.Namespace) -> None: + def do_pyscript(self, args: argparse.Namespace) -> bool: """Run a Python script file inside the console""" script_path = os.path.expanduser(args.script_path) + py_return = False # Save current command line arguments orig_args = sys.argv - # Overwrite sys.argv to allow the script to take command line arguments - sys.argv = [script_path] + args.script_arguments + try: + # Overwrite sys.argv to allow the script to take command line arguments + sys.argv = [script_path] + args.script_arguments + + # Run the script - use repr formatting to escape things which + # need to be escaped to prevent issues on Windows + py_return = self.do_py("run({!r})".format(script_path)) - # Run the script - use repr formatting to escape things which need to be escaped to prevent issues on Windows - self.do_py("run({!r})".format(script_path)) + except KeyboardInterrupt: + pass + + finally: + # Restore command line arguments to original state + sys.argv = orig_args - # Restore command line arguments to original state - sys.argv = orig_args + return py_return # Only include the do_ipy() method if IPython is available on the system if ipython_available: # pragma: no cover |