diff --git a/news/609.feature b/news/609.feature new file mode 100644 index 00000000000..c41cdbcb279 --- /dev/null +++ b/news/609.feature @@ -0,0 +1,2 @@ +Pip freeze now implements PEP 610, so ``pip freeze`` has now 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 36a5c339a2a..69642601afd 100644 --- a/src/pip/_internal/operations/freeze.py +++ b/src/pip/_internal/operations/freeze.py @@ -19,6 +19,10 @@ 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, @@ -252,8 +256,20 @@ def __init__(self, name, req, editable, comments=()): @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 + # TODO 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 a62dd271dca..942efff15ed 100644 --- a/tests/functional/test_freeze.py +++ b/tests/functional/test_freeze.py @@ -782,3 +782,11 @@ def test_freeze_path_multiple(tmpdir, script, data): simple2==3.0 """) _check_output(result.stdout, expected) + + +def test_freeze_direct_url_archive(script, data, with_wheel): + req = "simple @ " + path_to_url(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