From f2fc7a92ba06ff338b64a8f6b966b921cfca1292 Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Fri, 22 Mar 2024 23:38:55 +0100 Subject: [PATCH 1/3] inspection/info: correctly raise PackageInfoError Previously, when processing wheel files, PackageInfo incorrectly returned an empty instance. This change ensures a PackageInfoError is correctly raised. (cherry picked from commit 23612d48a359269043766523b7411aee52d5f4b3) --- src/poetry/inspection/info.py | 4 +-- tests/repositories/test_http_repository.py | 30 +++++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/poetry/inspection/info.py b/src/poetry/inspection/info.py index 1c432e29f9b..37c8b6b30cc 100644 --- a/src/poetry/inspection/info.py +++ b/src/poetry/inspection/info.py @@ -539,8 +539,8 @@ def from_wheel(cls, path: Path) -> PackageInfo: try: wheel = pkginfo.Wheel(str(path)) return cls._from_distribution(wheel) - except ValueError: - return PackageInfo() + except ValueError as e: + raise PackageInfoError(path, e) @classmethod def from_bdist(cls, path: Path) -> PackageInfo: diff --git a/tests/repositories/test_http_repository.py b/tests/repositories/test_http_repository.py index eb0de86819d..20475bc2c3a 100644 --- a/tests/repositories/test_http_repository.py +++ b/tests/repositories/test_http_repository.py @@ -1,5 +1,6 @@ from __future__ import annotations +import contextlib import shutil from pathlib import Path @@ -12,6 +13,7 @@ from packaging.metadata import parse_email from poetry.core.packages.utils.link import Link +from poetry.inspection.info import PackageInfoError from poetry.inspection.lazy_wheel import HTTPRangeRequestUnsupported from poetry.repositories.http_repository import HTTPRepository from poetry.utils.helpers import HTTPRangeRequestSupported @@ -116,13 +118,18 @@ def test_get_info_from_wheel_state_sequence(mocker: MockerFixture) -> None: # 1. range request and download mock_metadata_from_wheel_url.side_effect = HTTPRangeRequestUnsupported - repo._get_info_from_wheel(link) + + with contextlib.suppress(PackageInfoError): + repo._get_info_from_wheel(link) + assert mock_metadata_from_wheel_url.call_count == 1 assert mock_download.call_count == 1 assert mock_download.call_args[1]["raise_accepts_ranges"] is False # 2. only download - repo._get_info_from_wheel(link) + with contextlib.suppress(PackageInfoError): + repo._get_info_from_wheel(link) + assert mock_metadata_from_wheel_url.call_count == 1 assert mock_download.call_count == 2 assert mock_download.call_args[1]["raise_accepts_ranges"] is True @@ -130,26 +137,37 @@ def test_get_info_from_wheel_state_sequence(mocker: MockerFixture) -> None: # 3. download and range request mock_metadata_from_wheel_url.side_effect = None mock_download.side_effect = HTTPRangeRequestSupported - repo._get_info_from_wheel(link) + + with contextlib.suppress(PackageInfoError): + repo._get_info_from_wheel(link) + assert mock_metadata_from_wheel_url.call_count == 2 assert mock_download.call_count == 3 assert mock_download.call_args[1]["raise_accepts_ranges"] is True # 4. only range request - repo._get_info_from_wheel(link) + with contextlib.suppress(PackageInfoError): + repo._get_info_from_wheel(link) + assert mock_metadata_from_wheel_url.call_count == 3 assert mock_download.call_count == 3 # 5. range request and download mock_metadata_from_wheel_url.side_effect = HTTPRangeRequestUnsupported mock_download.side_effect = None - repo._get_info_from_wheel(link) + + with contextlib.suppress(PackageInfoError): + repo._get_info_from_wheel(link) + assert mock_metadata_from_wheel_url.call_count == 4 assert mock_download.call_count == 4 assert mock_download.call_args[1]["raise_accepts_ranges"] is False # 6. only range request mock_metadata_from_wheel_url.side_effect = None - repo._get_info_from_wheel(link) + + with contextlib.suppress(PackageInfoError): + repo._get_info_from_wheel(link) + assert mock_metadata_from_wheel_url.call_count == 5 assert mock_download.call_count == 4 From 6740b0bd0fad7b2fb900547d37e6edbdae405dff Mon Sep 17 00:00:00 2001 From: Arun Babu Neelicattu Date: Fri, 22 Mar 2024 23:39:58 +0100 Subject: [PATCH 2/3] inspection: error on unsupported metadata versions Resolves: #9195 (cherry picked from commit 2a2abce88d091891f8e7ca2159b943d15ae2e7c3) --- src/poetry/inspection/info.py | 5 +++++ ...ta_version_unknown-0.1.0-py2.py3-none-any.whl | Bin 0 -> 1153 bytes tests/inspection/test_info.py | 14 ++++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 tests/fixtures/distributions/demo_metadata_version_unknown-0.1.0-py2.py3-none-any.whl diff --git a/src/poetry/inspection/info.py b/src/poetry/inspection/info.py index 37c8b6b30cc..3fae1739c9b 100644 --- a/src/poetry/inspection/info.py +++ b/src/poetry/inspection/info.py @@ -245,6 +245,11 @@ def _from_distribution( :param dist: The distribution instance to parse information from. """ + if dist.metadata_version not in pkginfo.distribution.HEADER_ATTRS: + # This check can be replaced once upstream implements strict parsing + # https://bugs.launchpad.net/pkginfo/+bug/2058697 + raise ValueError("Unknown metadata version") + requirements = None if dist.requires_dist: diff --git a/tests/fixtures/distributions/demo_metadata_version_unknown-0.1.0-py2.py3-none-any.whl b/tests/fixtures/distributions/demo_metadata_version_unknown-0.1.0-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..03988228fec381e1eb7267cbb8a549152ffdffee GIT binary patch literal 1153 zcmWIWW@Zs#W?Ke_98l9aHoi4WgZv)KB$_xKXRI1EB zEWUY3f|SMAZ>e?r^Pd^?KQVOgzo;Fl-YaGx*I#)iC`3g;J@tnD%a3;NH@XIJy>(;Q zZQixWRBY;xNp?&8^EGFm?Aemdlh;&l9(Lf-_w>$l-j@t`&n3HAi%fKi@n2$>C?!C;lHhzv{}t zbGrlPe=FGdRlI5Kq%CtTyyyAx7R;IXCtqPx4tHdbFWai(<eGA5L@q7F3{dy~2aG9-kbHSFmpVL^J zg9UrP35w)i+pV|bppH`OvgyxO?f5L1dy#ANvd{gxJC=Vva%jPkvo$d10PSW_WN6|l zd?^NGfv^A&gA%%ae0*kJW=VX!UO{Did|7Hyab|vAe7u6Kf;u=0sB;B)GcwsTXnrS literal 0 HcmV?d00001 diff --git a/tests/inspection/test_info.py b/tests/inspection/test_info.py index a23e4879769..e88792c4d1d 100644 --- a/tests/inspection/test_info.py +++ b/tests/inspection/test_info.py @@ -179,6 +179,20 @@ def test_info_from_wheel(demo_wheel: Path) -> None: assert info._source_url == demo_wheel.resolve().as_posix() +def test_info_from_wheel_metadata_version_unknown( + fixture_dir: FixtureDirGetter, +) -> None: + path = ( + fixture_dir("distributions") + / "demo_metadata_version_unknown-0.1.0-py2.py3-none-any.whl" + ) + + with pytest.raises(PackageInfoError) as e: + PackageInfo.from_wheel(path) + + assert "Unknown metadata version" in str(e.value) + + def test_info_from_wheel_metadata(demo_wheel_metadata: RawMetadata) -> None: info = PackageInfo.from_metadata(demo_wheel_metadata) demo_check_info(info) From ebd6a3d2970e5c025909a4d6d1f08f4e2141d028 Mon Sep 17 00:00:00 2001 From: Jeremy Fleischman Date: Sun, 24 Mar 2024 08:30:40 -0700 Subject: [PATCH 3/3] include metadata version in "unknown metadata" error message I thought this would be nice just to help people debug things in the future. (cherry picked from commit 8b9cf463b1c9300a4cc8065b366a9b6fc68b5952) --- src/poetry/inspection/info.py | 2 +- tests/inspection/test_info.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/poetry/inspection/info.py b/src/poetry/inspection/info.py index 3fae1739c9b..02cf66a2b35 100644 --- a/src/poetry/inspection/info.py +++ b/src/poetry/inspection/info.py @@ -248,7 +248,7 @@ def _from_distribution( if dist.metadata_version not in pkginfo.distribution.HEADER_ATTRS: # This check can be replaced once upstream implements strict parsing # https://bugs.launchpad.net/pkginfo/+bug/2058697 - raise ValueError("Unknown metadata version") + raise ValueError(f"Unknown metadata version: {dist.metadata_version}") requirements = None diff --git a/tests/inspection/test_info.py b/tests/inspection/test_info.py index e88792c4d1d..f62d1908e0f 100644 --- a/tests/inspection/test_info.py +++ b/tests/inspection/test_info.py @@ -190,7 +190,7 @@ def test_info_from_wheel_metadata_version_unknown( with pytest.raises(PackageInfoError) as e: PackageInfo.from_wheel(path) - assert "Unknown metadata version" in str(e.value) + assert "Unknown metadata version: 999.3" in str(e.value) def test_info_from_wheel_metadata(demo_wheel_metadata: RawMetadata) -> None: