Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass 'color' explicitly in error echoing #2273

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/click/exceptions.py
Expand Up @@ -5,6 +5,7 @@

from ._compat import get_text_stderr
from .utils import echo
from click.globals import resolve_color_default

if t.TYPE_CHECKING:
from .core import Context
Expand All @@ -28,6 +29,9 @@ class ClickException(Exception):

def __init__(self, message: str) -> None:
super().__init__(message)
# The context will be removed by the time we print the message, so cache
# the color settings here to be used later on (in `show`)
self.show_color = resolve_color_default()
self.message = message

def format_message(self) -> str:
Expand All @@ -40,7 +44,11 @@ def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None:
if file is None:
file = get_text_stderr()

echo(_("Error: {message}").format(message=self.format_message()), file=file)
echo(
_("Error: {message}").format(message=self.format_message()),
file=file,
color=self.show_color,
)


class UsageError(ClickException):
Expand Down
22 changes: 22 additions & 0 deletions tests/test_testing.py
Expand Up @@ -6,6 +6,7 @@

import click
from click._compat import WIN
from click.exceptions import ClickException
from click.testing import CliRunner


Expand Down Expand Up @@ -201,6 +202,27 @@ def cli():
assert not result.exception


@pytest.mark.skipif(WIN, reason="Test does not make sense on Windows.")
def test_with_color_errors():
class CLIError(ClickException):
def format_message(self) -> str:
return click.style(self.message, fg="red")

@click.command()
def cli():
raise CLIError("Red error")

runner = CliRunner()

result = runner.invoke(cli)
assert result.output == "Error: Red error\n"
assert result.exception

result = runner.invoke(cli, color=True)
assert result.output == f"Error: {click.style('Red error', fg='red')}\n"
assert result.exception


def test_with_color_but_pause_not_blocking():
@click.command()
def cli():
Expand Down