cpython icon indicating copy to clipboard operation
cpython copied to clipboard

custom prefixes for `argparse.BooleanOptionalAction`

Open e-kwsm opened this issue 1 year ago • 2 comments

Feature or enhancement

Proposal:

At the moment, argparse.BooleanOptionalAction gives e.g. --foo vs --no-foo, whose prefix is hardcoded:

https://github.com/python/cpython/blob/cd516cd1f5e94dba887353f421513fd172efadf3/Lib/argparse.py#L848
https://github.com/python/cpython/blob/cd516cd1f5e94dba887353f421513fd172efadf3/Lib/argparse.py#L863

It would be beneficial if we can change the prefixes of the binary options: e.g. --enable- vs --disable- like autoconf.

usage: [-h] [--enable-foo | --disable-foo]

options:
  -h, --help            show this help message and exit
  --enable-foo, --disable-foo
                        helpstring for foo

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

e-kwsm avatar May 22 '24 04:05 e-kwsm

This looks like reasonable request. But what API do you want?

  1. Two new parameters for positive and negative suffixes.
    parser.add_argument('--enable-foo', action=BooleanOptionalAction, true_prefix='--enable-', false_prefix='--disable-')
    
  2. Single parameter that takes a pair of suffixes.
    parser.add_argument('--enable-foo', action=BooleanOptionalAction, prefixes=('--enable-', '--disable-'))
    
  3. Simply a parameter for negative option strings.
    parser.add_argument('--enable-foo', action=BooleanOptionalAction, negative_option_strings=['--disable-foo'])
    

serhiy-storchaka avatar Oct 26 '24 18:10 serhiy-storchaka

In general, there's a lot going on in function signature to .add_argument already, I'm not sure that adding more keyword args is really going to help here.

Also, note that the currently hardcoded values have a fundamental issue with custom prefix_chars to ArgumentParser.

 p = ArgumentParser(prefix_chars='++')
 p.add_argument("++alpha", action=BooleanOptionalAction, help="Enable Alpha mode")

Perhaps, just documenting a recipe for this use case is reasonable.

def _add_bool_optional_group(p: ArgumentParser, dest: str, /, *, enable: str, disable: str, required:bool=True) -> ArgumentParser:
    g = p.add_mutually_exclusive_group(required=required)
    g.add_argument(enable, action='store_true', help=f"Enable {dest}", dest=dest, default=None)
    g.add_argument(disable, action='store_false', help=f"Disable {dest} ", dest=dest, default=None)
    return p


def to_parser() -> ArgumentParser:
    p = ArgumentParser(description="Example Tool", prog="example.py")
    return _add_bool_optional_group(p, "alpha_mode", enable="--alpha", disable="--disable-alpha", required=False)

mpkocher avatar Jun 29 '25 04:06 mpkocher