home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 July / maximum-cd-2011-07.iso / DiscContents / LibO_3.3.2_Win_x86_install_multi.exe / libreoffice1.cab / run.py < prev    next >
Encoding:
Python Source  |  2011-03-15  |  10.9 KB  |  339 lines

  1. import sys
  2. import linecache
  3. import time
  4. import socket
  5. import traceback
  6. import thread
  7. import threading
  8. import Queue
  9.  
  10. import CallTips
  11. import AutoComplete
  12.  
  13. import RemoteDebugger
  14. import RemoteObjectBrowser
  15. import StackViewer
  16. import rpc
  17.  
  18. import __main__
  19.  
  20. LOCALHOST = '127.0.0.1'
  21.  
  22. try:
  23.     import warnings
  24. except ImportError:
  25.     pass
  26. else:
  27.     def idle_formatwarning_subproc(message, category, filename, lineno,
  28.                                    file=None, line=None):
  29.         """Format warnings the IDLE way"""
  30.         s = "\nWarning (from warnings module):\n"
  31.         s += '  File \"%s\", line %s\n' % (filename, lineno)
  32.         line = linecache.getline(filename, lineno).strip() \
  33.             if line is None else line
  34.         if line:
  35.             s += "    %s\n" % line
  36.         s += "%s: %s\n" % (category.__name__, message)
  37.         return s
  38.     warnings.formatwarning = idle_formatwarning_subproc
  39.  
  40. # Thread shared globals: Establish a queue between a subthread (which handles
  41. # the socket) and the main thread (which runs user code), plus global
  42. # completion, exit and interruptable (the main thread) flags:
  43.  
  44. exit_now = False
  45. quitting = False
  46. interruptable = False
  47.  
  48. def main(del_exitfunc=False):
  49.     """Start the Python execution server in a subprocess
  50.  
  51.     In the Python subprocess, RPCServer is instantiated with handlerclass
  52.     MyHandler, which inherits register/unregister methods from RPCHandler via
  53.     the mix-in class SocketIO.
  54.  
  55.     When the RPCServer 'server' is instantiated, the TCPServer initialization
  56.     creates an instance of run.MyHandler and calls its handle() method.
  57.     handle() instantiates a run.Executive object, passing it a reference to the
  58.     MyHandler object.  That reference is saved as attribute rpchandler of the
  59.     Executive instance.  The Executive methods have access to the reference and
  60.     can pass it on to entities that they command
  61.     (e.g. RemoteDebugger.Debugger.start_debugger()).  The latter, in turn, can
  62.     call MyHandler(SocketIO) register/unregister methods via the reference to
  63.     register and unregister themselves.
  64.  
  65.     """
  66.     global exit_now
  67.     global quitting
  68.     global no_exitfunc
  69.     no_exitfunc = del_exitfunc
  70.     port = 8833
  71.     #time.sleep(15) # test subprocess not responding
  72.     if sys.argv[1:]:
  73.         port = int(sys.argv[1])
  74.     sys.argv[:] = [""]
  75.     sockthread = threading.Thread(target=manage_socket,
  76.                                   name='SockThread',
  77.                                   args=((LOCALHOST, port),))
  78.     sockthread.setDaemon(True)
  79.     sockthread.start()
  80.     while 1:
  81.         try:
  82.             if exit_now:
  83.                 try:
  84.                     exit()
  85.                 except KeyboardInterrupt:
  86.                     # exiting but got an extra KBI? Try again!
  87.                     continue
  88.             try:
  89.                 seq, request = rpc.request_queue.get(block=True, timeout=0.05)
  90.             except Queue.Empty:
  91.                 continue
  92.             method, args, kwargs = request
  93.             ret = method(*args, **kwargs)
  94.             rpc.response_queue.put((seq, ret))
  95.         except KeyboardInterrupt:
  96.             if quitting:
  97.                 exit_now = True
  98.             continue
  99.         except SystemExit:
  100.             raise
  101.         except:
  102.             type, value, tb = sys.exc_info()
  103.             try:
  104.                 print_exception()
  105.                 rpc.response_queue.put((seq, None))
  106.             except:
  107.                 # Link didn't work, print same exception to __stderr__
  108.                 traceback.print_exception(type, value, tb, file=sys.__stderr__)
  109.                 exit()
  110.             else:
  111.                 continue
  112.  
  113. def manage_socket(address):
  114.     for i in range(3):
  115.         time.sleep(i)
  116.         try:
  117.             server = MyRPCServer(address, MyHandler)
  118.             break
  119.         except socket.error, err:
  120.             print>>sys.__stderr__,"IDLE Subprocess: socket error: "\
  121.                                         + err[1] + ", retrying...."
  122.     else:
  123.         print>>sys.__stderr__, "IDLE Subprocess: Connection to "\
  124.                                "IDLE GUI failed, exiting."
  125.         show_socket_error(err, address)
  126.         global exit_now
  127.         exit_now = True
  128.         return
  129.     server.handle_request() # A single request only
  130.  
  131. def show_socket_error(err, address):
  132.     import Tkinter
  133.     import tkMessageBox
  134.     root = Tkinter.Tk()
  135.     root.withdraw()
  136.     if err[0] == 61: # connection refused
  137.         msg = "IDLE's subprocess can't connect to %s:%d.  This may be due "\
  138.               "to your personal firewall configuration.  It is safe to "\
  139.               "allow this internal connection because no data is visible on "\
  140.               "external ports." % address
  141.         tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root)
  142.     else:
  143.         tkMessageBox.showerror("IDLE Subprocess Error", "Socket Error: %s" % err[1])
  144.     root.destroy()
  145.  
  146. def print_exception():
  147.     import linecache
  148.     linecache.checkcache()
  149.     flush_stdout()
  150.     efile = sys.stderr
  151.     typ, val, tb = excinfo = sys.exc_info()
  152.     sys.last_type, sys.last_value, sys.last_traceback = excinfo
  153.     tbe = traceback.extract_tb(tb)
  154.     print>>efile, '\nTraceback (most recent call last):'
  155.     exclude = ("run.py", "rpc.py", "threading.py", "Queue.py",
  156.                "RemoteDebugger.py", "bdb.py")
  157.     cleanup_traceback(tbe, exclude)
  158.     traceback.print_list(tbe, file=efile)
  159.     lines = traceback.format_exception_only(typ, val)
  160.     for line in lines:
  161.         print>>efile, line,
  162.  
  163. def cleanup_traceback(tb, exclude):
  164.     "Remove excluded traces from beginning/end of tb; get cached lines"
  165.     orig_tb = tb[:]
  166.     while tb:
  167.         for rpcfile in exclude:
  168.             if tb[0][0].count(rpcfile):
  169.                 break    # found an exclude, break for: and delete tb[0]
  170.         else:
  171.             break        # no excludes, have left RPC code, break while:
  172.         del tb[0]
  173.     while tb:
  174.         for rpcfile in exclude:
  175.             if tb[-1][0].count(rpcfile):
  176.                 break
  177.         else:
  178.             break
  179.         del tb[-1]
  180.     if len(tb) == 0:
  181.         # exception was in IDLE internals, don't prune!
  182.         tb[:] = orig_tb[:]
  183.         print>>sys.stderr, "** IDLE Internal Exception: "
  184.     rpchandler = rpc.objecttable['exec'].rpchandler
  185.     for i in range(len(tb)):
  186.         fn, ln, nm, line = tb[i]
  187.         if nm == '?':
  188.             nm = "-toplevel-"
  189.         if not line and fn.startswith("<pyshell#"):
  190.             line = rpchandler.remotecall('linecache', 'getline',
  191.                                               (fn, ln), {})
  192.         tb[i] = fn, ln, nm, line
  193.  
  194. def flush_stdout():
  195.     try:
  196.         if sys.stdout.softspace:
  197.             sys.stdout.softspace = 0
  198.             sys.stdout.write("\n")
  199.     except (AttributeError, EOFError):
  200.         pass
  201.  
  202. def exit():
  203.     """Exit subprocess, possibly after first deleting sys.exitfunc
  204.  
  205.     If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any
  206.     sys.exitfunc will be removed before exiting.  (VPython support)
  207.  
  208.     """
  209.     if no_exitfunc:
  210.         try:
  211.             del sys.exitfunc
  212.         except AttributeError:
  213.             pass
  214.     sys.exit(0)
  215.  
  216. class MyRPCServer(rpc.RPCServer):
  217.  
  218.     def handle_error(self, request, client_address):
  219.         """Override RPCServer method for IDLE
  220.  
  221.         Interrupt the MainThread and exit server if link is dropped.
  222.  
  223.         """
  224.         global quitting
  225.         try:
  226.             raise
  227.         except SystemExit:
  228.             raise
  229.         except EOFError:
  230.             global exit_now
  231.             exit_now = True
  232.             thread.interrupt_main()
  233.         except:
  234.             erf = sys.__stderr__
  235.             print>>erf, '\n' + '-'*40
  236.             print>>erf, 'Unhandled server exception!'
  237.             print>>erf, 'Thread: %s' % threading.currentThread().getName()
  238.             print>>erf, 'Client Address: ', client_address
  239.             print>>erf, 'Request: ', repr(request)
  240.             traceback.print_exc(file=erf)
  241.             print>>erf, '\n*** Unrecoverable, server exiting!'
  242.             print>>erf, '-'*40
  243.             quitting = True
  244.             thread.interrupt_main()
  245.  
  246.  
  247. class MyHandler(rpc.RPCHandler):
  248.  
  249.     def handle(self):
  250.         """Override base method"""
  251.         executive = Executive(self)
  252.         self.register("exec", executive)
  253.         sys.stdin = self.console = self.get_remote_proxy("stdin")
  254.         sys.stdout = self.get_remote_proxy("stdout")
  255.         sys.stderr = self.get_remote_proxy("stderr")
  256.         import IOBinding
  257.         sys.stdin.encoding = sys.stdout.encoding = \
  258.                              sys.stderr.encoding = IOBinding.encoding
  259.         self.interp = self.get_remote_proxy("interp")
  260.         rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
  261.  
  262.     def exithook(self):
  263.         "override SocketIO method - wait for MainThread to shut us down"
  264.         time.sleep(10)
  265.  
  266.     def EOFhook(self):
  267.         "Override SocketIO method - terminate wait on callback and exit thread"
  268.         global quitting
  269.         quitting = True
  270.         thread.interrupt_main()
  271.  
  272.     def decode_interrupthook(self):
  273.         "interrupt awakened thread"
  274.         global quitting
  275.         quitting = True
  276.         thread.interrupt_main()
  277.  
  278.  
  279. class Executive(object):
  280.  
  281.     def __init__(self, rpchandler):
  282.         self.rpchandler = rpchandler
  283.         self.locals = __main__.__dict__
  284.         self.calltip = CallTips.CallTips()
  285.         self.autocomplete = AutoComplete.AutoComplete()
  286.  
  287.     def runcode(self, code):
  288.         global interruptable
  289.         try:
  290.             self.usr_exc_info = None
  291.             interruptable = True
  292.             try:
  293.                 exec code in self.locals
  294.             finally:
  295.                 interruptable = False
  296.         except:
  297.             self.usr_exc_info = sys.exc_info()
  298.             if quitting:
  299.                 exit()
  300.             # even print a user code SystemExit exception, continue
  301.             print_exception()
  302.             jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
  303.             if jit:
  304.                 self.rpchandler.interp.open_remote_stack_viewer()
  305.         else:
  306.             flush_stdout()
  307.  
  308.     def interrupt_the_server(self):
  309.         if interruptable:
  310.             thread.interrupt_main()
  311.  
  312.     def start_the_debugger(self, gui_adap_oid):
  313.         return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
  314.  
  315.     def stop_the_debugger(self, idb_adap_oid):
  316.         "Unregister the Idb Adapter.  Link objects and Idb then subject to GC"
  317.         self.rpchandler.unregister(idb_adap_oid)
  318.  
  319.     def get_the_calltip(self, name):
  320.         return self.calltip.fetch_tip(name)
  321.  
  322.     def get_the_completion_list(self, what, mode):
  323.         return self.autocomplete.fetch_completions(what, mode)
  324.  
  325.     def stackviewer(self, flist_oid=None):
  326.         if self.usr_exc_info:
  327.             typ, val, tb = self.usr_exc_info
  328.         else:
  329.             return None
  330.         flist = None
  331.         if flist_oid is not None:
  332.             flist = self.rpchandler.get_remote_proxy(flist_oid)
  333.         while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
  334.             tb = tb.tb_next
  335.         sys.last_type = typ
  336.         sys.last_value = val
  337.         item = StackViewer.StackTreeItem(flist, tb)
  338.         return RemoteObjectBrowser.remote_object_tree_item(item)
  339.