5

I'm trying to add a required input file name and an optional output file name to more than one subparser using the argparse module.

Here is my attempt:

# test_argparse.py

import argparse

def setup_parser():

    parser = argparse.ArgumentParser(prog='test_argparse.py',
                            formatter_class=argparse.RawDescriptionHelpFormatter,
                            description='Testing the argparse module.')

    parser.add_argument('--version', action='version', version='%(prog)s 1.0')

    subparsers = parser.add_subparsers()
    parser_actionA = subparsers.add_parser('actionA')
    parser_actionB = subparsers.add_parser('actionB')
    parser_actionC = subparsers.add_parser('actionC')

    parser.add_argument('infile', nargs=1, help='input mesh file name')
    parser.add_argument('outfile', nargs='?', help='output mesh file name')

    return parser

if __name__ == '__main__':
    parser = setup_parser()
    args = parser.parse_args()
    print args

If I execute this:

python test_argparse.py actionA infile outfile

it doesn't work, and what I get is:

usage: test_argparse.py [-h] [--version]
                    {actionA,actionB,actionC} ... infile [outfile]
test_argparse.py: error: unrecognized arguments: infile
codecool
  • 5,886
  • 4
  • 29
  • 40
Kevin Copps
  • 51
  • 1
  • 3
  • possible duplicate of [Python argparse - Add argument to multiple subparsers](http://stackoverflow.com/questions/7498595/python-argparse-add-argument-to-multiple-subparsers) – Chris Jun 19 '12 at 22:35
  • this issue may be more related to [Python argparse positional arguments and sub-commands](http://stackoverflow.com/questions/8668519/python-argparse-positional-arguments-and-sub-commands) in which the conclusion seems to be that this behavior is either a bug in argparse or a feature of the greedy pattern matching it uses underneath the covers. – Kevin Copps Jun 20 '12 at 15:29

1 Answers1

7

Define a new parser with common arguments and pass it to subparsers as parents:

files = argparse.ArgumentParser(add_help=False)
files.add_argument('infile', nargs=1, help='input mesh file name')
files.add_argument('outfile', nargs='?', help='output mesh file name')

subparsers = parser.add_subparsers()
parser_actionA = subparsers.add_parser('actionA', parents=[files])
parser_actionB = subparsers.add_parser('actionB', parents=[files])
etc..
georg
  • 211,518
  • 52
  • 313
  • 390
  • 1
    Is `parser` correct in your example? If I define `files` as you have, then `parser` "is not defined". Should it be `files` instead? – harperville May 03 '16 at 18:35
  • 1
    @harperville: yes, it's correct. This snippet extends the OP's code, where they have `parser` defined. – georg May 03 '16 at 18:39
  • 1
    The `add_help` directive was key to allowing me to continue in my quest to get this to work. Thanks for this answer. – harperville May 03 '16 at 19:26