Skip to content

Commit a0cbdd8

Browse files
vstinnerhroncokcmaloney
authored
[3.13] gh-141570: can_colorize: Expect fileno() to raise OSError, as documented (#141716) (#141748)
gh-141570: can_colorize: Expect fileno() to raise OSError, as documented (#141716) In Fedora, we've been given a slightly incomplete reproducer for a problematic Python 3.14 color-related change in argparse that leads to an exception when Python is used from mod_wsgi: https://bugzilla.redhat.com/2414940 mod_wsgi replaces sys.stdout with a custom object that raises OSError on .fileno(): https://github.com/GrahamDumpleton/mod_wsgi/blob/8460dbfcd5c7108892b3cde9fab7cbc1caa27886/src/server/wsgi_logger.c#L434-L440 This should be supported, as the documentation of fileno explicitly says: > An OSError is raised if the IO object does not use a file descriptor. https://docs.python.org/3.14/library/io.html#io.IOBase.fileno The previously expected exception inherits from OSError, so it is still expected. Fixes #141570 (cherry picked from commit 96f496a) Co-authored-by: Miro Hrončok <[email protected]> Co-authored-by: Cody Maloney <[email protected]>
1 parent c7064e7 commit a0cbdd8

File tree

3 files changed

+14
-2
lines changed

3 files changed

+14
-2
lines changed

Lib/_colorize.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from __future__ import annotations
2-
import io
32
import os
43
import sys
54

@@ -116,5 +115,5 @@ def _safe_getenv(k: str, fallback: str | None = None) -> str | None:
116115

117116
try:
118117
return os.isatty(file.fileno())
119-
except io.UnsupportedOperation:
118+
except OSError:
120119
return hasattr(file, "isatty") and file.isatty()

Lib/test/test__colorize.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,17 @@ def test_colorized_detection_checks_for_file(self):
129129
file.isatty.return_value = False
130130
self.assertEqual(_colorize.can_colorize(file=file), False)
131131

132+
# The documentation for file.fileno says:
133+
# > An OSError is raised if the IO object does not use a file descriptor.
134+
# gh-141570: Check OSError is caught and handled
135+
with unittest.mock.patch("os.isatty", side_effect=ZeroDivisionError):
136+
file = unittest.mock.MagicMock()
137+
file.fileno.side_effect = OSError
138+
file.isatty.return_value = True
139+
self.assertEqual(_colorize.can_colorize(file=file), True)
140+
file.isatty.return_value = False
141+
self.assertEqual(_colorize.can_colorize(file=file), False)
142+
132143

133144
if __name__ == "__main__":
134145
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Support :term:`file-like object` raising :exc:`OSError` from :meth:`~io.IOBase.fileno` in color
2+
detection (``_colorize.can_colorize()``). This can occur when ``sys.stdout`` is redirected.

0 commit comments

Comments
 (0)