Skip to content

Commit 4e2a593

Browse files
add support for printing dependency info to the resolution json!
1 parent f6489cc commit 4e2a593

File tree

5 files changed

+58
-4
lines changed

5 files changed

+58
-4
lines changed

src/pip/_internal/commands/download.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ def run(self, options: Values, args: List[str]) -> int:
182182
for candidate in requirement_set.candidates.mapping.values():
183183
# This will occur for the python version requirement, for example.
184184
if candidate.name not in requirement_set.requirements:
185+
assert (
186+
tuple(candidate.iter_dependencies(with_requires=True)) == ()
187+
)
185188
download_infos.implicit_requirements.append(
186189
candidate.as_serializable_requirement()
187190
)
@@ -190,10 +193,21 @@ def run(self, options: Values, args: List[str]) -> int:
190193
assert req.name is not None
191194
assert req.link is not None
192195
assert req.name not in download_infos.resolution
196+
197+
dependencies: List[Requirement] = []
198+
for maybe_dep in candidate.iter_dependencies(with_requires=True):
199+
if maybe_dep is None:
200+
continue
201+
maybe_req = maybe_dep.as_serializable_requirement()
202+
if maybe_req is None:
203+
continue
204+
dependencies.append(maybe_req)
205+
193206
download_infos.resolution[
194207
req.name
195-
] = RequirementDownloadInfo.from_req_and_link(
208+
] = RequirementDownloadInfo.from_req_and_link_and_deps(
196209
req=candidate.as_serializable_requirement(),
210+
dependencies=dependencies,
197211
link=req.link,
198212
)
199213
else:

src/pip/_internal/models/link.py

+16-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,17 @@
77
import urllib.parse
88
import xml.etree.ElementTree
99
from dataclasses import dataclass
10-
from typing import TYPE_CHECKING, Any, Dict, List, NamedTuple, Optional, Tuple, Union
10+
from typing import (
11+
TYPE_CHECKING,
12+
Any,
13+
Dict,
14+
Iterable,
15+
List,
16+
NamedTuple,
17+
Optional,
18+
Tuple,
19+
Union,
20+
)
1121

1222
from pip._vendor.packaging.requirements import Requirement
1323

@@ -395,18 +405,21 @@ def as_json(self) -> Dict[str, Union[str, Optional[Dict[str, str]]]]:
395405
class RequirementDownloadInfo:
396406
req: Requirement
397407
url: str
408+
dependencies: Tuple[Requirement, ...]
398409
file_hash: Optional[LinkHash]
399410
dist_info_metadata: Optional[DistInfoMetadata]
400411

401412
@classmethod
402-
def from_req_and_link(
413+
def from_req_and_link_and_deps(
403414
cls,
404415
req: Requirement,
416+
dependencies: Iterable[Requirement],
405417
link: Link,
406418
) -> "RequirementDownloadInfo":
407419
return cls(
408420
req=req,
409421
url=link.url,
422+
dependencies=tuple(dependencies),
410423
file_hash=link.get_link_hash(),
411424
dist_info_metadata=DistInfoMetadata.from_link(link),
412425
)
@@ -416,6 +429,7 @@ def as_json(self) -> Dict[str, Any]:
416429
"req": str(self.req),
417430
"url": self.url,
418431
"hash": self.file_hash and self.file_hash.as_json(),
432+
"dependencies": {dep.name: str(dep) for dep in self.dependencies},
419433
"dist_info_metadata": (
420434
self.dist_info_metadata and self.dist_info_metadata.as_json()
421435
),

src/pip/_internal/resolution/resolvelib/base.py

+4
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ def get_candidate_lookup(self) -> CandidateLookup:
9090
def format_for_error(self) -> str:
9191
...
9292

93+
@abc.abstractmethod
94+
def as_serializable_requirement(self) -> Optional[PkgRequirement]:
95+
...
96+
9397

9498
def _match_link(link: Link, candidate: "Candidate") -> bool:
9599
if candidate.source_link:

src/pip/_internal/resolution/resolvelib/requirements.py

+15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from typing import Optional
2+
3+
from pip._vendor.packaging.requirements import Requirement as PkgRequirement
14
from pip._vendor.packaging.specifiers import SpecifierSet
25
from pip._vendor.packaging.utils import NormalizedName, canonicalize_name
36

@@ -29,6 +32,9 @@ def name(self) -> str:
2932
# No need to canonicalize - the candidate did this
3033
return self.candidate.name
3134

35+
def as_serializable_requirement(self) -> PkgRequirement:
36+
return self.candidate.as_serializable_requirement()
37+
3238
def format_for_error(self) -> str:
3339
return self.candidate.format_for_error()
3440

@@ -77,6 +83,9 @@ def format_for_error(self) -> str:
7783

7884
return ", ".join(parts[:-1]) + " and " + parts[-1]
7985

86+
def as_serializable_requirement(self) -> Optional[PkgRequirement]:
87+
return self._ireq.req
88+
8089
def get_candidate_lookup(self) -> CandidateLookup:
8190
return None, self._ireq
8291

@@ -120,6 +129,9 @@ def name(self) -> str:
120129
def format_for_error(self) -> str:
121130
return str(self)
122131

132+
def as_serializable_requirement(self) -> PkgRequirement:
133+
return self._candidate.as_serializable_requirement()
134+
123135
def get_candidate_lookup(self) -> CandidateLookup:
124136
if self.specifier.contains(self._candidate.version, prereleases=True):
125137
return self._candidate, None
@@ -159,6 +171,9 @@ def name(self) -> str:
159171
def format_for_error(self) -> str:
160172
return str(self)
161173

174+
def as_serializable_requirement(self) -> Optional[PkgRequirement]:
175+
raise NotImplementedError()
176+
162177
def get_candidate_lookup(self) -> CandidateLookup:
163178
return None, None
164179

tests/unit/test_collector.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ def test_parse_links__yanked_reason(anchor_html: str, expected: Optional[str]) -
528528
RequirementDownloadInfo(
529529
_pkg1_requirement,
530530
"https://example.com/pkg1-1.0.tar.gz",
531+
(),
531532
None,
532533
None,
533534
),
@@ -544,6 +545,7 @@ def test_parse_links__yanked_reason(anchor_html: str, expected: Optional[str]) -
544545
RequirementDownloadInfo(
545546
_pkg1_requirement,
546547
"https://example.com/pkg1-1.0.tar.gz",
548+
(),
547549
None,
548550
DistInfoMetadata(
549551
metadata_url="https://example.com/pkg1-1.0.tar.gz.metadata",
@@ -563,6 +565,7 @@ def test_parse_links__yanked_reason(anchor_html: str, expected: Optional[str]) -
563565
RequirementDownloadInfo(
564566
_pkg1_requirement,
565567
"https://example.com/pkg1-1.0.tar.gz",
568+
(),
566569
None,
567570
DistInfoMetadata(
568571
metadata_url="https://example.com/pkg1-1.0.tar.gz.metadata",
@@ -582,6 +585,7 @@ def test_parse_links__yanked_reason(anchor_html: str, expected: Optional[str]) -
582585
RequirementDownloadInfo(
583586
_pkg1_requirement,
584587
"https://example.com/pkg1-1.0.tar.gz#sha512=abc132409cb",
588+
(),
585589
LinkHash(name="sha512", value="abc132409cb"),
586590
DistInfoMetadata(
587591
metadata_url="https://example.com/pkg1-1.0.tar.gz.metadata",
@@ -600,7 +604,10 @@ def test_parse_links__dist_info_metadata(
600604
) -> None:
601605
link = _test_parse_links_data_attribute(anchor_html, "dist_info_metadata", expected)
602606
assert DistInfoMetadata.from_link(link) == dist_info_metadata
603-
assert RequirementDownloadInfo.from_req_and_link(req, link) == download_info
607+
assert (
608+
RequirementDownloadInfo.from_req_and_link_and_deps(req, (), link)
609+
== download_info
610+
)
604611

605612

606613
def test_parse_links_caches_same_page_by_url() -> None:

0 commit comments

Comments
 (0)