gh-141570: can_colorize: Expect fileno() to raise OSError, as documented (GH-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 https://github.com/python/cpython/issues/141570
(cherry picked from commit
96f496a949b05054d0d043c3085f00cec2f83bf5)
Co-authored-by: Miro HronĨok <miro@hroncok.cz>
Co-authored-by: Cody Maloney <cmaloney@users.noreply.github.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
-import io
import os
import sys
try:
return os.isatty(file.fileno())
- except io.UnsupportedOperation:
+ except OSError:
return hasattr(file, "isatty") and file.isatty()
file.isatty.return_value = False
self.assertEqual(_colorize.can_colorize(file=file), False)
+ # The documentation for file.fileno says:
+ # > An OSError is raised if the IO object does not use a file descriptor.
+ # gh-141570: Check OSError is caught and handled
+ with unittest.mock.patch("os.isatty", side_effect=ZeroDivisionError):
+ file = unittest.mock.MagicMock()
+ file.fileno.side_effect = OSError
+ file.isatty.return_value = True
+ self.assertEqual(_colorize.can_colorize(file=file), True)
+ file.isatty.return_value = False
+ self.assertEqual(_colorize.can_colorize(file=file), False)
+
if __name__ == "__main__":
unittest.main()
--- /dev/null
+Support :term:`file-like object` raising :exc:`OSError` from :meth:`~io.IOBase.fileno` in color
+detection (``_colorize.can_colorize()``). This can occur when ``sys.stdout`` is redirected.