mirror of
https://github.com/django/django.git
synced 2025-06-05 11:39:13 +00:00
Refs #19973 -- Removed optparse support in management commands per deprecation timeline.
This commit is contained in:
parent
3bbebd06ad
commit
6a70cb5397
@ -100,19 +100,16 @@ def call_command(name, *args, **options):
|
|||||||
|
|
||||||
# Simulate argument parsing to get the option defaults (see #10080 for details).
|
# Simulate argument parsing to get the option defaults (see #10080 for details).
|
||||||
parser = command.create_parser('', name)
|
parser = command.create_parser('', name)
|
||||||
if command.use_argparse:
|
# Use the `dest` option name from the parser option
|
||||||
# Use the `dest` option name from the parser option
|
opt_mapping = {
|
||||||
opt_mapping = {sorted(s_opt.option_strings)[0].lstrip('-').replace('-', '_'): s_opt.dest
|
sorted(s_opt.option_strings)[0].lstrip('-').replace('-', '_'): s_opt.dest
|
||||||
for s_opt in parser._actions if s_opt.option_strings}
|
for s_opt in parser._actions if s_opt.option_strings
|
||||||
arg_options = {opt_mapping.get(key, key): value for key, value in options.items()}
|
}
|
||||||
defaults = parser.parse_args(args=args)
|
arg_options = {opt_mapping.get(key, key): value for key, value in options.items()}
|
||||||
defaults = dict(defaults._get_kwargs(), **arg_options)
|
defaults = parser.parse_args(args=args)
|
||||||
# Move positional args out of options to mimic legacy optparse
|
defaults = dict(defaults._get_kwargs(), **arg_options)
|
||||||
args = defaults.pop('args', ())
|
# Move positional args out of options to mimic legacy optparse
|
||||||
else:
|
args = defaults.pop('args', ())
|
||||||
# Legacy optparse method
|
|
||||||
defaults, _ = parser.parse_args(args=[])
|
|
||||||
defaults = dict(defaults.__dict__, **options)
|
|
||||||
if 'skip_checks' not in options:
|
if 'skip_checks' not in options:
|
||||||
defaults['skip_checks'] = True
|
defaults['skip_checks'] = True
|
||||||
|
|
||||||
@ -249,12 +246,10 @@ class ManagementUtility(object):
|
|||||||
# user will find out once they execute the command.
|
# user will find out once they execute the command.
|
||||||
pass
|
pass
|
||||||
parser = subcommand_cls.create_parser('', cwords[0])
|
parser = subcommand_cls.create_parser('', cwords[0])
|
||||||
if subcommand_cls.use_argparse:
|
options.extend(
|
||||||
options.extend((sorted(s_opt.option_strings)[0], s_opt.nargs != 0) for s_opt in
|
(sorted(s_opt.option_strings)[0], s_opt.nargs != 0)
|
||||||
parser._actions if s_opt.option_strings)
|
for s_opt in parser._actions if s_opt.option_strings
|
||||||
else:
|
)
|
||||||
options.extend((s_opt.get_opt_string(), s_opt.nargs != 0) for s_opt in
|
|
||||||
parser.option_list)
|
|
||||||
# filter out previously specified options from available options
|
# filter out previously specified options from available options
|
||||||
prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]]
|
prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]]
|
||||||
options = [opt for opt in options if opt[0] not in prev_opts]
|
options = [opt for opt in options if opt[0] not in prev_opts]
|
||||||
|
@ -9,7 +9,6 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from optparse import OptionParser
|
|
||||||
|
|
||||||
import django
|
import django
|
||||||
from django.core import checks
|
from django.core import checks
|
||||||
@ -152,12 +151,6 @@ class BaseCommand(object):
|
|||||||
|
|
||||||
Several attributes affect behavior at various steps along the way:
|
Several attributes affect behavior at various steps along the way:
|
||||||
|
|
||||||
``args``
|
|
||||||
A string listing the arguments accepted by the command,
|
|
||||||
suitable for use in help messages; e.g., a command which takes
|
|
||||||
a list of application names might set this to '<app_label
|
|
||||||
app_label ...>'.
|
|
||||||
|
|
||||||
``can_import_settings``
|
``can_import_settings``
|
||||||
A boolean indicating whether the command needs to be able to
|
A boolean indicating whether the command needs to be able to
|
||||||
import Django settings; if ``True``, ``execute()`` will verify
|
import Django settings; if ``True``, ``execute()`` will verify
|
||||||
@ -168,12 +161,6 @@ class BaseCommand(object):
|
|||||||
A short description of the command, which will be printed in
|
A short description of the command, which will be printed in
|
||||||
help messages.
|
help messages.
|
||||||
|
|
||||||
``option_list``
|
|
||||||
This is the list of ``optparse`` options which will be fed
|
|
||||||
into the command's ``OptionParser`` for parsing arguments.
|
|
||||||
Deprecated and will be removed in Django 1.10.
|
|
||||||
Use ``add_arguments`` instead.
|
|
||||||
|
|
||||||
``output_transaction``
|
``output_transaction``
|
||||||
A boolean indicating whether the command outputs SQL
|
A boolean indicating whether the command outputs SQL
|
||||||
statements; if ``True``, the output will automatically be
|
statements; if ``True``, the output will automatically be
|
||||||
@ -207,9 +194,7 @@ class BaseCommand(object):
|
|||||||
to settings. This condition will generate a CommandError.
|
to settings. This condition will generate a CommandError.
|
||||||
"""
|
"""
|
||||||
# Metadata about this command.
|
# Metadata about this command.
|
||||||
option_list = ()
|
|
||||||
help = ''
|
help = ''
|
||||||
args = ''
|
|
||||||
|
|
||||||
# Configuration shortcuts that alter various logic.
|
# Configuration shortcuts that alter various logic.
|
||||||
_called_from_command_line = False
|
_called_from_command_line = False
|
||||||
@ -227,10 +212,6 @@ class BaseCommand(object):
|
|||||||
self.style = color_style()
|
self.style = color_style()
|
||||||
self.stderr.style_func = self.style.ERROR
|
self.stderr.style_func = self.style.ERROR
|
||||||
|
|
||||||
@property
|
|
||||||
def use_argparse(self):
|
|
||||||
return not bool(self.option_list)
|
|
||||||
|
|
||||||
def get_version(self):
|
def get_version(self):
|
||||||
"""
|
"""
|
||||||
Return the Django version, which should be correct for all
|
Return the Django version, which should be correct for all
|
||||||
@ -255,59 +236,26 @@ class BaseCommand(object):
|
|||||||
Create and return the ``ArgumentParser`` which will be used to
|
Create and return the ``ArgumentParser`` which will be used to
|
||||||
parse the arguments to this command.
|
parse the arguments to this command.
|
||||||
"""
|
"""
|
||||||
if not self.use_argparse:
|
parser = CommandParser(self, prog="%s %s" % (os.path.basename(prog_name), subcommand),
|
||||||
def store_as_int(option, opt_str, value, parser):
|
description=self.help or None)
|
||||||
setattr(parser.values, option.dest, int(value))
|
parser.add_argument('--version', action='version', version=self.get_version())
|
||||||
|
parser.add_argument('-v', '--verbosity', action='store', dest='verbosity', default='1',
|
||||||
# Backwards compatibility: use deprecated optparse module
|
type=int, choices=[0, 1, 2, 3],
|
||||||
warnings.warn("OptionParser usage for Django management commands "
|
help='Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output')
|
||||||
"is deprecated, use ArgumentParser instead",
|
parser.add_argument('--settings',
|
||||||
RemovedInDjango110Warning)
|
help=(
|
||||||
parser = OptionParser(prog=prog_name,
|
'The Python path to a settings module, e.g. '
|
||||||
usage=self.usage(subcommand),
|
'"myproject.settings.main". If this isn\'t provided, the '
|
||||||
version=self.get_version())
|
'DJANGO_SETTINGS_MODULE environment variable will be used.'
|
||||||
parser.add_option('-v', '--verbosity', action='callback', dest='verbosity', default=1,
|
),
|
||||||
type='choice', choices=['0', '1', '2', '3'], callback=store_as_int,
|
)
|
||||||
help='Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output')
|
parser.add_argument('--pythonpath',
|
||||||
parser.add_option('--settings',
|
help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".')
|
||||||
help=(
|
parser.add_argument('--traceback', action='store_true',
|
||||||
'The Python path to a settings module, e.g. '
|
help='Raise on CommandError exceptions')
|
||||||
'"myproject.settings.main". If this isn\'t provided, the '
|
parser.add_argument('--no-color', action='store_true', dest='no_color', default=False,
|
||||||
'DJANGO_SETTINGS_MODULE environment variable will be used.'
|
help="Don't colorize the command output.")
|
||||||
),
|
self.add_arguments(parser)
|
||||||
)
|
|
||||||
parser.add_option('--pythonpath',
|
|
||||||
help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".'),
|
|
||||||
parser.add_option('--traceback', action='store_true',
|
|
||||||
help='Raise on CommandError exceptions')
|
|
||||||
parser.add_option('--no-color', action='store_true', dest='no_color', default=False,
|
|
||||||
help="Don't colorize the command output.")
|
|
||||||
for opt in self.option_list:
|
|
||||||
parser.add_option(opt)
|
|
||||||
else:
|
|
||||||
parser = CommandParser(self, prog="%s %s" % (os.path.basename(prog_name), subcommand),
|
|
||||||
description=self.help or None)
|
|
||||||
parser.add_argument('--version', action='version', version=self.get_version())
|
|
||||||
parser.add_argument('-v', '--verbosity', action='store', dest='verbosity', default='1',
|
|
||||||
type=int, choices=[0, 1, 2, 3],
|
|
||||||
help='Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output')
|
|
||||||
parser.add_argument('--settings',
|
|
||||||
help=(
|
|
||||||
'The Python path to a settings module, e.g. '
|
|
||||||
'"myproject.settings.main". If this isn\'t provided, the '
|
|
||||||
'DJANGO_SETTINGS_MODULE environment variable will be used.'
|
|
||||||
),
|
|
||||||
)
|
|
||||||
parser.add_argument('--pythonpath',
|
|
||||||
help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".')
|
|
||||||
parser.add_argument('--traceback', action='store_true',
|
|
||||||
help='Raise on CommandError exceptions')
|
|
||||||
parser.add_argument('--no-color', action='store_true', dest='no_color', default=False,
|
|
||||||
help="Don't colorize the command output.")
|
|
||||||
if self.args:
|
|
||||||
# Keep compatibility and always accept positional arguments, like optparse when args is set
|
|
||||||
parser.add_argument('args', nargs='*')
|
|
||||||
self.add_arguments(parser)
|
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
@ -335,14 +283,10 @@ class BaseCommand(object):
|
|||||||
self._called_from_command_line = True
|
self._called_from_command_line = True
|
||||||
parser = self.create_parser(argv[0], argv[1])
|
parser = self.create_parser(argv[0], argv[1])
|
||||||
|
|
||||||
if self.use_argparse:
|
options = parser.parse_args(argv[2:])
|
||||||
options = parser.parse_args(argv[2:])
|
cmd_options = vars(options)
|
||||||
cmd_options = vars(options)
|
# Move positional args out of options to mimic legacy optparse
|
||||||
# Move positional args out of options to mimic legacy optparse
|
args = cmd_options.pop('args', ())
|
||||||
args = cmd_options.pop('args', ())
|
|
||||||
else:
|
|
||||||
options, args = parser.parse_args(argv[2:])
|
|
||||||
cmd_options = vars(options)
|
|
||||||
handle_default_options(options)
|
handle_default_options(options)
|
||||||
try:
|
try:
|
||||||
self.execute(*args, **cmd_options)
|
self.execute(*args, **cmd_options)
|
||||||
|
@ -50,13 +50,6 @@ class Command(BaseCommand):
|
|||||||
'default value is localhost:8081-8179.'),
|
'default value is localhost:8081-8179.'),
|
||||||
|
|
||||||
test_runner_class = get_runner(settings, self.test_runner)
|
test_runner_class = get_runner(settings, self.test_runner)
|
||||||
if hasattr(test_runner_class, 'option_list'):
|
|
||||||
# Keeping compatibility with both optparse and argparse at this level
|
|
||||||
# would be too heavy for a non-critical item
|
|
||||||
raise RuntimeError(
|
|
||||||
"The method to extend accepted command-line arguments by the "
|
|
||||||
"test management command has changed in Django 1.8. Please "
|
|
||||||
"create an add_arguments class method to achieve this.")
|
|
||||||
|
|
||||||
if hasattr(test_runner_class, 'add_arguments'):
|
if hasattr(test_runner_class, 'add_arguments'):
|
||||||
test_runner_class.add_arguments(parser)
|
test_runner_class.add_arguments(parser)
|
||||||
|
@ -69,16 +69,6 @@ look like this::
|
|||||||
|
|
||||||
self.stdout.write('Successfully closed poll "%s"' % poll_id)
|
self.stdout.write('Successfully closed poll "%s"' % poll_id)
|
||||||
|
|
||||||
.. versionchanged:: 1.8
|
|
||||||
|
|
||||||
Before Django 1.8, management commands were based on the :py:mod:`optparse`
|
|
||||||
module, and positional arguments were passed in ``*args`` while optional
|
|
||||||
arguments were passed in ``**options``. Now that management commands use
|
|
||||||
:py:mod:`argparse` for argument parsing, all arguments are passed in
|
|
||||||
``**options`` by default, unless you name your positional arguments to
|
|
||||||
``args`` (compatibility mode). You are encouraged to exclusively use
|
|
||||||
``**options`` for new commands.
|
|
||||||
|
|
||||||
.. _management-commands-output:
|
.. _management-commands-output:
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
@ -128,12 +118,6 @@ options can be added in the :meth:`~BaseCommand.add_arguments` method like this:
|
|||||||
poll.delete()
|
poll.delete()
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
.. versionchanged:: 1.8
|
|
||||||
|
|
||||||
Previously, only the standard :py:mod:`optparse` library was supported and
|
|
||||||
you would have to extend the command ``option_list`` variable with
|
|
||||||
``optparse.make_option()``.
|
|
||||||
|
|
||||||
The option (``delete`` in our example) is available in the options dict
|
The option (``delete`` in our example) is available in the options dict
|
||||||
parameter of the handle method. See the :py:mod:`argparse` Python documentation
|
parameter of the handle method. See the :py:mod:`argparse` Python documentation
|
||||||
for more about ``add_argument`` usage.
|
for more about ``add_argument`` usage.
|
||||||
@ -227,19 +211,6 @@ Attributes
|
|||||||
All attributes can be set in your derived class and can be used in
|
All attributes can be set in your derived class and can be used in
|
||||||
:class:`BaseCommand`’s :ref:`subclasses<ref-basecommand-subclasses>`.
|
:class:`BaseCommand`’s :ref:`subclasses<ref-basecommand-subclasses>`.
|
||||||
|
|
||||||
.. attribute:: BaseCommand.args
|
|
||||||
|
|
||||||
A string listing the arguments accepted by the command,
|
|
||||||
suitable for use in help messages; e.g., a command which takes
|
|
||||||
a list of application names might set this to '<app_label
|
|
||||||
app_label ...>'.
|
|
||||||
|
|
||||||
.. deprecated:: 1.8
|
|
||||||
|
|
||||||
This should be done now in the :meth:`~BaseCommand.add_arguments()`
|
|
||||||
method, by calling the ``parser.add_argument()`` method. See the
|
|
||||||
``closepoll`` example above.
|
|
||||||
|
|
||||||
.. attribute:: BaseCommand.can_import_settings
|
.. attribute:: BaseCommand.can_import_settings
|
||||||
|
|
||||||
A boolean indicating whether the command needs to be able to
|
A boolean indicating whether the command needs to be able to
|
||||||
@ -261,17 +232,6 @@ All attributes can be set in your derived class and can be used in
|
|||||||
the message error returned in the case of missing arguments. The default is
|
the message error returned in the case of missing arguments. The default is
|
||||||
output by :py:mod:`argparse` ("too few arguments").
|
output by :py:mod:`argparse` ("too few arguments").
|
||||||
|
|
||||||
.. attribute:: BaseCommand.option_list
|
|
||||||
|
|
||||||
This is the list of ``optparse`` options which will be fed
|
|
||||||
into the command's ``OptionParser`` for parsing arguments.
|
|
||||||
|
|
||||||
.. deprecated:: 1.8
|
|
||||||
|
|
||||||
You should now override the :meth:`~BaseCommand.add_arguments` method
|
|
||||||
to add custom arguments accepted by your command. See :ref:`the example
|
|
||||||
above <custom-commands-options>`.
|
|
||||||
|
|
||||||
.. attribute:: BaseCommand.output_transaction
|
.. attribute:: BaseCommand.output_transaction
|
||||||
|
|
||||||
A boolean indicating whether the command outputs SQL statements; if
|
A boolean indicating whether the command outputs SQL statements; if
|
||||||
|
@ -738,15 +738,14 @@ Management commands that only accept positional arguments
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If you have written a custom management command that only accepts positional
|
If you have written a custom management command that only accepts positional
|
||||||
arguments and you didn't specify the
|
arguments and you didn't specify the ``args`` command variable, you might get
|
||||||
:attr:`~django.core.management.BaseCommand.args` command variable, you might
|
an error like ``Error: unrecognized arguments: ...``, as variable parsing is
|
||||||
get an error like ``Error: unrecognized arguments: ...``, as variable parsing
|
now based on :py:mod:`argparse` which doesn't implicitly accept positional
|
||||||
is now based on :py:mod:`argparse` which doesn't implicitly accept positional
|
|
||||||
arguments. You can make your command backwards compatible by simply setting the
|
arguments. You can make your command backwards compatible by simply setting the
|
||||||
:attr:`~django.core.management.BaseCommand.args` class variable. However, if
|
``args`` class variable. However, if you don't have to keep compatibility with
|
||||||
you don't have to keep compatibility with older Django versions, it's better to
|
older Django versions, it's better to implement the new
|
||||||
implement the new :meth:`~django.core.management.BaseCommand.add_arguments`
|
:meth:`~django.core.management.BaseCommand.add_arguments` method as described
|
||||||
method as described in :doc:`/howto/custom-management-commands`.
|
in :doc:`/howto/custom-management-commands`.
|
||||||
|
|
||||||
Custom test management command arguments through test runner
|
Custom test management command arguments through test runner
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -417,10 +417,6 @@ execute and tear down the test suite.
|
|||||||
|
|
||||||
.. versionchanged:: 1.8
|
.. versionchanged:: 1.8
|
||||||
|
|
||||||
Previously, you had to provide an ``option_list`` attribute to a
|
|
||||||
subclassed test runner to add options to the list of command-line
|
|
||||||
options that the :djadmin:`test` command could use.
|
|
||||||
|
|
||||||
The ``keepdb``, ``reverse``, and ``debug_sql`` arguments were added.
|
The ``keepdb``, ``reverse``, and ``debug_sql`` arguments were added.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
@ -448,18 +444,6 @@ Attributes
|
|||||||
By default it is set to ``unittest.defaultTestLoader``. You can override
|
By default it is set to ``unittest.defaultTestLoader``. You can override
|
||||||
this attribute if your tests are going to be loaded in unusual ways.
|
this attribute if your tests are going to be loaded in unusual ways.
|
||||||
|
|
||||||
.. attribute:: DiscoverRunner.option_list
|
|
||||||
|
|
||||||
This is the tuple of ``optparse`` options which will be fed into the
|
|
||||||
management command's ``OptionParser`` for parsing arguments. See the
|
|
||||||
documentation for Python's ``optparse`` module for more details.
|
|
||||||
|
|
||||||
.. deprecated:: 1.8
|
|
||||||
|
|
||||||
You should now override the :meth:`~DiscoverRunner.add_arguments` class
|
|
||||||
method to add custom arguments accepted by the :djadmin:`test`
|
|
||||||
management command.
|
|
||||||
|
|
||||||
Methods
|
Methods
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
from optparse import make_option
|
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
|
||||||
|
|
||||||
|
|
||||||
class Command(BaseCommand):
|
|
||||||
help = "Test optparse compatibility."
|
|
||||||
args = ''
|
|
||||||
|
|
||||||
option_list = BaseCommand.option_list + (
|
|
||||||
make_option("-s", "--style", default="Rock'n'Roll"),
|
|
||||||
make_option("-x", "--example")
|
|
||||||
)
|
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
|
||||||
options["example"]
|
|
||||||
# BaseCommand default option is available
|
|
||||||
options['verbosity']
|
|
||||||
assert (
|
|
||||||
isinstance(options['verbosity'], int), "verbosity option is not int, but %s" % type(options['verbosity'])
|
|
||||||
)
|
|
||||||
self.stdout.write("All right, let's dance %s." % options["style"])
|
|
@ -5,11 +5,10 @@ from django.core import management
|
|||||||
from django.core.management import BaseCommand, CommandError, find_commands
|
from django.core.management import BaseCommand, CommandError, find_commands
|
||||||
from django.core.management.utils import find_command, popen_wrapper
|
from django.core.management.utils import find_command, popen_wrapper
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.test import SimpleTestCase, ignore_warnings, override_settings
|
from django.test import SimpleTestCase, override_settings
|
||||||
from django.test.utils import captured_stderr, captured_stdout, extend_sys_path
|
from django.test.utils import captured_stderr, extend_sys_path
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
from django.utils.deprecation import RemovedInDjango110Warning
|
|
||||||
from django.utils.six import StringIO
|
from django.utils.six import StringIO
|
||||||
|
|
||||||
|
|
||||||
@ -104,20 +103,6 @@ class CommandTests(SimpleTestCase):
|
|||||||
self.assertNotIn("opt_3", out.getvalue())
|
self.assertNotIn("opt_3", out.getvalue())
|
||||||
self.assertNotIn("opt-3", out.getvalue())
|
self.assertNotIn("opt-3", out.getvalue())
|
||||||
|
|
||||||
@ignore_warnings(category=RemovedInDjango110Warning)
|
|
||||||
def test_optparse_compatibility(self):
|
|
||||||
"""
|
|
||||||
optparse should be supported during Django 1.8/1.9 releases.
|
|
||||||
"""
|
|
||||||
out = StringIO()
|
|
||||||
management.call_command('optparse_cmd', stdout=out)
|
|
||||||
self.assertEqual(out.getvalue(), "All right, let's dance Rock'n'Roll.\n")
|
|
||||||
|
|
||||||
# Simulate command line execution
|
|
||||||
with captured_stdout() as stdout, captured_stderr():
|
|
||||||
management.execute_from_command_line(['django-admin', 'optparse_cmd'])
|
|
||||||
self.assertEqual(stdout.getvalue(), "All right, let's dance Rock'n'Roll.\n")
|
|
||||||
|
|
||||||
def test_calling_a_command_with_only_empty_parameter_should_ends_gracefully(self):
|
def test_calling_a_command_with_only_empty_parameter_should_ends_gracefully(self):
|
||||||
out = StringIO()
|
out = StringIO()
|
||||||
management.call_command('hal', "--empty", stdout=out)
|
management.call_command('hal', "--empty", stdout=out)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user