fmenabe/python-clg

"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).

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!