summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2011-11-21 22:00:39 -0500
committerChris McDonough <chrism@plope.com>2011-11-21 22:00:39 -0500
commit6f4242bed8e7418984642da4e0ff861d39195410 (patch)
tree038feedeb6583852bd1514fb1e57076738d685c7
parent8a5db43e9b7671f49e118cbb888019445df0ae14 (diff)
parent995133918877809aeea06bce93149104ba800304 (diff)
downloadpyramid-6f4242bed8e7418984642da4e0ff861d39195410.tar.gz
pyramid-6f4242bed8e7418984642da4e0ff861d39195410.tar.bz2
pyramid-6f4242bed8e7418984642da4e0ff861d39195410.zip
Merge branch 'master' of github.com:Pylons/pyramid
-rw-r--r--docs/narr/commandline.rst22
-rw-r--r--pyramid/scripts/pshell.py46
-rw-r--r--pyramid/tests/test_scripts/dummy.py9
-rw-r--r--pyramid/tests/test_scripts/test_pshell.py92
4 files changed, 143 insertions, 26 deletions
diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst
index 0dc41e919..0f0e17ca6 100644
--- a/docs/narr/commandline.rst
+++ b/docs/narr/commandline.rst
@@ -111,6 +111,7 @@ For a URL that doesn't match any views, ``pviews`` will simply print out a
single: interactive shell
single: IPython
single: pshell
+ single: bpython
.. _interactive_shell:
@@ -267,23 +268,24 @@ exposed, and the request is configured to generate urls from the host
.. index::
single: IPython
+ single: bpython
-IPython
-~~~~~~~
+IPython or bpython
+~~~~~~~~~~~~~~~~~~
-If you have `IPython <http://en.wikipedia.org/wiki/IPython>`_ installed in
-the interpreter you use to invoke the ``pshell`` command, ``pshell`` will use
-an IPython interactive shell instead of a standard Python interpreter shell.
-If you don't want this to happen, even if you have IPython installed, you can
-pass the ``--disable-ipython`` flag to the ``pshell`` command to use a
-standard Python interpreter shell unconditionally.
+If you have `IPython <http://en.wikipedia.org/wiki/IPython>`_ or
+`bpython <http://bpython-interpreter.org/>`_ or both installed in
+the interpreter you use to invoke the ``pshell`` command, ``pshell`` will
+autodiscover them and use the first respectively found in this order :
+IPython, bpython, standard Python interpreter. However you could
+specifically invoke one of your choice with the ``-p choice`` or
+``--python-shell choice`` option.
.. code-block:: text
- [chrism@vitaminf shellenv]$ ../bin/pshell --disable-ipython \
+ [chrism@vitaminf shellenv]$ ../bin/pshell -p ipython | bpython | python \
development.ini#MyProject
-
.. index::
pair: routes; printing
single: proutes
diff --git a/pyramid/scripts/pshell.py b/pyramid/scripts/pshell.py
index 499d96aca..72e2c0a89 100644
--- a/pyramid/scripts/pshell.py
+++ b/pyramid/scripts/pshell.py
@@ -36,10 +36,9 @@ class PShellCommand(object):
summary = "Open an interactive shell with a Pyramid application loaded"
parser = optparse.OptionParser()
- parser.add_option('-d', '--disable-ipython',
- action='store_true',
- dest='disable_ipython',
- help="Don't use IPython even if it is available")
+ parser.add_option('-p', '--python-shell',
+ action='store', type='string', dest='python_shell',
+ default='', help='ipython | bpython | python')
parser.add_option('--setup',
dest='setup',
help=("A callable that will be passed the environment "
@@ -142,18 +141,36 @@ class PShellCommand(object):
for var in sorted(self.object_help.keys()):
help += '\n %-12s %s' % (var, self.object_help[var])
- if shell is None and not self.options.disable_ipython:
+ if shell is None:
+ shell = self.make_shell()
+
+ try:
+ shell(env, help)
+ finally:
+ closer()
+
+ def make_shell(self):
+ shell = None
+ user_shell = self.options.python_shell.lower()
+ if not user_shell:
+ shell = self.make_ipython_v0_11_shell()
+ if shell is None:
+ shell = self.make_ipython_v0_10_shell()
+ if shell is None:
+ shell = self.make_bpython_shell()
+
+ elif user_shell == 'ipython':
shell = self.make_ipython_v0_11_shell()
if shell is None:
shell = self.make_ipython_v0_10_shell()
+ elif user_shell == 'bpython':
+ shell = self.make_bpython_shell()
+
if shell is None:
shell = self.make_default_shell()
- try:
- shell(env, help)
- finally:
- closer()
+ return shell
def make_default_shell(self, interact=interact):
def shell(env, help):
@@ -163,6 +180,17 @@ class PShellCommand(object):
interact(banner, local=env)
return shell
+ def make_bpython_shell(self, BPShell=None):
+ if BPShell is None: # pragma: no cover
+ try:
+ from bpython import embed
+ BPShell = embed
+ except ImportError:
+ return None
+ def shell(env, help):
+ BPShell(locals_=env, banner=help + '\n')
+ return shell
+
def make_ipython_v0_11_shell(self, IPShellFactory=None):
if IPShellFactory is None: # pragma: no cover
try:
diff --git a/pyramid/tests/test_scripts/dummy.py b/pyramid/tests/test_scripts/dummy.py
index 3275f7804..d580203af 100644
--- a/pyramid/tests/test_scripts/dummy.py
+++ b/pyramid/tests/test_scripts/dummy.py
@@ -5,7 +5,7 @@ class DummyTweens(object):
self.name_to_alias = {}
def implicit(self):
return self._implicit
-
+
class Dummy:
pass
@@ -31,6 +31,11 @@ class DummyInteractor:
self.banner = banner
self.local = local
+class DummyBPythonShell:
+ def __call__(self, locals_, banner):
+ self.locals_ = locals_
+ self.banner = banner
+
class DummyIPShell(object):
IP = Dummy()
IP.BANNER = 'foo'
@@ -72,7 +77,7 @@ class DummyRoute(object):
def match(self, route):
return self.matchdict
-
+
class DummyRequest:
application_url = 'http://example.com:5432'
script_name = ''
diff --git a/pyramid/tests/test_scripts/test_pshell.py b/pyramid/tests/test_scripts/test_pshell.py
index e38da2077..765042152 100644
--- a/pyramid/tests/test_scripts/test_pshell.py
+++ b/pyramid/tests/test_scripts/test_pshell.py
@@ -21,7 +21,7 @@ class TestPShellCommand(unittest.TestCase):
if patch_options:
class Options(object): pass
self.options = Options()
- self.options.disable_ipython = True
+ self.options.python_shell = ''
self.options.setup = None
cmd.options = self.options
return cmd
@@ -34,6 +34,14 @@ class TestPShellCommand(unittest.TestCase):
self.assertEqual(interact.local, {'foo': 'bar'})
self.assertTrue('a help message' in interact.banner)
+ def test_make_bpython_shell(self):
+ command = self._makeOne()
+ bpython = dummy.DummyBPythonShell()
+ shell = command.make_bpython_shell(bpython)
+ shell({'foo': 'bar'}, 'a help message')
+ self.assertEqual(bpython.locals_, {'foo': 'bar'})
+ self.assertTrue('a help message' in bpython.banner)
+
def test_make_ipython_v0_11_shell(self):
command = self._makeOne()
ipshell_factory = dummy.DummyIPShellFactory()
@@ -58,6 +66,7 @@ class TestPShellCommand(unittest.TestCase):
shell = dummy.DummyShell()
command.make_ipython_v0_11_shell = lambda: None
command.make_ipython_v0_10_shell = lambda: None
+ command.make_bpython_shell = lambda: None
command.make_default_shell = lambda: shell
command.run()
self.assertTrue(self.config_factory.parser)
@@ -73,14 +82,15 @@ class TestPShellCommand(unittest.TestCase):
self.assertTrue(self.bootstrap.closer.called)
self.assertTrue(shell.help)
- def test_command_loads_default_shell_with_ipython_disabled(self):
+ def test_command_loads_default_shell_with_unknown_shell(self):
command = self._makeOne()
shell = dummy.DummyShell()
bad_shell = dummy.DummyShell()
command.make_ipython_v0_11_shell = lambda: bad_shell
command.make_ipython_v0_10_shell = lambda: bad_shell
+ command.make_bpython_shell = lambda: bad_shell
command.make_default_shell = lambda: shell
- command.options.disable_ipython = True
+ command.options.python_shell = 'unknow_python_shell'
command.run()
self.assertTrue(self.config_factory.parser)
self.assertEqual(self.config_factory.parser.filename,
@@ -101,8 +111,9 @@ class TestPShellCommand(unittest.TestCase):
shell = dummy.DummyShell()
command.make_ipython_v0_11_shell = lambda: shell
command.make_ipython_v0_10_shell = lambda: None
+ command.make_bpython_shell = lambda: None
command.make_default_shell = lambda: None
- command.options.disable_ipython = False
+ command.options.python_shell = 'ipython'
command.run()
self.assertTrue(self.config_factory.parser)
self.assertEqual(self.config_factory.parser.filename,
@@ -122,8 +133,9 @@ class TestPShellCommand(unittest.TestCase):
shell = dummy.DummyShell()
command.make_ipython_v0_11_shell = lambda: None
command.make_ipython_v0_10_shell = lambda: shell
+ command.make_bpython_shell = lambda: None
command.make_default_shell = lambda: None
- command.options.disable_ipython = False
+ command.options.python_shell = 'ipython'
command.run()
self.assertTrue(self.config_factory.parser)
self.assertEqual(self.config_factory.parser.filename,
@@ -138,6 +150,76 @@ class TestPShellCommand(unittest.TestCase):
self.assertTrue(self.bootstrap.closer.called)
self.assertTrue(shell.help)
+ def test_command_loads_bpython_shell(self):
+ command = self._makeOne()
+ shell = dummy.DummyBPythonShell()
+ command.make_ipython_v0_11_shell = lambda: None
+ command.make_ipython_v0_10_shell = lambda: None
+ command.make_bpython_shell = lambda: shell
+ command.options.python_shell = 'bpython'
+ command.run()
+ self.assertTrue(self.config_factory.parser)
+ self.assertEqual(self.config_factory.parser.filename,
+ '/foo/bar/myapp.ini')
+ self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp')
+ self.assertEqual(shell.locals_, {
+ 'app':self.bootstrap.app, 'root':self.bootstrap.root,
+ 'registry':self.bootstrap.registry,
+ 'request':self.bootstrap.request,
+ 'root_factory':self.bootstrap.root_factory,
+ })
+ self.assertTrue(self.bootstrap.closer.called)
+ self.assertTrue(shell.banner)
+
+ def test_shell_ipython_ordering(self):
+ command = self._makeOne()
+ shell0_11 = dummy.DummyShell()
+ shell0_10 = dummy.DummyShell()
+ command.make_ipython_v0_11_shell = lambda: shell0_11
+ command.make_ipython_v0_10_shell = lambda: shell0_10
+ command.make_bpython_shell = lambda: None
+ shell = command.make_shell()
+ self.assertEqual(shell, shell0_11)
+
+ command.options.python_shell = 'ipython'
+ shell = command.make_shell()
+ self.assertEqual(shell, shell0_11)
+
+ def test_shell_ordering(self):
+ command = self._makeOne()
+ ipshell = dummy.DummyShell()
+ bpshell = dummy.DummyShell()
+ dshell = dummy.DummyShell()
+ command.make_ipython_v0_11_shell = lambda: None
+ command.make_ipython_v0_10_shell = lambda: None
+ command.make_bpython_shell = lambda: None
+ command.make_default_shell = lambda: dshell
+
+ shell = command.make_shell()
+ self.assertEqual(shell, dshell)
+
+ command.options.python_shell = 'ipython'
+ shell = command.make_shell()
+ self.assertEqual(shell, dshell)
+
+ command.options.python_shell = 'bpython'
+ shell = command.make_shell()
+ self.assertEqual(shell, dshell)
+
+ command.make_ipython_v0_11_shell = lambda: ipshell
+ command.make_bpython_shell = lambda: bpshell
+ command.options.python_shell = 'ipython'
+ shell = command.make_shell()
+ self.assertEqual(shell, ipshell)
+
+ command.options.python_shell = 'bpython'
+ shell = command.make_shell()
+ self.assertEqual(shell, bpshell)
+
+ command.options.python_shell = 'python'
+ shell = command.make_shell()
+ self.assertEqual(shell, dshell)
+
def test_command_loads_custom_items(self):
command = self._makeOne()
model = dummy.Dummy()