diff --git a/news/609.feature b/news/609.feature new file mode 100644 index 000000000..1a2a6702a --- /dev/null +++ b/news/609.feature @@ -0,0 +1,2 @@ +pip now implements PEP 610, so ``pip freeze`` has better fidelity +in presence of distributions installed from Direct URL requirements. diff --git a/src/pip/_internal/operations/freeze.py b/src/pip/_internal/operations/freeze.py index 0ac3c4e90..3198c7757 100644 --- a/src/pip/_internal/operations/freeze.py +++ b/src/pip/_internal/operations/freeze.py @@ -19,6 +19,10 @@ from pip._internal.req.constructors import ( install_req_from_line, ) from pip._internal.req.req_file import COMMENT_RE +from pip._internal.utils.direct_url_helpers import ( + direct_url_as_pep440_direct_reference, + dist_get_direct_url, +) from pip._internal.utils.misc import ( dist_is_editable, get_installed_distributions, @@ -250,8 +254,20 @@ class FrozenRequirement(object): @classmethod def from_dist(cls, dist): # type: (Distribution) -> FrozenRequirement + # TODO `get_requirement_info` is taking care of editable requirements. + # TODO This should be refactored when we will add detection of + # editable that provide .dist-info metadata. req, editable, comments = get_requirement_info(dist) + if req is None and not editable: + # if PEP 610 metadata is present, attempt to use it + direct_url = dist_get_direct_url(dist) + if direct_url: + req = direct_url_as_pep440_direct_reference( + direct_url, dist.project_name + ) + comments = [] if req is None: + # name==version requirement req = dist.as_requirement() return cls(dist.project_name, req, editable, comments=comments) diff --git a/tests/functional/test_freeze.py b/tests/functional/test_freeze.py index dabfbde48..7027879bd 100644 --- a/tests/functional/test_freeze.py +++ b/tests/functional/test_freeze.py @@ -816,3 +816,11 @@ def test_freeze_path_multiple(tmpdir, script, data): simple2==3.0 """) _check_output(result.stdout, expected) + + +def test_freeze_direct_url_archive(script, shared_data, with_wheel): + req = "simple @ " + path_to_url(shared_data.packages / "simple-2.0.tar.gz") + assert req.startswith("simple @ file://") + script.pip("install", req) + result = script.pip("freeze") + assert req in result.stdout