@@ -2959,160 +2959,159 @@ def do_py(self, args: argparse.Namespace) -> bool:
29592959 return False
29602960 self ._in_py = True
29612961
2962- # noinspection PyBroadException
2963- try :
2964- # Support the run command even if called prior to invoking an interactive interpreter
2965- def run (filename : str ):
2966- """Run a Python script file in the interactive console.
2967-
2968- :param filename: filename of *.py script file to run
2969- """
2970- expanded_filename = os .path .expanduser (filename )
2962+ # Support the run command even if called prior to invoking an interactive interpreter
2963+ def py_run (filename : str ):
2964+ """Run a Python script file in the interactive console.
2965+ :param filename: filename of *.py script file to run
2966+ """
2967+ expanded_filename = os .path .expanduser (filename )
29712968
2972- # cmd_echo defaults to False for scripts. The user can always toggle this value in their script.
2973- bridge .cmd_echo = False
2969+ # cmd_echo defaults to False for scripts. The user can always toggle this value in their script.
2970+ bridge .cmd_echo = False
29742971
2975- try :
2976- with open (expanded_filename ) as f :
2977- interp .runcode (f .read ())
2978- except OSError as ex :
2979- error_msg = "Error opening script file '{}': {}" .format (expanded_filename , ex )
2980- self .perror (error_msg , traceback_war = False )
2972+ try :
2973+ with open (expanded_filename ) as f :
2974+ interp .runcode (f .read ())
2975+ except OSError as ex :
2976+ error_msg = "Error opening script file '{}': {}" .format (expanded_filename , ex )
2977+ self .perror (error_msg , traceback_war = False )
2978+
2979+ def py_quit ():
2980+ """Function callable from the interactive Python console to exit that environment"""
2981+ raise EmbeddedConsoleExit
2982+
2983+ # Set up Python environment
2984+ bridge = PyscriptBridge (self )
2985+ self .pystate [self .pyscript_name ] = bridge
2986+ self .pystate ['run' ] = py_run
2987+ self .pystate ['quit' ] = py_quit
2988+ self .pystate ['exit' ] = py_quit
2989+
2990+ if self .locals_in_py :
2991+ self .pystate ['self' ] = self
2992+ elif 'self' in self .pystate :
2993+ del self .pystate ['self' ]
2994+
2995+ localvars = self .pystate
2996+ from code import InteractiveConsole
2997+ interp = InteractiveConsole (locals = localvars )
2998+ interp .runcode ('import sys, os;sys.path.insert(0, os.getcwd())' )
2999+
3000+ # Check if the user is running a Python statement on the command line
3001+ if args .command :
3002+ full_command = args .command
3003+ if args .remainder :
3004+ full_command += ' ' + ' ' .join (args .remainder )
3005+
3006+ # Set cmd_echo to True so PyscriptBridge statements like: py app('help')
3007+ # run at the command line will print their output.
3008+ bridge .cmd_echo = True
3009+
3010+ # noinspection PyBroadException
3011+ try :
3012+ interp .runcode (full_command )
3013+ except BaseException :
3014+ pass
29813015
2982- bridge = PyscriptBridge (self )
2983- self .pystate ['run' ] = run
2984- self .pystate [self .pyscript_name ] = bridge
3016+ # If there are no args, then we will open an interactive Python console
3017+ else :
3018+ # Set up readline for Python console
3019+ if rl_type != RlType .NONE :
3020+ # Save cmd2 history
3021+ saved_cmd2_history = []
3022+ for i in range (1 , readline .get_current_history_length () + 1 ):
3023+ saved_cmd2_history .append (readline .get_history_item (i ))
29853024
2986- if self .locals_in_py :
2987- self .pystate ['self' ] = self
2988- elif 'self' in self .pystate :
2989- del self .pystate ['self' ]
2990-
2991- localvars = self .pystate
2992- from code import InteractiveConsole
2993- interp = InteractiveConsole (locals = localvars )
2994- interp .runcode ('import sys, os;sys.path.insert(0, os.getcwd())' )
2995-
2996- # Check if the user is running a Python statement on the command line
2997- if args .command :
2998- full_command = args .command
2999- if args .remainder :
3000- full_command += ' ' + ' ' .join (args .remainder )
3001-
3002- # Set cmd_echo to True so PyscriptBridge statements like: py app('help')
3003- # run at the command line will print their output.
3004- bridge .cmd_echo = True
3005- interp .runcode (full_command )
3025+ readline .clear_history ()
30063026
3007- # If there are no args, then we will open an interactive Python console
3008- else :
3009- # noinspection PyShadowingBuiltins
3010- def quit ():
3011- """Function callable from the interactive Python console to exit that environment"""
3012- raise EmbeddedConsoleExit
3027+ # Restore py's history
3028+ for item in self .py_history :
3029+ readline .add_history (item )
3030+
3031+ if self .use_rawinput and self .completekey :
3032+ # Set up tab completion for the Python console
3033+ # rlcompleter relies on the default settings of the Python readline module
3034+ if rl_type == RlType .GNU :
3035+ old_basic_quotes = ctypes .cast (rl_basic_quote_characters , ctypes .c_void_p ).value
3036+ rl_basic_quote_characters .value = orig_rl_basic_quotes
3037+
3038+ if 'gnureadline' in sys .modules :
3039+ # rlcompleter imports readline by name, so it won't use gnureadline
3040+ # Force rlcompleter to use gnureadline instead so it has our settings and history
3041+ saved_readline = None
3042+ if 'readline' in sys .modules :
3043+ saved_readline = sys .modules ['readline' ]
3044+
3045+ sys .modules ['readline' ] = sys .modules ['gnureadline' ]
3046+
3047+ old_delims = readline .get_completer_delims ()
3048+ readline .set_completer_delims (orig_rl_delims )
3049+
3050+ # rlcompleter will not need cmd2's custom display function
3051+ # This will be restored by cmd2 the next time complete() is called
3052+ if rl_type == RlType .GNU :
3053+ readline .set_completion_display_matches_hook (None )
3054+ elif rl_type == RlType .PYREADLINE :
3055+ readline .rl .mode ._display_completions = self ._display_matches_pyreadline
3056+
3057+ # Save off the current completer and set a new one in the Python console
3058+ # Make sure it tab completes from its locals() dictionary
3059+ old_completer = readline .get_completer ()
3060+ interp .runcode ("from rlcompleter import Completer" )
3061+ interp .runcode ("import readline" )
3062+ interp .runcode ("readline.set_completer(Completer(locals()).complete)" )
3063+
3064+ # Set up sys module for the Python console
3065+ self ._reset_py_display ()
3066+ keepstate = Statekeeper (sys , ('stdin' , 'stdout' ))
3067+ sys .stdout = self .stdout
3068+ sys .stdin = self .stdin
3069+
3070+ cprt = 'Type "help", "copyright", "credits" or "license" for more information.'
3071+ instructions = ('End with `Ctrl-D` (Unix) / `Ctrl-Z` (Windows), `quit()`, `exit()`.\n '
3072+ 'Non-Python commands can be issued with: {}("your command")\n '
3073+ 'Run Python code from external script files with: run("script.py")'
3074+ .format (self .pyscript_name ))
3075+
3076+ # noinspection PyBroadException
3077+ try :
3078+ interp .interact (banner = "Python {} on {}\n {}\n \n {}\n " .
3079+ format (sys .version , sys .platform , cprt , instructions ))
3080+ except BaseException :
3081+ pass
30133082
3014- self . pystate [ 'quit' ] = quit
3015- self . pystate [ 'exit' ] = quit
3083+ finally :
3084+ keepstate . restore ()
30163085
3017- # Set up readline for Python console
3086+ # Set up readline for cmd2
30183087 if rl_type != RlType .NONE :
3019- # Save cmd2 history
3020- saved_cmd2_history = []
3088+ # Save py's history
3089+ self . py_history . clear ()
30213090 for i in range (1 , readline .get_current_history_length () + 1 ):
3022- saved_cmd2_history .append (readline .get_history_item (i ))
3091+ self . py_history .append (readline .get_history_item (i ))
30233092
30243093 readline .clear_history ()
30253094
3026- # Restore py 's history
3027- for item in self . py_history :
3095+ # Restore cmd2 's history
3096+ for item in saved_cmd2_history :
30283097 readline .add_history (item )
30293098
30303099 if self .use_rawinput and self .completekey :
3031- # Set up tab completion for the Python console
3032- # rlcompleter relies on the default settings of the Python readline module
3033- if rl_type == RlType .GNU :
3034- old_basic_quotes = ctypes .cast (rl_basic_quote_characters , ctypes .c_void_p ).value
3035- rl_basic_quote_characters .value = orig_rl_basic_quotes
3036-
3037- if 'gnureadline' in sys .modules :
3038- # rlcompleter imports readline by name, so it won't use gnureadline
3039- # Force rlcompleter to use gnureadline instead so it has our settings and history
3040- saved_readline = None
3041- if 'readline' in sys .modules :
3042- saved_readline = sys .modules ['readline' ]
3043-
3044- sys .modules ['readline' ] = sys .modules ['gnureadline' ]
3045-
3046- old_delims = readline .get_completer_delims ()
3047- readline .set_completer_delims (orig_rl_delims )
3100+ # Restore cmd2's tab completion settings
3101+ readline .set_completer (old_completer )
3102+ readline .set_completer_delims (old_delims )
30483103
3049- # rlcompleter will not need cmd2's custom display function
3050- # This will be restored by cmd2 the next time complete() is called
30513104 if rl_type == RlType .GNU :
3052- readline .set_completion_display_matches_hook (None )
3053- elif rl_type == RlType .PYREADLINE :
3054- readline .rl .mode ._display_completions = self ._display_matches_pyreadline
3055-
3056- # Save off the current completer and set a new one in the Python console
3057- # Make sure it tab completes from its locals() dictionary
3058- old_completer = readline .get_completer ()
3059- interp .runcode ("from rlcompleter import Completer" )
3060- interp .runcode ("import readline" )
3061- interp .runcode ("readline.set_completer(Completer(locals()).complete)" )
3062-
3063- # Set up sys module for the Python console
3064- self ._reset_py_display ()
3065- keepstate = Statekeeper (sys , ('stdin' , 'stdout' ))
3066- sys .stdout = self .stdout
3067- sys .stdin = self .stdin
3068-
3069- cprt = 'Type "help", "copyright", "credits" or "license" for more information.'
3070- instructions = ('End with `Ctrl-D` (Unix) / `Ctrl-Z` (Windows), `quit()`, `exit()`.\n '
3071- 'Non-Python commands can be issued with: {}("your command")\n '
3072- 'Run Python code from external script files with: run("script.py")'
3073- .format (self .pyscript_name ))
3074-
3075- try :
3076- interp .interact (banner = "Python {} on {}\n {}\n \n {}\n " .
3077- format (sys .version , sys .platform , cprt , instructions ))
3078- except EmbeddedConsoleExit :
3079- pass
3080-
3081- finally :
3082- keepstate .restore ()
3083-
3084- # Set up readline for cmd2
3085- if rl_type != RlType .NONE :
3086- # Save py's history
3087- self .py_history .clear ()
3088- for i in range (1 , readline .get_current_history_length () + 1 ):
3089- self .py_history .append (readline .get_history_item (i ))
3105+ rl_basic_quote_characters .value = old_basic_quotes
30903106
3091- readline .clear_history ()
3092-
3093- # Restore cmd2's history
3094- for item in saved_cmd2_history :
3095- readline .add_history (item )
3096-
3097- if self .use_rawinput and self .completekey :
3098- # Restore cmd2's tab completion settings
3099- readline .set_completer (old_completer )
3100- readline .set_completer_delims (old_delims )
3101-
3102- if rl_type == RlType .GNU :
3103- rl_basic_quote_characters .value = old_basic_quotes
3104-
3105- if 'gnureadline' in sys .modules :
3106- # Restore what the readline module pointed to
3107- if saved_readline is None :
3108- del (sys .modules ['readline' ])
3109- else :
3110- sys .modules ['readline' ] = saved_readline
3107+ if 'gnureadline' in sys .modules :
3108+ # Restore what the readline module pointed to
3109+ if saved_readline is None :
3110+ del (sys .modules ['readline' ])
3111+ else :
3112+ sys .modules ['readline' ] = saved_readline
31113113
3112- except Exception :
3113- pass
3114- finally :
3115- self ._in_py = False
3114+ self ._in_py = False
31163115 return self ._should_quit
31173116
31183117 pyscript_parser = ACArgumentParser ()
@@ -3123,7 +3122,7 @@ def quit():
31233122 ACTION_ARG_CHOICES , ('path_complete' ,))
31243123
31253124 @with_argparser (pyscript_parser )
3126- def do_pyscript (self , args : argparse .Namespace ) -> None :
3125+ def do_pyscript (self , args : argparse .Namespace ) -> bool :
31273126 """Run a Python script file inside the console"""
31283127 script_path = os .path .expanduser (args .script_path )
31293128
@@ -3134,11 +3133,13 @@ def do_pyscript(self, args: argparse.Namespace) -> None:
31343133 sys .argv = [script_path ] + args .script_arguments
31353134
31363135 # Run the script - use repr formatting to escape things which need to be escaped to prevent issues on Windows
3137- self .do_py ("run({!r})" .format (script_path ))
3136+ py_return = self .do_py ("run({!r})" .format (script_path ))
31383137
31393138 # Restore command line arguments to original state
31403139 sys .argv = orig_args
31413140
3141+ return py_return
3142+
31423143 # Only include the do_ipy() method if IPython is available on the system
31433144 if ipython_available : # pragma: no cover
31443145 @with_argparser (ACArgumentParser ())
0 commit comments