|
3 | 3 | import sys |
4 | 4 | import functools |
5 | 5 | import difflib |
6 | | -import logging |
7 | 6 | import pprint |
8 | 7 | import re |
9 | 8 | import warnings |
@@ -297,73 +296,6 @@ def __exit__(self, exc_type, exc_value, tb): |
297 | 296 |
|
298 | 297 |
|
299 | 298 |
|
300 | | -_LoggingWatcher = collections.namedtuple("_LoggingWatcher", |
301 | | - ["records", "output"]) |
302 | | - |
303 | | - |
304 | | -class _CapturingHandler(logging.Handler): |
305 | | - """ |
306 | | - A logging handler capturing all (raw and formatted) logging output. |
307 | | - """ |
308 | | - |
309 | | - def __init__(self): |
310 | | - logging.Handler.__init__(self) |
311 | | - self.watcher = _LoggingWatcher([], []) |
312 | | - |
313 | | - def flush(self): |
314 | | - pass |
315 | | - |
316 | | - def emit(self, record): |
317 | | - self.watcher.records.append(record) |
318 | | - msg = self.format(record) |
319 | | - self.watcher.output.append(msg) |
320 | | - |
321 | | - |
322 | | - |
323 | | -class _AssertLogsContext(_BaseTestCaseContext): |
324 | | - """A context manager used to implement TestCase.assertLogs().""" |
325 | | - |
326 | | - LOGGING_FORMAT = "%(levelname)s:%(name)s:%(message)s" |
327 | | - |
328 | | - def __init__(self, test_case, logger_name, level): |
329 | | - _BaseTestCaseContext.__init__(self, test_case) |
330 | | - self.logger_name = logger_name |
331 | | - if level: |
332 | | - self.level = logging._nameToLevel.get(level, level) |
333 | | - else: |
334 | | - self.level = logging.INFO |
335 | | - self.msg = None |
336 | | - |
337 | | - def __enter__(self): |
338 | | - if isinstance(self.logger_name, logging.Logger): |
339 | | - logger = self.logger = self.logger_name |
340 | | - else: |
341 | | - logger = self.logger = logging.getLogger(self.logger_name) |
342 | | - formatter = logging.Formatter(self.LOGGING_FORMAT) |
343 | | - handler = _CapturingHandler() |
344 | | - handler.setFormatter(formatter) |
345 | | - self.watcher = handler.watcher |
346 | | - self.old_handlers = logger.handlers[:] |
347 | | - self.old_level = logger.level |
348 | | - self.old_propagate = logger.propagate |
349 | | - logger.handlers = [handler] |
350 | | - logger.setLevel(self.level) |
351 | | - logger.propagate = False |
352 | | - return handler.watcher |
353 | | - |
354 | | - def __exit__(self, exc_type, exc_value, tb): |
355 | | - self.logger.handlers = self.old_handlers |
356 | | - self.logger.propagate = self.old_propagate |
357 | | - self.logger.setLevel(self.old_level) |
358 | | - if exc_type is not None: |
359 | | - # let unexpected exceptions pass through |
360 | | - return False |
361 | | - if len(self.watcher.records) == 0: |
362 | | - self._raiseFailure( |
363 | | - "no logs of level {} or higher triggered on {}" |
364 | | - .format(logging.getLevelName(self.level), self.logger.name)) |
365 | | - |
366 | | - |
367 | 299 | class _OrderedChainMap(collections.ChainMap): |
368 | 300 | def __iter__(self): |
369 | 301 | seen = set() |
@@ -854,6 +786,8 @@ def assertLogs(self, logger=None, level=None): |
854 | 786 | self.assertEqual(cm.output, ['INFO:foo:first message', |
855 | 787 | 'ERROR:foo.bar:second message']) |
856 | 788 | """ |
| 789 | + # Lazy import to avoid importing logging if it is not needed. |
| 790 | + from ._log import _AssertLogsContext |
857 | 791 | return _AssertLogsContext(self, logger, level) |
858 | 792 |
|
859 | 793 | def _getAssertEqualityFunc(self, first, second): |
|
0 commit comments