"substrings" of long form arguments are "allowed"
jsivak opened this issue · 3 comments
Not sure if this is a bug or a feature:
I have a long form argument of "init_sequece" defined in my yaml config.
When I run my program like this:
python program.py --init
the program acts as if "--init-sequence" was fully passed on the commandline.
Is this expected / desired behavior?
This looks like a bug (feature?) in the argparse
module. Every subchain of an option is accepted:
In [1]: import argparse
In [2]: parser = argparse.ArgumentParser()
In [3]: parser.add_argument('--init-sequence', dest='init_sequence', action='store_true')
Out[3]: _StoreTrueAction(option_strings=['--init-sequence'], dest='init_sequence', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
In [4]: parser.parse_args(('--i',))
Out[4]: Namespace(init_sequence=True)
In [5]: parser.parse_args(('--init',))
Out[5]: Namespace(init_sequence=True)
In [6]: parser.parse_args(('--init-seq',))
Out[6]: Namespace(init_sequence=True)
If there is two distincts options init
and init_sequence
, subchains of init
generate errors because this is considering for being the boths options:
In [1]: import argparse
In [2]: parser = argparse.ArgumentParser()
In [3]: parser.add_argument('--init-sequence', dest='init_sequence', action='store_true')
Out[3]: _StoreTrueAction(option_strings=['--init-sequence'], dest='init_sequence', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
In [4]: parser.add_argument('--init', dest='init', action='store_true')
Out[4]: _StoreTrueAction(option_strings=['--init'], dest='init', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
In [5]: parser.parse_args(('--i',))
usage: ipython [-h] [--init-sequence] [--init]
ipython: error: ambiguous option: --i could match --init-sequence, --init
In [6]: parser.parse_args(('--init',))
Out[6]: Namespace(init=True, init_sequence=False)
In [7]: parser.parse_args(('--init-',))
Out[7]: Namespace(init=False, init_sequence=True)
In [8]: parser.parse_args(('--init-sequence',))
Out[8]: Namespace(init=False, init_sequence=True)
As this module is just initializing argparse.ArgumentParser
from a structured dictionnary, there is nothing I can do (and I don't see any option in argparse module for managing this behaviour).
Thanks for investigating.
Here are the docs about the "feature":
https://docs.python.org/3/library/argparse.html#argument-abbreviations-prefix-matching
Also here is a thread discussing the issue:
https://mail.python.org/pipermail/python-dev/2013-November/130601.html
and the bugs filed:
http://bugs.python.org/issue19814
I don't really like this behaviour so I add an option (allow_abbrev
) for managing it. It use the tip given at http://bugs.python.org/issue14910 (redefining the _get_option_tuples
method). By default abbrevations are disabled by clg (which is the opposite of argparse).
And thanks for the links!