classification
Title: argparse update help msg for % signs
Type: behavior Stage: resolved
Components: Documentation Versions: Python 3.2
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: Jeff.Yurkiw, bethard, docs@python, eric.araujo, eric.smith, python-dev
Priority: normal Keywords:

Created on 2011-12-30 22:29 by Jeff.Yurkiw, last changed 2012-06-27 01:00 by eric.araujo. This issue is now closed.

Files
File name Uploaded Description Edit
argparseBug.py Jeff.Yurkiw, 2011-12-30 22:29 Example code from the bug descriiption
Messages (7)
msg150404 - (view) Author: Jeff Yurkiw (Jeff.Yurkiw) Date: 2011-12-30 22:29
I discovered this while programming the command line interface for a python program that can take a passed argument and throw it into the 'where like' clause of a SQL expression (intended for a postgresql database).

The wildcard character for where-like statements is generally the percent sign, which is how I found this ("WHERE %s LIKE '%--value%')".

If you use any single '%' signs in an ArgumentParser.new_argument(help=)'s help description Python 3.2 will throw an error.

Workaround: You can avoid this issue by doubling up on all % signs that you want to display in your help text.

parser.add_argument(('--foo', action='store',help='%bar') throws an error.
parser.add_argument(('--foo', action='store',help='%%bar') displays '--foo FOO   %bar'.

Suggested fix:
When assigning help strings from add_argument(), throw them through a sanitizer and replace all occurrences of '%' with '%%' behind the scenes.

Example code (argparseBug.py):

from argparse import ArgumentParser

parser = ArgumentParser()
parser.add_argument('--foo', action='store', help='%bar')

args = parser.parse_args('-h'.split())

You get the following stacktrace:
Traceback (most recent call last):
  File "/path/to/script/argparseBug.py", line 6, in <module>
    args = parser.parse_args('-h'.split())
  File "/usr/lib/python3.2/argparse.py", line 1701, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/lib/python3.2/argparse.py", line 1733, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/lib/python3.2/argparse.py", line 1939, in _parse_known_args
    start_index = consume_optional(start_index)
  File "/usr/lib/python3.2/argparse.py", line 1879, in consume_optional
    take_action(action, args, option_string)
  File "/usr/lib/python3.2/argparse.py", line 1807, in take_action
    action(self, namespace, argument_values, option_string)
  File "/usr/lib/python3.2/argparse.py", line 994, in __call__
    parser.print_help()
  File "/usr/lib/python3.2/argparse.py", line 2331, in print_help
    self._print_message(self.format_help(), file)
  File "/usr/lib/python3.2/argparse.py", line 2305, in format_help
    return formatter.format_help()
  File "/usr/lib/python3.2/argparse.py", line 279, in format_help
    help = self._root_section.format_help()
  File "/usr/lib/python3.2/argparse.py", line 209, in format_help
    func(*args)
  File "/usr/lib/python3.2/argparse.py", line 209, in format_help
    func(*args)
  File "/usr/lib/python3.2/argparse.py", line 515, in _format_action
    help_text = self._expand_help(action)
  File "/usr/lib/python3.2/argparse.py", line 601, in _expand_help
    return self._get_help_string(action) % params
ValueError: unsupported format character 'b' (0x62) at index 1
msg150405 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2011-12-30 22:35
This is because the help text support substitution, as mentioned here: http://docs.python.org/dev/library/argparse.html#help

It's possible this documentation could be improved.
msg150480 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2012-01-02 22:04
In case I wasn't clear, I mean that the help string supports %-formatting variable expansion, such as "%(default)s". I think it would be good if a sentence were added to the end of the "help" section, saying something like:

Because the help string supports %-formatting, if you want a literal "%" to appear in the help string, you must escape it as "%%".
msg150513 - (view) Author: Jeff Yurkiw (Jeff.Yurkiw) Date: 2012-01-03 16:43
That would probably work too.
msg151026 - (view) Author: Steven Bethard (bethard) * (Python committer) Date: 2012-01-10 19:13
Eric's suggested doc fix looks good to me.
msg164041 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2012-06-26 06:18
New changeset c696416eb4e9 by Senthil Kumaran in branch '3.2':
Issue #13685 - Update argparse help message for % sign usage.
http://hg.python.org/cpython/rev/c696416eb4e9

New changeset 493d58c3c57f by Senthil Kumaran in branch 'default':
merge from 3.2 - Issue13685
http://hg.python.org/cpython/rev/493d58c3c57f
msg164117 - (view) Author: √Čric Araujo (eric.araujo) * (Python committer) Date: 2012-06-27 01:00
Senthil, would you mind porting the fix to 2.7?  Thanks.
History
Date User Action Args
2012-06-27 01:00:01eric.araujosetnosy: + eric.araujo
messages: + msg164117
2012-06-26 06:19:09orsenthilsetstatus: open -> closed
resolution: fixed
stage: resolved
2012-06-26 06:18:29python-devsetnosy: + python-dev
messages: + msg164041
2012-06-26 06:16:39orsenthilsettitle: argparse does not sanitize help strings for % signs -> argparse update help msg for % signs
2012-01-10 19:13:58bethardsetmessages: + msg151026
2012-01-07 00:05:11terry.reedysetnosy: + bethard
2012-01-03 16:43:42Jeff.Yurkiwsetmessages: + msg150513
2012-01-02 22:04:22eric.smithsetmessages: + msg150480
2011-12-30 22:35:20eric.smithsetnosy: + eric.smith, docs@python
messages: + msg150405

assignee: docs@python
components: + Documentation, - None
2011-12-30 22:29:26Jeff.Yurkiwcreate