text: import sys
  import linecache
  import time
  import socket
  import traceback
  import thread
  import threading
  import Queue
  
  import CallTips
  import AutoComplete
  from utils import tb_print_list
  
  import RemoteDebugger
  import RemoteObjectBrowser
  import StackViewer
  import rpc
  
  import __main__
  
  LOCALHOST = '127.0.0.1'
  
  try:
      import warnings
  except ImportError:
      pass
  else:
      def idle_formatwarning_subproc(message, category, filename, lineno,
                                     line=None):
          """Format warnings the IDLE way"""
          s = "\nWarning (from warnings module):\n"
          s += '  File \"%s\", line %s\n' % (filename, lineno)
          if line is None:
              line = linecache.getline(filename, lineno)
          line = line.strip()
          if line:
              s += "    %s\n" % line
          s += "%s: %s\n" % (category.__name__, message)
          return s
      warnings.formatwarning = idle_formatwarning_subproc
  
  # Thread shared globals: Establish a queue between a subthread (which handles
  # the socket) and the main thread (which runs user code), plus global
  # completion, exit and interruptable (the main thread) flags:
  
  exit_now = False
  quitting = False
  interruptable = False
  
  def main(del_exitfunc=False):
      """Start the Python execution server in a subprocess
  
      In the Python subprocess, RPCServer is instantiated with handlerclass
      MyHandler, which inherits register/unregister methods from RPCHandler via
      the mix-in class SocketIO.
  
      When the RPCServer 'server' is instantiated, the TCPServer initialization
      creates an instance of run.MyHandler and calls its handle() method.
      handle() instantiates a run.Executive object, passing it a reference to the
      MyHandler object.  That reference is saved as attribute rpchandler of the
      Executive instance.  The Executive methods have access to the reference and
      can pass it on to entities that they command
      (e.g. RemoteDebugger.Debugger.start_debugger()).  The latter, in turn, can
      call MyHandler(SocketIO) register/unregister methods via the reference to
      register and unregister themselves.
  
      """
      global exit_now
      global quitting
      global no_exitfunc
      no_exitfunc = del_exitfunc
      #time.sleep(15) # test subprocess not responding
      try:
          assert(len(sys.argv) > 1)
          port = int(sys.argv[-1])
      except:
          print>>sys.stderr, "IDLE Subprocess: no IP port passed in sys.argv."
          return
      sys.argv[:] = [""]
      sockthread = threading.Thread(target=manage_socket,
                                    name='SockThread',
                                    args=((LOCALHOST, port),))
      sockthread.setDaemon(True)
      sockthread.start()
      while 1:
          try:
              if exit_now:
                  try:
                      exit()
                  except KeyboardInterrupt:
                      # exiting but got an extra KBI? Try again!
                      continue
              try:
                  seq, request = rpc.request_queue.get(block=True, timeout=0.05)
              except Queue.Empty:
                  continue
              method, args, kwargs = request
              ret = method(*args, **kwargs)
              rpc.response_queue.put((seq, ret))
          except KeyboardInterrupt:
              if quitting:
                  exit_now = True
              continue
          except SystemExit:
              raise
          except:
              type, value, tb = sys.exc_info()
              try:
                  print_exception()
                  rpc.response_queue.put((seq, None))
              except:
                  # Link didn't work, print same exception to __stderr__
                  traceback.print_exception(type, value, tb, file=sys.__stderr__)
                  exit()
              else:
                  continue
  
  def manage_socket(address):
      for i in range(3):
          time.sleep(i)
          try:
              server = MyRPCServer(address, MyHandler)
              break
          except socket.error, err:
              print>>sys.__stderr__,"IDLE Subprocess: socket error: "\
                                          + err[1] + ", retrying...."
      else:
          print>>sys.__stderr__, "IDLE Subprocess: Connection to "\
                                 "IDLE GUI failed, exiting."
          show_socket_error(err, address)
          global exit_now
          exit_now = True
          return
      server.handle_request() # A single request only
  
  def show_socket_error(err, address):
      import Tkinter
      import tkMessageBox
      root = Tkinter.Tk()
      root.withdraw()
      if err[0] == 61: # connection refused
          msg = "IDLE's subprocess can't connect to %s:%d.  This may be due "\
                "to your personal firewall configuration.  It is safe to "\
                "allow this internal connection because no data is visible on "\
                "external ports." % address
          tkMessageBox.showerror("IDLE Subprocess Error", msg, parent=root)
      else:
          tkMessageBox.showerror("IDLE Subprocess Error", "Socket Error: %s" % err[1])
      root.destroy()
  
  def print_exception(temp_filename=None):
      import linecache
      linecache.checkcache()
      flush_stdout()
      efile = sys.stderr
      typ, val, tb = excinfo = sys.exc_info()
      sys.last_type, sys.last_value, sys.last_traceback = excinfo
      tbe = traceback.extract_tb(tb)
      print>>efile, '\nTraceback (most recent call last):'
      exclude = ("run.py", "rpc.py", "threading.py", "Queue.py",
                 "RemoteDebugger.py", "bdb.py")
      cleanup_traceback(tbe, exclude)
      if temp_filename is not None:
          # Replace the name of the temporary file by 'Untitled'
          main_fname = 'Untitled'
          new_tbe = []
          for t in tbe:
              fname = main_fname if t[0] == temp_filename else t[0]
              new_tbe.append((fname, ) + t[1:])
          tbe = new_tbe
      else:
          main_fname = tbe[0][0]
      tb_print_list(tbe, main_fname, sys.stdout, efile)
      lines = traceback.format_exception_only(typ, val)
      for line in lines:
          print>>efile, line,
  
  def cleanup_traceback(tb, exclude):
      "Remove excluded traces from beginning/end of tb; get cached lines"
      orig_tb = tb[:]
      while tb:
          for rpcfile in exclude:
              if tb[0][0].count(rpcfile):
                  break    # found an exclude, break for: and delete tb[0]
          else:
              break        # no excludes, have left RPC code, break while:
          del tb[0]
      while tb:
          for rpcfile in exclude:
              if tb[-1][0].count(rpcfile):
                  break
          else:
              break
          del tb[-1]
      if len(tb) == 0:
          # exception was in IDLE internals, don't prune!
          tb[:] = orig_tb[:]
          print>>sys.stderr, "** IDLE Internal Exception: "
      rpchandler = rpc.objecttable['exec'].rpchandler
      for i in range(len(tb)):
          fn, ln, nm, line = tb[i]
          if nm == '?':
              nm = "-toplevel-"
          if not line and fn.startswith("<pyshell#"):
              line = rpchandler.remotecall('linecache', 'getline',
                                                (fn, ln), {})
          tb[i] = fn, ln, nm, line
  
  def flush_stdout():
      try:
          if sys.stdout.softspace:
              sys.stdout.softspace = 0
              sys.stdout.write("\n")
      except (AttributeError, EOFError):
          pass
  
  def exit():
      """Exit subprocess, possibly after first deleting sys.exitfunc
  
      If config-main.cfg/.def 'General' 'delete-exitfunc' is True, then any
      sys.exitfunc will be removed before exiting.  (VPython support)
  
      """
      if no_exitfunc:
          try:
              del sys.exitfunc
          except AttributeError:
              pass
      sys.exit(0)
  
  class MyRPCServer(rpc.RPCServer):
  
      def handle_error(self, request, client_address):
          """Override RPCServer method for IDLE
  
          Interrupt the MainThread and exit server if link is dropped.
  
          """
          global quitting
          try:
              raise
          except SystemExit:
              raise
          except EOFError:
              global exit_now
              exit_now = True
              thread.interrupt_main()
          except:
              erf = sys.__stderr__
              print>>erf, '\n' + '-'*40
              print>>erf, 'Unhandled server exception!'
              print>>erf, 'Thread: %s' % threading.currentThread().getName()
              print>>erf, 'Client Address: ', client_address
              print>>erf, 'Request: ', repr(request)
              traceback.print_exc(file=erf)
              print>>erf, '\n*** Unrecoverable, server exiting!'
              print>>erf, '-'*40
              quitting = True
              thread.interrupt_main()
  
  
  class MyHandler(rpc.RPCHandler):
  
      def handle(self):
          """Override base method"""
          executive = Executive(self)
          self.register("exec", executive)
          sys.stdin = self.console = self.get_remote_proxy("stdin")
          sys.stdout = self.get_remote_proxy("stdout")
          sys.stderr = self.get_remote_proxy("stderr")
          import IOBinding
          sys.stdin.encoding = sys.stdout.encoding = \
                               sys.stderr.encoding = IOBinding.encoding
          self.interp = self.get_remote_proxy("interp")
          rpc.RPCHandler.getresponse(self, myseq=None, wait=0.05)
  
      def exithook(self):
          "override SocketIO method - wait for MainThread to shut us down"
          time.sleep(10)
  
      def EOFhook(self):
          "Override SocketIO method - terminate wait on callback and exit thread"
          global quitting
          quitting = True
          thread.interrupt_main()
  
      def decode_interrupthook(self):
          "interrupt awakened thread"
          global quitting
          quitting = True
          thread.interrupt_main()
  
  
  class Executive(object):
  
      def __init__(self, rpchandler):
          self.rpchandler = rpchandler
          self.locals = __main__.__dict__
          self.calltip = CallTips.CallTips()
          self.autocomplete = AutoComplete.AutoComplete()
  
      def runcode(self, code, temp_filename=None):
          global interruptable
          try:
              self.usr_exc_info = None
              interruptable = True
              try:
                  exec code in self.locals
              finally:
                  interruptable = False
          except:
              self.usr_exc_info = sys.exc_info()
              if quitting:
                  exit()
              # even print a user code SystemExit exception, continue
              print_exception(temp_filename)
              jit = self.rpchandler.console.getvar("<<toggle-jit-stack-viewer>>")
              if jit:
                  self.rpchandler.interp.open_remote_stack_viewer()
          else:
              if hasattr(sys,'exitfunc') and sys.exitfunc:
                  sys.exitfunc()
  
              flush_stdout()
  
      def interrupt_the_server(self):
          if interruptable:
              thread.interrupt_main()
  
      def start_the_debugger(self, gui_adap_oid):
          return RemoteDebugger.start_debugger(self.rpchandler, gui_adap_oid)
  
      def stop_the_debugger(self, idb_adap_oid):
          "Unregister the Idb Adapter.  Link objects and Idb then subject to GC"
          self.rpchandler.unregister(idb_adap_oid)
  
      def get_the_calltip(self, name):
          return self.calltip.fetch_tip(name)
  
      def get_the_completion_list(self, what, mode):
          return self.autocomplete.fetch_completions(what, mode)
  
      def stackviewer(self, flist_oid=None):
          if self.usr_exc_info:
              typ, val, tb = self.usr_exc_info
          else:
              return None
          flist = None
          if flist_oid is not None:
              flist = self.rpchandler.get_remote_proxy(flist_oid)
          while tb and tb.tb_frame.f_globals["__name__"] in ["rpc", "run"]:
              tb = tb.tb_next
          sys.last_type = typ
          sys.last_value = val
          item = StackViewer.StackTreeItem(flist, tb)
          return RemoteObjectBrowser.remote_object_tree_item(item)
  