Search code examples
pythonargparse

Minimum amount for action='append'?


I have an argparse argument that appends, and I want it to be called at least twice. (args.option would contain at least two lists) I know that one way would be to check it myself, but I would prefer a way to make argparse do it.

import argparse

parser = argparse.ArgumentParser(description='Do the thing')
parser.add_argument('-o', '--option', nargs=3, action='append', metavar=('A', 'B', 'C'))
args = parser.parse_args()
...

Solution

  • With that argument, each time you use a '-o' flag, it looks for 3 strings, and it puts them in a list in the output:

    In [127]: import argparse
         ...: 
         ...: parser = argparse.ArgumentParser(description='Do the thing')
         ...: parser.add_argument('-o', '--option', nargs=3, action='append', metavar=('A', 'B', 'C'));
    
    In [128]: parser.print_help()
    usage: ipykernel_launcher.py [-h] [-o A B C]
    
    Do the thing
    
    optional arguments:
      -h, --help            show this help message and exit
      -o A B C, --option A B C
    
    In [129]: parser.parse_args('-o 1 2 3 -o a b c'.split())
    Out[129]: Namespace(option=[['1', '2', '3'], ['a', 'b', 'c']])
    

    There's no mechanism in argparse to check the length of args.option. Nor any meta-nargs to requires the double use of '-o'.

    In [130]: parser.parse_args(''.split())
    Out[130]: Namespace(option=None
    In [131]: parser.parse_args('-o 1 2 3'.split())
    Out[131]: Namespace(option=[['1', '2', '3']])
    

    You could define 2 positionals with the same dest. The parsing works ok, but the usage formatting has problem, raising error with both help and error messages. I'd stick with checking len(args.option).