From c1f8dbd1d96d8e41a5ec73eb1665d0065509ac72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Fri, 17 Mar 2023 16:38:49 +0100 Subject: [PATCH] installer: support for unnormalized dist-info --- src/poetry/installation/wheel_installer.py | 34 +++++++++++++++++- ...ormalized_dist_info-0.1.0-py3-none-any.whl | Bin 0 -> 1225 bytes tests/installation/test_wheel_installer.py | 17 +++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/distributions/un_normalized_dist_info-0.1.0-py3-none-any.whl diff --git a/src/poetry/installation/wheel_installer.py b/src/poetry/installation/wheel_installer.py index c8df26960f8..d318abbcf44 100644 --- a/src/poetry/installation/wheel_installer.py +++ b/src/poetry/installation/wheel_installer.py @@ -10,6 +10,7 @@ from installer import install from installer.destinations import SchemeDictionaryDestination from installer.sources import WheelFile +from packaging.utils import canonicalize_name from poetry.__version__ import __version__ from poetry.utils._compat import WINDOWS @@ -25,6 +26,37 @@ from poetry.utils.env import Env +class PatchedWheelFile(WheelFile): + # TODO: Patch from https://github.com/pypa/installer/issues/134 + # can be removed if new installer release is available + @property + def dist_info_dir(self) -> str: + """Name of the dist-info directory.""" + if not hasattr(self, "_dist_info_dir"): + top_level_directories = { + path.split("/", 1)[0] for path in self._zipfile.namelist() + } + dist_infos = [ + name for name in top_level_directories if name.endswith(".dist-info") + ] + + assert ( + len(dist_infos) == 1 + ), "Wheel doesn't contain exactly one .dist-info directory" + dist_info_dir = dist_infos[0] + + # NAME-VER.dist-info + di_dname = dist_info_dir.rsplit("-", 2)[0] + norm_di_dname = canonicalize_name(di_dname) + norm_file_dname = canonicalize_name(self.distribution) + assert ( + norm_di_dname == norm_file_dname + ), "Wheel .dist-info directory doesn't match wheel filename" + + self._dist_info_dir = dist_info_dir + return self._dist_info_dir + + class WheelDestination(SchemeDictionaryDestination): """ """ @@ -97,7 +129,7 @@ def enable_bytecode_compilation(self, enable: bool = True) -> None: self._destination.bytecode_optimization_levels = (1,) if enable else () def install(self, wheel: Path) -> None: - with WheelFile.open(Path(wheel.as_posix())) as source: + with PatchedWheelFile.open(Path(wheel.as_posix())) as source: install( source=source, destination=self._destination.for_source(source), diff --git a/tests/fixtures/distributions/un_normalized_dist_info-0.1.0-py3-none-any.whl b/tests/fixtures/distributions/un_normalized_dist_info-0.1.0-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..c88f9d277ab223de75f3cb3292576df306f6db03 GIT binary patch literal 1225 zcmWIWW@Zs#U|`??Vnv1~uELiRK$aK~D+6(8UVL7DQEp;RW>soRd`f0^jvU*Fd?#L>ku#BplBHaY%Z+BdO`jZ=S z>pN}OHtv3!vu?ic@1h$sc|P@~aw`V-&bVEE&s45Q@%9JP8)}ZtG0*?HSNs3Hv`0ov zdT~;6OwNi&$Cn1ZVMPrH=UAKcP+$N=0I@C!0TJ%u>gvOL%8;wUfQR*h?eZ6_N?kj? zFg;RJvI_sXLZNfX+Y7gE|J?hRE$&{z$H0&4vZJIFH%z#)=eNj7uK8IjOiW~TS9LBw zQEay7{KMEyJW+>3i(f{D9B}0Ni*Vo0=EAU6>D1k~f$j(e&)-h32;_Z+hBsEG%ELB>mC69+jsRn~qPIwDHfY2yMIi!@-HFz4ig#j7%a7xU&i{tiWJNBZwj*HQFkAZ=aL4qMH iXNv#Rh?|Ts+TEbj1;h{VW@Q7ZVFAJ}pyM@}K|BE2Q>oAZ literal 0 HcmV?d00001 diff --git a/tests/installation/test_wheel_installer.py b/tests/installation/test_wheel_installer.py index 7fc4826f940..b831420b445 100644 --- a/tests/installation/test_wheel_installer.py +++ b/tests/installation/test_wheel_installer.py @@ -79,3 +79,20 @@ def test_enable_bytecode_compilation( assert list(cache_dir.glob("*.pyc")) else: assert not cache_dir.exists() + + +def test_install_wheel_with_unnormalized_dist_info( + fixture_dir: FixtureDirGetter, tmp_path: Path +) -> None: + wheel = fixture_dir("distributions/un_normalized_dist_info-0.1.0-py3-none-any.whl") + env = MockEnv(path=tmp_path) + installer = WheelInstaller(env) + installer.install(wheel) + dist_info_dir = ( + Path(env.paths["purelib"]) / "Un.normalized_dist-info-0.1.0.dist-info" + ) + assert dist_info_dir.exists() + assert (dist_info_dir / "INSTALLER").exists() + assert (dist_info_dir / "METADATA").exists() + assert (dist_info_dir / "RECORD").exists() + assert (dist_info_dir / "WHEEL").exists()