12
12
import pytest
13
13
from scripttest import FoundDir , TestFileEnvironment
14
14
15
+ from pip ._internal .utils .deprecation import DEPRECATION_MSG_PREFIX
15
16
from tests .lib .path import Path , curdir
16
17
17
18
DATA_DIR = Path (__file__ ).folder .folder .join ("data" ).abspath
@@ -262,6 +263,46 @@ def assert_installed(self, pkg_name, editable=True, with_files=[],
262
263
)
263
264
264
265
266
+ def check_stderr (
267
+ stderr , expect_stderr_warning = False , expect_stderr_error = False ,
268
+ ):
269
+ """
270
+ Check the given stderr for logged warnings and errors.
271
+
272
+ :param stderr: stderr output as a string.
273
+ :param expect_stderr_warning: whether a logged warning (or deprecation
274
+ message) is allowed.
275
+ :param expect_stderr_error: whether a logged error is allowed. Passing
276
+ True for this argument implies `expect_stderr_warning` since warnings
277
+ are weaker than errors.
278
+ """
279
+ if expect_stderr_error :
280
+ expect_stderr_warning = True
281
+
282
+ if expect_stderr_error :
283
+ # Then any stderr is acceptable.
284
+ return
285
+
286
+ lines = stderr .splitlines ()
287
+ for line in lines :
288
+ if line .startswith ('ERROR: ' ):
289
+ raise RuntimeError (
290
+ 'stderr has an unexpected error '
291
+ '(pass expect_stderr_error=True to permit this): {}'
292
+ .format (line )
293
+ )
294
+ if expect_stderr_warning :
295
+ continue
296
+
297
+ if (line .startswith ('WARNING: ' ) or
298
+ line .startswith (DEPRECATION_MSG_PREFIX )):
299
+ raise RuntimeError (
300
+ 'stderr has an unexpected warning '
301
+ '(pass expect_stderr_warning=True to permit this): {}'
302
+ .format (line )
303
+ )
304
+
305
+
265
306
class PipTestEnvironment (TestFileEnvironment ):
266
307
"""
267
308
A specialized TestFileEnvironment for testing pip
@@ -368,6 +409,17 @@ def _find_traverse(self, path, result):
368
409
super (PipTestEnvironment , self )._find_traverse (path , result )
369
410
370
411
def run (self , * args , ** kw ):
412
+ """
413
+ :param expect_stderr_warning: whether a logged warning (or
414
+ deprecation message) is allowed in stderr.
415
+ :param expect_stderr_error: whether a logged error is allowed in
416
+ stderr. Passing True for this argument implies
417
+ `expect_stderr_warning` since warnings are weaker than errors.
418
+ :param expect_stderr: allow any stderr (equivalent to passing
419
+ `expect_stderr_error`). This argument is an abbreviated version
420
+ of `expect_stderr_error` and is also kept for backwards
421
+ compatibility.
422
+ """
371
423
if self .verbose :
372
424
print ('>> running %s %s' % (args , kw ))
373
425
cwd = kw .pop ('cwd' , None )
@@ -377,11 +429,28 @@ def run(self, *args, **kw):
377
429
if sys .platform == 'win32' :
378
430
# Partial fix for ScriptTest.run using `shell=True` on Windows.
379
431
args = [str (a ).replace ('^' , '^^' ).replace ('&' , '^&' ) for a in args ]
380
- return TestPipResult (
381
- super (PipTestEnvironment , self ).run (cwd = cwd , * args , ** kw ),
382
- verbose = self .verbose ,
432
+
433
+ # Remove `expect_stderr_error` and `expect_stderr_warning` because
434
+ # those arguments are not supported by PipTestEnvironment.
435
+ expect_stderr_error = kw .pop ('expect_stderr_error' , False )
436
+ expect_stderr_warning = kw .pop ('expect_stderr_warning' , False )
437
+
438
+ if kw .get ('expect_error' ) or kw .get ('expect_stderr' ):
439
+ # Then default to allowing logged errors.
440
+ expect_stderr_error = True
441
+
442
+ # Pass expect_stderr=True to allow any stderr. We do this because
443
+ # we do our checking of stderr further on in check_stderr().
444
+ kw ['expect_stderr' ] = True
445
+ result = super (PipTestEnvironment , self ).run (cwd = cwd , * args , ** kw )
446
+
447
+ check_stderr (
448
+ result .stderr , expect_stderr_error = expect_stderr_error ,
449
+ expect_stderr_warning = expect_stderr_warning ,
383
450
)
384
451
452
+ return TestPipResult (result , verbose = self .verbose )
453
+
385
454
def pip (self , * args , ** kwargs ):
386
455
if self .pip_expect_stderr :
387
456
kwargs ['expect_stderr' ] = True
0 commit comments