CHANGES.txt | ●●●●● patch | view | raw | blame | history | |
docs/narr/commandline.rst | ●●●●● patch | view | raw | blame | history | |
pyramid/scripts/pshell.py | ●●●●● patch | view | raw | blame | history | |
pyramid/tests/test_scripts/test_pshell.py | ●●●●● patch | view | raw | blame | history | |
setup.py | ●●●●● patch | view | raw | blame | history |
CHANGES.txt
@@ -1,6 +1,19 @@ 1.6 (2015-04-14) ================ Backward Incompatibilities -------------------------- - IPython and BPython support have been removed from pshell in the core. To continue using them on Pyramid 1.6+ you must install the binding packages explicitly:: $ pip install pyramid_ipython or $ pip install pyramid_bpython Features -------- docs/narr/commandline.rst
@@ -107,9 +107,7 @@ .. index:: single: interactive shell single: IPython single: pshell single: bpython .. _interactive_shell: @@ -263,18 +261,13 @@ >>> request.route_url('home') 'https://www.example.com/' .. index:: single: IPython single: bpython .. _ipython_or_bpython: Alternative Shells ~~~~~~~~~~~~~~~~~~ If you have `IPython <http://en.wikipedia.org/wiki/IPython>`_ and/or `bpython <http://bpython-interpreter.org/>`_ in the interpreter you use to invoke the ``pshell`` command, ``pshell`` will autodiscover and use the first one found. However you could specifically invoke your choice with the ``-p choice`` or The ``pshell`` command can be easily extended with alternate REPLs if the default python REPL is not satisfactory. Assuming you have a binding installed such as ``pyramid_ipython`` it will normally be auto-selected and used. You may also specifically invoke your choice with the ``-p choice`` or ``--python-shell choice`` option. .. code-block:: text @@ -287,7 +280,7 @@ $ $VENV/bin/pshell --list-shells Available shells: bpython [not available] bpython ipython python @@ -309,29 +302,19 @@ .. code-block:: python def ptpython_shell_factory(): try: from ptpython.repl import embed except ImportError: # ptpython is not installed return None from ptpython.repl import embed def PTPShell(banner, **kwargs): print(banner) return embed(**kwargs) def shell(env, help): PTPShell(banner=help, locals=env) return shell If the factory returns ``None`` then it is assumed that the shell is not supported. def ptpython_shell_runner(env, help): print(help) return embed(locals=env) .. versionchanged:: 1.6 User-defined shells may be registered using entry points. Prior to this the only supported shells were ``ipython``, ``bpython`` and ``python``. ``ipython`` and ``bpython`` have been moved into their respective packages ``pyramid_ipython`` and ``pyramid_bpython``. Setting a Default Shell ~~~~~~~~~~~~~~~~~~~~~~~ pyramid/scripts/pshell.py
@@ -21,6 +21,13 @@ return command.run() def python_shell_runner(env, help, interact=interact): cprt = 'Type "help" for more information.' banner = "Python %s on %s\n%s" % (sys.version, sys.platform, cprt) banner += '\n\n' + help + '\n' interact(banner, local=env) class PShellCommand(object): usage = '%prog config_uri' description = """\ @@ -61,6 +68,7 @@ "[pshell] ini section.")) ConfigParser = configparser.ConfigParser # testing default_runner = python_shell_runner # testing loaded_objects = {} object_help = {} @@ -186,23 +194,18 @@ def show_shells(self): shells = self.find_all_shells() sorted_shells = sorted(shells.items(), key=lambda x: x[0].lower()) max_name = max([len(s) for s in shells]) sorted_names = sorted(shells.keys(), key=lambda x: x.lower()) self.out('Available shells:') for name, factory in sorted_shells: shell = factory() if shell is not None: self.out(' %s' % (name,)) else: self.out(' %s%s [not available]' % ( name, ' ' * (max_name - len(name)))) for name in sorted_names: self.out(' %s' % (name,)) return 0 def find_all_shells(self): pkg_resources = self.pkg_resources shells = {} for ep in self.pkg_resources.iter_entry_points('pyramid.pshell'): for ep in pkg_resources.iter_entry_points('pyramid.pshell_runner'): name = ep.name shell_factory = ep.load() shells[name] = shell_factory @@ -228,16 +231,15 @@ except ValueError: return 1 sorted_shells = sorted(shells.items(), key=order) for name, factory in sorted_shells: shell = factory() if shell is not None: break if len(sorted_shells) > 0: shell = sorted_shells[0][1] else: factory = shells.get(user_shell) runner = shells.get(user_shell) if factory is not None: shell = factory() if runner is not None: shell = runner if shell is None: raise ValueError( @@ -245,45 +247,9 @@ ) if shell is None: shell = self.make_default_shell() # should never happen, but just incase entry points are borked shell = self.default_runner return shell @classmethod def make_python_shell(cls, interact=interact): def shell(env, help): cprt = 'Type "help" for more information.' banner = "Python %s on %s\n%s" % (sys.version, sys.platform, cprt) banner += '\n\n' + help + '\n' interact(banner, local=env) return shell make_default_shell = make_python_shell @classmethod def make_bpython_shell(cls, 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 @classmethod def make_ipython_shell(cls, IPShellFactory=None): if IPShellFactory is None: # pragma: no cover try: from IPython.terminal.embed import ( InteractiveShellEmbed) IPShellFactory = InteractiveShellEmbed except ImportError: return None def shell(env, help): IPShell = IPShellFactory(banner2=help + '\n', user_ns=env) IPShell() return shell pyramid/tests/test_scripts/test_pshell.py
@@ -37,44 +37,12 @@ def _makeEntryPoints(self, command, shells): command.pkg_resources = dummy.DummyPkgResources(shells) def test_make_default_shell(self): command = self._makeOne() interact = dummy.DummyInteractor() shell = command.make_default_shell(interact) shell({'foo': 'bar'}, 'a help message') 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_shell(self): command = self._makeOne() ipshell_factory = dummy.DummyIPShellFactory() shell = command.make_ipython_shell(ipshell_factory) shell({'foo': 'bar'}, 'a help message') self.assertEqual(ipshell_factory.kw['user_ns'], {'foo': 'bar'}) self.assertTrue('a help message' in ipshell_factory.kw['banner2']) self.assertTrue(ipshell_factory.shell.called) def test_command_loads_default_shell(self): command = self._makeOne() shell = dummy.DummyShell() self._makeEntryPoints( command, { 'ipython': lambda: None, 'bpython': lambda: None, 'python': lambda: None, } ) self._makeEntryPoints(command, {}) command.make_default_shell = lambda: shell command.default_runner = shell command.run() self.assertTrue(self.config_factory.parser) self.assertEqual(self.config_factory.parser.filename, @@ -99,17 +67,10 @@ command.out = out shell = dummy.DummyShell() bad_shell = dummy.DummyShell() self._makeEntryPoints( command, { 'ipython': lambda: bad_shell, 'bpython': lambda: bad_shell, } ) self._makeEntryPoints(command, {}) command.make_default_shell = lambda: shell command.default_runner = shell command.options.python_shell = 'unknown_python_shell' result = command.run() self.assertEqual(result, 1) @@ -129,8 +90,8 @@ self._makeEntryPoints( command, { 'ipython': lambda: shell, 'bpython': lambda: bad_shell, 'ipython': shell, 'bpython': bad_shell, } ) @@ -150,33 +111,6 @@ self.assertTrue(self.bootstrap.closer.called) self.assertTrue(shell.help) def test_command_loads_bpython_shell(self): command = self._makeOne() shell = dummy.DummyBPythonShell() self._makeEntryPoints( command, { 'ipython': lambda: None, 'bpython': 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_entry_points(self): command = self._makeOne() dshell = dummy.DummyShell() @@ -184,12 +118,12 @@ self._makeEntryPoints( command, { 'ipython': lambda: dshell, 'bpython': lambda: dshell, 'ipython': dshell, 'bpython': dshell, } ) command.make_default_shell = lambda: None command.default_runner = None shell = command.make_shell() self.assertEqual(shell, dshell) @@ -199,15 +133,9 @@ bpshell = dummy.DummyShell() dshell = dummy.DummyShell() self._makeEntryPoints( command, { 'ipython': lambda: None, 'bpython': lambda: None, } ) self._makeEntryPoints(command, {}) command.make_default_shell = lambda: dshell command.default_runner = dshell shell = command.make_shell() self.assertEqual(shell, dshell) @@ -215,15 +143,12 @@ command.options.python_shell = 'ipython' self.assertRaises(ValueError, command.make_shell) command.options.python_shell = 'bpython' self.assertRaises(ValueError, command.make_shell) self._makeEntryPoints( command, { 'ipython': lambda: ipshell, 'bpython': lambda: bpshell, 'python': lambda: dshell, 'ipython': ipshell, 'bpython': bpshell, 'python': dshell, } ) @@ -248,13 +173,13 @@ self._makeEntryPoints( command, { 'ipython': lambda: ipshell, 'bpython': lambda: bpshell, 'python': lambda: dshell, 'ipython': ipshell, 'bpython': bpshell, 'python': dshell, } ) command.make_default_shell = lambda: dshell command.default_runner = dshell command.preferred_shells = ['ipython', 'bpython'] shell = command.make_shell() @@ -319,9 +244,8 @@ self._makeEntryPoints( command, { 'ipython': lambda: ipshell, 'bpython': lambda: None, 'python': lambda: dshell, 'ipython': ipshell, 'python': dshell, } ) self.config_factory.items = [ @@ -434,9 +358,8 @@ self._makeEntryPoints( command, { 'ipython': lambda: dshell, 'bpython': lambda: None, 'python': lambda: dshell, 'ipython': dshell, 'python': dshell, } ) @@ -445,10 +368,21 @@ self.assertEqual(result, 0) self.assertEqual(out_calls, [ 'Available shells:', ' bpython [not available]', ' ipython', ' python', ]) class Test_python_shell_runner(unittest.TestCase): def _callFUT(self, env, help, interact): from pyramid.scripts.pshell import python_shell_runner return python_shell_runner(env, help, interact=interact) def test_it(self): interact = dummy.DummyInteractor() self._callFUT({'foo': 'bar'}, 'a help message', interact) self.assertEqual(interact.local, {'foo': 'bar'}) self.assertTrue('a help message' in interact.banner) class Test_main(unittest.TestCase): def _callFUT(self, argv): @@ -458,4 +392,3 @@ def test_it(self): result = self._callFUT(['pshell']) self.assertEqual(result, 2) setup.py
@@ -111,10 +111,8 @@ starter=pyramid.scaffolds:StarterProjectTemplate zodb=pyramid.scaffolds:ZODBProjectTemplate alchemy=pyramid.scaffolds:AlchemyProjectTemplate [pyramid.pshell] ipython=pyramid.scripts.pshell:PShellCommand.make_ipython_shell bpython=pyramid.scripts.pshell:PShellCommand.make_bpython_shell python=pyramid.scripts.pshell:PShellCommand.make_python_shell [pyramid.pshell_runner] python=pyramid.scripts.pshell:python_shell_runner [console_scripts] pcreate = pyramid.scripts.pcreate:main pserve = pyramid.scripts.pserve:main