Merge pull request #5311 from thisch/coloredcaplog
Use same code for setting up cli/non-cli formatter
This commit is contained in:
		
						commit
						84569ca4da
					
				|  | @ -0,0 +1,2 @@ | ||||||
|  | Captured logs that are output for each failing test are formatted using the | ||||||
|  | ColoredLevelFormatter. | ||||||
|  | @ -18,6 +18,11 @@ from _pytest.pathlib import Path | ||||||
| 
 | 
 | ||||||
| DEFAULT_LOG_FORMAT = "%(levelname)-8s %(name)s:%(filename)s:%(lineno)d %(message)s" | DEFAULT_LOG_FORMAT = "%(levelname)-8s %(name)s:%(filename)s:%(lineno)d %(message)s" | ||||||
| DEFAULT_LOG_DATE_FORMAT = "%H:%M:%S" | DEFAULT_LOG_DATE_FORMAT = "%H:%M:%S" | ||||||
|  | _ANSI_ESCAPE_SEQ = re.compile(r"\x1b\[[\d;]+m") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def _remove_ansi_escape_sequences(text): | ||||||
|  |     return _ANSI_ESCAPE_SEQ.sub("", text) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ColoredLevelFormatter(logging.Formatter): | class ColoredLevelFormatter(logging.Formatter): | ||||||
|  | @ -257,8 +262,8 @@ class LogCaptureFixture(object): | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def text(self): |     def text(self): | ||||||
|         """Returns the log text.""" |         """Returns the formatted log text.""" | ||||||
|         return self.handler.stream.getvalue() |         return _remove_ansi_escape_sequences(self.handler.stream.getvalue()) | ||||||
| 
 | 
 | ||||||
|     @property |     @property | ||||||
|     def records(self): |     def records(self): | ||||||
|  | @ -394,7 +399,7 @@ class LoggingPlugin(object): | ||||||
|             config.option.verbose = 1 |             config.option.verbose = 1 | ||||||
| 
 | 
 | ||||||
|         self.print_logs = get_option_ini(config, "log_print") |         self.print_logs = get_option_ini(config, "log_print") | ||||||
|         self.formatter = logging.Formatter( |         self.formatter = self._create_formatter( | ||||||
|             get_option_ini(config, "log_format"), |             get_option_ini(config, "log_format"), | ||||||
|             get_option_ini(config, "log_date_format"), |             get_option_ini(config, "log_date_format"), | ||||||
|         ) |         ) | ||||||
|  | @ -428,6 +433,19 @@ class LoggingPlugin(object): | ||||||
|         if self._log_cli_enabled(): |         if self._log_cli_enabled(): | ||||||
|             self._setup_cli_logging() |             self._setup_cli_logging() | ||||||
| 
 | 
 | ||||||
|  |     def _create_formatter(self, log_format, log_date_format): | ||||||
|  |         # color option doesn't exist if terminal plugin is disabled | ||||||
|  |         color = getattr(self._config.option, "color", "no") | ||||||
|  |         if color != "no" and ColoredLevelFormatter.LEVELNAME_FMT_REGEX.search( | ||||||
|  |             log_format | ||||||
|  |         ): | ||||||
|  |             formatter = ColoredLevelFormatter( | ||||||
|  |                 create_terminal_writer(self._config), log_format, log_date_format | ||||||
|  |             ) | ||||||
|  |         else: | ||||||
|  |             formatter = logging.Formatter(log_format, log_date_format) | ||||||
|  |         return formatter | ||||||
|  | 
 | ||||||
|     def _setup_cli_logging(self): |     def _setup_cli_logging(self): | ||||||
|         config = self._config |         config = self._config | ||||||
|         terminal_reporter = config.pluginmanager.get_plugin("terminalreporter") |         terminal_reporter = config.pluginmanager.get_plugin("terminalreporter") | ||||||
|  | @ -438,23 +456,12 @@ class LoggingPlugin(object): | ||||||
|         capture_manager = config.pluginmanager.get_plugin("capturemanager") |         capture_manager = config.pluginmanager.get_plugin("capturemanager") | ||||||
|         # if capturemanager plugin is disabled, live logging still works. |         # if capturemanager plugin is disabled, live logging still works. | ||||||
|         log_cli_handler = _LiveLoggingStreamHandler(terminal_reporter, capture_manager) |         log_cli_handler = _LiveLoggingStreamHandler(terminal_reporter, capture_manager) | ||||||
|         log_cli_format = get_option_ini(config, "log_cli_format", "log_format") | 
 | ||||||
|         log_cli_date_format = get_option_ini( |         log_cli_formatter = self._create_formatter( | ||||||
|             config, "log_cli_date_format", "log_date_format" |             get_option_ini(config, "log_cli_format", "log_format"), | ||||||
|         ) |             get_option_ini(config, "log_cli_date_format", "log_date_format"), | ||||||
|         if ( |  | ||||||
|             config.option.color != "no" |  | ||||||
|             and ColoredLevelFormatter.LEVELNAME_FMT_REGEX.search(log_cli_format) |  | ||||||
|         ): |  | ||||||
|             log_cli_formatter = ColoredLevelFormatter( |  | ||||||
|                 create_terminal_writer(config), |  | ||||||
|                 log_cli_format, |  | ||||||
|                 datefmt=log_cli_date_format, |  | ||||||
|             ) |  | ||||||
|         else: |  | ||||||
|             log_cli_formatter = logging.Formatter( |  | ||||||
|                 log_cli_format, datefmt=log_cli_date_format |  | ||||||
|         ) |         ) | ||||||
|  | 
 | ||||||
|         log_cli_level = get_actual_log_level(config, "log_cli_level", "log_level") |         log_cli_level = get_actual_log_level(config, "log_cli_level", "log_level") | ||||||
|         self.log_cli_handler = log_cli_handler |         self.log_cli_handler = log_cli_handler | ||||||
|         self.live_logs_context = lambda: catching_logs( |         self.live_logs_context = lambda: catching_logs( | ||||||
|  |  | ||||||
|  | @ -1084,3 +1084,48 @@ def test_log_set_path(testdir): | ||||||
|     with open(os.path.join(report_dir_base, "test_second"), "r") as rfh: |     with open(os.path.join(report_dir_base, "test_second"), "r") as rfh: | ||||||
|         content = rfh.read() |         content = rfh.read() | ||||||
|         assert "message from test 2" in content |         assert "message from test 2" in content | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_colored_captured_log(testdir): | ||||||
|  |     """ | ||||||
|  |     Test that the level names of captured log messages of a failing test are | ||||||
|  |     colored. | ||||||
|  |     """ | ||||||
|  |     testdir.makepyfile( | ||||||
|  |         """ | ||||||
|  |         import logging | ||||||
|  | 
 | ||||||
|  |         logger = logging.getLogger(__name__) | ||||||
|  | 
 | ||||||
|  |         def test_foo(): | ||||||
|  |             logger.info('text going to logger from call') | ||||||
|  |             assert False | ||||||
|  |         """ | ||||||
|  |     ) | ||||||
|  |     result = testdir.runpytest("--log-level=INFO", "--color=yes") | ||||||
|  |     assert result.ret == 1 | ||||||
|  |     result.stdout.fnmatch_lines( | ||||||
|  |         [ | ||||||
|  |             "*-- Captured log call --*", | ||||||
|  |             "\x1b[32mINFO    \x1b[0m*text going to logger from call", | ||||||
|  |         ] | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def test_colored_ansi_esc_caplogtext(testdir): | ||||||
|  |     """ | ||||||
|  |     Make sure that caplog.text does not contain ANSI escape sequences. | ||||||
|  |     """ | ||||||
|  |     testdir.makepyfile( | ||||||
|  |         """ | ||||||
|  |         import logging | ||||||
|  | 
 | ||||||
|  |         logger = logging.getLogger(__name__) | ||||||
|  | 
 | ||||||
|  |         def test_foo(caplog): | ||||||
|  |             logger.info('text going to logger from call') | ||||||
|  |             assert '\x1b' not in caplog.text | ||||||
|  |         """ | ||||||
|  |     ) | ||||||
|  |     result = testdir.runpytest("--log-level=INFO", "--color=yes") | ||||||
|  |     assert result.ret == 0 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue