Skip to content

Instantly share code, notes, and snippets.

@pde
Last active November 19, 2016 01:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pde/daec08cadc21bca0d62852020887ee13 to your computer and use it in GitHub Desktop.
Save pde/daec08cadc21bca0d62852020887ee13 to your computer and use it in GitHub Desktop.
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