#26597: Optparse for `noinput` and `interactive` can produce unwanted results
when
passed togeather
-------------------------------------+-------------------------------------
Reporter: JBKahn | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.8
Severity: Normal | Resolution:
Keywords: migrate argparse | Triage Stage:
command | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by JBKahn):
* needs_better_patch: => 0
* needs_tests: => 0
* needs_docs: => 0
Old description:
> Because of the way options are parsed on:
> https://github.com/django/django/blob/1.8.13/django/core/management/__init__.py#L106-L108
>
> You can end up with the dictionary returning `.item` back in one of two
> orders when you pass both `interactive` and `noinput`.
>
> I assume this is present on other management commands, but I have not
> tested them.
>
> The following command:
> `arg_options = {opt_mapping.get(key, key): value for key, value in
> options.items()}`
> can be run as:
> `{{'noinput': 'interactive'}.get(key, key): value for key, value in
> [('verbosity', 0), ('fake', True), ('list', True), ('fake_initial',
> True), ('app_label', 'tests'), ('noinput', True), ('interactive',
> False)]}`
> or
> `{{'noinput': 'interactive'}.get(key, key): value for key, value in
> [('verbosity', 0), ('fake', True), ('list', True), ('fake_initial',
> True), ('app_label', 'tests'), ('interactive', False), ('noinput',
> True)]}`
>
> leading to `interactive` being False or True, respectively.
>
> The weird thing, is that `noinput` and `interactive` are opposite
> commands and yet this code uses it for the same value. Makes my scripts
> sometimes fail.
New description:
The option mapping for argparse in `call_command` is incorrectly mapping
args. For example, it maps `noinput` to `interactive` and does not take
into account that they are opposites. Here's where the bug is:
Because of the way options are parsed on:
https://github.com/django/django/blob/1.8.13/django/core/management/__init__.py#L106-L108
You can end up with the dictionary returning `.items` back in one of two
orders when you pass both `interactive` and `noinput`. Which is what I was
doing in a test case.
I assume this is present on other management commands, but I have not
tested them.
(note, I simplified `opt_mapping` to just the example)
The following command:
`arg_options = {opt_mapping.get(key, key): value for key, value in
options.items()}`
can be run as:
`{{'noinput': 'interactive'}.get(key, key): value for key, value in
[('verbosity', 0), ('fake', True), ('list', True), ('fake_initial', True),
('app_label', 'tests'), ('noinput', True), ('interactive', False)]}`
or
`{{'noinput': 'interactive'}.get(key, key): value for key, value in
[('verbosity', 0), ('fake', True), ('list', True), ('fake_initial', True),
('app_label', 'tests'), ('interactive', False), ('noinput', True)]}`
leading to `interactive` being False or True, respectively.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/26597#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/064.64c659074a9ab53a8ac43defb1c54fa6%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.