diff options
| author | Chris McDonough <chrism@plope.com> | 2011-11-21 22:00:39 -0500 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2011-11-21 22:00:39 -0500 |
| commit | 6f4242bed8e7418984642da4e0ff861d39195410 (patch) | |
| tree | 038feedeb6583852bd1514fb1e57076738d685c7 | |
| parent | 8a5db43e9b7671f49e118cbb888019445df0ae14 (diff) | |
| parent | 995133918877809aeea06bce93149104ba800304 (diff) | |
| download | pyramid-6f4242bed8e7418984642da4e0ff861d39195410.tar.gz pyramid-6f4242bed8e7418984642da4e0ff861d39195410.tar.bz2 pyramid-6f4242bed8e7418984642da4e0ff861d39195410.zip | |
Merge branch 'master' of github.com:Pylons/pyramid
| -rw-r--r-- | docs/narr/commandline.rst | 22 | ||||
| -rw-r--r-- | pyramid/scripts/pshell.py | 46 | ||||
| -rw-r--r-- | pyramid/tests/test_scripts/dummy.py | 9 | ||||
| -rw-r--r-- | pyramid/tests/test_scripts/test_pshell.py | 92 |
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() |
