|
3 | 3 | import dataclasses |
4 | 4 | import hashlib |
5 | 5 | import os |
| 6 | +import posixpath |
6 | 7 | import re |
7 | 8 | import warnings |
8 | 9 | from functools import cached_property |
|
21 | 22 | from pdm.models.reporter import BaseReporter |
22 | 23 | from pdm.models.requirements import ( |
23 | 24 | FileRequirement, |
| 25 | + NamedRequirement, |
24 | 26 | Requirement, |
25 | 27 | VcsRequirement, |
26 | 28 | _egg_info_re, |
|
47 | 49 | from pdm.environments import BaseEnvironment |
48 | 50 |
|
49 | 51 |
|
| 52 | +ALLOWED_HASHES = hashlib.algorithms_guaranteed - {"shake_128", "shake_256", "sha1", "md5"} |
| 53 | + |
| 54 | + |
50 | 55 | def _dist_info_files(whl_zip: ZipFile) -> list[str]: |
51 | 56 | """Identify the .dist-info folder inside a wheel ZipFile.""" |
52 | 57 | res = [] |
@@ -335,7 +340,9 @@ def revision(self) -> str: |
335 | 340 | ) |
336 | 341 |
|
337 | 342 | def direct_url(self) -> dict[str, Any] | None: |
338 | | - """PEP 610 direct_url.json data""" |
| 343 | + """PEP 610 direct_url.json data |
| 344 | + https://peps.python.org/pep-0610/ |
| 345 | + """ |
339 | 346 | req = self.req |
340 | 347 | if isinstance(req, VcsRequirement): |
341 | 348 | if req.editable: |
@@ -383,6 +390,29 @@ def direct_url(self) -> dict[str, Any] | None: |
383 | 390 | else: |
384 | 391 | return None |
385 | 392 |
|
| 393 | + def provenance_url(self) -> dict[str, Any] | None: |
| 394 | + """PEP 710 provenance_url.json data |
| 395 | + https://peps.python.org/pep-0710/ |
| 396 | + """ |
| 397 | + req = self.req |
| 398 | + if not isinstance(req, NamedRequirement): |
| 399 | + return None |
| 400 | + assert self.link is not None |
| 401 | + comes_from = self.link.comes_from # e.g. https://pypi.org/simple/requests/ |
| 402 | + if comes_from is None: # can't determine the index_url |
| 403 | + return None |
| 404 | + # FIXME: what about find-links source? |
| 405 | + index_url = posixpath.dirname(comes_from.rstrip("/")) + "/" |
| 406 | + return { |
| 407 | + "url": self.link.url_without_fragment, |
| 408 | + "index_url": index_url, |
| 409 | + "archive_info": { |
| 410 | + "hashes": { |
| 411 | + name: hashes[0] for name, hashes in (self.link.hash_option or {}).items() if name in ALLOWED_HASHES |
| 412 | + }, |
| 413 | + }, |
| 414 | + } |
| 415 | + |
386 | 416 | def build(self) -> Path: |
387 | 417 | """Call PEP 517 build hook to build the candidate into a wheel""" |
388 | 418 | self._obtain(allow_all=False) |
|
0 commit comments