﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
33041	call_command() returns different values for options than manage.py when nargs is specified.	Kevin Follstad	nobody	"Maybe I am not understanding something in the documentation, but this seems like a bug (tested on 3.1.7).

When nargs is specified for an option, according to the argparse documentation, the parsed option should always be a list containing the option's values. However that is not the case if options are specified as kw=""the-kw-option"" when passed to call_command. For example:

''main/test/management/commands/commandbug.py:''

{{{
from django.core.management.base import BaseCommand
from django.core.management import call_command

# Broken: kw is not a list
def call_commandbug1():
    call_command(""commandbug"", ""the-positional-arg"", kw=""the-kw-arg"")

# Works: kw is a list
def call_commandbug2():
    call_command(""commandbug"", ""the-positional-arg"", ""--kw=the-kw-arg"")


class Command(BaseCommand):
    help = ""Minimal call_command bug demo""

    def add_arguments(self, parser):
        parser.add_argument(
            ""positional"", nargs=1, type=str, help=""Positional arg""
        )
        parser.add_argument(
            ""--kw"",
            nargs=1,
            type=str,
            help=""Keyword arg"",
        )
        super().add_arguments(parser)

    def handle(self, *args, **options):
        print(options)
}}}

When run from call_command1 the value of kw is not a list:

{{{
$> ./manage.py shell
Python 3.9.6 (default, Jun 30 2021, 10:22:16) 
In [1]: from main.test.management.commands.commandbug import call_commandbug1, call_commandbug2
In [2]: call_commandbug1()
{'verbosity': 1, 'settings': None, 'pythonpath': None, 'traceback': False, 'no_color': False, 'force_color': False, 'skip_checks': True, 'positional': ['the-positional-arg'], 'kw': 'the-kw-arg'}
}}}

When run from call_command2, the value is kw is a list matching argparse:

{{{
In [3]: call_commandbug2()
{'verbosity': 1, 'settings': None, 'pythonpath': None, 'traceback': False, 'no_color': False, 'force_color': False, 'skip_checks': True, 'positional': ['the-positional-arg'], 'kw': ['the-kw-arg']}
}}}

When run via manage.py it also works as expected / per argparse:

{{{
$> ./manage.py commandbug ""the-positional-arg"" --kw ""the-kw-arg""
{'verbosity': 1, 'settings': None, 'pythonpath': None, 'traceback': False, 'no_color': False, 'force_color': False, 'skip_checks': False, 'positional': ['the-positional-arg'], 'kw': ['the-kw-arg']}
}}}

Hopefully this makes sense, and is a useful observation.
On an unrelated note, thanks for all you do! Django has been a life changing framework for me."	Bug	closed	Core (Management commands)	3.1	Normal	invalid	call_command nargs		Unreviewed	0	0	0	0	0	0
