def __init__(self,args=[],stdin=None,stdout=None, completekey='tab',intro=None,debug=False,GUI='TkAgg'): """ Init """ # Prompt self.ps1 = "pds>" self.ps2 = "...>" # Set stdin/out if stdin is not None: sys.stdin = self.stdin = stdin self.use_rawinput = False else: self.stdin = sys.stdin self.use_rawinput = True if stdout is not None: sys.stdout = self.stdout = stdout #sys.stderr = stdout else: self.stdout = sys.stdout # Startup strings self.intro = self.__doc__ if intro: self.intro = self.intro + intro if self.intro: self.stdout.write(str(self.intro)+"\n") # Interpretor self.interp = Interpretor() # Data and vars self.debug = debug self.GUI = GUI self.queue = [] self.error_break = True self.commands = {} # Builtin commands self.pds_commands = {'quit':self.do_quit, 'exit':self.do_quit, #'EOF':self.do_quit, 'show':self.do_show, 'help':self.do_help, 'load':self.do_load, 'debug':self.do_debug, 'fexec':self.do_execfile, 'save':self.do_save, 'restore':self.do_restore, 'clear':self.do_clear, 'addcmd':self.do_addcmd, 'alias':self.do_addalias} # run startup self.startup(args=args) # check for cmd in self.pds_commands.keys(): if cmd in PYTHON_KEY_WORDS: print "Warning: command '%s' is a python keyword" % cmd # setup readline if have it. -- add later self.completekey = completekey
def __init__(self, args=[], stdin=None, stdout=None, completekey='tab', intro=None, debug=False, GUI='TkAgg'): """ Init """ # Prompt self.ps1 = "pds>" self.ps2 = "...>" # Set stdin/out if stdin is not None: sys.stdin = self.stdin = stdin self.use_rawinput = False else: self.stdin = sys.stdin self.use_rawinput = True if stdout is not None: sys.stdout = self.stdout = stdout #sys.stderr = stdout else: self.stdout = sys.stdout # Startup strings self.intro = self.__doc__ if intro: self.intro = self.intro + intro if self.intro: self.stdout.write(str(self.intro) + "\n") # Interpretor self.interp = Interpretor() # Data and vars self.debug = debug self.GUI = GUI self.queue = [] self.error_break = True self.commands = {} # Builtin commands self.pds_commands = { 'quit': self.do_quit, 'exit': self.do_quit, #'EOF':self.do_quit, 'show': self.do_show, 'help': self.do_help, 'load': self.do_load, 'debug': self.do_debug, 'fexec': self.do_execfile, 'save': self.do_save, 'restore': self.do_restore, 'clear': self.do_clear, 'addcmd': self.do_addcmd, 'alias': self.do_addalias } # run startup self.startup(args=args) # check for cmd in self.pds_commands.keys(): if cmd in PYTHON_KEY_WORDS: print "Warning: command '%s' is a python keyword" % cmd # setup readline if have it. -- add later self.completekey = completekey
class Shell(_NumShell): __doc__ = """ **************************************** * Python Data Shell * * Type 'help' to get started * **************************************** """ max_save_lines = 500 ############################################################# def __init__(self,args=[],stdin=None,stdout=None, completekey='tab',intro=None,debug=False,GUI='TkAgg'): """ Init """ # Prompt self.ps1 = "pds>" self.ps2 = "...>" # Set stdin/out if stdin is not None: sys.stdin = self.stdin = stdin self.use_rawinput = False else: self.stdin = sys.stdin self.use_rawinput = True if stdout is not None: sys.stdout = self.stdout = stdout #sys.stderr = stdout else: self.stdout = sys.stdout # Startup strings self.intro = self.__doc__ if intro: self.intro = self.intro + intro if self.intro: self.stdout.write(str(self.intro)+"\n") # Interpretor self.interp = Interpretor() # Data and vars self.debug = debug self.GUI = GUI self.queue = [] self.error_break = True self.commands = {} # Builtin commands self.pds_commands = {'quit':self.do_quit, 'exit':self.do_quit, #'EOF':self.do_quit, 'show':self.do_show, 'help':self.do_help, 'load':self.do_load, 'debug':self.do_debug, 'fexec':self.do_execfile, 'save':self.do_save, 'restore':self.do_restore, 'clear':self.do_clear, 'addcmd':self.do_addcmd, 'alias':self.do_addalias} # run startup self.startup(args=args) # check for cmd in self.pds_commands.keys(): if cmd in PYTHON_KEY_WORDS: print "Warning: command '%s' is a python keyword" % cmd # setup readline if have it. -- add later self.completekey = completekey ############################################################# def startup(self,args=[]): """ set up builtins and exec startup arguments """ # Builtins from builtins import __pdsbuiltins__ self.interp.symbol_table.data["__pds__"] = __pdsbuiltins__ # add module functions to __builtins__ startup = [] startup.append("__builtins__.update({'group':__pds__.group})") startup.append("__builtins__.update({'ls':__pds__._ls})") startup.append("__builtins__.update({'cd':__pds__._cd})") startup.append("__builtins__.update({'pwd':__pds__._cwd})") startup.append("__builtins__.update({'rimport':__pds__.rimport})") startup.append("__builtins__.update({'path':__pds__._path})") startup.append("__builtins__.update({'source':__pds__.source})") startup.append("__builtins__.update({'info':__pds__.info})") # functions we want to use with command syntax self.do_addcmd('ls',"__pds__.ls") self.do_addcmd('pwd',"__pds__.pwd") self.do_addcmd('cd',"__pds__.cd") self.do_addcmd('more',"__pds__.more") self.do_addcmd('path',"__pds__.path") self.do_addcmd('rimport',"__pds__.rimport") self.do_addcmd('source',"__pds__.source") self.do_addcmd('info',"__pds__.info") # if numeric/scientific stuff is included # load it. Note leave this here in case there # are cmd line args below that depend on numerics... if hasattr(self,'num_setup'): tmp = self.num_setup() startup = startup + tmp # any other args add to queue if type(args) == types.ListType: for a in args: s = a.strip() startup.append(s) self.queue = startup # execute the queue here before moving on # otherwise startup stuff is not available # to files executed before we start the loop # also allow it to run through even if there is # an error... self.error_break = False self.exec_queue() self.error_break = True return ############################################################################ def loop(self,): """ The prompt loop Repeatedly issue a prompt, accept input, parse an initial prefix off the received input, and dispatch to action methods, passing them the remainder of the line as argument. Modified from cmd.Cmd.cmdloop. Note for the python interpretor to work it is important that blank lines are passed, and that lines are not stripped entirely (ie leave white space on left) """ stop = COMPLETE while stop != QUIT: if stop == CONTINUE: prompt = self.ps2 else: prompt = self.ps1 if self.use_rawinput: try: line = raw_input(prompt) except EOFError: line = 'quit' else: self.stdout.write(prompt) self.stdout.flush() line = self.stdin.readline() if line == None: line = 'quit' else: #line = line[:-1] # chop \n line = line.rstrip() # chop \n # split on ';' and exec the line lines = split_cmd_line(line) for s in lines: stop = self.exec_line(s) if stop == QUIT: break return SUCCESS ############################################################# def exec_queue(self): """ Execute lines in self.queue """ if len(self.queue) == 0: return SUCCESS for line in self.queue: # split on ';' and exec the line lines = split_cmd_line(line) for s in lines: stop = self.exec_line(s) if stop == QUIT: self.queue = [] return QUIT elif (stop == EXECERROR) and (self.error_break == True): self.queue = [] print "Error executing shell.queue" return EXECERROR return SUCCESS ############################################################# def exec_line(self, line): """ Exec a single line This method first inspect the first token of the command line If its a '!' send it to the shell If its a 'command' call _exec_cmd() Otherwise pass to the interpretor The return value from this method should always be one of: QUIT, SUCCESS, COMPLETE, CONTINUE, EXECERROR Exceptions from the interpretor are handled here. Note for the python interpretor to work it is important that blank lines are passed in and that lines are not stripped entirely (ie leave left white space). We also let the interpretor handle comments (#). """ s = str(line).rstrip() try: if len(s) > 0: #if self.debug: print '**line:%s' % (s) # see if its shell cmd if s.startswith('!'): os.system(s[1:]) return COMPLETE # look for commands words = s.split() cmd = words[0].strip() if len(words) > 1: idx = s.find(cmd)+len(cmd) arg = s[idx:].strip() else: arg = '' else: cmd = None # if its a cmd execute it in _exec_cmd if cmd: if cmd in self.pds_commands.keys(): return self._exec_cmd(cmd,arg) elif cmd in self.commands.keys(): return self._exec_cmd(cmd,arg) # otherwise pass to the interpretor return self.interp.execute(s) except: err_str = "Error executing line:\n'%s'" % s if self.debug: PrintExceptErr(err_str,print_trace=True) else: #PrintExceptErr(err_str,print_trace=False) PrintExceptErr(err_str,print_trace=True) # clear the exception and interpretors buffer # sys.exc_clear() self.interp.console.resetbuffer() return EXECERROR ############################################################# def _exec_cmd(self,cmd,arg): """ execute commands Note only call this from exec_line for proper error / exception handling! """ ret = None # local commands if cmd in self.pds_commands.keys(): fun = self.pds_commands[cmd] ret = fun(arg) # other commands elif cmd in self.commands.keys(): cmd_fun = self.commands[cmd] s = cmd_fun + ' ' + arg s = command2expr(s,symtable=self.interp.symbol_table) if self.debug: print '**command repacked: ', s ret = self.interp.execute(s) else: print "Error: uknown command: %s" % cmd #if ret == None: if ret not in (QUIT, SUCCESS, COMPLETE, CONTINUE, EXECERROR): return COMPLETE else: return ret ############################################################# ############################################################# ## Builtin commands ############################################################# ############################################################# def do_quit(self,arg): """ Quit the shell """ try: self.close_pyplot() except: pass return QUIT ############################################################# def do_debug(self,arg): """ Toggle debug flag """ if self.debug == True: print "Debug off" self.debug = False else: print "Debug on" self.debug = True return SUCCESS ############################################################# def do_load(self,fname): """ Load file of pds commands for execution Note that file execution will halt if there is an error in the file. This default behaviour can be changed by setting the flag self.error_break = False If the file has a '.sav' extension we first try to read it using restore (ie assume its a pickle) """ if fname[-4:] == '.sav': if self._restore(fname) == 1: return COMPLETE if os.path.exists(fname) and os.path.isfile(fname): f = open(fname) lines = f.readlines() f.close() else: print 'File error: cannot find file to load for %s ' % fname return COMPLETE if len(lines) == 0: return COMPLETE # execute the lines through the queue self.queue = [] self.queue.extend(lines) ret = self.exec_queue() if ret == EXECERROR: print "Error in file %s" % fname if self.debug: print 'load done' return COMPLETE ############################################################# def do_execfile(self,fname): """ Execute a file of python code Note that the file will be executed as if it was imported into the '__main__' namespace """ if not os.path.exists(fname): files = [] for p in sys.path: f = os.path.join(p,fname) if os.path.exists(f): files.append(f) if len(files) == 0: print "File '%s' not found" % fname return SUCCESS elif len(files) == 1: fname = files[0] else: print "Warning multiple files found on path" print "Please specify the full path in fname or change the" print "working directory to the directory with the correct file" for f in files: print " %s" % f return SUCCESS return self.interp.execute_file(fname) ############################################################# def do_addcmd(self,*arg): """ Add a command interface to a function Allows a function to be called with command syntax. >>addcmd mycmd, myfun results in >>mycmd arg1, arg2, key=xx being repackaged to >>myfun(arg1,arg2,key=xx) which is then sent to the interpretor """ if len(arg) == 1: arg = arg[0] words = arg.split(',') if len(words) != 2: print "Error parsing cmd/func names" cmd_name = words[0].strip() func_name = words[1].strip() elif len(arg) == 2: cmd_name = arg[0].strip() func_name = arg[1].strip() else: print "Wrong number of arguments" return SUCCESS cmd_name = trimstring(cmd_name) func_name = trimstring(func_name) if len(cmd_name) == 0 or len(func_name) == 0: print "Error parsing cmd/func names" return SUCCESS # do a check if cmd_name in PYTHON_KEY_WORDS: print "Error: command '%s' is a python keyword" % cmd_name return SUCCESS if cmd_name in self.pds_commands.keys(): print "Error: command '%s' is a builtin keyword" % cmd_name return SUCCESS if cmd_name in self.commands.keys(): print "Warning: overwriting command '%s' " % cmd_name self.commands[cmd_name] = func_name else: self.commands.update({cmd_name:func_name}) return SUCCESS ############################################################# def do_addalias(self,*arg): """ Create a command shortcut for a function. The alias is just a way of making shortcuts for repetitive taks >>alias myalias, 'myfun(args)' results in >>myalias being repackaged to >>myfun(args) which is then sent to the interpretor Note alias's are added to the command list (see 'show' and 'help addcmd') Example: -------- pds>alias "code", "cd('~/code')" pds>code pds>pwd /home/bob/code """ if len(arg) == 1: arg = arg[0] words = arg.split(',') if len(words) != 2: print "Error parsing cmd/func names" cmd_name = words[0].strip() func_name = words[1].strip() elif len(arg) == 2: cmd_name = arg[0].strip() func_name = arg[1].strip() else: print "Wrong number of arguments" return SUCCESS cmd_name = trimstring(cmd_name) func_name = trimstring(func_name) if len(cmd_name) == 0 or len(func_name) == 0: print "Error parsing cmd/func names" return SUCCESS # do a check if cmd_name in PYTHON_KEY_WORDS: print "Error: command '%s' is a python keyword" % cmd_name return SUCCESS s = "__%s__ = lambda : %s" % (cmd_name,func_name) ret = self.exec_line(s) s = "addcmd '%s', '__%s__'" % (cmd_name,cmd_name) ret = self.exec_line(s) ############################################################## ############################################################## ## save / restore state and clear variables ############################################################## ############################################################## def do_save(self,args): """ Save program state to a file Note this may fail since not all objects can be pickled... needs improvement! Examples: --------- >>save # save all to default fname >>save fname # save all to fname >>save data fname # save data to file """ from pds.shellutil import pickle_1 as pickle #from pds.shellutil import pickle_2 as pickle # parse input, get filename args = split_args(args) dname = None if len(args) == 0: t = time.strftime("%Y_%m_%d_%H%M", time.localtime()) fname = 'save_%s.sav' % t else: if len(args) == 1: fname = args[0] elif len(args) == 2: dname = args[0] fname = args[1] else: return # get data dictionary data = self.interp.symbol_table.get_data_dict(name=dname) if data == None: return SUCCESS # pickle it pickle(data,fname) ############################################################## def do_restore(self,fname): """ Restore state from a file that was created with save """ self._restore(fname) return SUCCESS def _restore(self,fname): from pds.shellutil import unpickle_1 as unpickle #from pds.shellutil import unpickle_2 as unpickle pdata = unpickle(fname) if pdata == None: print "No data" return 0 if len(pdata) > 0: self.interp.symbol_table.put_data_dict(pdata) return 1 return 0 ############################################################## def do_clear(self,arg): """ Clear all 'data' from the workspace This clears everything that looks like a variable, ie simple data types and class instances """ args = split_args(arg) if len(args) == 0: dname = [None] else: dname = args for d in dname: data = self.interp.symbol_table.get_data_dict(name=d) for key in data.keys(): del self.interp.symbol_table.data[key] return SUCCESS ############################################################## ############################################################# ## Help and Show ############################################################# ############################################################## def do_help(self,arg): """ Display help. Example: -------- >>help # displays help options """ if arg == None or len(arg) == 0: #print self.help_str print HELP_STR return SUCCESS (opts, args) = getopt.getopt(arg.split(), "u",["use"]) for key,val in opts: if key in ("-u", "--use"): #print self.help_use_str print HELP_USE_STR for a in args: if a in self.pds_commands.keys(): #tmp = getattr(self,a) tmp = self.pds_commands[a] help(tmp) elif a in self.commands.keys(): cmd_fun = self.commands[a] s = "help(%s)" % cmd_fun ret = self.exec_line(s) else: s = "help(%s)" % a ret = self.exec_line(s) return SUCCESS ############################################################# def do_show(self,arg): """ List functions and variables. Options: >>show -ath group -------- -a = show all (include symbols with names that have a leading '_' ) -b = show builtins (defined in __builtins__ ). Note this option trumps tunnel (ie -t is ignored). -t = tunnel, display attributes within a class instance or module. Note modules are only displayed with one level of tunneling (ie -t option is ignored if a module is passed as an argument). However, this will tunnel on all class instances. """ tunnel=False skip=True (opts, args) = getopt.getopt(arg.split(), "abt",["all","builtins","tunnel"]) for key,val in opts: if key in ("-a", "--all"): skip=False if key in ("-b", "--builtin"): self._show_builtins(_skip=skip) return if key in ("-t", "--tunnel"): tunnel=True if len(args)>0: #arg = ' '.join(args) for a in args: self._show(symbol=a,tunnel=tunnel,_skip=skip) else: self._show(tunnel=tunnel,_skip=skip) return SUCCESS ############################################################# def _show_builtins(self,_skip=True): """ """ print "\n***** Builtins ******" # show python keywords print "\n==== Python Key Words ====" print show_list(PYTHON_KEY_WORDS,textwidth=TEXT_WIDTH) # get builtins d = self.interp.symbol_table.list_builtins(_skip=_skip) self._print_show(d) return SUCCESS ############################################################# def _show(self,symbol=None,tunnel=False,_skip=True): """ """ if symbol: ty = self.interp.symbol_table.sym_type(symbol) if ty == None: print "Symbol '%s' not found" % symbol return SUCCESS elif ty in ('oth'): print "Symbol '%s' of uknown type" % symbol print type(self.interp.symbol_table.get_symbol(symbol)) return SUCCESS else: ty = None print "\n==== Commands ====" tmp = self.commands.keys() tmp = tmp + self.pds_commands.keys() tmp.sort() print show_list(tmp,textwidth=TEXT_WIDTH) if ty == 'var': tmp = self.interp.symbol_table.get_symbol(symbol) print repr(tmp) return SUCCESS elif ty == 'fnc': tmp = self.interp.symbol_table.get_symbol(symbol) print help(tmp) return SUCCESS else: d = self.interp.symbol_table.list_symbols(symbol=symbol, tunnel=tunnel, _skip=_skip) self._print_show(d) return SUCCESS ############################################################# def _print_show(self,d): """ Print stuff """ if d == None: return SUCCESS if len(d['mod'])> 0: print "\n==== Modules ====" print show_list(d['mod'],textwidth=TEXT_WIDTH) if len(d['fnc'])> 0: print "\n==== Functions / Classes ====" print show_list(d['fnc'],textwidth=TEXT_WIDTH) if len(d['ins'])> 0: print "\n==== Instances ====" print show_list(d['ins'],textwidth=TEXT_WIDTH) if len(d['var'])> 0: print "\n==== Variables ====" print show_list(d['var'],textwidth=TEXT_WIDTH) if len(d['oth'])> 0: print "\n==== Other Python Objects ====" print show_list(d['oth'],textwidth=TEXT_WIDTH) print "\n" return SUCCESS
class Shell(_NumShell): __doc__ = """ **************************************** * Python Data Shell * * Type 'help' to get started * **************************************** """ max_save_lines = 500 ############################################################# def __init__(self, args=[], stdin=None, stdout=None, completekey='tab', intro=None, debug=False, GUI='TkAgg'): """ Init """ # Prompt self.ps1 = "pds>" self.ps2 = "...>" # Set stdin/out if stdin is not None: sys.stdin = self.stdin = stdin self.use_rawinput = False else: self.stdin = sys.stdin self.use_rawinput = True if stdout is not None: sys.stdout = self.stdout = stdout #sys.stderr = stdout else: self.stdout = sys.stdout # Startup strings self.intro = self.__doc__ if intro: self.intro = self.intro + intro if self.intro: self.stdout.write(str(self.intro) + "\n") # Interpretor self.interp = Interpretor() # Data and vars self.debug = debug self.GUI = GUI self.queue = [] self.error_break = True self.commands = {} # Builtin commands self.pds_commands = { 'quit': self.do_quit, 'exit': self.do_quit, #'EOF':self.do_quit, 'show': self.do_show, 'help': self.do_help, 'load': self.do_load, 'debug': self.do_debug, 'fexec': self.do_execfile, 'save': self.do_save, 'restore': self.do_restore, 'clear': self.do_clear, 'addcmd': self.do_addcmd, 'alias': self.do_addalias } # run startup self.startup(args=args) # check for cmd in self.pds_commands.keys(): if cmd in PYTHON_KEY_WORDS: print "Warning: command '%s' is a python keyword" % cmd # setup readline if have it. -- add later self.completekey = completekey ############################################################# def startup(self, args=[]): """ set up builtins and exec startup arguments """ # Builtins from builtins import __pdsbuiltins__ self.interp.symbol_table.data["__pds__"] = __pdsbuiltins__ # add module functions to __builtins__ startup = [] startup.append("__builtins__.update({'group':__pds__.group})") startup.append("__builtins__.update({'ls':__pds__._ls})") startup.append("__builtins__.update({'cd':__pds__._cd})") startup.append("__builtins__.update({'pwd':__pds__._cwd})") startup.append("__builtins__.update({'rimport':__pds__.rimport})") startup.append("__builtins__.update({'path':__pds__._path})") startup.append("__builtins__.update({'source':__pds__.source})") startup.append("__builtins__.update({'info':__pds__.info})") # functions we want to use with command syntax self.do_addcmd('ls', "__pds__.ls") self.do_addcmd('pwd', "__pds__.pwd") self.do_addcmd('cd', "__pds__.cd") self.do_addcmd('more', "__pds__.more") self.do_addcmd('path', "__pds__.path") self.do_addcmd('rimport', "__pds__.rimport") self.do_addcmd('source', "__pds__.source") self.do_addcmd('info', "__pds__.info") # if numeric/scientific stuff is included # load it. Note leave this here in case there # are cmd line args below that depend on numerics... if hasattr(self, 'num_setup'): tmp = self.num_setup() startup = startup + tmp # any other args add to queue if type(args) == types.ListType: for a in args: s = a.strip() startup.append(s) self.queue = startup # execute the queue here before moving on # otherwise startup stuff is not available # to files executed before we start the loop # also allow it to run through even if there is # an error... self.error_break = False self.exec_queue() self.error_break = True return ############################################################################ def loop(self, ): """ The prompt loop Repeatedly issue a prompt, accept input, parse an initial prefix off the received input, and dispatch to action methods, passing them the remainder of the line as argument. Modified from cmd.Cmd.cmdloop. Note for the python interpretor to work it is important that blank lines are passed, and that lines are not stripped entirely (ie leave white space on left) """ stop = COMPLETE while stop != QUIT: if stop == CONTINUE: prompt = self.ps2 else: prompt = self.ps1 if self.use_rawinput: try: line = raw_input(prompt) except EOFError: line = 'quit' else: self.stdout.write(prompt) self.stdout.flush() line = self.stdin.readline() if line == None: line = 'quit' else: #line = line[:-1] # chop \n line = line.rstrip() # chop \n # split on ';' and exec the line lines = split_cmd_line(line) for s in lines: stop = self.exec_line(s) if stop == QUIT: break return SUCCESS ############################################################# def exec_queue(self): """ Execute lines in self.queue """ if len(self.queue) == 0: return SUCCESS for line in self.queue: # split on ';' and exec the line lines = split_cmd_line(line) for s in lines: stop = self.exec_line(s) if stop == QUIT: self.queue = [] return QUIT elif (stop == EXECERROR) and (self.error_break == True): self.queue = [] print "Error executing shell.queue" return EXECERROR return SUCCESS ############################################################# def exec_line(self, line): """ Exec a single line This method first inspect the first token of the command line If its a '!' send it to the shell If its a 'command' call _exec_cmd() Otherwise pass to the interpretor The return value from this method should always be one of: QUIT, SUCCESS, COMPLETE, CONTINUE, EXECERROR Exceptions from the interpretor are handled here. Note for the python interpretor to work it is important that blank lines are passed in and that lines are not stripped entirely (ie leave left white space). We also let the interpretor handle comments (#). """ s = str(line).rstrip() try: if len(s) > 0: #if self.debug: print '**line:%s' % (s) # see if its shell cmd if s.startswith('!'): os.system(s[1:]) return COMPLETE # look for commands words = s.split() cmd = words[0].strip() if len(words) > 1: idx = s.find(cmd) + len(cmd) arg = s[idx:].strip() else: arg = '' else: cmd = None # if its a cmd execute it in _exec_cmd if cmd: if cmd in self.pds_commands.keys(): return self._exec_cmd(cmd, arg) elif cmd in self.commands.keys(): return self._exec_cmd(cmd, arg) # otherwise pass to the interpretor return self.interp.execute(s) except: err_str = "Error executing line:\n'%s'" % s if self.debug: PrintExceptErr(err_str, print_trace=True) else: #PrintExceptErr(err_str,print_trace=False) PrintExceptErr(err_str, print_trace=True) # clear the exception and interpretors buffer # sys.exc_clear() self.interp.console.resetbuffer() return EXECERROR ############################################################# def _exec_cmd(self, cmd, arg): """ execute commands Note only call this from exec_line for proper error / exception handling! """ ret = None # local commands if cmd in self.pds_commands.keys(): fun = self.pds_commands[cmd] ret = fun(arg) # other commands elif cmd in self.commands.keys(): cmd_fun = self.commands[cmd] s = cmd_fun + ' ' + arg s = command2expr(s, symtable=self.interp.symbol_table) if self.debug: print '**command repacked: ', s ret = self.interp.execute(s) else: print "Error: uknown command: %s" % cmd #if ret == None: if ret not in (QUIT, SUCCESS, COMPLETE, CONTINUE, EXECERROR): return COMPLETE else: return ret ############################################################# ############################################################# ## Builtin commands ############################################################# ############################################################# def do_quit(self, arg): """ Quit the shell """ try: self.close_pyplot() except: pass return QUIT ############################################################# def do_debug(self, arg): """ Toggle debug flag """ if self.debug == True: print "Debug off" self.debug = False else: print "Debug on" self.debug = True return SUCCESS ############################################################# def do_load(self, fname): """ Load file of pds commands for execution Note that file execution will halt if there is an error in the file. This default behaviour can be changed by setting the flag self.error_break = False If the file has a '.sav' extension we first try to read it using restore (ie assume its a pickle) """ if fname[-4:] == '.sav': if self._restore(fname) == 1: return COMPLETE if os.path.exists(fname) and os.path.isfile(fname): f = open(fname) lines = f.readlines() f.close() else: print 'File error: cannot find file to load for %s ' % fname return COMPLETE if len(lines) == 0: return COMPLETE # execute the lines through the queue self.queue = [] self.queue.extend(lines) ret = self.exec_queue() if ret == EXECERROR: print "Error in file %s" % fname if self.debug: print 'load done' return COMPLETE ############################################################# def do_execfile(self, fname): """ Execute a file of python code Note that the file will be executed as if it was imported into the '__main__' namespace """ if not os.path.exists(fname): files = [] for p in sys.path: f = os.path.join(p, fname) if os.path.exists(f): files.append(f) if len(files) == 0: print "File '%s' not found" % fname return SUCCESS elif len(files) == 1: fname = files[0] else: print "Warning multiple files found on path" print "Please specify the full path in fname or change the" print "working directory to the directory with the correct file" for f in files: print " %s" % f return SUCCESS return self.interp.execute_file(fname) ############################################################# def do_addcmd(self, *arg): """ Add a command interface to a function Allows a function to be called with command syntax. >>addcmd mycmd, myfun results in >>mycmd arg1, arg2, key=xx being repackaged to >>myfun(arg1,arg2,key=xx) which is then sent to the interpretor """ if len(arg) == 1: arg = arg[0] words = arg.split(',') if len(words) != 2: print "Error parsing cmd/func names" cmd_name = words[0].strip() func_name = words[1].strip() elif len(arg) == 2: cmd_name = arg[0].strip() func_name = arg[1].strip() else: print "Wrong number of arguments" return SUCCESS cmd_name = trimstring(cmd_name) func_name = trimstring(func_name) if len(cmd_name) == 0 or len(func_name) == 0: print "Error parsing cmd/func names" return SUCCESS # do a check if cmd_name in PYTHON_KEY_WORDS: print "Error: command '%s' is a python keyword" % cmd_name return SUCCESS if cmd_name in self.pds_commands.keys(): print "Error: command '%s' is a builtin keyword" % cmd_name return SUCCESS if cmd_name in self.commands.keys(): print "Warning: overwriting command '%s' " % cmd_name self.commands[cmd_name] = func_name else: self.commands.update({cmd_name: func_name}) return SUCCESS ############################################################# def do_addalias(self, *arg): """ Create a command shortcut for a function. The alias is just a way of making shortcuts for repetitive taks >>alias myalias, 'myfun(args)' results in >>myalias being repackaged to >>myfun(args) which is then sent to the interpretor Note alias's are added to the command list (see 'show' and 'help addcmd') Example: -------- pds>alias "code", "cd('~/code')" pds>code pds>pwd /home/bob/code """ if len(arg) == 1: arg = arg[0] words = arg.split(',') if len(words) != 2: print "Error parsing cmd/func names" cmd_name = words[0].strip() func_name = words[1].strip() elif len(arg) == 2: cmd_name = arg[0].strip() func_name = arg[1].strip() else: print "Wrong number of arguments" return SUCCESS cmd_name = trimstring(cmd_name) func_name = trimstring(func_name) if len(cmd_name) == 0 or len(func_name) == 0: print "Error parsing cmd/func names" return SUCCESS # do a check if cmd_name in PYTHON_KEY_WORDS: print "Error: command '%s' is a python keyword" % cmd_name return SUCCESS s = "__%s__ = lambda : %s" % (cmd_name, func_name) ret = self.exec_line(s) s = "addcmd '%s', '__%s__'" % (cmd_name, cmd_name) ret = self.exec_line(s) ############################################################## ############################################################## ## save / restore state and clear variables ############################################################## ############################################################## def do_save(self, args): """ Save program state to a file Note this may fail since not all objects can be pickled... needs improvement! Examples: --------- >>save # save all to default fname >>save fname # save all to fname >>save data fname # save data to file """ from pds.shellutil import pickle_1 as pickle #from pds.shellutil import pickle_2 as pickle # parse input, get filename args = split_args(args) dname = None if len(args) == 0: t = time.strftime("%Y_%m_%d_%H%M", time.localtime()) fname = 'save_%s.sav' % t else: if len(args) == 1: fname = args[0] elif len(args) == 2: dname = args[0] fname = args[1] else: return # get data dictionary data = self.interp.symbol_table.get_data_dict(name=dname) if data == None: return SUCCESS # pickle it pickle(data, fname) ############################################################## def do_restore(self, fname): """ Restore state from a file that was created with save """ self._restore(fname) return SUCCESS def _restore(self, fname): from pds.shellutil import unpickle_1 as unpickle #from pds.shellutil import unpickle_2 as unpickle pdata = unpickle(fname) if pdata == None: print "No data" return 0 if len(pdata) > 0: self.interp.symbol_table.put_data_dict(pdata) return 1 return 0 ############################################################## def do_clear(self, arg): """ Clear all 'data' from the workspace This clears everything that looks like a variable, ie simple data types and class instances """ args = split_args(arg) if len(args) == 0: dname = [None] else: dname = args for d in dname: data = self.interp.symbol_table.get_data_dict(name=d) for key in data.keys(): del self.interp.symbol_table.data[key] return SUCCESS ############################################################## ############################################################# ## Help and Show ############################################################# ############################################################## def do_help(self, arg): """ Display help. Example: -------- >>help # displays help options """ if arg == None or len(arg) == 0: #print self.help_str print HELP_STR return SUCCESS (opts, args) = getopt.getopt(arg.split(), "u", ["use"]) for key, val in opts: if key in ("-u", "--use"): #print self.help_use_str print HELP_USE_STR for a in args: if a in self.pds_commands.keys(): #tmp = getattr(self,a) tmp = self.pds_commands[a] help(tmp) elif a in self.commands.keys(): cmd_fun = self.commands[a] s = "help(%s)" % cmd_fun ret = self.exec_line(s) else: s = "help(%s)" % a ret = self.exec_line(s) return SUCCESS ############################################################# def do_show(self, arg): """ List functions and variables. Options: >>show -ath group -------- -a = show all (include symbols with names that have a leading '_' ) -b = show builtins (defined in __builtins__ ). Note this option trumps tunnel (ie -t is ignored). -t = tunnel, display attributes within a class instance or module. Note modules are only displayed with one level of tunneling (ie -t option is ignored if a module is passed as an argument). However, this will tunnel on all class instances. """ tunnel = False skip = True (opts, args) = getopt.getopt(arg.split(), "abt", ["all", "builtins", "tunnel"]) for key, val in opts: if key in ("-a", "--all"): skip = False if key in ("-b", "--builtin"): self._show_builtins(_skip=skip) return if key in ("-t", "--tunnel"): tunnel = True if len(args) > 0: #arg = ' '.join(args) for a in args: self._show(symbol=a, tunnel=tunnel, _skip=skip) else: self._show(tunnel=tunnel, _skip=skip) return SUCCESS ############################################################# def _show_builtins(self, _skip=True): """ """ print "\n***** Builtins ******" # show python keywords print "\n==== Python Key Words ====" print show_list(PYTHON_KEY_WORDS, textwidth=TEXT_WIDTH) # get builtins d = self.interp.symbol_table.list_builtins(_skip=_skip) self._print_show(d) return SUCCESS ############################################################# def _show(self, symbol=None, tunnel=False, _skip=True): """ """ if symbol: ty = self.interp.symbol_table.sym_type(symbol) if ty == None: print "Symbol '%s' not found" % symbol return SUCCESS elif ty in ('oth'): print "Symbol '%s' of uknown type" % symbol print type(self.interp.symbol_table.get_symbol(symbol)) return SUCCESS else: ty = None print "\n==== Commands ====" tmp = self.commands.keys() tmp = tmp + self.pds_commands.keys() tmp.sort() print show_list(tmp, textwidth=TEXT_WIDTH) if ty == 'var': tmp = self.interp.symbol_table.get_symbol(symbol) print repr(tmp) return SUCCESS elif ty == 'fnc': tmp = self.interp.symbol_table.get_symbol(symbol) print help(tmp) return SUCCESS else: d = self.interp.symbol_table.list_symbols(symbol=symbol, tunnel=tunnel, _skip=_skip) self._print_show(d) return SUCCESS ############################################################# def _print_show(self, d): """ Print stuff """ if d == None: return SUCCESS if len(d['mod']) > 0: print "\n==== Modules ====" print show_list(d['mod'], textwidth=TEXT_WIDTH) if len(d['fnc']) > 0: print "\n==== Functions / Classes ====" print show_list(d['fnc'], textwidth=TEXT_WIDTH) if len(d['ins']) > 0: print "\n==== Instances ====" print show_list(d['ins'], textwidth=TEXT_WIDTH) if len(d['var']) > 0: print "\n==== Variables ====" print show_list(d['var'], textwidth=TEXT_WIDTH) if len(d['oth']) > 0: print "\n==== Other Python Objects ====" print show_list(d['oth'], textwidth=TEXT_WIDTH) print "\n" return SUCCESS