Complement of choices in argparse

Introduce a complement to choices in argument parser’s add_argument

Proposal:

The choices kwarg handling in argparse._ActionsContainer.add_argument enables user to restrict the argument’s value to a specified list of approved values. The feature being proposed will allow users to only accept those values for argument which are not in the provided choice list.

Motivation:

My program only needed filename/filepaths as input to my file argument.
While creating argument for accepting a file using argparse.FileType I wanted to restrict the argument to accept any filename/filepath but not - as - enables stdin input.

The user can get a helpful option help message, like,
non-acceptable choices {'-', 'i', ...}

Suggestion:

  1. A new kwarg unacceptable_choices (or a better name) can be introduced.
  2. Make choices not just accept a list but also an expression like so:
choices=not in ('-')

PS:

  1. Please forgive any errors or coarse language as this is my first feature request. Better ideas are welcome as well.
  2. I know (‘-’) in the example looks like a smiley.

Sounds like a good usecase for subclassing argparse.FileType:

class NotDashFileType(argparse.FileType):
    def __call__(self, string):
        if string == "-":
            raise argparse.ArgumentTypeError("file must not be '-'")
        return super().__call__(string)

P.S. “nice variety!” is compliment of choices, unacceptable_choices is a complement of choices

3 Likes

Thanks @bschubert for the code example and for suggesting a correction on the ‘compliment’ typo.
I’ve made edits as suggested.

That’s a syntactic change, which is a pretty heavy change to make for a particular API call. An additional keyword argument like prohibited that takes a predicate would make more sense.

p.add_argument('divisor', prohibited=lambda x: x == 0)

Thanks @chepner. This a good suggestion, prohibited is also a good name for unacceptable_choices.

Thanks team
any other suggestions for this?