This issue tracker has been migrated to GitHub ,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2015年04月28日 17:57 by invisibleroads, last changed 2022年04月11日 14:58 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| argparse-with-exception.py | invisibleroads, 2015年04月28日 17:57 | |||
| Messages (4) | |||
|---|---|---|---|
| msg242192 - (view) | Author: Roy Hyunjin Han (invisibleroads) * | Date: 2015年04月28日 17:57 | |
Exceptions and arguments disappear when using argparse inside a "with" statement. The behavior was confusing and frustrating because I could not pinpoint why certain arguments were missing or unrecognized. Unhandled exceptions inside the with statement typically trigger a traceback, unless __exit__ returns True, in which the exception is "swallowed" (https://www.python.org/dev/peps/pep-0343/). However, the NameError exception and tile_indices argument disappear because of a premature sys.exit (https://hg.python.org/cpython/file/default/Lib/argparse.py#l2385). ``` """ $ python exception-in-with.py EXPECTED Traceback (most recent call last): File "exception-in-with.py", line 51, in <module> abc # !!! NameError: name 'abc' is not defined ACTUAL usage: exception-in-with.py [-h] --image_path PATH exception-in-with.py: error: argument --image_path is required $ python exception-in-with.py --image_path x EXPECTED == ACTUAL Traceback (most recent call last): File "exception-in-with.py", line 51, in <module> abc # !!! NameError: name 'abc' is not defined $ python exception-in-with.py --image_path x --tile_indices 1 EXPECTED Traceback (most recent call last): File "exception-in-with.py", line 51, in <module> abc # !!! NameError: name 'abc' is not defined ACTUAL usage: exception-in-with.py [-h] --image_path PATH exception-in-with.py: error: unrecognized arguments: --tile_indices 1 """ from argparse import ArgumentParser class Starter(object): def __init__(self): self.argument_parser = ArgumentParser() def __enter__(self): return self def __exit__(self, exception_type, exception_value, exception_traceback): self.argument_parser.parse_args() def add_argument(self, *args, **kw): self.argument_parser.add_argument(*args, **kw) with Starter() as starter: starter.add_argument('--image_path', metavar='PATH', required=True) abc # !!! starter.add_argument('--tile_indices', metavar='INTEGER') ``` |
|||
| msg242196 - (view) | Author: Benjamin Peterson (benjamin.peterson) * (Python committer) | Date: 2015年04月28日 18:29 | |
I'm not sure why this is so surprising. parse_args in __exit__ raises a SystmExit, which the Python interpreter takes to mean the program is responsibly exiting. I don't think any other behavior would be reasonable. e.g. sys.exit() in an except clause shouldn't cause the exception to be printed. |
|||
| msg242692 - (view) | Author: Roy Hyunjin Han (invisibleroads) * | Date: 2015年05月06日 17:39 | |
The behavior may not be surprising from a technical perspective, but it is unintuitive. I think exceptions inside a with statement should trigger a traceback, unless you are saying that it is the responsibility of the author to catch and raise the exception inside __exit__, which feels to me like a workaround that is specific to parse_args. |
|||
| msg242693 - (view) | Author: R. David Murray (r.david.murray) * (Python committer) | Date: 2015年05月06日 17:52 | |
What is happening here is that the __exit__ method gets passed the exception, and then instead of returning and allowing the exception to propagate and be printed, it raises SystemExit (via parse_args), which causes Python to immediately shut down, *before* __exit__ returns and the exception is propagated. So yes, you'd have to do something specific for argparse (which raises a SystemExit exception if parsing fails) if you want to do something non-normal with SystemExit. That is, you'll need to catch SystemExit. This is really a duplicate of issue 9938. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:58:16 | admin | set | github: 68258 |
| 2015年05月06日 17:52:11 | r.david.murray | set | dependencies:
+ Add optional keyword argument exit_on_error to argparse.ArgumentParser versions: + Python 3.4, Python 3.5, - Python 3.3 nosy: + r.david.murray messages: + msg242693 resolution: not a bug -> duplicate stage: resolved |
| 2015年05月06日 17:39:00 | invisibleroads | set | messages: + msg242692 |
| 2015年04月28日 18:29:16 | benjamin.peterson | set | status: open -> closed nosy: + benjamin.peterson messages: + msg242196 resolution: not a bug |
| 2015年04月28日 17:57:25 | invisibleroads | create | |