[Django] #33041: Call_command returns different values for options than manage.py (and itself) when nargs is specified

27 views
Skip to first unread message

Django

unread,
Aug 20, 2021, 4:52:59 PM8/20/21
to django-...@googlegroups.com
#33041: Call_command returns different values for options than manage.py (and
itself) when nargs is specified
-------------------------------------+-------------------------------------
Reporter: kfollstad | Owner: nobody
Type: Bug | Status: new
Component: | Version: 3.1
Uncategorized |
Severity: Normal | Keywords: call_command nargs
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
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.

--
Ticket URL: <https://code.djangoproject.com/ticket/33041>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Aug 20, 2021, 4:59:19 PM8/20/21
to django-...@googlegroups.com
#33041: Call_command returns different values for options than manage.py (and
itself) when nargs is specified
-------------------------------------+-------------------------------------
Reporter: Kevin Follstad | Owner: nobody
Type: Bug | Status: new
Component: Core (Management | Version: 3.1
commands) |
Severity: Normal | Resolution:

Keywords: call_command nargs | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Kevin Follstad):

* component: Uncategorized => Core (Management commands)


--
Ticket URL: <https://code.djangoproject.com/ticket/33041#comment:1>

Django

unread,
Aug 24, 2021, 12:59:03 AM8/24/21
to django-...@googlegroups.com
#33041: Call_command returns different values for options than manage.py (and
itself) when nargs is specified
-------------------------------------+-------------------------------------
Reporter: Kevin Follstad | Owner: nobody
Type: Bug | Status: closed

Component: Core (Management | Version: 3.1
commands) |
Severity: Normal | Resolution: invalid

Keywords: call_command nargs | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => invalid


Comment:

Thanks for the ticket, however it's
[https://docs.djangoproject.com/en/3.2/ref/django-admin/#running-
management-commands-from-your-code documented] that named options are
passed without ''"triggering the argument parser, which means you’ll need
to pass the correct type"''.

> On an unrelated note, thanks for all you do! Django has been a life
changing framework for me.

💗

--
Ticket URL: <https://code.djangoproject.com/ticket/33041#comment:2>

Django

unread,
Aug 24, 2021, 1:00:23 AM8/24/21
to django-...@googlegroups.com
#33041: call_command() returns different values for options than manage.py when
nargs is specified.

-------------------------------------+-------------------------------------
Reporter: Kevin Follstad | Owner: nobody
Type: Bug | Status: closed
Component: Core (Management | Version: 3.1
commands) |
Severity: Normal | Resolution: invalid
Keywords: call_command nargs | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

--
Ticket URL: <https://code.djangoproject.com/ticket/33041#comment:3>

Reply all
Reply to author
Forward
0 new messages