| """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 |
| |