(Run on python 3.6.0)
TL;DR
Usage: prog.py {caesar | vigenere} [key]
parser = argparse.ArgumentParser()
subp = parser.add_subparsers()
caesar = subp.add_parser("caesar", aliases=["c"], allow_abbrev=True)
args = parser.parse_args()
$ python prog.py caes 123
prog.py: error: invalid choice: 'caes' (choose from 'caesar', 'c')
Why is the subparser
abbreviation invalid even with allow_abbrev=True
?
LONG VER
Basically, having an issue getting argparse
to accept abbreviated subparsers
names/aliases.
Here's the code:
Usage: prog.py [caesar] [key]
import sys, argparse
def main(argv):
parser = argparse.ArgumentParser
(description="runs text through X cipher")
subp = parser.add_subparsers\
(help="sub-command help")
#<ArgumentParser object>
caesar = subp.add_parser\
("caesar", aliases=["c"], allow_abbrev=True)
caesar.add_argument\
("key", metavar = "key (any integer)",\
type = int, default = 0)
args = parser.parse_args()
print(caesar)
if __name__ == "__main__":
sys.argv = list(str(c).lower() for c in sys.argv[0:])
main(sys.argv)
So from the code above, it should be expected that any of the following should be accepted:
- "Caesar" or "caesar"
- "C" or "c"
- Any abbreviation in between "c" and "caesar"
So here's the problem:
This works: $ python prog.py c 123
O
This gives an error: $ python prog.py caes 123
X
prog.py: error: invalid choice: 'cae' (choose from 'caesar', 'c')
Now here's the confusing part.
According to the argparse doc:
ArgumentParser supports the creation of such sub-commands with the add_subparsers() method. The add_subparsers() method is normally called with no arguments and returns a special action object. This object has a single method, add_parser(), which takes a command name and any ArgumentParser constructor arguments, and returns an ArgumentParser object that can be modified as usual.
okay, so any
object created with add_subparser()
can create its ownArgumentParser object
withobject.add_parser()
right?...which means this newly created
ArgumentParser
object should be able to accept anyArgumentParser
arguments yeah?
ArgumentParser definition:
class
argparse.ArgumentParser(
prog=None, usage=None,
description=None, epilog=None,
parents=[],formatter_class=argparse.HelpFormatter,
prefix_chars='-',fromfile_prefix_chars=None,
argument_default=None,conflict_handler='error',
add_help=True, allow_abbrev=True)
Create a new ArgumentParser object. All parameters should be passed as keyword arguments. Each parameter has its own more detailed description below, but in short they are:
allow_abbrev
- Allows long options to be abbreviated if the abbreviation is unambiguous.(default: True)
Changed in version 3.5: allow_abbrev parameter was added.
(this was on python 3.6.0)
Thanks in advance, guys