Fixed #29133 -- Fixed call_command() crash if a required option is passed in options.

This commit is contained in:
Alex Tomic 2018-03-02 12:25:08 -05:00 committed by Tim Graham
parent 40bac28faa
commit a1a3e51561
3 changed files with 31 additions and 1 deletions

View File

@ -117,7 +117,14 @@ def call_command(command_name, *args, **options):
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=[str(a) for a in args])
parse_args = [str(a) for a in args]
# Any required arguments which are passed in via **options must must be
# passed to parse_args().
parse_args += [
'{}={}'.format(min(opt.option_strings), arg_options[opt.dest])
for opt in parser._actions if opt.required and opt.dest in options
]
defaults = parser.parse_args(args=parse_args)
defaults = dict(defaults._get_kwargs(), **arg_options)
# Raise an error if any unknown options were passed.
stealth_options = set(command.base_stealth_options + command.stealth_options)

View File

@ -0,0 +1,11 @@
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('-n', '--need-me', required=True)
parser.add_argument('-t', '--need-me-too', required=True, dest='needme2')
def handle(self, *args, **options):
self.stdout.write(','.join(options))

View File

@ -194,6 +194,18 @@ class CommandTests(SimpleTestCase):
with self.assertRaisesMessage(TypeError, msg):
management.call_command('dance', unrecognized=1, unrecognized2=1)
def test_call_command_with_required_parameters_in_options(self):
out = StringIO()
management.call_command('required_option', need_me='foo', needme2='bar', stdout=out)
self.assertIn('need_me', out.getvalue())
self.assertIn('needme2', out.getvalue())
def test_call_command_with_required_parameters_in_mixed_options(self):
out = StringIO()
management.call_command('required_option', '--need-me=foo', needme2='bar', stdout=out)
self.assertIn('need_me', out.getvalue())
self.assertIn('needme2', out.getvalue())
class CommandRunTests(AdminScriptTestCase):
"""