Title: User input to argparse raises Index_Error: "-a=" on a 'store_true' action
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.8, Python 3.7, Python 2.7
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: paul.j3, rhettinger, shihai1991, xtreak
Priority: normal Keywords: patch

Created on 2019-03-12 01:36 by paul.j3, last changed 2019-09-03 05:18 by shihai1991.

File name Uploaded Description Edit
parse_v1.patch shihai1991, 2019-09-02 18:28
Pull Requests
URL Status Linked Edit
PR 15656 open shihai1991, 2019-09-03 05:13
Messages (7)
msg337709 - (view) Author: paul j3 (paul.j3) * (Python triager) Date: 2019-03-12 01:36
Test case:

    parser = argparse.ArgumentParser()
    parser.add_argument("-a", action="store_true")
    args = parser.parse_args("-a=".split())

raises an Index_Error, which is not caught by the argparse error mechanism.

This is an unusual case, the coincidence of several user errors - 'store_true' which shouldn't take an argument and a short optional with a bare =.  So it's unlikely to occur.  Still, argparse shouldn't ever respond to a command line value with an uncaught error.

The traceback shows that it occurs during the handling of the explicit_arg in consume_optional.

Traceback (most recent call last):
  File "", line 5, in <module>
    args = parser.parse_args("-a=".split())
  File "/usr/lib/python3.6/", line 1743, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/lib/python3.6/", line 1775, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/lib/python3.6/", line 1981, in _parse_known_args
    start_index = consume_optional(start_index)
  File "/usr/lib/python3.6/", line 1881, in consume_optional
    option_string = char + explicit_arg[0]
IndexError: string index out of range

The issue was raised in a Stackoverflow question, where I and the poster explore why it occurs, and possible fixes.
msg351031 - (view) Author: hai shi (shihai1991) * Date: 2019-09-02 18:09
I do something such as:
p = argparse.ArgumentParser()
p.add_argument('-a', action='store_true')
p.add_argument('-b', action='store_true')

thos code code jump in 1903, and the explicit_arg's value is: 'b='

1901   action_tuples.append((action, [], option_string))
1902   char = option_string[0]
1903   option_string = char + explicit_arg[0]

IMHO, we should judge this explicit_arg's value before jump this judgment statement.
msg351035 - (view) Author: hai shi (shihai1991) * Date: 2019-09-02 18:28
Adding a judgment of explicit_args in judgment statement in the patch.
msg351047 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2019-09-03 01:07
FWIW, raising an uncaught exception isn't what we normally consider a "crash".  We typically save that designation for segfaults.

Ideally, a good patch/pr will also have tests.

Also, given the rarity of the exception, I would be reserved about backporting, keeping it to 3.8 and 3.9.
msg351048 - (view) Author: hai shi (shihai1991) * Date: 2019-09-03 01:13
Thanks, Raymond. This patch not a formal patch, just show what i want to do. if everything agree this behavior, I would add a normal PR.
msg351050 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2019-09-03 03:52
Why did you switch back to "crash"?
msg351061 - (view) Author: hai shi (shihai1991) * Date: 2019-09-03 05:18
oh, sorry, pls ignore it. I misunderstand your opinion.
Date User Action Args
2019-09-03 05:18:27shihai1991settype: crash -> behavior
messages: + msg351061
2019-09-03 05:13:31shihai1991setstage: needs patch -> patch review
pull_requests: + pull_request15323
2019-09-03 03:52:37rhettingersetmessages: + msg351050
2019-09-03 01:13:38shihai1991settype: behavior -> crash
messages: + msg351048
2019-09-03 01:07:59rhettingersetnosy: + rhettinger
type: crash -> behavior
messages: + msg351047
2019-09-02 18:28:32shihai1991setfiles: + parse_v1.patch
keywords: + patch
messages: + msg351035
2019-09-02 18:09:49shihai1991setnosy: + shihai1991
messages: + msg351031
2019-03-12 02:49:00xtreaksetnosy: + xtreak

versions: + Python 2.7, Python 3.7, Python 3.8
2019-03-12 01:36:10paul.j3create