Skip to content

Commit ddd7dba

Browse files
committed
importlib: Read distribution name/version from metadata directory name, if possible
importlib does not cache metadata in-memory, so querying even simple attributes like distribution names and versions can quickly become expensive (as each access requires reading METADATA). Fortunately, `Distribution.canonical_name` is optimized to parse the metadata directory name to query the name if possible. This commit extends this optimization to the finder implementation and version attribute. .egg-info directory names tend to not include the version so they are not considered for optimizing version lookup. simplewheel-2.0-1-py2.py3-none-any.whl had to be modified to rename the .dist-info directory which mistakenly included the wheel build tag (in violation of the wheel specification). simplewheel/__init__.py simplewheel-2.0-1.dist-info/DESCRIPTION.rst simplewheel-2.0-1.dist-info/metadata.json simplewheel-2.0-1.dist-info/top_level.txt simplewheel-2.0-1.dist-info/WHEEL simplewheel-2.0-1.dist-info/METADATA simplewheel-2.0-1.dist-info/RECORD Otherwise, it was mistaken for part of the version and led pip to think the wheel was a post-release, breaking tests...
1 parent e884c00 commit ddd7dba

File tree

6 files changed

+19
-16
lines changed

6 files changed

+19
-16
lines changed

news/aa82171b-1578-4128-8db3-9aa72b3a6a84.trivial.rst

Whitespace-only changes.

src/pip/_internal/metadata/importlib/_compat.py

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import importlib.metadata
2+
import os
23
from typing import Any, Optional, Protocol, cast
34

45

@@ -49,6 +50,13 @@ def get_dist_name(dist: importlib.metadata.Distribution) -> str:
4950
The ``name`` attribute is only available in Python 3.10 or later. We are
5051
targeting exactly that, but Mypy does not know this.
5152
"""
53+
# Try to get the name from the metadata directory name.
54+
# This is much faster than reading metadata.
55+
if info_location := get_info_location(dist):
56+
stem, suffix = os.path.splitext(info_location.name)
57+
if suffix in (".dist-info", ".egg-info"):
58+
return stem.split("-", 1)[0]
59+
5260
name = cast(Any, dist).name
5361
if not isinstance(name, str):
5462
raise BadMetadata(dist, reason="invalid metadata entry 'name'")

src/pip/_internal/metadata/importlib/_dists.py

+9-14
Original file line numberDiff line numberDiff line change
@@ -153,25 +153,20 @@ def installed_location(self) -> Optional[str]:
153153
return None
154154
return normalize_path(str(self._installed_location))
155155

156-
def _get_dist_name_from_location(self) -> Optional[str]:
157-
"""Try to get the name from the metadata directory name.
158-
159-
This is much faster than reading metadata.
160-
"""
161-
if self._info_location is None:
162-
return None
163-
stem, suffix = os.path.splitext(self._info_location.name)
164-
if suffix not in (".dist-info", ".egg-info"):
165-
return None
166-
return stem.split("-", 1)[0]
167-
168156
@property
169157
def canonical_name(self) -> NormalizedName:
170-
name = self._get_dist_name_from_location() or get_dist_name(self._dist)
171-
return canonicalize_name(name)
158+
return canonicalize_name(get_dist_name(self._dist))
172159

173160
@property
174161
def version(self) -> DistributionVersion:
162+
# Try to get the version from the metadata directory name.
163+
# This is much faster than reading metadata.
164+
if self._info_location is not None:
165+
stem, suffix = os.path.splitext(self._info_location.name)
166+
if suffix == ".dist-info":
167+
version = stem.split("-", 1)[1]
168+
return parse_version(version)
169+
175170
return parse_version(self._dist.version)
176171

177172
def is_file(self, path: InfoPath) -> bool:
Binary file not shown.

tests/functional/test_install.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,7 @@ def test_install_nonlocal_compatible_wheel(
11721172
)
11731173
assert result.returncode == SUCCESS
11741174

1175-
distinfo = Path("scratch") / "target" / "simplewheel-2.0-1.dist-info"
1175+
distinfo = Path("scratch") / "target" / "simplewheel-2.0.dist-info"
11761176
result.did_create(distinfo)
11771177

11781178
# Test install without --target

tests/functional/test_install_report.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def test_install_report_basic(
3939
assert url.endswith("/packages/simplewheel-2.0-1-py2.py3-none-any.whl")
4040
assert (
4141
simplewheel_report["download_info"]["archive_info"]["hash"]
42-
== "sha256=191d6520d0570b13580bf7642c97ddfbb46dd04da5dd2cf7bef9f32391dfe716"
42+
== "sha256=71e1ca6b16ae3382a698c284013f66504f2581099b2ce4801f60e9536236ceee"
4343
)
4444

4545

0 commit comments

Comments
 (0)