summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/library/argparse.rst21
-rw-r--r--Lib/argparse.py7
-rw-r--r--Lib/test/test_argparse.py79
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS4
5 files changed, 100 insertions, 12 deletions
diff --git a/Doc/library/argparse.rst b/Doc/library/argparse.rst
index b3a1171..45eddca 100644
--- a/Doc/library/argparse.rst
+++ b/Doc/library/argparse.rst
@@ -203,8 +203,8 @@ argument to :class:`ArgumentParser`.
add_help
^^^^^^^^
-By default, ArgumentParser objects add a ``-h/--help`` option which simply
-displays the parser's help message. For example, consider a file named
+By default, ArgumentParser objects add an option which simply displays
+the parser's help message. For example, consider a file named
``myprogram.py`` containing the following code::
import argparse
@@ -234,12 +234,27 @@ This can be achieved by passing ``False`` as the ``add_help=`` argument to
optional arguments:
--foo FOO foo help
+The help option is typically ``-h/--help``. The exception to this is
+if the ``prefix_chars=`` is specified and does not include ``'-'``, in
+which case ``-h`` and ``--help`` are not valid options. In
+this case, the first character in ``prefix_chars`` is used to prefix
+the help options::
+
+ >>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='+/')
+ >>> parser.print_help()
+ usage: PROG [+h]
+
+ optional arguments:
+ +h, ++help show this help message and exit
+
+
prefix_chars
^^^^^^^^^^^^
Most command-line options will use ``'-'`` as the prefix, e.g. ``-f/--foo``.
-Parsers that need to support additional prefix characters, e.g. for options
+Parsers that need to support different or additional prefix
+characters, e.g. for options
like ``+f`` or ``/foo``, may specify them using the ``prefix_chars=`` argument
to the ArgumentParser constructor::
diff --git a/Lib/argparse.py b/Lib/argparse.py
index f9279aa..654ac48 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -1563,13 +1563,16 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
# add help and version arguments if necessary
# (using explicit default to override global argument_default)
+ default_prefix = '-' if '-' in prefix_chars else prefix_chars[0]
if self.add_help:
self.add_argument(
- '-h', '--help', action='help', default=SUPPRESS,
+ default_prefix+'h', default_prefix*2+'help',
+ action='help', default=SUPPRESS,
help=_('show this help message and exit'))
if self.version:
self.add_argument(
- '-v', '--version', action='version', default=SUPPRESS,
+ default_prefix+'v', default_prefix*2+'version',
+ action='version', default=SUPPRESS,
version=self.version,
help=_("show program's version number and exit"))
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 30e53ab..3e1bf25 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -420,7 +420,7 @@ class TestOptionalsSingleDoubleDash(ParserTestCase):
class TestOptionalsAlternatePrefixChars(ParserTestCase):
- """Test an Optional with a double-dash option string"""
+ """Test an Optional with option strings with custom prefixes"""
parser_signature = Sig(prefix_chars='+:/', add_help=False)
argument_signatures = [
@@ -428,7 +428,7 @@ class TestOptionalsAlternatePrefixChars(ParserTestCase):
Sig('::bar'),
Sig('/baz', action='store_const', const=42),
]
- failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz']
+ failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz', '-h', '--help', '+h', '::help', '/help']
successes = [
('', NS(f=False, bar=None, baz=None)),
('+f', NS(f=True, bar=None, baz=None)),
@@ -439,6 +439,27 @@ class TestOptionalsAlternatePrefixChars(ParserTestCase):
]
+class TestOptionalsAlternatePrefixCharsAddedHelp(ParserTestCase):
+ """When ``-`` not in prefix_chars, default operators created for help
+ should use the prefix_chars in use rather than - or --
+ http://bugs.python.org/issue9444"""
+
+ parser_signature = Sig(prefix_chars='+:/', add_help=True)
+ argument_signatures = [
+ Sig('+f', action='store_true'),
+ Sig('::bar'),
+ Sig('/baz', action='store_const', const=42),
+ ]
+ failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz']
+ successes = [
+ ('', NS(f=False, bar=None, baz=None)),
+ ('+f', NS(f=True, bar=None, baz=None)),
+ ('::ba B', NS(f=False, bar='B', baz=None)),
+ ('+f ::bar B', NS(f=True, bar='B', baz=None)),
+ ('+f /b', NS(f=True, bar=None, baz=42)),
+ ('/ba +f', NS(f=True, bar=None, baz=42))
+ ]
+
class TestOptionalsShortLong(ParserTestCase):
"""Test a combination of single- and double-dash option strings"""
@@ -1666,12 +1687,18 @@ class TestAddSubparsers(TestCase):
def assertArgumentParserError(self, *args, **kwargs):
self.assertRaises(ArgumentParserError, *args, **kwargs)
- def _get_parser(self, subparser_help=False):
+ def _get_parser(self, subparser_help=False, prefix_chars=None):
# create a parser with a subparsers argument
- parser = ErrorRaisingArgumentParser(
- prog='PROG', description='main description')
- parser.add_argument(
- '--foo', action='store_true', help='foo help')
+ if prefix_chars:
+ parser = ErrorRaisingArgumentParser(
+ prog='PROG', description='main description', prefix_chars=prefix_chars)
+ parser.add_argument(
+ prefix_chars[0] * 2 + 'foo', action='store_true', help='foo help')
+ else:
+ parser = ErrorRaisingArgumentParser(
+ prog='PROG', description='main description')
+ parser.add_argument(
+ '--foo', action='store_true', help='foo help')
parser.add_argument(
'bar', type=float, help='bar help')
@@ -1750,6 +1777,44 @@ class TestAddSubparsers(TestCase):
--foo foo help
'''))
+ def test_help_extra_prefix_chars(self):
+ # Make sure - is still used for help if it is a non-first prefix char
+ parser = self._get_parser(prefix_chars='+:-')
+ self.assertEqual(parser.format_usage(),
+ 'usage: PROG [-h] [++foo] bar {1,2} ...\n')
+ self.assertEqual(parser.format_help(), textwrap.dedent('''\
+ usage: PROG [-h] [++foo] bar {1,2} ...
+
+ main description
+
+ positional arguments:
+ bar bar help
+ {1,2} command help
+
+ optional arguments:
+ -h, --help show this help message and exit
+ ++foo foo help
+ '''))
+
+
+ def test_help_alternate_prefix_chars(self):
+ parser = self._get_parser(prefix_chars='+:/')
+ self.assertEqual(parser.format_usage(),
+ 'usage: PROG [+h] [++foo] bar {1,2} ...\n')
+ self.assertEqual(parser.format_help(), textwrap.dedent('''\
+ usage: PROG [+h] [++foo] bar {1,2} ...
+
+ main description
+
+ positional arguments:
+ bar bar help
+ {1,2} command help
+
+ optional arguments:
+ +h, ++help show this help message and exit
+ ++foo foo help
+ '''))
+
def test_parser_command_help(self):
self.assertEqual(self.command_help_parser.format_usage(),
'usage: PROG [-h] [--foo] bar {1,2} ...\n')
diff --git a/Misc/ACKS b/Misc/ACKS
index 15436f4..197a502 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -782,6 +782,7 @@ John Tromp
Jason Trowbridge
Anthony Tuininga
Stephen Turner
+Theodore Turocy
Bill Tutt
Doobee R. Tzeck
Eren Türkay
diff --git a/Misc/NEWS b/Misc/NEWS
index 323b0a3..431c3d5 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -24,6 +24,10 @@ Core and Builtins
Library
-------
+- Issue #9444: Argparse now uses the first element of prefix_chars as
+ the option character for the added 'h/help' option if prefix_chars
+ does not contain a '-', instead of raising an error.
+
- Issue #9354: Provide getsockopt() in asyncore's file_wrapper.
- Issue #7781: Fix restricting stats by entry counts in the pstats