@@ -150,7 +150,9 @@ def exit(self, status=0, msg=None):
150150
151151 We override exit so it doesn't automatically exit the application.
152152 """
153- self .values ._exit = True
153+ if self .values is not None :
154+ self .values ._exit = True
155+
154156 if msg :
155157 print (msg )
156158
@@ -159,10 +161,9 @@ def print_help(self, *args, **kwargs):
159161
160162 We override it so that before the standard optparse help, it prints the do_* method docstring, if available.
161163 """
162- try :
164+ if self . _func . __doc__ :
163165 print (self ._func .__doc__ )
164- except AttributeError :
165- pass
166+
166167 optparse .OptionParser .print_help (self , * args , ** kwargs )
167168
168169 def error (self , msg ):
@@ -195,9 +196,12 @@ def remaining_args(opts_plus_args, arg_list):
195196
196197def _which (editor ):
197198 try :
198- return subprocess .Popen (['which' , editor ], stdout = subprocess .PIPE , stderr = subprocess .STDOUT ).communicate ()[0 ]
199- except OSError :
200- return None
199+ editor_path = subprocess .check_output (['which' , editor ], stderr = subprocess .STDOUT ).strip ()
200+ if six .PY3 :
201+ editor_path = editor_path .decode ()
202+ except subprocess .CalledProcessError :
203+ editor_path = None
204+ return editor_path
201205
202206
203207def strip_quotes (arg ):
@@ -297,7 +301,7 @@ def new_func(instance, arg):
297301 result = func (instance , arg , opts )
298302 return result
299303
300- new_func .__doc__ = '%s\n %s' % (func .__doc__ , option_parser .format_help ())
304+ new_func .__doc__ = '%s%s' % (func .__doc__ + ' \n ' if func . __doc__ else '' , option_parser .format_help ())
301305 return new_func
302306
303307 return option_setup
@@ -746,7 +750,7 @@ def _redirect_output(self, statement):
746750
747751 # NOTE: We couldn't get a real pipe working via subprocess for Python 3.x prior to 3.5.
748752 # So to allow compatibility with Python 2.7 and 3.3+ we are redirecting output to a temporary file.
749- # And once command is complete we are using the "cat" shell command to pipe to whatever .
753+ # And once command is complete we are the temp file as stdin for the shell command to pipe to.
750754 # TODO: Once support for Python 3.x prior to 3.5 is no longer necessary, replace with a real subprocess pipe
751755
752756 # Redirect stdout to a temporary file
@@ -789,8 +793,8 @@ def _restore_output(self, statement):
789793 # Pipe the contents of tempfile to the specified shell command
790794 with open (self ._temp_filename ) as fd :
791795 pipe_proc = subprocess .Popen (shlex .split (statement .parsed .pipeTo ), stdin = fd ,
792- stdout = subprocess .PIPE , stderr = subprocess . PIPE )
793- output , err = pipe_proc .communicate ()
796+ stdout = subprocess .PIPE )
797+ output , _ = pipe_proc .communicate ()
794798
795799 if six .PY3 :
796800 self .stdout .write (output .decode ())
@@ -969,13 +973,8 @@ def do_help(self, arg):
969973 # Getting help for a specific command
970974 funcname = self ._func_named (arg )
971975 if funcname :
972- fn = getattr (self , funcname )
973- try :
974- # Use Optparse help for @options commands
975- fn .optionParser .print_help (file = self .stdout )
976- except AttributeError :
977- # No special behavior needed, delegate to cmd base class do_help()
978- cmd .Cmd .do_help (self , funcname [3 :])
976+ # No special behavior needed, delegate to cmd base class do_help()
977+ cmd .Cmd .do_help (self , funcname [3 :])
979978 else :
980979 # Show a menu of what commands help can be gotten for
981980 self ._help_menu ()
@@ -1140,7 +1139,7 @@ def do_shell(self, command):
11401139 """Execute a command as if at the OS prompt.
11411140
11421141 Usage: shell <command> [arguments]"""
1143- proc = subprocess .Popen (command , stdout = self .stdout , stderr = sys . stderr , shell = True )
1142+ proc = subprocess .Popen (command , stdout = self .stdout , shell = True )
11441143 proc .communicate ()
11451144
11461145 def path_complete (self , text , line , begidx , endidx , dir_exe_only = False , dir_only = False ):
@@ -1573,7 +1572,7 @@ def do_save(self, arg):
15731572 try :
15741573 args = self .saveparser .parseString (arg )
15751574 except pyparsing .ParseException :
1576- self .perror ('Could not understand save target %s' % arg )
1575+ self .perror ('Could not understand save target %s' % arg , traceback_war = False )
15771576 raise SyntaxError (self .do_save .__doc__ )
15781577
15791578 # If a filename was supplied then use that, otherwise use a temp file
@@ -1588,21 +1587,20 @@ def do_save(self, arg):
15881587 elif args .idx :
15891588 saveme = self .history [int (args .idx ) - 1 ]
15901589 else :
1591- saveme = ''
15921590 # Wrap in try to deal with case of empty history
15931591 try :
15941592 # Since this save command has already been added to history, need to go one more back for previous
15951593 saveme = self .history [- 2 ]
15961594 except IndexError :
1597- pass
1595+ self .perror ('History is empty, nothing to save.' , traceback_war = False )
1596+ return
15981597 try :
15991598 f = open (os .path .expanduser (fname ), 'w' )
16001599 f .write (saveme )
16011600 f .close ()
16021601 self .pfeedback ('Saved to {}' .format (fname ))
1603- except Exception :
1604- self .perror ('Error saving {}' .format (fname ))
1605- raise
1602+ except Exception as e :
1603+ self .perror ('Saving {!r} - {}' .format (fname , e ), traceback_war = False )
16061604
16071605 def do__relative_load (self , file_path ):
16081606 """Runs commands in script file that is encoded as either ASCII or UTF-8 text.
0 commit comments