Fixed #25483 -- Allowed passing non-string arguments to call_command
Thanks KS Chan for the report and Tim Graham for the review.
This commit is contained in:
parent
fa2e1e633a
commit
3f22e83e90
|
@ -16,6 +16,7 @@ from django.core.management.base import (
|
||||||
from django.core.management.color import color_style
|
from django.core.management.color import color_style
|
||||||
from django.utils import autoreload, lru_cache, six
|
from django.utils import autoreload, lru_cache, six
|
||||||
from django.utils._os import npath, upath
|
from django.utils._os import npath, upath
|
||||||
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
|
|
||||||
def find_commands(management_dir):
|
def find_commands(management_dir):
|
||||||
|
@ -106,7 +107,7 @@ def call_command(name, *args, **options):
|
||||||
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()}
|
arg_options = {opt_mapping.get(key, key): value for key, value in options.items()}
|
||||||
defaults = parser.parse_args(args=args)
|
defaults = parser.parse_args(args=[force_text(a) for a in args])
|
||||||
defaults = dict(defaults._get_kwargs(), **arg_options)
|
defaults = dict(defaults._get_kwargs(), **arg_options)
|
||||||
# Move positional args out of options to mimic legacy optparse
|
# Move positional args out of options to mimic legacy optparse
|
||||||
args = defaults.pop('args', ())
|
args = defaults.pop('args', ())
|
||||||
|
|
|
@ -7,6 +7,7 @@ class Command(BaseCommand):
|
||||||
requires_system_checks = True
|
requires_system_checks = True
|
||||||
|
|
||||||
def add_arguments(self, parser):
|
def add_arguments(self, parser):
|
||||||
|
parser.add_argument("integer", nargs='?', type=int, default=0)
|
||||||
parser.add_argument("-s", "--style", default="Rock'n'Roll")
|
parser.add_argument("-s", "--style", default="Rock'n'Roll")
|
||||||
parser.add_argument("-x", "--example")
|
parser.add_argument("-x", "--example")
|
||||||
parser.add_argument("--opt-3", action='store_true', dest='option3')
|
parser.add_argument("--opt-3", action='store_true', dest='option3')
|
||||||
|
@ -18,3 +19,5 @@ class Command(BaseCommand):
|
||||||
if options['verbosity'] > 0:
|
if options['verbosity'] > 0:
|
||||||
self.stdout.write("I don't feel like dancing %s." % options["style"])
|
self.stdout.write("I don't feel like dancing %s." % options["style"])
|
||||||
self.stdout.write(','.join(options.keys()))
|
self.stdout.write(','.join(options.keys()))
|
||||||
|
if options['integer'] > 0:
|
||||||
|
self.stdout.write("You passed %d as a positional argument." % options['integer'])
|
||||||
|
|
|
@ -103,6 +103,14 @@ 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())
|
||||||
|
|
||||||
|
def test_call_command_option_parsing_non_string_arg(self):
|
||||||
|
"""
|
||||||
|
It should be possible to pass non-string arguments to call_command.
|
||||||
|
"""
|
||||||
|
out = StringIO()
|
||||||
|
management.call_command('dance', 1, verbosity=0, stdout=out)
|
||||||
|
self.assertIn("You passed 1 as a positional argument.", out.getvalue())
|
||||||
|
|
||||||
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…
Reference in New Issue