0

How do I tell argparse that I want to allow a command line argument only once?

import sys
import argparse

parser = argparse.ArgumentParser()
parser.add_argument(
    "--out",
    required=True,
)

parsed = parser.parse_args(sys.argv[1:])
print(f"out: {parsed.out}")

If I call this code like this:

python3 argparsetest.py --out 1 --out 2 --out 3

it prints

out: 3

But I would rather have it error out telling the user that the --out argument can only be used once.

I looked at the nargs option, but that says how many following arguments should be considered for --out, not how often I can pass the --out.

There is the required option which forces the user to supply the argument (at least once), but I'm looking for limiting the upper number of how often the argument can be used, not the lower.

I've seen Only one command line argument with argparse but this is from 2013 and I am hoping that there is an easier way to do this now.

How can I limit the number of uses of a command line flag?

Robert
  • 7,394
  • 40
  • 45
  • 64
  • There was an `append` option that would return repeated entries in a list, then you could enforce that no list be longer than 1 item in length. – RufusVS Jun 28 '21 at 23:12
  • No changes in that regard. I know the `argparse` docs are long, and a pain to read, but such feature would only make them longer :) Why is this important to you? Why would your users do this? – hpaulj Jun 28 '21 at 23:18
  • I need to pass these arguments on to another program, which only accepts it once. I was hoping there was something like `required` (more than zero) and I wouldn't have to collect via `append` and then check manually. In my program, it may make sense to users to try and pass this argument multiple times and I don't want them to be surprised that all but the last get ignored. – Robert Jun 29 '21 at 14:19

1 Answers1

2

Following up on my comment:

import sys
import argparse

# args = sys.argv[1:]

args = "--out 1 --out 2 --out 3".split()

print(f"Input args: {args}")


parser = argparse.ArgumentParser()
parser.add_argument(
    "--out",
    action="append",
    required=True,
)

parsed = vars(parser.parse_args(args))

for key, val in parsed.items():
    if isinstance(val, list):
        print(f"{key} specified {len(val)} times!")
        parsed[key] = val[0]  # or val[-1]

print(parsed)
RufusVS
  • 4,008
  • 3
  • 29
  • 40
  • This is a good example of using the flexibility that `argparse` already provides. 'append' already allows you to accept repeated values. Usually it's used because you want to use them all, but selecting just one, or objecting to a certain number is consistent with that design. And as far as I can tell, it doesn't complicate the `usage`. – hpaulj Jun 29 '21 at 02:18