Skip to content

Commit c429c82

Browse files
committed
Restore colors in regular logging messages
Also, reflects that `--no-color` does not mean no-ansi-escapes but only affects colour rules.
1 parent c31bfec commit c429c82

File tree

2 files changed

+22
-16
lines changed

2 files changed

+22
-16
lines changed

src/pip/_internal/utils/logging.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from pip._vendor.rich.highlighter import NullHighlighter
1919
from pip._vendor.rich.logging import RichHandler
2020
from pip._vendor.rich.segment import Segment
21+
from pip._vendor.rich.style import Style
2122

2223
from pip._internal.exceptions import DiagnosticPipError
2324
from pip._internal.utils._log import VERBOSE, getLogger
@@ -148,6 +149,8 @@ def __init__(self, stream: Optional[TextIO], no_color: bool) -> None:
148149

149150
# Our custom override on rich's logger, to make things work as we need them to.
150151
def emit(self, record: logging.LogRecord) -> None:
152+
style: Optional[Style] = None
153+
151154
# If we are given a diagnostic error to present, present it with indentation.
152155
if record.msg == "[present-diagnostic]" and len(record.args) == 1:
153156
diagnostic_error: DiagnosticPipError = record.args[0] # type: ignore[index]
@@ -159,9 +162,12 @@ def emit(self, record: logging.LogRecord) -> None:
159162
else:
160163
message = self.format(record)
161164
renderable = self.render_message(record, message)
162-
165+
if record.levelno >= logging.ERROR:
166+
style = Style(color="red")
167+
elif record.levelno >= logging.WARNING:
168+
style = Style(color="yellow")
163169
try:
164-
self.console.print(renderable, overflow="ignore", crop=False)
170+
self.console.print(renderable, overflow="ignore", crop=False, style=style)
165171
except Exception:
166172
self.handleError(record)
167173

@@ -252,7 +258,6 @@ def setup_logging(verbosity: int, no_color: bool, user_log_file: Optional[str])
252258
"stderr": "ext://sys.stderr",
253259
}
254260
handler_classes = {
255-
"subprocess": "logging.StreamHandler",
256261
"stream": "pip._internal.utils.logging.RichPipStreamHandler",
257262
"file": "pip._internal.utils.logging.BetterRotatingFileHandler",
258263
}
@@ -310,8 +315,9 @@ def setup_logging(verbosity: int, no_color: bool, user_log_file: Optional[str])
310315
# from the "subprocessor" logger.
311316
"console_subprocess": {
312317
"level": level,
313-
"class": handler_classes["subprocess"],
318+
"class": handler_classes["stream"],
314319
"stream": log_streams["stderr"],
320+
"no_color": no_color,
315321
"filters": ["restrict_to_subprocess"],
316322
"formatter": "indent",
317323
},

tests/functional/test_no_color.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
Test specific for the --no-color option
33
"""
44
import os
5+
import shutil
56
import subprocess
7+
import sys
68

79
import pytest
810

9-
from tests.lib import PipTestEnvironment
11+
from tests.lib import PipTestEnvironment, TestData
1012

1113

14+
@pytest.mark.skipif(shutil.which("script") is None, reason="no 'script' executable")
1215
def test_no_color(script: PipTestEnvironment) -> None:
1316
"""Ensure colour output disabled when --no-color is passed."""
1417
# Using 'script' in this test allows for transparently testing pip's output
@@ -19,12 +22,13 @@ def test_no_color(script: PipTestEnvironment) -> None:
1922
# 'script' and well as the mere use of the same.
2023
#
2124
# This test will stay until someone has the time to rewrite it.
22-
command = (
23-
"script --flush --quiet --return /tmp/pip-test-no-color.txt "
24-
'--command "pip uninstall {} noSuchPackage"'
25-
)
25+
pip_command = f"pip uninstall {{}} noSuchPackage"
26+
if sys.platform == "darwin":
27+
command = f"script -q /tmp/pip-test-no-color.txt {pip_command}"
28+
else:
29+
command = f'script -q /tmp/pip-test-no-color.txt --command "{pip_command}"'
2630

27-
def get_run_output(option: str) -> str:
31+
def get_run_output(option: str = "") -> str:
2832
cmd = command.format(option)
2933
proc = subprocess.Popen(
3034
cmd,
@@ -33,8 +37,6 @@ def get_run_output(option: str) -> str:
3337
stderr=subprocess.PIPE,
3438
)
3539
proc.communicate()
36-
if proc.returncode:
37-
pytest.skip("Unable to capture output using script: " + cmd)
3840

3941
try:
4042
with open("/tmp/pip-test-no-color.txt") as output_file:
@@ -43,7 +45,5 @@ def get_run_output(option: str) -> str:
4345
finally:
4446
os.unlink("/tmp/pip-test-no-color.txt")
4547

46-
assert "\x1b" in get_run_output(option=""), "Expected color in output"
47-
assert "\x1b" not in get_run_output(
48-
option="--no-color"
49-
), "Expected no color in output"
48+
assert "\x1b[3" in get_run_output(""), "Expected color in output"
49+
assert "\x1b[3" not in get_run_output("--no-color"), "Expected no color in output"

0 commit comments

Comments
 (0)