--- ipython-0.6.15/IPython/Shell.py	2005-05-31 12:23:20.000000000 -0600
+++ trunk/IPython/Shell.py	2006-01-02 12:40:33.000000000 -0700
@@ -4,7 +4,7 @@
 All the matplotlib support code was co-developed with John Hunter,
 matplotlib's author.
 
-$Id: Shell.py,v 1.47 2005/05/31 18:23:20 fperez Exp $"""
+$Id: Shell.py 965 2005-12-28 23:23:09Z fperez $"""
 
 #*****************************************************************************
 #       Copyright (C) 2001-2004 Fernando Perez <fperez@...76...>
@@ -20,19 +20,18 @@
 # Code begins
 import __main__
 import __builtin__
-import sys
 import os
-import code
-import threading
+import sys
 import signal
+import threading
 
 import IPython
+from IPython import ultraTB
+from IPython.genutils import Term,warn,error,flag_calls
 from IPython.iplib import InteractiveShell
 from IPython.ipmaker import make_IPython
-from IPython.genutils import Term,warn,error,flag_calls
-from IPython.Struct import Struct
 from IPython.Magic import Magic
-from IPython import ultraTB
+from IPython.Struct import Struct
 
 # global flag to pass around information about Ctrl-C without exceptions
 KBINT = False
@@ -48,10 +47,10 @@
 class IPShell:
     """Create an IPython instance."""
     
-    def __init__(self,argv=None,user_ns=None,debug=1,
-                 shell_class=InteractiveShell):
-        self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
-                               shell_class=shell_class)
+    def __init__(self,argv=None,user_ns=None,user_global_ns=None,
+                 debug=1,shell_class=InteractiveShell):
+        self.IP = make_IPython(argv,user_ns=user_ns,user_global_ns=user_global_ns,
+                               debug=debug,shell_class=shell_class)
 
     def mainloop(self,sys_exit=0,banner=None):
         self.IP.mainloop(banner)
@@ -132,10 +131,6 @@
         #self.IP = make_IPython(argv,user_ns=__main__.__dict__)
         self.IP = make_IPython(argv,rc_override=rc_override,embedded=True)
 
-        self.IP.name_space_init()
-        # mark this as an embedded instance so we know if we get a crash
-        # post-mortem
-        self.IP.rc.embedded = 1
         # copy our own displayhook also
         self.sys_displayhook_embed = sys.displayhook
         # and leave the system's display hook clean
@@ -216,8 +211,8 @@
 
         If you need to manually"""
 
-        if dummy not in [0,1]:
-            raise ValueError,'dummy parameter must be 0 or 1'
+        if dummy not in [0,1,False,True]:
+            raise ValueError,'dummy parameter must be boolean'
         self.__dummy_mode = dummy
 
     def get_dummy_mode(self):
@@ -265,11 +260,16 @@
     # McErlean and John Finlay.  Modified with corrections by Antoon Pardon,
     # from the pygtk mailing list, to avoid lockups with system calls.
 
+    # class attribute to indicate whether the class supports threads or not.
+    # Subclasses with thread support should override this as needed.
+    isthreaded = True
+
     def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
-                 user_ns = None, banner2='',**kw):
+                 user_ns=None,user_global_ns=None,banner2='',**kw):
         """Similar to the normal InteractiveShell, but with threading control"""
         
-        IPython.iplib.InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2)
+        InteractiveShell.__init__(self,name,usage,rc,user_ns,
+                                  user_global_ns,banner2)
 
         # Locking control variable
         self.thread_ready = threading.Condition()
@@ -312,7 +312,6 @@
         # Case 3
         # Store code in self, so the execution thread can handle it
         self.thread_ready.acquire()
-        self.code_to_run_src = source
         self.code_to_run = code
         self.thread_ready.wait()  # Wait until processed in timeout interval
         self.thread_ready.release()
@@ -400,15 +399,6 @@
                 self.mpl_use._called = True
         
         self.matplotlib = matplotlib
-
-        # Take control of matplotlib's error handling, which can normally
-        # lock up the python interpreter when raw_input() is called
-        import matplotlib.backends as backend
-        backend.error_msg = error
-        
-        # we'll handle the mainloop, tell show not to
-        import matplotlib.backends
-        matplotlib.backends.show._needmain = False
         self.mpl_backend = matplotlib.rcParams['backend']
 
         # we also need to block switching of interactive backends by use()
@@ -417,9 +407,6 @@
         # overwrite the original matplotlib.use with our wrapper
         matplotlib.use = use
 
-        # We need to detect at runtime whether show() is called by the user.
-        # For this, we wrap it into a decorator which adds a 'called' flag.
-        backend.draw_if_interactive = flag_calls(backend.draw_if_interactive)
 
         # This must be imported last in the matplotlib series, after
         # backend/interactivity choices have been made
@@ -432,6 +419,11 @@
             self.pylab = matlab
             self.pylab_name = 'matlab'
 
+        self.pylab.show._needmain = False
+        # We need to detect at runtime whether show() is called by the user.
+        # For this, we wrap it into a decorator which adds a 'called' flag.
+        self.pylab.draw_if_interactive = flag_calls(self.pylab.draw_if_interactive)
+
         # Build a user namespace initialized with matplotlib/matlab features.
         user_ns = {'__name__':'__main__',
                    '__builtins__' : __builtin__ }
@@ -448,7 +440,7 @@
         b="""
   Welcome to pylab, a matplotlib-based Python environment.
   For more information, type 'help(pylab)'.
-  """
+"""
         return user_ns,b
 
     def mplot_exec(self,fname,*where,**kw):
@@ -488,17 +480,19 @@
     """Single-threaded shell with matplotlib support."""
 
     def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
-                 user_ns = None, **kw):
+                 user_ns=None,user_global_ns=None,**kw):
         user_ns,b2 = self._matplotlib_config(name)
-        InteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
+        InteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
+                                  banner2=b2,**kw)
 
 class MatplotlibMTShell(MatplotlibShellBase,MTInteractiveShell):
     """Multi-threaded shell with matplotlib support."""
 
     def __init__(self,name,usage=None,rc=Struct(opts=None,args=None),
-                 user_ns = None, **kw):
+                 user_ns=None,user_global_ns=None, **kw):
         user_ns,b2 = self._matplotlib_config(name)
-        MTInteractiveShell.__init__(self,name,usage,rc,user_ns,banner2=b2,**kw)
+        MTInteractiveShell.__init__(self,name,usage,rc,user_ns,user_global_ns,
+                                    banner2=b2,**kw)
 
 #-----------------------------------------------------------------------------
 # Utility functions for the different GUI enabled IPShell* classes.
@@ -569,9 +563,6 @@
     """Modifies pyGTK's mainloop with a dummy so user code does not
     block IPython.  This function returns the original `gtk.mainloop`
     function that has been hijacked.
-
-    NOTE: Make sure you import this *AFTER* you call
-    pygtk.require(...).
     """    
     def dummy_mainloop(*args, **kw):
         pass
@@ -597,11 +588,9 @@
     
     TIMEOUT = 100 # Millisecond interval between timeouts.
 
-    def __init__(self,argv=None,user_ns=None,debug=1,
-                 shell_class=MTInteractiveShell):
+    def __init__(self,argv=None,user_ns=None,user_global_ns=None,
+                 debug=1,shell_class=MTInteractiveShell):
 
-        import pygtk
-        pygtk.require("2.0")
         import gtk
         
         self.gtk = gtk
@@ -613,18 +602,33 @@
         if gtk.pygtk_version >= (2,4,0): mainquit = self.gtk.main_quit
         else:                            mainquit = self.gtk.mainquit
 
-        self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
+        self.IP = make_IPython(argv,user_ns=user_ns,
+                               user_global_ns=user_global_ns,
+                               debug=debug,
                                shell_class=shell_class,
                                on_kill=[mainquit])
+
+        # HACK: slot for banner in self; it will be passed to the mainloop
+        # method only and .run() needs it.  The actual value will be set by
+        # .mainloop().
+        self._banner = None 
+
         threading.Thread.__init__(self)
 
     def run(self):
-        self.IP.mainloop()
+        self.IP.mainloop(self._banner)
         self.IP.kill()
 
-    def mainloop(self):
+    def mainloop(self,sys_exit=0,banner=None):
+
+        self._banner = banner
         
-        self.gtk.timeout_add(self.TIMEOUT, self.on_timer)
+        if self.gtk.pygtk_version >= (2,4,0):
+            import gobject
+            gobject.idle_add(self.on_timer)
+        else:
+            self.gtk.idle_add(self.on_timer)
+
         if sys.platform != 'win32':
             try:
                 if self.gtk.gtk_version[0] >= 2:
@@ -661,8 +665,8 @@
     
     TIMEOUT = 100 # Millisecond interval between timeouts.
 
-    def __init__(self,argv=None,user_ns=None,debug=1,
-                 shell_class=MTInteractiveShell):
+    def __init__(self,argv=None,user_ns=None,user_global_ns=None,
+                 debug=1,shell_class=MTInteractiveShell):
 
         import wxPython.wx as wx
 
@@ -673,9 +677,16 @@
         # Allows us to use both Tk and GTK.
         self.tk = get_tk()
         
-        self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
+        self.IP = make_IPython(argv,user_ns=user_ns,
+                               user_global_ns=user_global_ns,
+                               debug=debug,
                                shell_class=shell_class,
                                on_kill=[self.wxexit])
+        # HACK: slot for banner in self; it will be passed to the mainloop
+        # method only and .run() needs it.  The actual value will be set by
+        # .mainloop().
+        self._banner = None 
+
         self.app = None
 
     def wxexit(self, *args):
@@ -684,10 +695,12 @@
             self.app.ExitMainLoop()
 
     def run(self):
-        self.IP.mainloop()
+        self.IP.mainloop(self._banner)
         self.IP.kill()
 
-    def mainloop(self):
+    def mainloop(self,sys_exit=0,banner=None):
+
+        self._banner = banner
         
         self.start()
 
@@ -736,8 +749,8 @@
     
     TIMEOUT = 100 # Millisecond interval between timeouts.
 
-    def __init__(self,argv=None,user_ns=None,debug=0,
-                 shell_class=MTInteractiveShell):
+    def __init__(self,argv=None,user_ns=None,user_global_ns=None,
+                 debug=0,shell_class=MTInteractiveShell):
         
         import qt
 
@@ -759,20 +772,31 @@
         # Allows us to use both Tk and QT.
         self.tk = get_tk()
 
-        self.IP = make_IPython(argv,user_ns=user_ns,debug=debug,
+        self.IP = make_IPython(argv,user_ns=user_ns,
+                               user_global_ns=user_global_ns,
+                               debug=debug,
                                shell_class=shell_class,
                                on_kill=[qt.qApp.exit])
+
+        # HACK: slot for banner in self; it will be passed to the mainloop
+        # method only and .run() needs it.  The actual value will be set by
+        # .mainloop().
+        self._banner = None 
+        
         threading.Thread.__init__(self)
 
     def run(self):
-        self.IP.mainloop()
+        self.IP.mainloop(self._banner)
         self.IP.kill()
 
-    def mainloop(self):
+    def mainloop(self,sys_exit=0,banner=None):
+
+        import qt
+
+        self._banner = banner
 
-        import qt, sys
         if qt.QApplication.startingUp():
-          a = qt.QApplication.QApplication( sys.argv )
+          a = qt.QApplication.QApplication(sys.argv)
         self.timer = qt.QTimer()
         qt.QObject.connect( self.timer, qt.SIGNAL( 'timeout()' ), self.on_timer )
 
@@ -798,32 +822,36 @@
 
     Having this on a separate class simplifies the external driver code."""
     
-    def __init__(self,argv=None,user_ns=None,debug=1):
-        IPShell.__init__(self,argv,user_ns,debug,shell_class=MatplotlibShell)
+    def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
+        IPShell.__init__(self,argv,user_ns,user_global_ns,debug,
+                         shell_class=MatplotlibShell)
 
 class IPShellMatplotlibGTK(IPShellGTK):
     """Subclass IPShellGTK with MatplotlibMTShell as the internal shell.
 
     Multi-threaded class, meant for the GTK* backends."""
     
-    def __init__(self,argv=None,user_ns=None,debug=1):
-        IPShellGTK.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
+    def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
+        IPShellGTK.__init__(self,argv,user_ns,user_global_ns,debug,
+                            shell_class=MatplotlibMTShell)
 
 class IPShellMatplotlibWX(IPShellWX):
     """Subclass IPShellWX with MatplotlibMTShell as the internal shell.
 
     Multi-threaded class, meant for the WX* backends."""
     
-    def __init__(self,argv=None,user_ns=None,debug=1):
-        IPShellWX.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
+    def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
+        IPShellWX.__init__(self,argv,user_ns,user_global_ns,debug,
+                           shell_class=MatplotlibMTShell)
 
 class IPShellMatplotlibQt(IPShellQt):
     """Subclass IPShellQt with MatplotlibMTShell as the internal shell.
 
     Multi-threaded class, meant for the Qt* backends."""
     
-    def __init__(self,argv=None,user_ns=None,debug=1):
-        IPShellQt.__init__(self,argv,user_ns,debug,shell_class=MatplotlibMTShell)
+    def __init__(self,argv=None,user_ns=None,user_global_ns=None,debug=1):
+        IPShellQt.__init__(self,argv,user_ns,user_global_ns,debug,
+                           shell_class=MatplotlibMTShell)
 
 #-----------------------------------------------------------------------------
 # Factory functions to actually start the proper thread-aware shell
@@ -862,12 +890,13 @@
 
     global USE_TK
     # Crude sys.argv hack to extract the threading options.
-    if len(sys.argv) > 1:
-        if len(sys.argv) > 2:
-            arg2 = sys.argv[2]
+    argv = sys.argv
+    if len(argv) > 1:
+        if len(argv) > 2:
+            arg2 = argv[2]
             if arg2.endswith('-tk'):
                 USE_TK = True
-        arg1 = sys.argv[1]
+        arg1 = argv[1]
         if arg1.endswith('-gthread'):
             shell = IPShellGTK
         elif arg1.endswith( '-qthread' ):
