Skip to content
Open
15 changes: 9 additions & 6 deletions Lib/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
]


import io as _io
import os as _os
import re as _re
import sys as _sys
Expand Down Expand Up @@ -2885,12 +2886,14 @@ def print_help(self, file=None):
self._print_message(help_text, file)

def _print_message(self, message, file=None):
if message:
file = file or _sys.stderr
try:
file.write(message)
except (AttributeError, OSError):
pass
if not message:
return
if file is None:
file = _sys.stderr
elif not isinstance(file, _io.IOBase):
raise ValueError(f"invalid file object {file}")
if file is not None:
file.write(message)
Comment thread
ZeroIntensity marked this conversation as resolved.

def _get_theme(self, file=None):
# If self.color is False, _colorize is not imported
Expand Down
9 changes: 9 additions & 0 deletions Lib/test/test_argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ def test_skip_invalid_stdout(self):
func()
self.assertRegex(mocked_stderr.getvalue(), r'usage:')

def test_invalid_file_only(self):
Comment thread
ptim0626 marked this conversation as resolved.
parser = argparse.ArgumentParser()
for func in (parser.print_usage, parser.print_help):
for invalid_f in ("invalid file", "", 0):
with (
self.subTest(func=func, invalid_f=invalid_f),
self.assertRaises(ValueError),
):
func(file=invalid_f)

class TestLazyImports(unittest.TestCase):
LAZY_IMPORTS = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:meth:`argparse.ArgumentParser.print_usage` and
:meth:`argparse.ArgumentParser.print_help` won't silently fail when an invalid
file object is specified. Patch by Timothy Poon.
Loading