Skip to content

Commit

Permalink
Display dependency chain on each Collecting line
Browse files Browse the repository at this point in the history
This tremendously helps understand why a package is being fetched and
can help investigate and fix dependency resolver backtracking issues
when incoherent constraints/package sets are provided or when new
versions of a package trigger a completely different backtracking
strategy, leading to very hard to debug situations.
  • Loading branch information
iXce committed Aug 16, 2022
1 parent bd54161 commit ccaf0c4
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
Empty file.
10 changes: 10 additions & 0 deletions src/pip/_internal/operations/prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,16 @@ def _log_preparing_link(self, req: InstallRequirement) -> None:
message = "Collecting %s"
information = str(req.req or req)

# If we used req.req, inject requirement source if available (this
# would already be included if we used req directly)
if req.req and req.comes_from:
if isinstance(req.comes_from, str):
comes_from: Optional[str] = req.comes_from
else:
comes_from = req.comes_from.from_path()
if comes_from:
information += f" (from {comes_from})"

if (message, information) != self._previous_requirement_header:
self._previous_requirement_header = (message, information)
logger.info(message, information)
Expand Down
58 changes: 58 additions & 0 deletions tests/functional/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -2344,3 +2344,61 @@ def test_install_8559_wheel_package_present(
allow_stderr_warning=False,
)
assert DEPRECATION_MSG_PREFIX not in result.stderr


def test_install_pip_prints_req_chain_local(script: PipTestEnvironment) -> None:
"""
Test installing a local package with a dependency and check that the
dependency chain is reported.
"""

req_path = script.scratch_path.joinpath("requirements.txt")
req_path.write_text("base==0.1.0")

create_basic_wheel_for_package(
script,
"base",
"0.1.0",
depends=["dep"],
)
dep_path = create_basic_wheel_for_package(
script,
"dep",
"0.1.0",
)

result = script.pip(
"install",
"--no-cache-dir",
"--no-index",
"--find-links",
script.scratch_path,
"-r",
req_path,
)
assert_re_match(
rf"Processing .*{re.escape(os.path.basename(dep_path))} "
rf"\(from base==0.1.0->-r {re.escape(str(req_path))} \(line 1\)\)",
result.stdout,
)


@pytest.mark.network
def test_install_pip_prints_req_chain_pypi(script: PipTestEnvironment) -> None:
"""
Test installing a package with a dependency from PyPI and check that the
dependency chain is reported.
"""
req_path = script.scratch_path.joinpath("requirements.txt")
req_path.write_text("Paste[openid]==1.7.5.1")

result = script.pip(
"install",
"-r",
req_path,
)

assert (
f"Collecting python-openid "
f"(from Paste[openid]==1.7.5.1->-r {req_path} (line 1))" in result.stdout
)

0 comments on commit ccaf0c4

Please sign in to comment.