| """Remote | 
 |      This module is imported by the loader and serves to control | 
 |      the execution of the user program.  It presently executes files | 
 |      and reports exceptions to IDLE.  It could be extended to provide | 
 |      other services, such as interactive mode and debugging.  To that | 
 |      end, it could be a subclass of e.g. InteractiveInterpreter. | 
 |  | 
 |      Two other classes, pseudoIn and pseudoOut, are file emulators also | 
 |      used by loader. | 
 | """ | 
 | import sys, os | 
 | import traceback | 
 |  | 
 | class Remote:     | 
 |     def __init__(self, main, master): | 
 |         self.main = main | 
 |         self.master = master | 
 |         self.this_file = self.canonic( self.__init__.im_func.func_code.co_filename ) | 
 |  | 
 |     def canonic(self, path): | 
 |         return os.path.normcase(os.path.abspath(path)) | 
 |  | 
 |     def mainloop(self): | 
 |         while 1: | 
 |             args = self.master.get_command() | 
 |  | 
 |             try: | 
 |                 f = getattr(self,args[0]) | 
 |                 apply(f,args[1:]) | 
 |             except: | 
 |                 if not self.report_exception(): raise | 
 |  | 
 |     def finish(self): | 
 |         sys.exit() | 
 |  | 
 |     def run(self, *argv): | 
 |         sys.argv = argv | 
 |  | 
 |         path = self.canonic( argv[0] ) | 
 |         dir = self.dir = os.path.dirname(path) | 
 |         os.chdir(dir) | 
 |  | 
 |         sys.path[0] = dir | 
 |  | 
 |         usercode = open(path) | 
 |         exec usercode in self.main | 
 |  | 
 |     def report_exception(self): | 
 |         try: | 
 |             type, value, tb = sys.exc_info() | 
 |             sys.last_type = type | 
 |             sys.last_value = value | 
 |             sys.last_traceback = tb | 
 |  | 
 |             tblist = traceback.extract_tb(tb) | 
 |  | 
 |             # Look through the traceback, canonicalizing filenames and | 
 |             #   eliminating leading and trailing system modules. | 
 |             first = last = 1 | 
 |             for i in range(len(tblist)): | 
 |                 filename, lineno, name, line = tblist[i] | 
 |                 filename = self.canonic(filename) | 
 |                 tblist[i] = filename, lineno, name, line | 
 |  | 
 |                 dir = os.path.dirname(filename) | 
 |                 if filename == self.this_file: | 
 |                     first = i+1 | 
 |                 elif dir==self.dir: | 
 |                     last = i+1 | 
 |  | 
 |             # Canonicalize the filename in a syntax error, too: | 
 |             if type is SyntaxError: | 
 |                 try: | 
 |                     msg, (filename, lineno, offset, line) = value | 
 |                     filename = self.canonic(filename) | 
 |                     value = msg, (filename, lineno, offset, line) | 
 |                 except: | 
 |                     pass | 
 |  | 
 |             return self.master.program_exception( type, value, tblist, first, last ) | 
 |         finally: | 
 |             # avoid any circular reference through the traceback | 
 |             del tb | 
 |  | 
 | class pseudoIn: | 
 |     def __init__(self, readline): | 
 |         self.readline = readline | 
 |     def isatty(): | 
 |         return 1 | 
 |  | 
 | class pseudoOut: | 
 |     def __init__(self, func, **kw): | 
 |         self.func = func | 
 |         self.kw = kw | 
 |     def write(self, *args): | 
 |         return apply( self.func, args, self.kw ) | 
 |     def writelines(self, l): | 
 |         map(self.write, l) | 
 |     def flush(self): | 
 |         pass | 
 |  |