2

When specifying the same argument multiple times, the default argparse behaviour is that the last specified value "wins", overwriting the previous value. I want argparse to show an error when the same argument is specified multiple times instead of silently overwriting the first specified value.

How can that be done?

My current code:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
    '-t', '--test',      # either of this switches
    type=str,            # parameter is string
    dest='test',         # store in 'test'.
    required=True        # required
)

Calling the script:

myscript.py -t hello -t world

leads to no errors, test has the value world. I want argparse to show an error in this case, as the default behaviour is error prone from my point of view.

stefan.at.kotlin
  • 15,347
  • 38
  • 147
  • 270

1 Answers1

4

The simplest option is to use action="append" and check if the result has len > 1:

parser.add_argument(
    '-t', '--test',
    type=str,
    dest='test',
    action='append',
    required=True
)

args = parser.parse_args()

if len(args.test) > 1:
   ...error

But a nicer way would be to solve the problem within the parser, so that you get unified error handling. This can be done with a custom Action like this:

class Once(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        if hasattr(self, 'seen'):
            raise argparse.ArgumentError(self, 'only one please')
        setattr(self, 'seen', True)
        setattr(namespace, self.dest, values)


parser = argparse.ArgumentParser()
parser.add_argument(
    '-t', '--test',
    type=str,
    dest='test',
    action=Once,
    required=True
)
georg
  • 211,518
  • 52
  • 313
  • 390
  • Thanks! Previously didn't find the duplicates, but after comparing duplicates and this one, I like this one more, the error by argpase.ArgumentError looks nicer to me. – stefan.at.kotlin Mar 30 '19 at 15:40
  • Thanks, but see my update. `if getattr(namespace...` has problems with default arguments, an explicit flag appears to be cleaner. – georg Mar 30 '19 at 19:24