--- shell.py	2009-09-14 10:27:12.000000000 -0400
+++ /home/seamus/shell.py	2009-09-14 17:10:14.000000000 -0400
@@ -6,8 +6,10 @@ class Command(NoArgsCommand):
     option_list = NoArgsCommand.option_list + (
         make_option('--plain', action='store_true', dest='plain',
             help='Tells Django to use plain Python, not IPython.'),
+        make_option('--bpython', action='store_true', dest='bpython',
+            help='Tells Django to use bpython, not IPython.'),
     )
-    help = "Runs a Python interactive interpreter. Tries to use IPython, if it's available."
+    help = "Runs a Python interactive interpreter. Tries to use IPython, if it's available.  If IPython is not available, tries to use bpython. "
 
     requires_model_validation = False
 
@@ -18,42 +20,62 @@ class Command(NoArgsCommand):
         loaded_models = get_models()
 
         use_plain = options.get('plain', False)
-
+	use_bpython = options.get('bpython',False)
         try:
-            if use_plain:
-                # Don't bother loading IPython, because the user wants plain Python.
+            if use_plain or use_bpython:
+                if use_bpython:
+                    use_plain = None
                 raise ImportError
             import IPython
-            # Explicitly pass an empty list as arguments, because otherwise IPython
-            # would use sys.argv from this script.
             shell = IPython.Shell.IPShell(argv=[])
             shell.mainloop()
         except ImportError:
-            import code
-            # Set up a dictionary to serve as the environment for the shell, so
-            # that tab completion works on objects that are imported at runtime.
-            # See ticket 5082.
-            imported_objects = {}
-            try: # Try activating rlcompleter, because it's handy.
-                import readline
+            try:
+                if use_plain:
+                    raise ImportError
+                import bpython
+                # Older versions of bpython do not support embed().  When
+                # specifying the --bpython flag, an attributeError is raised
+                # telling the user to upgrade.  Otherwise, fall back to the 
+                # plain interpreter.
+                try:
+                    bpython.embed()
+                except AttributeError:
+                    if use_bpython:
+                        raise AttributeError("Your version of bpython does not support embedding.  Please upgrade to the latest version.")
+                    else:
+                        raise ImportError
             except ImportError:
-                pass
-            else:
-                # We don't have to wrap the following import in a 'try', because
-                # we already know 'readline' was imported successfully.
-                import rlcompleter
-                readline.set_completer(rlcompleter.Completer(imported_objects).complete)
-                readline.parse_and_bind("tab:complete")
+                # When specifying the --bpython flag and the import fails,
+                # do not fall back to the plain interpreter.
+		if use_bpython:
+                    raise ImportError("You do not have bpython installed")
+                import code
+                # Set up a dictionary to serve as the environment for the shell, so
+                # that tab completion works on objects that are imported at runtime.
+                # See ticket 5082.
+                imported_objects = {}
+                try: # Try activating rlcompleter, because it's handy.
+                    import readline
+                except ImportError:
+                    pass
+                else:
+                    # We don't have to wrap the following import in a 'try', because
+                    # we already know 'readline' was imported successfully.
+                    import rlcompleter
+                    readline.set_completer(rlcompleter.Completer(imported_objects).complete)
+                    readline.parse_and_bind("tab:complete")
 
-            # We want to honor both $PYTHONSTARTUP and .pythonrc.py, so follow system
-            # conventions and get $PYTHONSTARTUP first then import user.
-            if not use_plain: 
-                pythonrc = os.environ.get("PYTHONSTARTUP") 
-                if pythonrc and os.path.isfile(pythonrc): 
-                    try: 
-                        execfile(pythonrc) 
-                    except NameError: 
-                        pass
+                # We want to honor both $PYTHONSTARTUP and .pythonrc.py, so follow system
+                # conventions and get $PYTHONSTARTUP first then import user.
+                if not use_plain:
+                    pythonrc = os.environ.get("PYTHONSTARTUP")
+                    if pythonrc and os.path.isfile(pythonrc):
+                        try:
+                            execfile(pythonrc)
+                        except NameError:
+                            pass
                 # This will import .pythonrc.py as a side-effect
-                import user
-            code.interact(local=imported_objects)
+                    import user
+                code.interact(local=imported_objects)
+
