https://github.com/python/cpython/commit/115400b5090f14233b72b255e483b4485c868100
commit: 115400b5090f14233b72b255e483b4485c868100
branch: main
author: Timothy Poon <[email protected]>
committer: savannahostrowski <[email protected]>
date: 2026-08-07T18:40:02Z
summary:

gh-153967: handle invalid file object in argparse._print_message (#153969)

Co-authored-by: Peter Bierma <[email protected]>
Co-authored-by: Chris Eibl <[email protected]>
Co-authored-by: Savannah Ostrowski <[email protected]>

files:
A Misc/NEWS.d/next/Library/2026-07-18-16-05-38.gh-issue-153967.-OUNXe.rst
M Lib/argparse.py
M Lib/test/test_argparse.py

diff --git a/Lib/argparse.py b/Lib/argparse.py
index fe9fde7f65830f..38e1c0d0ed78fd 100644
--- a/Lib/argparse.py
+++ b/Lib/argparse.py
@@ -2917,11 +2917,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
+        if not message:
+            return
+        if file is None:
+            file = _sys.stderr
+        if file is not None:
             try:
                 file.write(message)
-            except (AttributeError, OSError):
+            except OSError:
                 pass
 
     def _get_theme(self, file=None):
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 1193cdca3e4e19..75beb5ede13fef 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -80,6 +80,24 @@ 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)
+
+    def test_exit_when_stderr_oserror(self):
+        parser = argparse.ArgumentParser()
+        with (mock.patch('argparse._sys.stderr.write',
+                         side_effect=OSError('not raise this')),
+              self.assertRaises(SystemExit),
+              ):
+            parser.exit(status=0, message='foo')
+
 
 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 00000000000000..5f520140f43a8e
--- /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.

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to