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

Colorize live-log levelnames #3142

Merged
merged 1 commit into from Jan 30, 2018

Conversation

Projects
None yet
3 participants
@thisch
Copy link
Contributor

thisch commented Jan 23, 2018

I propose to prettify the default output of the live logs a bit by colorizing the levelnames.

A screenshot paints a thousand words:
image

@thisch thisch changed the base branch from master to features Jan 23, 2018

@thisch thisch force-pushed the thisch:only_colorize_levelname branch from c7d729c to 216b21a Jan 23, 2018

@coveralls

This comment has been minimized.

Copy link

coveralls commented Jan 23, 2018

Coverage Status

Coverage decreased (-0.02%) to 92.628% when pulling ebab1b6 on thisch:only_colorize_levelname into 49773b5 on pytest-dev:features.

@thisch thisch force-pushed the thisch:only_colorize_levelname branch 2 times, most recently from 87013c4 to d797e3f Jan 26, 2018

@thisch thisch changed the title WIP: Colorize live-log levelnames Colorize live-log levelnames Jan 26, 2018

@thisch thisch force-pushed the thisch:only_colorize_levelname branch from d797e3f to ed1051f Jan 26, 2018

@thisch

This comment has been minimized.

Copy link
Contributor Author

thisch commented Jan 26, 2018

What do you think about this?

Are there tests that test the text colors of the pytest output, where I can take a look at?

@nicoddemus

This comment has been minimized.

Copy link
Member

nicoddemus commented Jan 26, 2018

Are there tests that test the text colors of the pytest output, where I can take a look at?

Unfortunately no AFAIK. 😕

@thisch

This comment has been minimized.

Copy link
Contributor Author

thisch commented Jan 26, 2018

Note that I successfully tested this PR in cpython2.7 and in cpython3.6.

@nicoddemus

This comment has been minimized.

Copy link
Member

nicoddemus commented Jan 27, 2018

This is how it looks on Windows:

colored-log

👍

@nicoddemus
Copy link
Member

nicoddemus left a comment

This looks great @thisch, please take a look at my comments! 👍

DEFAULT_LOG_FORMAT = '%(filename)-25s %(lineno)4d %(levelname)-8s %(message)s'
DEFAULT_LOG_DATE_FORMAT = '%H:%M:%S'

# move to __init__ of ColoredLevelFormatter?
LEVELNAME_FMT_REGEX = re.compile(r'%\(levelname\)([+-]?\d*s)')

This comment has been minimized.

@nicoddemus

nicoddemus Jan 27, 2018

Member

Probably both LEVELNAME_FMT_REGEX and LOGLEVEL_COLOROPTS would be better off being class attributes of ColoredLevelFormatter.

def __init__(self, *args, **kwargs):
super(ColoredLevelFormatter, self).__init__(
*args, **kwargs)
if py.std.sys.version_info[0] >= 3:

This comment has been minimized.

@nicoddemus

nicoddemus Jan 27, 2018

Member

Please use six.PY3 instead (this will make it easier later to find python2-specific code)

fmt = self._level_to_fmt_mapping.get(
record.levelno, self._original_fmt)

if py.std.sys.version_info[0] >= 3:

This comment has been minimized.

@nicoddemus

nicoddemus Jan 27, 2018

Member

Ditto here for six.PY3 👍

LEVELNAME_FMT_REGEX = re.compile(r'%\(levelname\)([+-]?\d*s)')


class ColoredLevelFormatter(logging.Formatter):

This comment has been minimized.

@nicoddemus

nicoddemus Jan 27, 2018

Member

To test this, probably the way to go is to unittest the ColoredLevelFormatter class directly: create an instance and pass different LogRecord instances and ensure they have the correct markup applied. Also interesting to use custom log levels and ensure they don't have any markup.

This comment has been minimized.

@thisch

thisch Jan 27, 2018

Author Contributor

Unfortunately this does not work, since tw.markup() does not add ANSI escape sequences around the string in the unit tests:

(Pdb++) tw.markup('abc', red=True)
'abc'
(Pdb++) tw.hasmarkup
False

Any ideas?

This comment has been minimized.

@thisch

thisch Jan 27, 2018

Author Contributor

I'll do some mocking and then it should work.

This comment has been minimized.

@thisch

thisch Jan 30, 2018

Author Contributor

@thisch thisch force-pushed the thisch:only_colorize_levelname branch from ed1051f to c1da614 Jan 27, 2018

@thisch

This comment has been minimized.

Copy link
Contributor Author

thisch commented Jan 30, 2018

I guess that this is already too late for pytest 3.4, right?

@thisch

This comment has been minimized.

Copy link
Contributor Author

thisch commented Jan 30, 2018

BTW, I don't understand why the tests fail.

@nicoddemus

This comment has been minimized.

Copy link
Member

nicoddemus commented Jan 30, 2018

I guess that this is already too late for pytest 3.4, right?

I plan to release 3.4 when I get home later, but if we merge this until then I will be happy to generate the package again.

BTW, I don't understand why the tests fail.

No idea either, seems to be some bad interaction with mock... I suggest to try to use monkeypatch in your test instead of mock to see if the problem goes away (plus it will work on Python 2 as well).

@thisch thisch force-pushed the thisch:only_colorize_levelname branch from c1da614 to 6c0a8ac Jan 30, 2018

@thisch

This comment has been minimized.

Copy link
Contributor Author

thisch commented Jan 30, 2018

Let's hope that the tests now pass.

@nicoddemus

This comment has been minimized.

Copy link
Member

nicoddemus commented Jan 30, 2018

Just remembered this now and would like to confirm, passing --color=no disables the colors?

@thisch thisch force-pushed the thisch:only_colorize_levelname branch from 6c0a8ac to 1ad52b9 Jan 30, 2018

@thisch

This comment has been minimized.

Copy link
Contributor Author

thisch commented Jan 30, 2018

Now the color config option should be taken into account. This made the monkeypatching code obsolete.

@@ -376,7 +432,10 @@ def _setup_cli_logging(self):
log_cli_handler = _LiveLoggingStreamHandler(terminal_reporter, capture_manager)
log_cli_format = get_option_ini(self._config, 'log_cli_format', 'log_format')
log_cli_date_format = get_option_ini(self._config, 'log_cli_date_format', 'log_date_format')
log_cli_formatter = logging.Formatter(log_cli_format, datefmt=log_cli_date_format)
if ColoredLevelFormatter.LEVELNAME_FMT_REGEX.search(log_cli_format):
log_cli_formatter = ColoredLevelFormatter(self._config, log_cli_format, datefmt=log_cli_date_format)

This comment has been minimized.

@thisch

thisch Jan 30, 2018

Author Contributor

I could also perform the color check in the condition in line 435. Then I don't need to pass self._config to the __init__ method of ColoredLevelFormatter.

This comment has been minimized.

@nicoddemus

nicoddemus Jan 30, 2018

Member

Seems better

This comment has been minimized.

@thisch

thisch Jan 30, 2018

Author Contributor

I didn't know that color is a ternary type ('yes', 'no' and 'auto'). So I can't add self._config.option.color == 'yes' and to the if condition. If the value of the color option is 'auto' the TerminalWriter.init determines if the terminal supports markup or not.

An alternative would be to pass a terminalwriter object (_pytest.config.create_terminal_writer(self._config)) as the first arg of ColoredLevelFormatter. Don't know if this makes it better.

This comment has been minimized.

@nicoddemus

nicoddemus Jan 30, 2018

Member

An alternative would be to pass a terminalwriter object (_pytest.config.create_terminal_writer(self._config)) as the first arg of ColoredLevelFormatter. Don't know if this makes it better.

This reduces the number of dependencies at least (ColoredLevelFormatter will then depend only on TerminalWriter, instead of Config and TerminalWriter with the current code), so feel free to go with this route.

@thisch thisch force-pushed the thisch:only_colorize_levelname branch from 1ad52b9 to ebab1b6 Jan 30, 2018

@thisch

This comment has been minimized.

Copy link
Contributor Author

thisch commented Jan 30, 2018

If all tests pass, this is ready for merging.

@nicoddemus nicoddemus merged commit 71a7b3c into pytest-dev:features Jan 30, 2018

2 checks passed

continuous-integration/appveyor/pr AppVeyor build succeeded
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
@nicoddemus

This comment has been minimized.

Copy link
Member

nicoddemus commented Jan 30, 2018

Thanks @thisch!

@nicoddemus nicoddemus referenced this pull request Jan 30, 2018

Merged

Release 3.4.0 #3162

@thisch thisch deleted the thisch:only_colorize_levelname branch Feb 23, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.