From 897c514e13993346cc5b368ea28bac73907c4e42 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Thu, 9 Mar 2023 13:21:34 +0100 Subject: [PATCH 1/3] [colorize_ansi] Remove the possibility to use anything else than a MessageStyle --- doc/whatsnew/fragments/8412.breaking | 3 + pylint/reporters/text.py | 97 +++++++--------------------- 2 files changed, 26 insertions(+), 74 deletions(-) create mode 100644 doc/whatsnew/fragments/8412.breaking diff --git a/doc/whatsnew/fragments/8412.breaking b/doc/whatsnew/fragments/8412.breaking new file mode 100644 index 0000000000..ef12ebd183 --- /dev/null +++ b/doc/whatsnew/fragments/8412.breaking @@ -0,0 +1,3 @@ +``colorize_ansi`` now only accept a ``MessageStyle`` object. + +Refs #8412 diff --git a/pylint/reporters/text.py b/pylint/reporters/text.py index c25b31f7ed..a3860d8f97 100644 --- a/pylint/reporters/text.py +++ b/pylint/reporters/text.py @@ -15,7 +15,7 @@ import sys import warnings from dataclasses import asdict, fields -from typing import TYPE_CHECKING, Dict, NamedTuple, Optional, TextIO, cast, overload +from typing import TYPE_CHECKING, Dict, NamedTuple, Optional, TextIO, cast from pylint.message import Message from pylint.reporters import BaseReporter @@ -37,6 +37,24 @@ class MessageStyle(NamedTuple): style: tuple[str, ...] = () """Tuple of style strings (see `ANSI_COLORS` for available values).""" + def get_ansi_code(self) -> str: + """Return ANSI escape code corresponding to color and style. + + :raise KeyError: if a nonexistent color or style identifier is given + + :return: the built escape code + """ + ansi_code = [ANSI_STYLES[effect] for effect in self.style] + if self.color: + if self.color.isdigit(): + ansi_code.extend(["38", "5"]) + ansi_code.append(self.color) + else: + ansi_code.append(ANSI_COLORS[self.color]) + if ansi_code: + return ANSI_PREFIX + ";".join(ansi_code) + ANSI_END + return "" + ColorMappingDict = Dict[str, MessageStyle] @@ -70,81 +88,12 @@ class MessageStyle(NamedTuple): """All fields of the Message class.""" -def _get_ansi_code(msg_style: MessageStyle) -> str: - """Return ANSI escape code corresponding to color and style. - - :param msg_style: the message style - - :raise KeyError: if a nonexistent color or style identifier is given - - :return: the built escape code - """ - ansi_code = [ANSI_STYLES[effect] for effect in msg_style.style] - if msg_style.color: - if msg_style.color.isdigit(): - ansi_code.extend(["38", "5"]) - ansi_code.append(msg_style.color) - else: - ansi_code.append(ANSI_COLORS[msg_style.color]) - if ansi_code: - return ANSI_PREFIX + ";".join(ansi_code) + ANSI_END - return "" - - -@overload -def colorize_ansi( - msg: str, - msg_style: MessageStyle | None = ..., -) -> str: - ... - - -@overload -def colorize_ansi( - msg: str, - msg_style: str | None = ..., - style: str = ..., - *, - color: str | None = ..., -) -> str: - # Remove for pylint 3.0 - ... - - -def colorize_ansi( - msg: str, - msg_style: MessageStyle | str | None = None, - style: str = "", - **kwargs: str | None, -) -> str: - r"""colorize message by wrapping it with ANSI escape codes - - :param msg: the message string to colorize - - :param msg_style: the message style - or color (for backwards compatibility): the color of the message style - - :param style: the message's style elements, this will be deprecated - - :param \**kwargs: used to accept `color` parameter while it is being deprecated - - :return: the ANSI escaped string - """ - # TODO: 3.0: Remove deprecated typing and only accept MessageStyle as parameter - if not isinstance(msg_style, MessageStyle): - warnings.warn( - "In pylint 3.0, the colorize_ansi function of Text reporters will only accept a " - "MessageStyle parameter", - DeprecationWarning, - stacklevel=2, - ) - color = kwargs.get("color") - style_attrs = tuple(_splitstrip(style)) - msg_style = MessageStyle(color or msg_style, style_attrs) - # If both color and style are not defined, then leave the text as is +def colorize_ansi(msg: str, msg_style: MessageStyle) -> str: + """Colorize message by wrapping it with ANSI escape codes.""" if msg_style.color is None and len(msg_style.style) == 0: + # If both color and style are not defined, then leave the text as is. return msg - escape_code = _get_ansi_code(msg_style) + escape_code = msg_style.get_ansi_code() # If invalid (or unknown) color, don't wrap msg with ANSI codes if escape_code: return f"{escape_code}{msg}{ANSI_RESET}" From 64e5b95986604ae3265ad839b0b137bae1799669 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Thu, 9 Mar 2023 19:56:35 +0100 Subject: [PATCH 2/3] Make ansi_color protected --- pylint/reporters/text.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pylint/reporters/text.py b/pylint/reporters/text.py index a3860d8f97..0f44257b91 100644 --- a/pylint/reporters/text.py +++ b/pylint/reporters/text.py @@ -37,7 +37,7 @@ class MessageStyle(NamedTuple): style: tuple[str, ...] = () """Tuple of style strings (see `ANSI_COLORS` for available values).""" - def get_ansi_code(self) -> str: + def _get_ansi_code(self) -> str: """Return ANSI escape code corresponding to color and style. :raise KeyError: if a nonexistent color or style identifier is given @@ -93,7 +93,7 @@ def colorize_ansi(msg: str, msg_style: MessageStyle) -> str: if msg_style.color is None and len(msg_style.style) == 0: # If both color and style are not defined, then leave the text as is. return msg - escape_code = msg_style.get_ansi_code() + escape_code = msg_style._get_ansi_code() # If invalid (or unknown) color, don't wrap msg with ANSI codes if escape_code: return f"{escape_code}{msg}{ANSI_RESET}" From f591319bb94309d44b456726619ef1cd2968d861 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Thu, 9 Mar 2023 19:59:47 +0100 Subject: [PATCH 3/3] Make __get_ansi_code private --- pylint/reporters/text.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/pylint/reporters/text.py b/pylint/reporters/text.py index 0f44257b91..2803ed286b 100644 --- a/pylint/reporters/text.py +++ b/pylint/reporters/text.py @@ -37,7 +37,7 @@ class MessageStyle(NamedTuple): style: tuple[str, ...] = () """Tuple of style strings (see `ANSI_COLORS` for available values).""" - def _get_ansi_code(self) -> str: + def __get_ansi_code(self) -> str: """Return ANSI escape code corresponding to color and style. :raise KeyError: if a nonexistent color or style identifier is given @@ -55,6 +55,16 @@ def _get_ansi_code(self) -> str: return ANSI_PREFIX + ";".join(ansi_code) + ANSI_END return "" + def _colorize_ansi(self, msg: str) -> str: + if self.color is None and len(self.style) == 0: + # If both color and style are not defined, then leave the text as is. + return msg + escape_code = self.__get_ansi_code() + # If invalid (or unknown) color, don't wrap msg with ANSI codes + if escape_code: + return f"{escape_code}{msg}{ANSI_RESET}" + return msg + ColorMappingDict = Dict[str, MessageStyle] @@ -90,14 +100,7 @@ def _get_ansi_code(self) -> str: def colorize_ansi(msg: str, msg_style: MessageStyle) -> str: """Colorize message by wrapping it with ANSI escape codes.""" - if msg_style.color is None and len(msg_style.style) == 0: - # If both color and style are not defined, then leave the text as is. - return msg - escape_code = msg_style._get_ansi_code() - # If invalid (or unknown) color, don't wrap msg with ANSI codes - if escape_code: - return f"{escape_code}{msg}{ANSI_RESET}" - return msg + return msg_style._colorize_ansi(msg) def make_header(msg: Message) -> str: