diff --git a/Lib/argparse.py b/Lib/argparse.py index 29e6ebb9634261a..66e901bfb42cfad 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -2885,12 +2885,12 @@ 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 + if file is not None: + file.write(message) def _get_theme(self, file=None): # If self.color is False, _colorize is not imported diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 1dc3f538f4ad8ba..b6f61adbea84cd2 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -79,6 +79,15 @@ def test_skip_invalid_stdout(self): func() self.assertRegex(mocked_stderr.getvalue(), r'usage:') + def test_invalid_file_only(self): + 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(AttributeError), + ): + func(file=invalid_f) class TestLazyImports(unittest.TestCase): LAZY_IMPORTS = { diff --git a/Misc/NEWS.d/next/Library/2026-07-18-16-05-38.gh-issue-153967.-OUNXe.rst b/Misc/NEWS.d/next/Library/2026-07-18-16-05-38.gh-issue-153967.-OUNXe.rst new file mode 100644 index 000000000000000..5f520140f43a8ea --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-18-16-05-38.gh-issue-153967.-OUNXe.rst @@ -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.