PyXR

c:\python24\lib \ idlelib \ run.py



0001 import sys
0002 import os
0003 import linecache
0004 import time
0005 import socket
0006 import traceback
0007 import thread
0008 import threading
0009 import Queue
0010 
0011 import CallTips
0012 import RemoteDebugger
0013 import RemoteObjectBrowser
0014 import StackViewer
0015 import rpc
0016 
0017 import __main__
0018 
0019 LOCALHOST = '127.0.0.1'
0020 
0021 try:
0022     import warnings
0023 except ImportError:
0024     pass
0025 else:
0026     def idle_formatwarning_subproc(message, category, filename, lineno):
0027         """Format warnings the IDLE way"""
0028         s = "\nWarning (from warnings module):\n"
0029         s += '  File \"%s\", line %s\n' % (filename, lineno)
0030         line = linecache.getline(filename, lineno).strip()
0031         if line:
0032             s += "    %s\n" % line
0033         s += "%s: %s\n" % (category.__name__, message)
0034         return s
0035     warnings.formatwarning = idle_formatwarning_subproc
0036 
0037 # Thread shared globals: Establish a queue between a subthread (which handles
0038 # the socket) and the main thread (which runs user code), plus global
0039 # completion and exit flags:
0040 
0041 exit_now = False
0042 quitting = False
0043 
0044 def main(del_exitfunc=False):
0045     """Start the Python execution server in a subprocess
0046 
0047     In the Python subprocess, RPCServer is instantiated with handlerclass
0048     MyHandler, which inherits register/unregister methods from RPCHandler via
0049     the mix-in class SocketIO.
0050 
0051     When the RPCServer 'server' is instantiated, the TCPServer initialization
0052     creates an instance of run.MyHandler and calls its handle() method.
0053     handle() instantiates a run.Executive object, passing it a reference to the
0054     MyHandler object.  That reference is saved as attribute rpchandler of the
0055     Executive instance.  The Executive methods have access to the reference and
0056     can pass it on to entities that they command
0057     (e.g. RemoteDebugger.Debugger.start_debugger()).  The latter, in turn, can
0058     call MyHandler(SocketIO) register/unregister methods via the reference to
0059     register and unregister themselves.
0060 
0061     """
0062     global exit_now
0063     global quitting
0064     global no_exitfunc
0065     no_exitfunc = del_exitfunc
0066     port = 8833
0067     #time.sleep(15) # test subprocess not responding
0068     if sys.argv[1:]:
0069         port = int(sys.argv[1])
0070     sys.argv[:] = [""]
0071     sockthread = threading.Thread(target=manage_socket,
0072                                   name='SockThread',
0073                                   args=((LOCALHOST, port),))
0074     sockthread.setDaemon(True)
0075     sockthread.start()
0076     while 1:
0077         try:
0078             if exit_now:
0079                 try:
0080                     exit()
0081                 except KeyboardInterrupt:
0082                     # exiting but got an extra KBI? Try again!
0083                     continue
0084             try:
0085                 seq, request = rpc.request_queue.get(0)
0086             except Queue.Empty:
0087                 time.sleep(0.05)
0088                 continue
0089             method, args, kwargs = request
0090             ret = method(*args, **kwargs)
0091             rpc.response_queue.put((seq, ret))
0092         except KeyboardInterrupt:
0093             if quitting:
0094                 exit_now = True
0095             continue
0096         except SystemExit:
0097             raise
0098         except:
0099             type, value, tb = sys.exc_info()
0100             try:
0101                 print_exception()
0102                 rpc.response_queue.put((seq, None))
0103             except:
0104                 # Link didn't work, print same exception to __stderr__
0105                 traceback.print_exception(type, value, tb, file=sys.__stderr__)
0106                 exit()
0107             else:
0108                 continue
0109 
0110 def manage_socket(address):
0111     for i in range(3):
0112         time.sleep(i)
0113         try:
0114             server = MyRPCServer(address, MyHandler)
0115             break
0116         except socket.error, err:
0117             print>>sys.__stderr__,"IDLE Subprocess: socket error: "\
0118                                         + err[1] + ", retrying...."
0119     else:
0120         print>>sys.__stderr__, "IDLE Subprocess: Connection to "\
0121                                "IDLE GUI failed, exiting."
0122         show_socket_error(err, address)
0123         global exit_now
0124         exit_now = True
0125         return
0126     server.handle_request() # A single request only
0127 
0128 def show_socket_error(err, address):
0129     import Tkinter
0130     import tkMessageBox
0131     root = Tkinter.Tk()
0132     root.withdraw()
0133     if err[0] == 61: # connection refused
0134         msg = "IDLE's subprocess can't connect to %s:%d.  This may be due "\
0135               "to your personal firewall configuration.  It is safe to "\
0136               "allow this internal connection because no data is visible on "\
0137               "external ports." % address
0138         tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root)
0139     else:
0140         tkMessageBox.showerror("IDLE Subprocess Error", "Socket Error: %s" % err[1])
0141     root.destroy()
0142 
0143 def print_exception():
0144     import linecache
0145     linecache.checkcache()
0146     flush_stdout()
0147     efile = sys.stderr
0148     typ, val, tb = excinfo = sys.exc_info()
0149     sys.last_type, sys.last_value, sys.last_traceback = excinfo
0150     tbe = traceback.extract_tb(tb)
0151     print>>efile, '\nTraceback (most recent call last):'
0152     exclude = ("run.py", "rpc.py", "threading.py", "Queue.py",
0153                "RemoteDebugger.py", "bdb.py")
0154     cleanup_traceback(tbe, exclude)
0155     traceback.print_list(tbe, file=efile)
0156     lines = traceback.format_exception_only(typ, val)
0157     for line in lines:
0158         print>>efile, line,
0159 
0160 def cleanup_traceback(tb, exclude):
0161     "Remove excluded traces from beginning/end of tb; get cached lines"
0162     orig_tb = tb[:]
0163     while tb:
0164         for rpcfile in exclude:
0165             if tb[0][0].count(rpcfile):
0166                 break    # found an exclude, break for: and delete tb[0]
0167         else:
0168             break        # no excludes, have left RPC code, break while:
0169         del tb[0]
0170     while tb:
0171         for rpcfile in exclude:
0172             if tb[-1][0].count(rpcfile):
0173                 break
0174         else:
0175             break
0176         del tb[-1]
0177     if len(tb) == 0:
0178         # exception was in IDLE internals, don't prune!
0179         tb[:] = orig_tb[:]
0180         print>>sys.stderr, "** IDLE Internal Exception: "
0181     rpchandler = rpc.objecttable['exec'].rpchandler
0182     for i in range(len(tb)):
0183         fn, ln, nm, line = tb[i]
0184         if nm == '?':
0185             nm = "-toplevel-"
0186         if not line and fn.startswith("<pyshell#"):
0187             line = rpchandler.remotecall('linecache', 'getline',
0188                                               (fn, ln), {})
0189         tb[i] = fn, ln, nm, line
0190 
0191 def flush_stdout():
0192     try:
0193         if sys.stdout.softspace:
0194             sys.stdout.softspace = 0
0195             sys.stdout.write("\n")
0196     except (AttributeError, EOFError):
0197         pass
0198 
0199 def exit():
0200     """Exit subprocess, possibly after first deleting sys.exitfunc
0201 
0202     If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any
0203     sys.exitfunc will be removed before exiting.  (VPython support)
0204 
0205     """
0206     if no_exitfunc:
0207         del sys.exitfunc
0208     sys.exit(0)
0209 
0210 class MyRPCServer(rpc.RPCServer):
0211 
0212     def handle_error(self, request, client_address):
0213         """Override RPCServer method for IDLE
0214 
0215         Interrupt the MainThread and exit server if link is dropped.
0216 
0217         """
0218         try:
0219             raise
0220         except SystemExit:
0221             raise
0222         except EOFError:
0223             global exit_now
0224             exit_now = True
0225             thread.interrupt_main()
0226         except:
0227             erf = sys.__stderr__
0228             print>>erf, '\n' + '-'*40
0229             print>>erf, 'Unhandled server exception!'
0230             print>>erf, 'Thread: %s' % threading.currentThread().getName()
0231             print>>erf, 'Client Address: ', client_address
0232             print>>erf, 'Request: ', repr(request)
0233             traceback.print_exc(file=erf)
0234             print>>erf, '\n*** Unrecoverable, server exiting!'
0235             print>>erf, '-'*40
0236             exit()
0237 
0238 
0239 class MyHandler(rpc.RPCHandler):
0240 
0241     def handle(self):
0242         """Override base method"""
0243         executive = Executive(self)
0244         self.register("exec", executive)
0245         sys.stdin = self.console = self.get_remote_proxy("stdin")
0246         sys.stdout = self.get_remote_proxy("stdout")
0247         sys.stderr = self.get_remote_proxy("stderr")
0248         import IOBinding
0249         sys.stdin.encoding = sys.stdout.encoding = \
0250                              sys.stderr.encoding = IOBinding.encoding
0251         self.interp = self.get_remote_proxy("interp")
0252         rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
0253 
0254     def exithook(self):
0255         "override SocketIO method - wait for MainThread to shut us down"
0256         time.sleep(10)
0257 
0258     def EOFhook(self):
0259         "Override SocketIO method - terminate wait on callback and exit thread"
0260         global quitting
0261         quitting = True
0262         thread.interrupt_main()
0263 
0264     def decode_interrupthook(self):
0265         "interrupt awakened thread"
0266         global quitting
0267         quitting = True
0268         thread.interrupt_main()
0269 
0270 
0271 class Executive:
0272 
0273     def __init__(self, rpchandler):
0274         self.rpchandler = rpchandler
0275         self.locals = __main__.__dict__
0276         self.calltip = CallTips.CallTips()
0277 
0278     def runcode(self, code):
0279         try:
0280             self.usr_exc_info = None
0281             exec code in self.locals
0282         except:
0283             self.usr_exc_info = sys.exc_info()
0284             if quitting:
0285                 exit()
0286             # even print a user code SystemExit exception, continue
0287             print_exception()
0288             jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
0289             if jit:
0290                 self.rpchandler.interp.open_remote_stack_viewer()
0291         else:
0292             flush_stdout()
0293 
0294     def interrupt_the_server(self):
0295         thread.interrupt_main()
0296 
0297     def start_the_debugger(self, gui_adap_oid):
0298         return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
0299 
0300     def stop_the_debugger(self, idb_adap_oid):
0301         "Unregister the Idb Adapter.  Link objects and Idb then subject to GC"
0302         self.rpchandler.unregister(idb_adap_oid)
0303 
0304     def get_the_calltip(self, name):
0305         return self.calltip.fetch_tip(name)
0306 
0307     def stackviewer(self, flist_oid=None):
0308         if self.usr_exc_info:
0309             typ, val, tb = self.usr_exc_info
0310         else:
0311             return None
0312         flist = None
0313         if flist_oid is not None:
0314             flist = self.rpchandler.get_remote_proxy(flist_oid)
0315         while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
0316             tb = tb.tb_next
0317         sys.last_type = typ
0318         sys.last_value = val
0319         item = StackViewer.StackTreeItem(flist, tb)
0320         return RemoteObjectBrowser.remote_object_tree_item(item)
0321 

Generated by PyXR 0.9.4
SourceForge.net Logo