Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#32047 closed Bug (fixed)

Required mutually exclusive groups don't work with boolean arguments.

Reported by: Mark Gajdosik Owned by: Hasan Ramezani
Component: Core (Management commands) Version: 3.1
Severity: Normal Keywords: call_command, exclusive group, store_true, action, explicit, error
Cc: Hasan Ramezani, Alex Tomic Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have the following management command (called test.py):

from django.core.management import BaseCommand


class Command(BaseCommand):
    def add_arguments(self, parser):
        group = parser.add_mutually_exclusive_group(required=True)
        group.add_argument('--value', type=str)
        group.add_argument('--flag', action='store_true')

    def handle(self, *args, **options):
        pass

Running ./manage.py test --flag or ./manage.py --value foo, the command works as expected. Using call_command to call the command from my code fails if I pass --flag, e.g.:

from django.core.management import call_command

call_command('test', flag=True)

This gets me the following traceback:

argparse.ArgumentError: argument --flag: ignored explicit argument 'True'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/home/mark/.local/share/virtualenvs/backend-KlVhwr95/lib/python3.8/site-packages/django/core/management/__init__.py", line 147, in call_command
    defaults = parser.parse_args(args=parse_args)
  File "/home/mark/.local/share/virtualenvs/backend-KlVhwr95/lib/python3.8/site-packages/django/core/management/base.py", line 57, in parse_args
    return super().parse_args(args, namespace)
  File "/usr/lib/python3.8/argparse.py", line 1780, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/lib/python3.8/argparse.py", line 1819, in parse_known_args
    self.error(str(err))
  File "/home/mark/.local/share/virtualenvs/backend-KlVhwr95/lib/python3.8/site-packages/django/core/management/base.py", line 63, in error
    raise CommandError("Error: %s" % message)
django.core.management.base.CommandError: Error: argument --flag: ignored explicit argument 'True'

Change History (12)

comment:1 by Mark Gajdosik, 4 years ago

Probably stating the obvious, but I get the same error when running the command from console and passing value to the --flag explicitly, e.g. ./manage.py test --flag=True.

comment:2 by Mariusz Felisiak, 4 years ago

Resolution: invalid
Status: newclosed
Summary: Management commands: Mutually exclusive argument groups don't work with 'store_true' arguments & call_commandMutually exclusive argument groups don't work with 'store_true' arguments & call_command

Please do not use Trac as a support channel. You should pass argument without a value, e.g. call_command('test', '--flag').

comment:3 by Mariusz Felisiak, 4 years ago

Mark's response via email:

  1. I'm not using your trac as a support channel. This was the first time I used it and I doubt I'll use it again.
  2. RE the actual issue: docs for call_comamnd clearly state: "command options that take no arguments are passed as keywords with True or False". This works fine, until the arg is placed inside a group. The docs don't mention this.

I understand that Django devs are busy, but at least try understanding what the ticket is saying before rushing to close it. Thank you.

Kind Regards,
Mark Gajdosik

comment:4 by Mariusz Felisiak, 4 years ago

Cc: Hasan Ramezani Alex Tomic added
Summary: Mutually exclusive argument groups don't work with 'store_true' arguments & call_commandRequired mutually exclusive groups don't work boolean arguments.
Triage Stage: UnreviewedAccepted
  1. I'm not using your trac as a support channel. This was the first time I used it and I doubt I'll use it again.

I'm sorry you had a bad experience. From the ticket description I assumed that you're trying to find a way to pass a boolean argument, that's why I took it as a support question.

  1. RE the actual issue: docs for call_comamnd clearly state: "command options that take no arguments are passed as keywords with True or False". This works fine, until the arg is placed inside a group. The docs don't mention this.

Good catch, I can reproduce this issue for a required mutually exclusive groups with boolean arguments. We should probably change preparing boolean arguments before passing them to parse_args().

comment:5 by Mariusz Felisiak, 4 years ago

Resolution: invalid
Status: closednew

comment:6 by Mariusz Felisiak, 4 years ago

Summary: Required mutually exclusive groups don't work boolean arguments.Required mutually exclusive groups don't work with boolean arguments.

comment:7 by Mark Gajdosik, 4 years ago

I'm sorry you had a bad experience. From the ticket description I assumed that you're trying to find a way to pass a boolean argument, that's why I took it as a support question.

I'm to blame for that as I failed to describe the issue clearly. Thank you for reopening the ticket and for your initial suggestion, which helped me around the issue.

comment:8 by Hasan Ramezani, 4 years ago

Has patch: set
Owner: changed from nobody to Hasan Ramezani
Status: newassigned
Version 0, edited 4 years ago by Hasan Ramezani (next)

comment:9 by Mariusz Felisiak, 4 years ago

Patch needs improvement: set

comment:10 by Mariusz Felisiak, 4 years ago

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:11 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

Resolution: fixed
Status: assignedclosed

In 6eb3f53b:

Fixed #32047 -- Fixed call_command() crash if a constant option from required mutually exclusive group is passed in options.

comment:12 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

In efe74ff:

Refs #32047 -- Added test for using call_command() with constant required options.

Note: See TracTickets for help on using tickets.
Back to Top