Opened 9 years ago

Closed 9 years ago

#25483 closed Cleanup/optimization (fixed)

call_command() should pass positional argument as str() instead of int()

Reported by: KS Chan Owned by: nobody
Component: Core (Management commands) Version: dev
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

Since argparse is adopted, int() argument should be passed as str() and let argparse to handle it. This is better mentioned in the doc.

See below example:

# management/commands/callme.py
from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument('poll_id', nargs='+', type=int)

    def handle(self, *args, **options):
        for poll_id in options['poll_id']:
            self.stdout.write('%d' % poll_id)


# python manage.py shell
>>> from django.core.management import call_command
>>> call_command('callme', 1, 2, 3)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/mrkschan/tmp/tcallcommand/env/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 109, in call_command
    defaults = parser.parse_args(args=args)
  File "/home/mrkschan/tmp/tcallcommand/env/local/lib/python2.7/site-packages/django/core/management/base.py", line 64, in parse_args
    return super(CommandParser, self).parse_args(args, namespace)
  File "/usr/lib/python2.7/argparse.py", line 1690, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/lib/python2.7/argparse.py", line 1722, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/lib/python2.7/argparse.py", line 1763, in _parse_known_args
    option_tuple = self._parse_optional(arg_string)
  File "/usr/lib/python2.7/argparse.py", line 2050, in _parse_optional
    if not arg_string[0] in self.prefix_chars:
TypeError: 'int' object has no attribute '__getitem__'
>>> call_command('callme', '1', '2', '3')
1
2
3

Change History (5)

comment:1 by Claude Paroz, 9 years ago

Component: DocumentationCore (Management commands)
Triage Stage: UnreviewedAccepted
Type: UncategorizedCleanup/optimization
Version: 1.8master

I think we could force all args to text before passing them to parse_args.

comment:2 by Claude Paroz, 9 years ago

Has patch: set

comment:3 by Tim Graham, 9 years ago

Triage Stage: AcceptedReady for checkin

comment:4 by Tim Graham, 9 years ago

Summary: [doc] Using call_command() should pass positional argument as str() instead of int()call_command() should pass positional argument as str() instead of int()

comment:5 by Claude Paroz <claude@…>, 9 years ago

Resolution: fixed
Status: newclosed

In 3f22e83:

Fixed #25483 -- Allowed passing non-string arguments to call_command

Thanks KS Chan for the report and Tim Graham for the review.

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