gh-153967: handle invalid file object in argparse._print_message - #153969
gh-153967: handle invalid file object in argparse._print_message#153969ptim0626 wants to merge 14 commits into
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 |
|
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 |
Thanks, and this was added. |
|
Now I have no idea why |
|
That would be #154106. I just updated the branch, which should fix it. |
|
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) | |
| except OSError: | |
| 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
def exit(self, status=0, message=None):
if message:
try:
self._print_message(message, _sys.stderr)
except OSError:
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.
The fix for the above issue, which raises a
ValueErrorif an invalidfileis explicitly passed toargparse.print_usageandargparse.print_help. Tests added.