diff --git a/src/pip/_internal/cli/base_command.py b/src/pip/_internal/cli/base_command.py index 8a602bab4..975f3fe2c 100644 --- a/src/pip/_internal/cli/base_command.py +++ b/src/pip/_internal/cli/base_command.py @@ -130,7 +130,7 @@ class Command(object): # Set verbosity so that it can be used elsewhere. self.verbosity = options.verbose - options.quiet - setup_logging( + level_number = setup_logging( verbosity=self.verbosity, no_color=options.no_color, user_log_file=options.log, @@ -197,7 +197,7 @@ class Command(object): # Bypass our logger and write any remaining messages to stderr # because stdout no longer works. print('ERROR: Pipe to stdout was broken', file=sys.stderr) - if logger.getEffectiveLevel() <= logging.DEBUG: + if level_number <= logging.DEBUG: traceback.print_exc(file=sys.stderr) return ERROR diff --git a/src/pip/_internal/utils/logging.py b/src/pip/_internal/utils/logging.py index a86aaf1df..579d69621 100644 --- a/src/pip/_internal/utils/logging.py +++ b/src/pip/_internal/utils/logging.py @@ -216,6 +216,8 @@ class MaxLevelFilter(logging.Filter): def setup_logging(verbosity, no_color, user_log_file): """Configures and sets up all of the logging + + Returns the requested logging level, as its integer value. """ # Determine the level to be logging at. @@ -230,6 +232,8 @@ def setup_logging(verbosity, no_color, user_log_file): else: level = "INFO" + level_number = getattr(logging, level) + # The "root" logger should match the "console" level *unless* we also need # to log to a user log file. include_user_log = user_log_file is not None @@ -310,3 +314,5 @@ def setup_logging(verbosity, no_color, user_log_file): } }, }) + + return level_number diff --git a/tests/functional/test_broken_stdout.py b/tests/functional/test_broken_stdout.py index afb66f5a5..cb98e31f0 100644 --- a/tests/functional/test_broken_stdout.py +++ b/tests/functional/test_broken_stdout.py @@ -1,3 +1,4 @@ +import os import subprocess import sys @@ -42,6 +43,23 @@ def test_broken_stdout_pipe(deprecated_python): assert returncode == _BROKEN_STDOUT_RETURN_CODE +def test_broken_stdout_pipe__log_option(deprecated_python, tmpdir): + """ + Test a broken pipe to stdout when --log is passed. + """ + log_path = os.path.join(str(tmpdir), 'log.txt') + stderr, returncode = setup_broken_stdout_test( + ['pip', '--log', log_path, 'list'], + deprecated_python=deprecated_python, + ) + + # Check that no traceback occurs. + assert 'raise BrokenStdoutLoggingError()' not in stderr + assert stderr.count('Traceback') == 0 + + assert returncode == _BROKEN_STDOUT_RETURN_CODE + + def test_broken_stdout_pipe__verbose(deprecated_python): """ Test a broken pipe to stdout with verbose logging enabled.