mirror of
				https://github.com/python/cpython.git
				synced 2025-10-25 10:44:55 +00:00 
			
		
		
		
	
		
			
	
	
		
			102 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			102 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | """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 | ||
|  | 
 |