1
+ import contextlib
2
+ import logging
1
3
import errno
2
4
import importlib
3
5
import io
24
26
TESTFN = os_helper .TESTFN
25
27
26
28
29
+ class LogCaptureHandler (logging .StreamHandler ):
30
+ """
31
+ A logging handler that stores log records and the log text.
32
+
33
+ derrived from pytest caplog
34
+
35
+ The MIT License (MIT)
36
+
37
+ Copyright (c) 2004 Holger Krekel and others
38
+
39
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
40
+ this software and associated documentation files (the "Software"), to deal in
41
+ the Software without restriction, including without limitation the rights to
42
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
43
+ of the Software, and to permit persons to whom the Software is furnished to do
44
+ so, subject to the following conditions:
45
+
46
+ The above copyright notice and this permission notice shall be included in all
47
+ copies or substantial portions of the Software.
48
+
49
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
54
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
55
+ SOFTWARE.
56
+ """
57
+
58
+ def __init__ (self ) -> None :
59
+ """Create a new log handler."""
60
+ super ().__init__ (io .StringIO ())
61
+ self .records = []
62
+
63
+ def emit (self , record : logging .LogRecord ) -> None :
64
+ """Keep the log records in a list in addition to the log text."""
65
+ self .records .append (record )
66
+ super ().emit (record )
67
+
68
+ def reset (self ):
69
+ self .records = []
70
+ self .stream = io .StringIO ()
71
+
72
+ def clear (self ):
73
+ self .records .clear ()
74
+ self .stream = io .StringIO ()
75
+
76
+ def handleError (self , record ):
77
+ if logging .raiseExceptions :
78
+ # Fail the test if the log message is bad (emit failed).
79
+ # The default behavior of logging is to print "Logging error"
80
+ # to stderr with the call stack and some extra details.
81
+ # pytest wants to make such mistakes visible during testing.
82
+ raise
83
+
84
+
85
+ @contextlib .contextmanager
86
+ def _caplog ():
87
+ handler = LogCaptureHandler ()
88
+ root_logger = logging .getLogger ()
89
+ root_logger .addHandler (handler )
90
+ try :
91
+ yield handler
92
+ finally :
93
+ root_logger .removeHandler (handler )
94
+
95
+
27
96
class TestSupport (unittest .TestCase ):
28
97
@classmethod
29
98
def setUpClass (cls ):
@@ -187,7 +256,7 @@ def test_temp_dir__existing_dir__quiet_true(self):
187
256
path = os .path .realpath (path )
188
257
189
258
try :
190
- with warnings_helper .check_warnings () as recorder :
259
+ with warnings_helper .check_warnings () as recorder , _caplog () as caplog :
191
260
with os_helper .temp_dir (path , quiet = True ) as temp_path :
192
261
self .assertEqual (path , temp_path )
193
262
warnings = [str (w .message ) for w in recorder .warnings ]
@@ -196,11 +265,14 @@ def test_temp_dir__existing_dir__quiet_true(self):
196
265
finally :
197
266
shutil .rmtree (path )
198
267
199
- self .assertEqual (len (warnings ), 1 , warnings )
200
- warn = warnings [0 ]
201
- self .assertTrue (warn .startswith (f'tests may fail, unable to create '
202
- f'temporary directory { path !r} : ' ),
203
- warn )
268
+ self .assertListEqual (warnings , [])
269
+ self .assertEqual (len (caplog .records ), 1 )
270
+ record , = caplog .records
271
+ self .assertStartsWith (
272
+ record .getMessage (),
273
+ f'tests may fail, unable to create '
274
+ f'temporary directory { path !r} : '
275
+ )
204
276
205
277
@support .requires_fork ()
206
278
def test_temp_dir__forked_child (self ):
@@ -260,35 +332,41 @@ def test_change_cwd__non_existent_dir__quiet_true(self):
260
332
261
333
with os_helper .temp_dir () as parent_dir :
262
334
bad_dir = os .path .join (parent_dir , 'does_not_exist' )
263
- with warnings_helper .check_warnings () as recorder :
335
+ with warnings_helper .check_warnings () as recorder , _caplog () as caplog :
264
336
with os_helper .change_cwd (bad_dir , quiet = True ) as new_cwd :
265
337
self .assertEqual (new_cwd , original_cwd )
266
338
self .assertEqual (os .getcwd (), new_cwd )
267
339
warnings = [str (w .message ) for w in recorder .warnings ]
268
340
269
- self .assertEqual (len (warnings ), 1 , warnings )
270
- warn = warnings [0 ]
271
- self .assertTrue (warn .startswith (f'tests may fail, unable to change '
272
- f'the current working directory '
273
- f'to { bad_dir !r} : ' ),
274
- warn )
341
+ self .assertListEqual (warnings , [])
342
+ self .assertEqual (len (caplog .records ), 1 )
343
+ record , = caplog .records
344
+ self .assertStartsWith (
345
+ record .getMessage (),
346
+ f'tests may fail, unable to change '
347
+ f'the current working directory '
348
+ f'to { bad_dir !r} : '
349
+ )
275
350
276
351
# Tests for change_cwd()
277
352
278
353
def test_change_cwd__chdir_warning (self ):
279
354
"""Check the warning message when os.chdir() fails."""
280
355
path = TESTFN + '_does_not_exist'
281
- with warnings_helper .check_warnings () as recorder :
356
+ with warnings_helper .check_warnings () as recorder , _caplog () as caplog :
282
357
with os_helper .change_cwd (path = path , quiet = True ):
283
358
pass
284
359
messages = [str (w .message ) for w in recorder .warnings ]
285
360
286
- self .assertEqual (len (messages ), 1 , messages )
287
- msg = messages [0 ]
288
- self .assertTrue (msg .startswith (f'tests may fail, unable to change '
289
- f'the current working directory '
290
- f'to { path !r} : ' ),
291
- msg )
361
+ self .assertListEqual (messages , [])
362
+ self .assertEqual (len (caplog .records ), 1 )
363
+ record , = caplog .records
364
+ self .assertStartsWith (
365
+ record .getMessage (),
366
+ f'tests may fail, unable to change '
367
+ f'the current working directory '
368
+ f'to { path !r} : ' ,
369
+ )
292
370
293
371
# Tests for temp_cwd()
294
372
0 commit comments