Refactored the shell command to fix IPython and make way for BPython support.

This commit is contained in:
Ryan Petrello
2012-03-20 19:14:54 -04:00
parent bf57ddc8b8
commit 8cb08af541
2 changed files with 60 additions and 19 deletions

View File

@@ -3,14 +3,60 @@ Shell command for Pecan.
""" """
from pecan.commands import BaseCommand from pecan.commands import BaseCommand
from webtest import TestApp from webtest import TestApp
from warnings import warn
import sys import sys
class NativePythonShell(object):
@classmethod
def invoke(cls, ns, banner):
import code
py_prefix = sys.platform.startswith('java') and 'J' or 'P'
shell_banner = 'Pecan Interactive Shell\n%sython %s\n\n' % \
(py_prefix, sys.version)
shell = code.InteractiveConsole(locals=ns)
try:
import readline # noqa
except ImportError:
pass
shell.interact(shell_banner + banner)
class IPythonShell(object):
@classmethod
def invoke(cls, ns, banner):
try:
from IPython.frontend.terminal.embed import (
InteractiveShellEmbed
)
shell = InteractiveShellEmbed(banner2=banner)
shell(local_ns=ns)
except ImportError:
from IPython.Shell import IPShellEmbed
shell = IPShellEmbed(argv=self.args)
shell.set_banner(shell.IP.BANNER + '\n\n' + banner)
shell(local_ns=ns, global_ns={})
class ShellCommand(BaseCommand): class ShellCommand(BaseCommand):
""" """
Open an interactive shell with the Pecan app loaded. Open an interactive shell with the Pecan app loaded.
""" """
SHELLS = {
'python': NativePythonShell,
'ipython': IPythonShell
}
arguments = BaseCommand.arguments + ({
'command': '--shell',
'help': 'which Python shell to use',
'choices': SHELLS.keys(),
'default': 'python'
},)
def run(self, args): def run(self, args):
super(ShellCommand, self).run(args) super(ShellCommand, self).run(args)
@@ -44,23 +90,21 @@ class ShellCommand(BaseCommand):
) )
banner += ' %-10s - Models from %s\n' % ('model', model_name) banner += ' %-10s - Models from %s\n' % ('model', model_name)
# launch the shell, using IPython if available self.invoke_shell(locs, banner)
def invoke_shell(self, locs, banner):
shell = self.SHELLS[self.args.shell]
try: try:
from IPython.Shell import IPShellEmbed shell().invoke(locs, banner)
shell = IPShellEmbed(argv=self.args) except ImportError, e:
shell.set_banner(shell.IP.BANNER + '\n\n' + banner) warn(
shell(local_ns=locs, global_ns={}) ("%s is not installed, `%s`, "
except ImportError: "falling back to native shell") % (self.args.shell, e),
import code RuntimeWarning
py_prefix = sys.platform.startswith('java') and 'J' or 'P' )
shell_banner = 'Pecan Interactive Shell\n%sython %s\n\n' % \ if shell == NativePythonShell:
(py_prefix, sys.version) raise
shell = code.InteractiveConsole(locals=locs) NativePythonShell().invoke(locs, banner)
try:
import readline # noqa
except ImportError:
pass
shell.interact(shell_banner + banner)
def load_model(self, config): def load_model(self, config):
for package_name in getattr(config.app, 'modules', []): for package_name in getattr(config.app, 'modules', []):

View File

@@ -76,11 +76,8 @@ setup(
'Operating System :: Microsoft :: Windows', 'Operating System :: Microsoft :: Windows',
'Operating System :: POSIX', 'Operating System :: POSIX',
'Programming Language :: Python', 'Programming Language :: Python',
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Internet :: WWW/HTTP :: WSGI', 'Topic :: Internet :: WWW/HTTP :: WSGI',
'Topic :: Software Development :: Libraries :: Application Frameworks' 'Topic :: Software Development :: Libraries :: Application Frameworks'
], ],