Skip to content

Commit c5e6bc2

Browse files
committed
-v shows subprocess output
adds VERBOSE custom log level between DEBUG and INFO used when `-v` is given. Now require -vv to enable full debug output. Messages can be logged with VERBOSE level to promote them to `-v` output instead of `-vv`
1 parent c1251a8 commit c5e6bc2

File tree

10 files changed

+41
-24
lines changed

10 files changed

+41
-24
lines changed

news/9447.feature.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Require ``-vv`` for full debug-level output, ``-v`` now only enables showing subprocess output, e.g. of ``setup.py install``.

src/pip/_internal/commands/cache.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from pip._internal.cli.base_command import Command
77
from pip._internal.cli.status_codes import ERROR, SUCCESS
88
from pip._internal.exceptions import CommandError, PipError
9+
from pip._internal.utils.logging import VERBOSE
910
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
1011

1112
if MYPY_CHECK_RUNNING:
@@ -188,7 +189,7 @@ def remove_cache_items(self, options, args):
188189

189190
for filename in files:
190191
os.unlink(filename)
191-
logger.debug('Removed %s', filename)
192+
logger.log(VERBOSE, 'Removed %s', filename)
192193
logger.info('Files removed: %s', len(files))
193194

194195
def purge_cache(self, options, args):

src/pip/_internal/commands/install.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from pip._internal.req.req_tracker import get_requirement_tracker
2222
from pip._internal.utils.distutils_args import parse_distutils_args
2323
from pip._internal.utils.filesystem import test_writable_dir
24+
from pip._internal.utils.logging import VERBOSE
2425
from pip._internal.utils.misc import (
2526
ensure_dir,
2627
get_installed_version,
@@ -236,7 +237,7 @@ def run(self, options, args):
236237

237238
install_options = options.install_options or []
238239

239-
logger.debug("Using %s", get_pip_version())
240+
logger.log(VERBOSE, "Using %s", get_pip_version())
240241
options.use_user_site = decide_user_install(
241242
options.use_user_site,
242243
prefix_path=options.prefix_path,

src/pip/_internal/req/req_uninstall.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from pip._internal.exceptions import UninstallationError
1212
from pip._internal.locations import bin_py, bin_user
1313
from pip._internal.utils.compat import WINDOWS
14-
from pip._internal.utils.logging import indent_log
14+
from pip._internal.utils.logging import VERBOSE, indent_log
1515
from pip._internal.utils.misc import (
1616
ask,
1717
dist_in_usersite,
@@ -398,7 +398,7 @@ def remove(self, auto_confirm=False, verbose=False):
398398

399399
for path in sorted(compact(for_rename)):
400400
moved.stash(path)
401-
logger.debug('Removing file or directory %s', path)
401+
logger.log(VERBOSE, 'Removing file or directory %s', path)
402402

403403
for pth in self.pth.values():
404404
pth.remove()
@@ -613,7 +613,7 @@ def add(self, entry):
613613

614614
def remove(self):
615615
# type: () -> None
616-
logger.debug('Removing pth entries from %s:', self.file)
616+
logger.log(VERBOSE, 'Removing pth entries from %s:', self.file)
617617

618618
# If the file doesn't exist, log a warning and return
619619
if not os.path.isfile(self.file):
@@ -634,7 +634,7 @@ def remove(self):
634634
lines[-1] = lines[-1] + endline.encode("utf-8")
635635
for entry in self.entries:
636636
try:
637-
logger.debug('Removing entry: %s', entry)
637+
logger.log(VERBOSE, 'Removing entry: %s', entry)
638638
lines.remove((entry + endline).encode("utf-8"))
639639
except ValueError:
640640
pass

src/pip/_internal/utils/logging.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
subprocess_logger = getLogger('pip.subprocessor')
3232

3333

34+
# custom log level for `--verbose` output
35+
# between DEBUG and INFO
36+
VERBOSE = 15
37+
38+
3439
class BrokenStdoutLoggingError(Exception):
3540
"""
3641
Raised if BrokenPipeError occurs for the stdout stream while logging.
@@ -245,19 +250,22 @@ def setup_logging(verbosity, no_color, user_log_file):
245250
Returns the requested logging level, as its integer value.
246251
"""
247252

253+
logging.addLevelName(VERBOSE, "VERBOSE")
248254
# Determine the level to be logging at.
249-
if verbosity >= 1:
250-
level = "DEBUG"
255+
if verbosity >= 2:
256+
level_number = logging.DEBUG
257+
elif verbosity == 1:
258+
level_number = VERBOSE
251259
elif verbosity == -1:
252-
level = "WARNING"
260+
level_number = logging.WARNING
253261
elif verbosity == -2:
254-
level = "ERROR"
262+
level_number = logging.ERROR
255263
elif verbosity <= -3:
256-
level = "CRITICAL"
264+
level_number = logging.CRITICAL
257265
else:
258-
level = "INFO"
266+
level_number = logging.INFO
259267

260-
level_number = getattr(logging, level)
268+
level = logging.getLevelName(level_number)
261269

262270
# The "root" logger should match the "console" level *unless* we also need
263271
# to log to a user log file.

src/pip/_internal/utils/subprocess.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22
import os
33
import shlex
44
import subprocess
5+
from functools import partial
56

67
from pip._internal.cli.spinners import SpinnerInterface, open_spinner
78
from pip._internal.exceptions import InstallationSubprocessError
89
from pip._internal.utils.compat import console_to_str, str_to_display
9-
from pip._internal.utils.logging import subprocess_logger
10+
from pip._internal.utils.logging import VERBOSE, subprocess_logger
1011
from pip._internal.utils.misc import HiddenText, path_to_display
1112
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
1213

@@ -158,8 +159,8 @@ def call_subprocess(
158159
else:
159160
# Then log the subprocess output using DEBUG. This also ensures
160161
# it will be logged to the log file (aka user_log), if enabled.
161-
log_subprocess = subprocess_logger.debug
162-
used_level = logging.DEBUG
162+
log_subprocess = partial(subprocess_logger.log, VERBOSE)
163+
used_level = VERBOSE
163164

164165
# Whether the subprocess will be visible in the console.
165166
showing_subprocess = subprocess_logger.getEffectiveLevel() <= used_level

tests/functional/test_broken_stdout.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def test_broken_stdout_pipe__verbose(deprecated_python):
6565
Test a broken pipe to stdout with verbose logging enabled.
6666
"""
6767
stderr, returncode = setup_broken_stdout_test(
68-
['pip', '-v', 'list'], deprecated_python=deprecated_python,
68+
['pip', '-vv', 'list'], deprecated_python=deprecated_python,
6969
)
7070

7171
# Check that a traceback occurs and that it occurs at most once.

tests/functional/test_new_resolver_hashes.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def test_new_resolver_hash_intersect(script, requirements_template, message):
7676
"--no-deps",
7777
"--no-index",
7878
"--find-links", find_links.index_html,
79-
"--verbose",
79+
"-vv",
8080
"--requirement", requirements_txt,
8181
)
8282

@@ -108,7 +108,7 @@ def test_new_resolver_hash_intersect_from_constraint(script):
108108
"--no-deps",
109109
"--no-index",
110110
"--find-links", find_links.index_html,
111-
"--verbose",
111+
"-vv",
112112
"--constraint", constraints_txt,
113113
"--requirement", requirements_txt,
114114
)

tests/unit/test_base_command.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def test_raise_broken_stdout__debug_logging(self, capsys):
8080
"""
8181
Test raising BrokenStdoutLoggingError with debug logging enabled.
8282
"""
83-
stderr = self.call_main(capsys, ['-v'])
83+
stderr = self.call_main(capsys, ['-vv'])
8484

8585
assert 'ERROR: Pipe to stdout was broken' in stderr
8686
assert 'Traceback (most recent call last):' in stderr

tests/unit/test_utils_subprocess.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from pip._internal.cli.spinners import SpinnerInterface
99
from pip._internal.exceptions import InstallationSubprocessError
10+
from pip._internal.utils.logging import VERBOSE
1011
from pip._internal.utils.misc import hide_value
1112
from pip._internal.utils.subprocess import (
1213
call_subprocess,
@@ -163,7 +164,11 @@ def test_make_subprocess_output_error__non_ascii_line():
163164
)
164165
def test_call_subprocess_stdout_only(capfd, monkeypatch, stdout_only, expected):
165166
log = []
166-
monkeypatch.setattr(subprocess_logger, "debug", lambda *args: log.append(args[0]))
167+
monkeypatch.setattr(
168+
subprocess_logger,
169+
"log",
170+
lambda level, *args: log.append(args[0]),
171+
)
167172
out = call_subprocess(
168173
[
169174
sys.executable,
@@ -269,9 +274,9 @@ def test_debug_logging(self, capfd, caplog):
269274
result = call_subprocess(args, spinner=spinner)
270275

271276
expected = (['Hello', 'world'], [
272-
('pip.subprocessor', DEBUG, 'Running command '),
273-
('pip.subprocessor', DEBUG, 'Hello'),
274-
('pip.subprocessor', DEBUG, 'world'),
277+
('pip.subprocessor', VERBOSE, 'Running command '),
278+
('pip.subprocessor', VERBOSE, 'Hello'),
279+
('pip.subprocessor', VERBOSE, 'world'),
275280
])
276281
# The spinner shouldn't spin in this case since the subprocess
277282
# output is already being logged to the console.

0 commit comments

Comments
 (0)