@@ -2957,161 +2957,170 @@ def do_py(self, args: argparse.Namespace) -> bool:
2957
2957
self .perror (err , traceback_war = False )
2958
2958
self ._last_result = CommandResult ('' , err )
2959
2959
return False
2960
- self ._in_py = True
2961
2960
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 )
2961
+ try :
2962
+ self ._in_py = True
2968
2963
2969
- # cmd_echo defaults to False for scripts. The user can always toggle this value in their script.
2970
- bridge .cmd_echo = False
2964
+ # Support the run command even if called prior to invoking an interactive interpreter
2965
+ def py_run (filename : str ):
2966
+ """Run a Python script file in the interactive console.
2967
+ :param filename: filename of *.py script file to run
2968
+ """
2969
+ expanded_filename = os .path .expanduser (filename )
2971
2970
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
2971
+ # cmd_echo defaults to False for scripts. The user can always toggle this value in their script.
2972
+ bridge .cmd_echo = False
3015
2973
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 ))
2974
+ try :
2975
+ with open (expanded_filename ) as f :
2976
+ interp .runcode (f .read ())
2977
+ except OSError as ex :
2978
+ error_msg = "Error opening script file '{}': {}" .format (expanded_filename , ex )
2979
+ self .perror (error_msg , traceback_war = False )
3024
2980
3025
- readline .clear_history ()
2981
+ def py_quit ():
2982
+ """Function callable from the interactive Python console to exit that environment"""
2983
+ raise EmbeddedConsoleExit
3026
2984
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
2985
+ # Set up Python environment
2986
+ bridge = PyscriptBridge (self )
2987
+ self .pystate [self .pyscript_name ] = bridge
2988
+ self .pystate ['run' ] = py_run
2989
+ self .pystate ['quit' ] = py_quit
2990
+ self .pystate ['exit' ] = py_quit
3082
2991
3083
- finally :
3084
- keepstate .restore ()
2992
+ if self .locals_in_py :
2993
+ self .pystate ['self' ] = self
2994
+ elif 'self' in self .pystate :
2995
+ del self .pystate ['self' ]
2996
+
2997
+ localvars = self .pystate
2998
+ from code import InteractiveConsole
2999
+ interp = InteractiveConsole (locals = localvars )
3000
+ interp .runcode ('import sys, os;sys.path.insert(0, os.getcwd())' )
3001
+
3002
+ # Check if the user is running a Python statement on the command line
3003
+ if args .command :
3004
+ full_command = args .command
3005
+ if args .remainder :
3006
+ full_command += ' ' + ' ' .join (args .remainder )
3007
+
3008
+ # Set cmd_echo to True so PyscriptBridge statements like: py app('help')
3009
+ # run at the command line will print their output.
3010
+ bridge .cmd_echo = True
3011
+
3012
+ # noinspection PyBroadException
3013
+ try :
3014
+ interp .runcode (full_command )
3015
+ except BaseException :
3016
+ # We don't care about any exception that happened in the interactive console
3017
+ pass
3085
3018
3086
- # Set up readline for cmd2
3019
+ # If there are no args, then we will open an interactive Python console
3020
+ else :
3021
+ # Set up readline for Python console
3087
3022
if rl_type != RlType .NONE :
3088
- # Save py's history
3089
- self . py_history . clear ()
3023
+ # Save cmd2 history
3024
+ saved_cmd2_history = []
3090
3025
for i in range (1 , readline .get_current_history_length () + 1 ):
3091
- self . py_history .append (readline .get_history_item (i ))
3026
+ saved_cmd2_history .append (readline .get_history_item (i ))
3092
3027
3093
3028
readline .clear_history ()
3094
3029
3095
- # Restore cmd2 's history
3096
- for item in saved_cmd2_history :
3030
+ # Restore py 's history
3031
+ for item in self . py_history :
3097
3032
readline .add_history (item )
3098
3033
3099
3034
if self .use_rawinput and self .completekey :
3100
- # Restore cmd2's tab completion settings
3101
- readline .set_completer (old_completer )
3102
- readline .set_completer_delims (old_delims )
3103
-
3035
+ # Set up tab completion for the Python console
3036
+ # rlcompleter relies on the default settings of the Python readline module
3104
3037
if rl_type == RlType .GNU :
3105
- rl_basic_quote_characters .value = old_basic_quotes
3038
+ old_basic_quotes = ctypes .cast (rl_basic_quote_characters , ctypes .c_void_p ).value
3039
+ rl_basic_quote_characters .value = orig_rl_basic_quotes
3106
3040
3107
3041
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
3042
+ # rlcompleter imports readline by name, so it won't use gnureadline
3043
+ # Force rlcompleter to use gnureadline instead so it has our settings and history
3044
+ saved_readline = None
3045
+ if 'readline' in sys .modules :
3046
+ saved_readline = sys .modules ['readline' ]
3047
+
3048
+ sys .modules ['readline' ] = sys .modules ['gnureadline' ]
3049
+
3050
+ old_delims = readline .get_completer_delims ()
3051
+ readline .set_completer_delims (orig_rl_delims )
3052
+
3053
+ # rlcompleter will not need cmd2's custom display function
3054
+ # This will be restored by cmd2 the next time complete() is called
3055
+ if rl_type == RlType .GNU :
3056
+ readline .set_completion_display_matches_hook (None )
3057
+ elif rl_type == RlType .PYREADLINE :
3058
+ readline .rl .mode ._display_completions = self ._display_matches_pyreadline
3059
+
3060
+ # Save off the current completer and set a new one in the Python console
3061
+ # Make sure it tab completes from its locals() dictionary
3062
+ old_completer = readline .get_completer ()
3063
+ interp .runcode ("from rlcompleter import Completer" )
3064
+ interp .runcode ("import readline" )
3065
+ interp .runcode ("readline.set_completer(Completer(locals()).complete)" )
3066
+
3067
+ # Set up sys module for the Python console
3068
+ self ._reset_py_display ()
3069
+ keepstate = Statekeeper (sys , ('stdin' , 'stdout' ))
3070
+ sys .stdout = self .stdout
3071
+ sys .stdin = self .stdin
3072
+
3073
+ cprt = 'Type "help", "copyright", "credits" or "license" for more information.'
3074
+ instructions = ('End with `Ctrl-D` (Unix) / `Ctrl-Z` (Windows), `quit()`, `exit()`.\n '
3075
+ 'Non-Python commands can be issued with: {}("your command")\n '
3076
+ 'Run Python code from external script files with: run("script.py")'
3077
+ .format (self .pyscript_name ))
3078
+
3079
+ # noinspection PyBroadException
3080
+ try :
3081
+ interp .interact (banner = "Python {} on {}\n {}\n \n {}\n " .
3082
+ format (sys .version , sys .platform , cprt , instructions ))
3083
+ except BaseException :
3084
+ # We don't care about any exception that happened in the interactive console
3085
+ pass
3086
+
3087
+ finally :
3088
+ keepstate .restore ()
3089
+
3090
+ # Set up readline for cmd2
3091
+ if rl_type != RlType .NONE :
3092
+ # Save py's history
3093
+ self .py_history .clear ()
3094
+ for i in range (1 , readline .get_current_history_length () + 1 ):
3095
+ self .py_history .append (readline .get_history_item (i ))
3096
+
3097
+ readline .clear_history ()
3098
+
3099
+ # Restore cmd2's history
3100
+ for item in saved_cmd2_history :
3101
+ readline .add_history (item )
3102
+
3103
+ if self .use_rawinput and self .completekey :
3104
+ # Restore cmd2's tab completion settings
3105
+ readline .set_completer (old_completer )
3106
+ readline .set_completer_delims (old_delims )
3107
+
3108
+ if rl_type == RlType .GNU :
3109
+ rl_basic_quote_characters .value = old_basic_quotes
3110
+
3111
+ if 'gnureadline' in sys .modules :
3112
+ # Restore what the readline module pointed to
3113
+ if saved_readline is None :
3114
+ del (sys .modules ['readline' ])
3115
+ else :
3116
+ sys .modules ['readline' ] = saved_readline
3117
+
3118
+ except KeyboardInterrupt :
3119
+ pass
3120
+
3121
+ finally :
3122
+ self ._in_py = False
3113
3123
3114
- self ._in_py = False
3115
3124
return self ._should_quit
3116
3125
3117
3126
pyscript_parser = ACArgumentParser ()
@@ -3125,18 +3134,25 @@ def py_quit():
3125
3134
def do_pyscript (self , args : argparse .Namespace ) -> bool :
3126
3135
"""Run a Python script file inside the console"""
3127
3136
script_path = os .path .expanduser (args .script_path )
3137
+ py_return = False
3128
3138
3129
3139
# Save current command line arguments
3130
3140
orig_args = sys .argv
3131
3141
3132
- # Overwrite sys.argv to allow the script to take command line arguments
3133
- sys .argv = [script_path ] + args .script_arguments
3142
+ try :
3143
+ # Overwrite sys.argv to allow the script to take command line arguments
3144
+ sys .argv = [script_path ] + args .script_arguments
3134
3145
3135
- # Run the script - use repr formatting to escape things which need to be escaped to prevent issues on Windows
3136
- py_return = self .do_py ("run({!r})" .format (script_path ))
3146
+ # Run the script - use repr formatting to escape things which
3147
+ # need to be escaped to prevent issues on Windows
3148
+ py_return = self .do_py ("run({!r})" .format (script_path ))
3137
3149
3138
- # Restore command line arguments to original state
3139
- sys .argv = orig_args
3150
+ except KeyboardInterrupt :
3151
+ pass
3152
+
3153
+ finally :
3154
+ # Restore command line arguments to original state
3155
+ sys .argv = orig_args
3140
3156
3141
3157
return py_return
3142
3158
0 commit comments