Skip to content

Commit 383af39

Browse files
authored
[3.13] gh-128595: Default to stdout isatty for colour detection instead of stderr (GH-128498) (#129057)
Co-authored-by: Hugo van Kemenade <[email protected]> Co-authored-by: Serhiy Storchaka <[email protected]> Co-authored-by: Victor Stinner <[email protected]> Fix `test__colorize` unexpected keyword argument 'file' on buildbots (#129070)
1 parent 972d953 commit 383af39

File tree

6 files changed

+19
-10
lines changed

6 files changed

+19
-10
lines changed

Lib/_colorize.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@ class ANSIColors:
2424
setattr(NoColors, attr, "")
2525

2626

27-
def get_colors(colorize: bool = False) -> ANSIColors:
28-
if colorize or can_colorize():
27+
def get_colors(colorize: bool = False, *, file=None) -> ANSIColors:
28+
if colorize or can_colorize(file=file):
2929
return ANSIColors()
3030
else:
3131
return NoColors
3232

3333

34-
def can_colorize() -> bool:
34+
def can_colorize(*, file=None) -> bool:
35+
if file is None:
36+
file = sys.stdout
37+
3538
if not sys.flags.ignore_environment:
3639
if os.environ.get("PYTHON_COLORS") == "0":
3740
return False
@@ -47,7 +50,7 @@ def can_colorize() -> bool:
4750
if os.environ.get("TERM") == "dumb":
4851
return False
4952

50-
if not hasattr(sys.stderr, "fileno"):
53+
if not hasattr(file, "fileno"):
5154
return False
5255

5356
if sys.platform == "win32":
@@ -60,6 +63,6 @@ def can_colorize() -> bool:
6063
return False
6164

6265
try:
63-
return os.isatty(sys.stderr.fileno())
66+
return os.isatty(file.fileno())
6467
except io.UnsupportedOperation:
65-
return sys.stderr.isatty()
68+
return file.isatty()

Lib/doctest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1558,7 +1558,7 @@ def out(s):
15581558
save_displayhook = sys.displayhook
15591559
sys.displayhook = sys.__displayhook__
15601560
saved_can_colorize = _colorize.can_colorize
1561-
_colorize.can_colorize = lambda: False
1561+
_colorize.can_colorize = lambda *args, **kwargs: False
15621562
color_variables = {"PYTHON_COLORS": None, "FORCE_COLOR": None}
15631563
for key in color_variables:
15641564
color_variables[key] = os.environ.pop(key, None)

Lib/test/support/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2700,7 +2700,7 @@ def no_color():
27002700
from .os_helper import EnvironmentVarGuard
27012701

27022702
with (
2703-
swap_attr(_colorize, "can_colorize", lambda: False),
2703+
swap_attr(_colorize, "can_colorize", lambda file=None: False),
27042704
EnvironmentVarGuard() as env,
27052705
):
27062706
for var in {"FORCE_COLOR", "NO_COLOR", "PYTHON_COLORS"}:

Lib/test/test__colorize.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010

1111
def setUpModule():
12-
_colorize.can_colorize = lambda: False
12+
_colorize.can_colorize = lambda *args, **kwargs: False
1313

1414

1515
def tearDownModule():
@@ -21,6 +21,7 @@ class TestColorizeFunction(unittest.TestCase):
2121
def test_colorized_detection_checks_for_environment_variables(self):
2222
flags = unittest.mock.MagicMock(ignore_environment=False)
2323
with (unittest.mock.patch("os.isatty") as isatty_mock,
24+
unittest.mock.patch("sys.stdout") as stdout_mock,
2425
unittest.mock.patch("sys.stderr") as stderr_mock,
2526
unittest.mock.patch("sys.flags", flags),
2627
unittest.mock.patch("_colorize.can_colorize", ORIGINAL_CAN_COLORIZE),
@@ -29,6 +30,8 @@ def test_colorized_detection_checks_for_environment_variables(self):
2930
contextlib.nullcontext()) as vt_mock):
3031

3132
isatty_mock.return_value = True
33+
stdout_mock.fileno.return_value = 1
34+
stdout_mock.isatty.return_value = True
3235
stderr_mock.fileno.return_value = 2
3336
stderr_mock.isatty.return_value = True
3437
with unittest.mock.patch("os.environ", {'TERM': 'dumb'}):
@@ -61,6 +64,7 @@ def test_colorized_detection_checks_for_environment_variables(self):
6164
self.assertEqual(_colorize.can_colorize(), True)
6265

6366
isatty_mock.return_value = False
67+
stdout_mock.isatty.return_value = False
6468
stderr_mock.isatty.return_value = False
6569
self.assertEqual(_colorize.can_colorize(), False)
6670

Lib/traceback.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def print_exception(exc, /, value=_sentinel, tb=_sentinel, limit=None, \
135135

136136
def _print_exception_bltin(exc, /):
137137
file = sys.stderr if sys.stderr is not None else sys.__stderr__
138-
colorize = _colorize.can_colorize()
138+
colorize = _colorize.can_colorize(file=file)
139139
return print_exception(exc, limit=BUILTIN_EXCEPTION_LIMIT, file=file, colorize=colorize)
140140

141141

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Default to stdout isatty for color detection instead of stderr. Patch by
2+
Hugo van Kemenade.

0 commit comments

Comments
 (0)