Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Patch python3.7's argparse.py to support overriding the strings that are shown as default values for flags
diff --git a/Lib/argparse.py b/Lib/argparse.py
index 209b4e9..254b803 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -665,11 +665,11 @@ class ArgumentDefaultsHelpFormatter(HelpFormatter):
def _get_help_string(self, action):
help = action.help
- if '%(default)' not in action.help:
+ if '%(default)' not in help and '%(help_default)' not in help:
if action.default is not SUPPRESS:
defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
if action.option_strings or action.nargs in defaulting_nargs:
- help += ' (default: %(default)s)'
+ help += ' (default: %(help_default)s)'
return help
@@ -782,6 +782,13 @@ class Action(_AttributeHolder):
- help -- The help string describing the argument.
+ - help_default -- A string describing the default value of the
+ argument to the user, if the internal Pythonic default value would
+ be confusing. For instance some flags to interactive programs need
+ help_default="Ask"; another common pattern is
+ '--disable-thing', dest='thing', action='store_false', default=True,
+ help_default='False' or help_default='Enabled'.
+
- metavar -- The name to be used for the option's argument with the
help string. If None, the 'dest' value will be used as the name.
"""
@@ -796,6 +803,7 @@ class Action(_AttributeHolder):
choices=None,
required=False,
help=None,
+ help_default=None,
metavar=None):
self.option_strings = option_strings
self.dest = dest
@@ -806,6 +814,7 @@ class Action(_AttributeHolder):
self.choices = choices
self.required = required
self.help = help
+ self.help_default = default if help_default is None else help_default
self.metavar = metavar
def _get_kwargs(self):
@@ -818,6 +827,7 @@ class Action(_AttributeHolder):
'type',
'choices',
'help',
+ 'help_default',
'metavar',
]
return [(name, getattr(self, name)) for name in names]
@@ -838,6 +848,7 @@ class _StoreAction(Action):
choices=None,
required=False,
help=None,
+ help_default=None,
metavar=None):
if nargs == 0:
raise ValueError('nargs for store actions must be > 0; if you '
@@ -855,6 +866,7 @@ class _StoreAction(Action):
choices=choices,
required=required,
help=help,
+ help_default=help_default,
metavar=metavar)
def __call__(self, parser, namespace, values, option_string=None):
@@ -870,6 +882,7 @@ class _StoreConstAction(Action):
default=None,
required=False,
help=None,
+ help_default=None,
metavar=None):
super(_StoreConstAction, self).__init__(
option_strings=option_strings,
@@ -878,7 +891,8 @@ class _StoreConstAction(Action):
const=const,
default=default,
required=required,
- help=help)
+ help=help,
+ help_default=help_default)
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, self.const)
@@ -891,14 +905,16 @@ class _StoreTrueAction(_StoreConstAction):
dest,
default=False,
required=False,
- help=None):
+ help=None,
+ help_default=None):
super(_StoreTrueAction, self).__init__(
option_strings=option_strings,
dest=dest,
const=True,
default=default,
required=required,
- help=help)
+ help=help,
+ help_default=help_default)
class _StoreFalseAction(_StoreConstAction):
@@ -908,14 +924,16 @@ class _StoreFalseAction(_StoreConstAction):
dest,
default=True,
required=False,
- help=None):
+ help=None,
+ help_default=None):
super(_StoreFalseAction, self).__init__(
option_strings=option_strings,
dest=dest,
const=False,
default=default,
required=required,
- help=help)
+ help=help,
+ help_default=help_default)
class _AppendAction(Action):
@@ -930,6 +948,7 @@ class _AppendAction(Action):
choices=None,
required=False,
help=None,
+ help_default=None,
metavar=None):
if nargs == 0:
raise ValueError('nargs for append actions must be > 0; if arg '
@@ -947,6 +966,7 @@ class _AppendAction(Action):
choices=choices,
required=required,
help=help,
+ help_default=help_default,
metavar=metavar)
def __call__(self, parser, namespace, values, option_string=None):
@@ -964,6 +984,7 @@ class _AppendConstAction(Action):
default=None,
required=False,
help=None,
+ help_default=None,
metavar=None):
super(_AppendConstAction, self).__init__(
option_strings=option_strings,
@@ -973,6 +994,7 @@ class _AppendConstAction(Action):
default=default,
required=required,
help=help,
+ help_default=help_default,
metavar=metavar)
def __call__(self, parser, namespace, values, option_string=None):
@@ -988,14 +1010,16 @@ class _CountAction(Action):
dest,
default=None,
required=False,
- help=None):
+ help=None,
+ help_default=None):
super(_CountAction, self).__init__(
option_strings=option_strings,
dest=dest,
nargs=0,
default=default,
required=required,
- help=help)
+ help=help,
+ help_default=help_default)
def __call__(self, parser, namespace, values, option_string=None):
new_count = _ensure_value(namespace, self.dest, 0) + 1
@@ -1008,13 +1032,15 @@ class _HelpAction(Action):
option_strings,
dest=SUPPRESS,
default=SUPPRESS,
- help=None):
+ help=None,
+ help_default=None):
super(_HelpAction, self).__init__(
option_strings=option_strings,
dest=dest,
default=default,
nargs=0,
- help=help)
+ help=help,
+ help_default=help_default)
def __call__(self, parser, namespace, values, option_string=None):
parser.print_help()
@@ -1065,6 +1091,7 @@ class _SubParsersAction(Action):
parser_class,
dest=SUPPRESS,
help=None,
+ help_default=None,
metavar=None):
self._prog_prefix = prog
@@ -1078,6 +1105,7 @@ class _SubParsersAction(Action):
nargs=PARSER,
choices=self._name_parser_map,
help=help,
+ help_default=help_default,
metavar=metavar)
def add_parser(self, name, **kwargs):
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index bc83161..d7f95b9 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -4010,6 +4010,8 @@ class TestHelpArgumentDefaults(HelpTestCase):
argument_signatures = [
Sig('--foo', help='foo help - oh and by the way, %(default)s'),
Sig('--bar', action='store_true', help='bar help'),
+ Sig('--disable-floopery', action='store_false', help='disable floopery',
+ dest='floopery', default=True, help_default='False'),
Sig('spam', help='spam help'),
Sig('badger', nargs='?', default='wooden', help='badger help'),
]
@@ -4018,25 +4020,27 @@ class TestHelpArgumentDefaults(HelpTestCase):
[Sig('--baz', type=int, default=42, help='baz help')]),
]
usage = '''\
- usage: PROG [-h] [--foo FOO] [--bar] [--baz BAZ] spam [badger]
+ usage: PROG [-h] [--foo FOO] [--bar] [--disable-floopery] [--baz BAZ]
+ spam [badger]
'''
help = usage + '''\
description
positional arguments:
- spam spam help
- badger badger help (default: wooden)
+ spam spam help
+ badger badger help (default: wooden)
optional arguments:
- -h, --help show this help message and exit
- --foo FOO foo help - oh and by the way, None
- --bar bar help (default: False)
+ -h, --help show this help message and exit
+ --foo FOO foo help - oh and by the way, None
+ --bar bar help (default: False)
+ --disable-floopery disable floopery (default: False)
title:
description
- --baz BAZ baz help (default: 42)
+ --baz BAZ baz help (default: 42)
'''
version = ''
@@ -4488,7 +4492,7 @@ class TestStrings(TestCase):
string = (
"Action(option_strings=['--foo', '-a', '-b'], dest='b', "
"nargs='+', const=None, default=42, type='int', "
- "choices=[1, 2, 3], help='HELP', metavar='METAVAR')")
+ "choices=[1, 2, 3], help='HELP', help_default=42, metavar='METAVAR')")
self.assertStringEqual(option, string)
def test_argument(self):
@@ -4504,7 +4508,7 @@ class TestStrings(TestCase):
string = (
"Action(option_strings=[], dest='x', nargs='?', "
"const=None, default=2.5, type=%r, choices=[0.5, 1.5, 2.5], "
- "help='H HH H', metavar='MV MV MV')" % float)
+ "help='H HH H', help_default=2.5, metavar='MV MV MV')" % float)
self.assertStringEqual(argument, string)
def test_namespace(self):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.