#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


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 17 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 17 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 17 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):
        def handle(self, *args, **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 17 months ago by timo

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

Looks reasonable.

comment:5 Changed 16 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 16 months ago by timgraham

  • Triage Stage changed from Accepted to Ready for checkin

comment:8 Changed 16 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