[Python-checkins] r83675 - in python/branches/py3k: Doc/library/argparse.rst Lib/argparse.py Lib/test/test_argparse.py Misc/ACKS Misc/NEWS

r.david.murray python-checkins at python.org
Tue Aug 3 19:56:09 CEST 2010


Author: r.david.murray
Date: Tue Aug  3 19:56:09 2010
New Revision: 83675

Log:
#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.



Modified:
   python/branches/py3k/Doc/library/argparse.rst
   python/branches/py3k/Lib/argparse.py
   python/branches/py3k/Lib/test/test_argparse.py
   python/branches/py3k/Misc/ACKS
   python/branches/py3k/Misc/NEWS

Modified: python/branches/py3k/Doc/library/argparse.rst
==============================================================================
--- python/branches/py3k/Doc/library/argparse.rst	(original)
+++ python/branches/py3k/Doc/library/argparse.rst	Tue Aug  3 19:56:09 2010
@@ -203,8 +203,8 @@
 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 @@
    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::
 

Modified: python/branches/py3k/Lib/argparse.py
==============================================================================
--- python/branches/py3k/Lib/argparse.py	(original)
+++ python/branches/py3k/Lib/argparse.py	Tue Aug  3 19:56:09 2010
@@ -1561,13 +1561,16 @@
 
         # 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"))
 

Modified: python/branches/py3k/Lib/test/test_argparse.py
==============================================================================
--- python/branches/py3k/Lib/test/test_argparse.py	(original)
+++ python/branches/py3k/Lib/test/test_argparse.py	Tue Aug  3 19:56:09 2010
@@ -417,7 +417,7 @@
 
 
 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 = [
@@ -425,7 +425,7 @@
         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)),
@@ -436,6 +436,27 @@
     ]
 
 
+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"""
 
@@ -1655,12 +1676,18 @@
     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')
 
@@ -1739,6 +1766,44 @@
               --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')

Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS	(original)
+++ python/branches/py3k/Misc/ACKS	Tue Aug  3 19:56:09 2010
@@ -802,6 +802,7 @@
 Jason Trowbridge
 Anthony Tuininga
 Stephen Turner
+Theodore Turocy
 Bill Tutt
 Doobee R. Tzeck
 Eren Türkay

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Tue Aug  3 19:56:09 2010
@@ -35,6 +35,10 @@
 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 #7372: Fix pstats regression when stripping paths from profile
   data generated with the profile module.
 


More information about the Python-checkins mailing list