#22985 closed Bug (fixed)

call_command() ignores dest from make_option() and uses kwarg name instead

Reported by: giuliettamasina Owned by: nobody
Component: Core (Management commands) Version: master
Severity: Normal Keywords:
Cc: 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

Let's say I've defined a custom manage command and added an option to it like this:

option_list = BaseCommand.option_list + (
    make_option('--myoption', action='store', dest='my_opt_var'),
)

I can now call this from the command-line like this:

./manage.py mycommand --my_opt_var=abc

And there will now be an entry in the options dictionary: options['my_opt_var']

However, if I call the same command from code:

call_command('mycommand', myoption='abc')

The added entry will instead use the name of the keyword argument: options['myoption']

I would expect call_command() to use what I've specified through the dest parameter of make_option()

Change History (8)

comment:1 Changed 12 months ago by timo

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Note that we've switched to argparse in master (1.8). Could you check if the issue still exists?

comment:2 Changed 12 months ago by giuliettamasina

Yeah, I actually only tried this in 1.7b3, will try it in master and update this ticket with more info.

comment:3 Changed 12 months ago by giuliettamasina

Seems like this is still the case in master. These are the steps I did to reproduce:

  1. Start a new project and a new app, and add the new app to settings.
  2. In the new app, create the path management/commands/my_command.py with all the intermediate __init__.py files.
  3. In my_command.py paste the following code:
    from django.core.management.base import BaseCommand
    
    
    class Command(BaseCommand):
    
        def add_arguments(self, parser):
            parser.add_argument('--myflag',
                                action='store',
                                dest='mydest',
                                default=False)
    
        def handle(self, *args, **options):
            print(options)
    
  4. From the command-line, run ./manage.py shell, and then run these lines:
    >>> from django.core import management
    >>> management.call_command('my_command', myflag='abc')
    

This will print:

{'settings': None, 'pythonpath': None, 'verbosity': 1, 'traceback': False, 'no_color': False, 'mydest': False, 'myflag': 'abc'}

I would expect it to print:

{'settings': None, 'pythonpath': None, 'verbosity': 1, 'traceback': False, 'no_color': False, 'mydest': 'abc'}

comment:4 Changed 12 months ago by timo

  • Triage Stage changed from Unreviewed to Accepted
  • Type changed from Uncategorized to Bug

Looks reasonable.

comment:5 Changed 11 months ago by areski

You will have similar problem with Django 1.6.5 except that 'mydest' will be None instead of False.

comment:7 Changed 11 months ago by timgraham

  • Triage Stage changed from Accepted to Ready for checkin

comment:8 Changed 11 months ago by Claude Paroz <claude@…>

  • Resolution set to fixed
  • Status changed from new to closed

In 2cc8ffe258008096a70791115b2daa12f0ef0192:

Fixed #22985 -- Made call_command accept option name parameter

Thanks giulettamasina for the report and Tim Graham for the review.

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