Uh oh!
There was an error while loading. Please reload this page.
gh-153967: handle invalid file object in argparse._print_message - #153969
Conversation
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
ZeroIntensity
commented
Jul 18, 2026
This is also a user-facing change; please add a news entry. |
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
ptim0626
commented
Jul 18, 2026
Thanks, and this was added. |
Uh oh!
There was an error while loading. Please reload this page.
ptim0626
commented
Jul 19, 2026
Now I have no idea why |
ZeroIntensity
commented
Jul 19, 2026
That would be #154106. I just updated the branch, which should fix it. |
ptim0626
commented
Jul 19, 2026
The merge fixed the |
No worries. |
| if file is None: | ||
| file = _sys.stderr | ||
| if file is not None: | ||
| file.write(message) |
There was a problem hiding this comment.
Could we continue to suppress OSError? If writing to sys.stderr raises OSError during ArgumentParser.exit(), the exception escapes before _sys.exit(status) is reached, changing the exception from SystemExit to OSError. We should also add a test for this, probably.
| file.write(message) | |
| try: | |
| file.write(message) | |
| exceptOSError: | |
| pass |
There was a problem hiding this comment.
Thanks for catching this so the existing behaviour is kept. I have put a test and made the change accordingly.
One issue of catching OSError inside _print_message is that if, e.g. a non-writable file object, is passed to print_usage/print_help, it will silently fail. The users may benefit from getting a clearer message about what's gone wrong if an error message io.UnsupportedOperation: not writable is emitted (an example of passing a non-writable file). A lot of file-related exceptions are inherited from OSError such as PermissionError etc. Instead of putting the try ... except inside _print_message, could we do
defexit(self, status=0, message=None):
ifmessage:
try:
self._print_message(message, _sys.stderr)
exceptOSError:
pass_sys.exit(status)This will:
- ensure
argparse.exitstill raisesSystemExitwhensys.stderrraisesOSError - give clearer exception message when invalid file object (e.g. permission issue, non-writable, wrong file path etc) is passed to
print_usage/print_helpand not silently failed
Happy to keep the current state if it is more appropriate.
There was a problem hiding this comment.
That makes sense for explicitly supplied output destinations, but I think changing where OSError propagates is broader than the original fix. Catching it only in exit() also would not cover error(), since that calls print_usage(_sys.stderr) before reaching exit().
I’d prefer to keep the current behavior in this PR and handle more precise OSError propagation separately, where we can consider explicit destinations, default streams, and the other output-and-exit paths together.
Uh oh!
There was an error while loading. Please reload this page.
The fix for the above issue, which raises a
ValueErrorif an invalidfileis explicitly passed toargparse.print_usageandargparse.print_help. Tests added.