15
15
from .util import (strclass , safe_repr , _count_diff_all_purpose ,
16
16
_count_diff_hashable , _common_shorten_repr )
17
17
18
+ logging = None # imported lazily
19
+
18
20
__unittest = True
19
21
20
22
_subtest_msg_sentinel = object ()
@@ -299,6 +301,35 @@ def __exit__(self, exc_type, exc_value, tb):
299
301
_LoggingWatcher = collections .namedtuple ("_LoggingWatcher" ,
300
302
["records" , "output" ])
301
303
304
+ # Import logging lazily for assertLogs().
305
+ # assertLogs() is one of the least used assertions, and most tests do
306
+ # not need to import logging.
307
+
308
+ def _lazy_logging_import ():
309
+ global logging
310
+ global _CapturingHandler
311
+ if logging :
312
+ return
313
+
314
+ import logging
315
+ class _CapturingHandler (logging .Handler ):
316
+ """
317
+ A logging handler capturing all (raw and formatted) logging output.
318
+ """
319
+
320
+ def __init__ (self ):
321
+ logging .Handler .__init__ (self )
322
+ self .watcher = _LoggingWatcher ([], [])
323
+
324
+ def flush (self ):
325
+ pass
326
+
327
+ def emit (self , record ):
328
+ self .watcher .records .append (record )
329
+ msg = self .format (record )
330
+ self .watcher .output .append (msg )
331
+
332
+
302
333
class _AssertLogsContext (_BaseTestCaseContext ):
303
334
"""A context manager used to implement TestCase.assertLogs()."""
304
335
@@ -307,39 +338,19 @@ class _AssertLogsContext(_BaseTestCaseContext):
307
338
def __init__ (self , test_case , logger_name , level ):
308
339
_BaseTestCaseContext .__init__ (self , test_case )
309
340
self .logger_name = logger_name
310
- import logging
311
- self .logging = logging
341
+ _lazy_logging_import ()
312
342
if level :
313
343
self .level = logging ._nameToLevel .get (level , level )
314
344
else :
315
345
self .level = logging .INFO
316
346
self .msg = None
317
347
318
348
def __enter__ (self ):
319
- logging = self .logging
320
349
if isinstance (self .logger_name , logging .Logger ):
321
350
logger = self .logger = self .logger_name
322
351
else :
323
352
logger = self .logger = logging .getLogger (self .logger_name )
324
353
formatter = logging .Formatter (self .LOGGING_FORMAT )
325
-
326
- class _CapturingHandler (logging .Handler ):
327
- """
328
- A logging handler capturing all (raw and formatted) logging output.
329
- """
330
-
331
- def __init__ (self ):
332
- logging .Handler .__init__ (self )
333
- self .watcher = _LoggingWatcher ([], [])
334
-
335
- def flush (self ):
336
- pass
337
-
338
- def emit (self , record ):
339
- self .watcher .records .append (record )
340
- msg = self .format (record )
341
- self .watcher .output .append (msg )
342
-
343
354
handler = _CapturingHandler ()
344
355
handler .setFormatter (formatter )
345
356
self .watcher = handler .watcher
@@ -361,7 +372,7 @@ def __exit__(self, exc_type, exc_value, tb):
361
372
if len (self .watcher .records ) == 0 :
362
373
self ._raiseFailure (
363
374
"no logs of level {} or higher triggered on {}"
364
- .format (self . logging .getLevelName (self .level ), self .logger .name ))
375
+ .format (logging .getLevelName (self .level ), self .logger .name ))
365
376
366
377
367
378
class _OrderedChainMap (collections .ChainMap ):
0 commit comments