Fixed #25838 -- Added "python" as an interface to the shell command.

Deprecates the "--plain" option.
This commit is contained in:
Jon Dufresne 2015-12-13 11:33:39 -08:00 committed by Tim Graham
parent b10f66831b
commit f1628f6be1
4 changed files with 70 additions and 54 deletions

View File

@ -1,20 +1,23 @@
import os
import warnings
from django.core.management.base import BaseCommand
from django.utils.deprecation import RemovedInDjango20Warning
class Command(BaseCommand):
help = "Runs a Python interactive interpreter. Tries to use IPython or bpython, if one of them is available."
requires_system_checks = False
shells = ['ipython', 'bpython']
shells = ['ipython', 'bpython', 'python']
def add_arguments(self, parser):
parser.add_argument('--plain', action='store_true', dest='plain',
help='Tells Django to use plain Python, not IPython or bpython.')
help='Tells Django to use plain Python, not IPython or bpython. '
'Deprecated, use the `-i python` or `--interface python` option instead.')
parser.add_argument('--no-startup', action='store_true', dest='no_startup',
help='When using plain Python, ignore the PYTHONSTARTUP environment variable and ~/.pythonrc.py script.')
parser.add_argument('-i', '--interface', choices=self.shells, dest='interface',
help='Specify an interactive interpreter interface. Available options: "ipython" and "bpython"')
help='Specify an interactive interpreter interface. Available options: "ipython", "bpython", and "python"')
def _ipython_pre_011(self):
"""Start IPython pre-0.11"""
@ -34,7 +37,7 @@ class Command(BaseCommand):
from IPython import start_ipython
start_ipython(argv=[])
def ipython(self):
def ipython(self, options):
"""Start any version of IPython"""
for ip in (self._ipython, self._ipython_pre_100, self._ipython_pre_011):
try:
@ -46,56 +49,55 @@ class Command(BaseCommand):
# no IPython, raise ImportError
raise ImportError("No IPython")
def bpython(self):
def bpython(self, options):
import bpython
bpython.embed()
def run_shell(self, shell=None):
available_shells = [shell] if shell else self.shells
def python(self, options):
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.
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 .pythonrc.py.
if not options['no_startup']:
for pythonrc in (os.environ.get("PYTHONSTARTUP"), '~/.pythonrc.py'):
if not pythonrc:
continue
pythonrc = os.path.expanduser(pythonrc)
if not os.path.isfile(pythonrc):
continue
try:
with open(pythonrc) as handle:
exec(compile(handle.read(), pythonrc, 'exec'), imported_objects)
except NameError:
pass
code.interact(local=imported_objects)
def handle(self, **options):
if options['plain']:
warnings.warn(
"The --plain option is deprecated in favor of the -i python or --interface python option.",
RemovedInDjango20Warning
)
options['interface'] = 'python'
available_shells = [options['interface']] if options['interface'] else self.shells
for shell in available_shells:
try:
return getattr(self, shell)()
return getattr(self, shell)(options)
except ImportError:
pass
raise ImportError
def handle(self, **options):
try:
if options['plain']:
# Don't bother loading IPython, because the user wants plain Python.
raise ImportError
self.run_shell(shell=options['interface'])
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
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 .pythonrc.py.
if not options['no_startup']:
for pythonrc in (os.environ.get("PYTHONSTARTUP"), '~/.pythonrc.py'):
if not pythonrc:
continue
pythonrc = os.path.expanduser(pythonrc)
if not os.path.isfile(pythonrc):
continue
try:
with open(pythonrc) as handle:
exec(compile(handle.read(), pythonrc, 'exec'), imported_objects)
except NameError:
pass
code.interact(local=imported_objects)
raise ImportError("Couldn't load any of the specified interfaces.")

View File

@ -126,6 +126,8 @@ details on these changes.
* ``django.utils.functional.allow_lazy()`` will be removed.
* The ``shell --plain`` option will be removed.
.. _deprecation-removed-in-1.10:
1.10

View File

@ -933,9 +933,15 @@ Starts the Python interactive interpreter.
Django will use IPython_ or bpython_ if either is installed. If you have a
rich shell installed but want to force use of the "plain" Python interpreter,
use the ``--plain`` option, like so::
use the ``-i python`` or ``--interface python`` option, like so::
django-admin shell --plain
django-admin shell -i python
django-admin shell --interface python
.. deprecated:: 1.10
In older versions, use the ``--plain`` option. This is deprecated and will
be removed in Django 2.0.
If you would like to specify either IPython or bpython as your interpreter if
you have both installed you can specify an alternative interpreter interface
@ -957,12 +963,12 @@ bpython::
.. _bpython: http://bpython-interpreter.org/
When the "plain" Python interactive interpreter starts (be it because
``--plain`` was specified or because no other interactive interface is
available) it reads the script pointed to by the :envvar:`PYTHONSTARTUP`
``--interface python`` was specified or because no other interactive interface
is available) it reads the script pointed to by the :envvar:`PYTHONSTARTUP`
environment variable and the ``~/.pythonrc.py`` script. If you don't wish this
behavior you can use the ``--no-startup`` option. e.g.::
django-admin shell --plain --no-startup
django-admin shell --interface python --no-startup
showmigrations [<app_label> [<app_label>]]
------------------------------------------

View File

@ -212,6 +212,9 @@ Management Commands
* :djadmin:`makemigrations` now displays the path to the migration files that
it generates.
* The :djadmin:`shell` ``--interface`` option now accepts ``python`` to force
use of the "plain" Python interpreter.
Migrations
^^^^^^^^^^
@ -432,6 +435,9 @@ Miscellaneous
:func:`~django.utils.functional.keep_lazy` function which can be used with a
more natural decorator syntax.
* The ``shell --plain`` option is deprecated in favor of ``-i python`` or
``--interface python``.
.. _removed-features-1.10:
Features removed in 1.10