mirror of
https://github.com/django/django.git
synced 2024-12-22 17:16:24 +00:00
Fixed #27600 -- Suppressed the REPL during shell's reading from stdin.
Thanks Adam Chainz for review and guidance.
This commit is contained in:
parent
24fa728a47
commit
bf6392bb75
@ -1,4 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
|
import select
|
||||||
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
@ -7,7 +9,12 @@ from django.utils.deprecation import RemovedInDjango20Warning
|
|||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
class Command(BaseCommand):
|
||||||
help = "Runs a Python interactive interpreter. Tries to use IPython or bpython, if one of them is available."
|
help = (
|
||||||
|
"Runs a Python interactive interpreter. Tries to use IPython or "
|
||||||
|
"bpython, if one of them is available. Any standard input is executed "
|
||||||
|
"as code."
|
||||||
|
)
|
||||||
|
|
||||||
requires_system_checks = False
|
requires_system_checks = False
|
||||||
shells = ['ipython', 'bpython', 'python']
|
shells = ['ipython', 'bpython', 'python']
|
||||||
|
|
||||||
@ -114,6 +121,12 @@ class Command(BaseCommand):
|
|||||||
exec(options['command'])
|
exec(options['command'])
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Execute stdin if it has anything to read and exit.
|
||||||
|
# Not supported on Windows due to select.select() limitations.
|
||||||
|
if sys.platform != 'win32' and select.select([sys.stdin], [], [], 0)[0]:
|
||||||
|
exec(sys.stdin.read())
|
||||||
|
return
|
||||||
|
|
||||||
available_shells = [options['interface']] if options['interface'] else self.shells
|
available_shells = [options['interface']] if options['interface'] else self.shells
|
||||||
|
|
||||||
for shell in available_shells:
|
for shell in available_shells:
|
||||||
|
@ -979,6 +979,22 @@ Lets you pass a command as a string to execute it as Django, like so::
|
|||||||
|
|
||||||
django-admin shell --command="import django; print(django.__version__)"
|
django-admin shell --command="import django; print(django.__version__)"
|
||||||
|
|
||||||
|
You can also pass code in on standard input to execute it. For example:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
$ django-admin shell <<EOF
|
||||||
|
> import django
|
||||||
|
> print(django.__version__)
|
||||||
|
> EOF
|
||||||
|
|
||||||
|
On Windows, the REPL is output due to implementation limits of
|
||||||
|
:func:`select.select` on that platform.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.11
|
||||||
|
|
||||||
|
In older versions, the REPL is also output on UNIX systems.
|
||||||
|
|
||||||
``showmigrations``
|
``showmigrations``
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
from django import __version__
|
from django import __version__
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase, mock
|
||||||
from django.test.utils import patch_logger
|
from django.test.utils import captured_stdin, captured_stdout, patch_logger
|
||||||
|
|
||||||
|
|
||||||
class ShellCommandTestCase(SimpleTestCase):
|
class ShellCommandTestCase(SimpleTestCase):
|
||||||
@ -17,3 +20,12 @@ class ShellCommandTestCase(SimpleTestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(len(logger), 1)
|
self.assertEqual(len(logger), 1)
|
||||||
self.assertEqual(logger[0], __version__)
|
self.assertEqual(logger[0], __version__)
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.platform == 'win32', "Windows select() doesn't support file descriptors.")
|
||||||
|
@mock.patch('django.core.management.commands.shell.select')
|
||||||
|
def test_stdin_read(self, select):
|
||||||
|
with captured_stdin() as stdin, captured_stdout() as stdout:
|
||||||
|
stdin.write('print(100)\n')
|
||||||
|
stdin.seek(0)
|
||||||
|
call_command('shell')
|
||||||
|
self.assertEqual(stdout.getvalue().strip(), '100')
|
||||||
|
Loading…
Reference in New Issue
Block a user