Skip to content

Commit

Permalink
Restore colors in regular logging messages
Browse files Browse the repository at this point in the history
Also, reflects that `--no-color` does not mean no-ansi-escapes but only
affects colour rules.
  • Loading branch information
pradyunsg committed Dec 5, 2021
1 parent c31bfec commit c429c82
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 16 deletions.
14 changes: 10 additions & 4 deletions src/pip/_internal/utils/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from pip._vendor.rich.highlighter import NullHighlighter
from pip._vendor.rich.logging import RichHandler
from pip._vendor.rich.segment import Segment
from pip._vendor.rich.style import Style

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

# Our custom override on rich's logger, to make things work as we need them to.
def emit(self, record: logging.LogRecord) -> None:
style: Optional[Style] = None

# If we are given a diagnostic error to present, present it with indentation.
if record.msg == "[present-diagnostic]" and len(record.args) == 1:
diagnostic_error: DiagnosticPipError = record.args[0] # type: ignore[index]
Expand All @@ -159,9 +162,12 @@ def emit(self, record: logging.LogRecord) -> None:
else:
message = self.format(record)
renderable = self.render_message(record, message)

if record.levelno >= logging.ERROR:
style = Style(color="red")
elif record.levelno >= logging.WARNING:
style = Style(color="yellow")
try:
self.console.print(renderable, overflow="ignore", crop=False)
self.console.print(renderable, overflow="ignore", crop=False, style=style)
except Exception:
self.handleError(record)

Expand Down Expand Up @@ -252,7 +258,6 @@ def setup_logging(verbosity: int, no_color: bool, user_log_file: Optional[str])
"stderr": "ext://sys.stderr",
}
handler_classes = {
"subprocess": "logging.StreamHandler",
"stream": "pip._internal.utils.logging.RichPipStreamHandler",
"file": "pip._internal.utils.logging.BetterRotatingFileHandler",
}
Expand Down Expand Up @@ -310,8 +315,9 @@ def setup_logging(verbosity: int, no_color: bool, user_log_file: Optional[str])
# from the "subprocessor" logger.
"console_subprocess": {
"level": level,
"class": handler_classes["subprocess"],
"class": handler_classes["stream"],
"stream": log_streams["stderr"],
"no_color": no_color,
"filters": ["restrict_to_subprocess"],
"formatter": "indent",
},
Expand Down
24 changes: 12 additions & 12 deletions tests/functional/test_no_color.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
Test specific for the --no-color option
"""
import os
import shutil
import subprocess
import sys

import pytest

from tests.lib import PipTestEnvironment
from tests.lib import PipTestEnvironment, TestData


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

def get_run_output(option: str) -> str:
def get_run_output(option: str = "") -> str:
cmd = command.format(option)
proc = subprocess.Popen(
cmd,
Expand All @@ -33,8 +37,6 @@ def get_run_output(option: str) -> str:
stderr=subprocess.PIPE,
)
proc.communicate()
if proc.returncode:
pytest.skip("Unable to capture output using script: " + cmd)

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

assert "\x1b" in get_run_output(option=""), "Expected color in output"
assert "\x1b" not in get_run_output(
option="--no-color"
), "Expected no color in output"
assert "\x1b[3" in get_run_output(""), "Expected color in output"
assert "\x1b[3" not in get_run_output("--no-color"), "Expected no color in output"

0 comments on commit c429c82

Please sign in to comment.