blob: facba78ce0467d38237ffe08d0dd0a3b4ab93093 [file] [log] [blame]
"""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