GeezerVison is showing github.com — Argparse.parse_args exits on unrecognized option with exit_on_error=False · Issue #85427 · python/cpython
Argparse.parse_args exits on unrecognized option with exit_on_error=False #85427Descriptionmatthewhughes934 mannequin
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = None
created_at = <Date 2020-07-09.08:40:33.198>
labels = ['type-bug', 'library', '3.9']
title = 'Argparse.parse_args exits on unrecognized option with exit_on_error=False'
updated_at = <Date 2022-01-29.03:10:17.942>
user = 'https://github.com/matthewhughes934'
bugs.python.org fields:
activity = <Date 2022-01-29.03:10:17.942>
actor = 'jacobtylerwalls'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Library (Lib)']
creation = <Date 2020-07-09.08:40:33.198>
creator = 'mhughes'
dependencies = []
files = ['49310']
hgrepos = []
issue_num = 41255
keywords = ['patch']
message_count = 10.0
messages = ['373382', '373383', '373385', '373405', '373437', '373440', '373470', '396345', '397975', '401629']
nosy_count = 7.0
nosy_names = ['rhettinger', 'paul.j3', 'xtreak', 'mhughes', 'jacobtylerwalls', 'bigbird', 'joshmeranda']
pr_nums = ['27295', '30832']
priority = 'normal'
resolution = None
stage = 'patch review'
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue41255'
versions = ['Python 3.9']
Reacted by Ioannis Triantafillou, psasselum, Joakim Joensuu, RedoX and John Hennig Activitymatthewhughes934 commented on Jul 9, 2020 matthewhughes934mannequin MannequinAuthor More actions >>> import argparse
>>> parser = argparse.ArgumentParser(exit_on_error=False)
>>> parser.parse_args(["--unknown"])
usage: [-h]
: error: unrecognized arguments: --unknown
The docs https://docs.python.org/3.10/library/argparse.html#exit-on-error say:
Normally, when you pass an invalid argument list to the parse_args() method of an ArgumentParser, it will exit with error info.
If the user would like catch errors manually, the feature can be enable by setting exit_on_error to False:
This description _appears_ to be at odds with the observed behavior. Reacted by Sam Steingold and John Hennig tirkarthi commented on Jul 9, 2020 I guess the docs by manually mean that ArgumentError will be raised when exit_on_error is False that can be handled. By default with exit_on_error being True self.error() which raises SystemExit and catching SystemExit can mask other errors. This was added in bpo-9938 with #59567. There is also a typo in the docs that it should have used enabled instead of enable in "the feature can be enable by setting exit_on_error to False" matthewhughes934 commented on Jul 9, 2020 matthewhughes934mannequin MannequinAuthor More actions
typo in the docs that it should have used enabled instead of enable
Well spotted, I'll happily fix this up.
I guess the docs by manually mean that ArgumentError will be raised when exit_on_error is False that can be handled.
To be clear, in this case, even with exit_on_error=False, ArgumentError is _not_ being raised, but SystemExit is. matthewhughes934 commented on Jul 9, 2020 matthewhughes934mannequin MannequinAuthor More actions I've attached a patch containing tests showing the current behavior, namely that exit_on_error does not change the behavior of argparse.ArgumentParser.parse_args in either case:
- An unrecognized option is given
- A required option is not given
Should the docs be updated to note this? paulj3 commented on Jul 10, 2020 I didn't pay attention to the patch that added this "exit_on_error" parameter. So I don't know exactly what error handling it was supposed to handle or why. But given the location of the code change, it does not handle every possible error.
Specifically it's in parser.parse_known_args() where it calls _parse_known_args(). With this parameter True, a argparse.ArgumentError is caught and converted to parse.error() call. That's the original behavior.
With False, there's no special handling for ArgumentError. Catching that is left to the developer, as illustrated in the docs.
In the documented example, it's a 'type' error. 'choices' would also behave this way. 'nargs' errors also. But not all errors are handled like this.
Inside _parse_known_args(), self.error() is called several times, once for 'required' arguments failure, and for a required mutually_exclusive_group error. I count 9 self.error() calls; exit_on_error only changes one of those.
The error highlighted in this issue is called in parser.parse_args(). This calls parse_known_args(), and raises an error if there are 'extras', unrecognized strings.
So clearly the new docs is is describing this new parameter in overly broad terms. It only changes the handling of a subset of parser.error() calls. Off hand I can't think of clean way of refining the description without getting overly technical about the error handling.
Developers already had the documented option of changing the parse.error() and parse.exit() methods. paulj3 commented on Sep 11, 2021 In
https://stackoverflow.com/questions/69108632/unable-to-catch-exception-error-for-argparse
it looked like exit_on_error does not work when using subparsers. On on further thought, I realized that it has to included in the definition of the subparser. As with other ArgumentParser parameters, the subparsers does not inherit from the main parser.
So it's basically a documentation issue. The add_parser method is described briefly as:
which takes a command name and any ArgumentParser constructor
arguments, and returns an ArgumentParser object that can be
modified as usual.
But as my experience shows, its relevance is easily missed, even by an experienced users. ed-ij commented on Mar 31, 2023 Just wanted to bump this after attempting to use the exit_on_error argument to prevent sys.exit() being called.
The documentation could at least be improved until a better implementation is available. Adding a note in the documentation for this function which links to the "Exiting methods" section would also be helpful in the interim although I agree with bigbirdcode and joshmeranda that you shouldn't have to override methods just to have control over error handling. Reacted by psasselum, Dima Matveev, RedoX, John Hennig, Ganesh N Sivalingam and edna serhiy-storchaka commented on Jun 26, 2024 I wrote #121056 before discovering this issue. It is basically an extended version of #30832.
We now have 3 duplicate issues with 4 open PRs (and one incomplete PR was already merged). It is time to finish this. Reacted by Dolan Murvihill
MetadataMetadataStatusShow more project fields
DevelopmentNo branches or pull requestsIssue actions
|