mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Merged revisions 83675 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r83675 | r.david.murray | 2010-08-03 13:56:09 -0400 (Tue, 03 Aug 2010) | 12 lines #9444: use first of prefix_chars for help opt instead of raising error An argparse option parser created with a prefix_chars that did not include a '-' would happily add -h and --help options, and then throw an error when it tried to format the help because the - was an invalid prefix character. This patch makes it use the first character of prefix_chars as the character for the help options if and only if '-' is not one of the valid prefix_chars. Fix by Theodore Turocy, unit tests by Catherine Devlin. ........
This commit is contained in:
parent
0f98128d6e
commit
1cbf78e040
5 changed files with 101 additions and 13 deletions
|
@ -203,8 +203,8 @@ argument to :class:`ArgumentParser`.
|
||||||
add_help
|
add_help
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
By default, ArgumentParser objects add a ``-h/--help`` option which simply
|
By default, ArgumentParser objects add an option which simply displays
|
||||||
displays the parser's help message. For example, consider a file named
|
the parser's help message. For example, consider a file named
|
||||||
``myprogram.py`` containing the following code::
|
``myprogram.py`` containing the following code::
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
@ -234,12 +234,27 @@ This can be achieved by passing ``False`` as the ``add_help=`` argument to
|
||||||
optional arguments:
|
optional arguments:
|
||||||
--foo FOO foo help
|
--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
|
prefix_chars
|
||||||
^^^^^^^^^^^^
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
Most command-line options will use ``'-'`` as the prefix, e.g. ``-f/--foo``.
|
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
|
like ``+f`` or ``/foo``, may specify them using the ``prefix_chars=`` argument
|
||||||
to the ArgumentParser constructor::
|
to the ArgumentParser constructor::
|
||||||
|
|
||||||
|
|
|
@ -1563,13 +1563,16 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer):
|
||||||
|
|
||||||
# add help and version arguments if necessary
|
# add help and version arguments if necessary
|
||||||
# (using explicit default to override global argument_default)
|
# (using explicit default to override global argument_default)
|
||||||
|
default_prefix = '-' if '-' in prefix_chars else prefix_chars[0]
|
||||||
if self.add_help:
|
if self.add_help:
|
||||||
self.add_argument(
|
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'))
|
help=_('show this help message and exit'))
|
||||||
if self.version:
|
if self.version:
|
||||||
self.add_argument(
|
self.add_argument(
|
||||||
'-v', '--version', action='version', default=SUPPRESS,
|
default_prefix+'v', default_prefix*2+'version',
|
||||||
|
action='version', default=SUPPRESS,
|
||||||
version=self.version,
|
version=self.version,
|
||||||
help=_("show program's version number and exit"))
|
help=_("show program's version number and exit"))
|
||||||
|
|
||||||
|
|
|
@ -420,7 +420,7 @@ class TestOptionalsSingleDoubleDash(ParserTestCase):
|
||||||
|
|
||||||
|
|
||||||
class TestOptionalsAlternatePrefixChars(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)
|
parser_signature = Sig(prefix_chars='+:/', add_help=False)
|
||||||
argument_signatures = [
|
argument_signatures = [
|
||||||
|
@ -428,6 +428,28 @@ class TestOptionalsAlternatePrefixChars(ParserTestCase):
|
||||||
Sig('::bar'),
|
Sig('::bar'),
|
||||||
Sig('/baz', action='store_const', const=42),
|
Sig('/baz', action='store_const', const=42),
|
||||||
]
|
]
|
||||||
|
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)),
|
||||||
|
('::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 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']
|
failures = ['--bar', '-fbar', '-b B', 'B', '-f', '--bar B', '-baz']
|
||||||
successes = [
|
successes = [
|
||||||
('', NS(f=False, bar=None, baz=None)),
|
('', NS(f=False, bar=None, baz=None)),
|
||||||
|
@ -435,10 +457,9 @@ class TestOptionalsAlternatePrefixChars(ParserTestCase):
|
||||||
('::ba B', NS(f=False, bar='B', baz=None)),
|
('::ba B', NS(f=False, bar='B', baz=None)),
|
||||||
('+f ::bar B', NS(f=True, bar='B', baz=None)),
|
('+f ::bar B', NS(f=True, bar='B', baz=None)),
|
||||||
('+f /b', NS(f=True, bar=None, baz=42)),
|
('+f /b', NS(f=True, bar=None, baz=42)),
|
||||||
('/ba +f', NS(f=True, bar=None, baz=42)),
|
('/ba +f', NS(f=True, bar=None, baz=42))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class TestOptionalsShortLong(ParserTestCase):
|
class TestOptionalsShortLong(ParserTestCase):
|
||||||
"""Test a combination of single- and double-dash option strings"""
|
"""Test a combination of single- and double-dash option strings"""
|
||||||
|
|
||||||
|
@ -1666,12 +1687,18 @@ class TestAddSubparsers(TestCase):
|
||||||
def assertArgumentParserError(self, *args, **kwargs):
|
def assertArgumentParserError(self, *args, **kwargs):
|
||||||
self.assertRaises(ArgumentParserError, *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
|
# create a parser with a subparsers argument
|
||||||
parser = ErrorRaisingArgumentParser(
|
if prefix_chars:
|
||||||
prog='PROG', description='main description')
|
parser = ErrorRaisingArgumentParser(
|
||||||
parser.add_argument(
|
prog='PROG', description='main description', prefix_chars=prefix_chars)
|
||||||
'--foo', action='store_true', help='foo help')
|
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(
|
parser.add_argument(
|
||||||
'bar', type=float, help='bar help')
|
'bar', type=float, help='bar help')
|
||||||
|
|
||||||
|
@ -1750,6 +1777,44 @@ class TestAddSubparsers(TestCase):
|
||||||
--foo foo help
|
--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):
|
def test_parser_command_help(self):
|
||||||
self.assertEqual(self.command_help_parser.format_usage(),
|
self.assertEqual(self.command_help_parser.format_usage(),
|
||||||
'usage: PROG [-h] [--foo] bar {1,2} ...\n')
|
'usage: PROG [-h] [--foo] bar {1,2} ...\n')
|
||||||
|
|
|
@ -782,6 +782,7 @@ John Tromp
|
||||||
Jason Trowbridge
|
Jason Trowbridge
|
||||||
Anthony Tuininga
|
Anthony Tuininga
|
||||||
Stephen Turner
|
Stephen Turner
|
||||||
|
Theodore Turocy
|
||||||
Bill Tutt
|
Bill Tutt
|
||||||
Doobee R. Tzeck
|
Doobee R. Tzeck
|
||||||
Eren Türkay
|
Eren Türkay
|
||||||
|
|
|
@ -24,6 +24,10 @@ Core and Builtins
|
||||||
Library
|
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 #9354: Provide getsockopt() in asyncore's file_wrapper.
|
||||||
|
|
||||||
- Issue #7781: Fix restricting stats by entry counts in the pstats
|
- Issue #7781: Fix restricting stats by entry counts in the pstats
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue