Skip to content

Commit 03d9ed6

Browse files
committed
only download metadata we need (instead of all metadata)
1 parent 682d9b2 commit 03d9ed6

File tree

1 file changed

+69
-83
lines changed

1 file changed

+69
-83
lines changed

src/poetry/repositories/http_repository.py

+69-83
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import functools
44
import hashlib
55

6-
from collections import defaultdict
76
from contextlib import contextmanager
87
from pathlib import Path
98
from typing import TYPE_CHECKING
@@ -16,7 +15,6 @@
1615

1716
from poetry.core.constraints.version import parse_constraint
1817
from poetry.core.packages.dependency import Dependency
19-
from poetry.core.packages.utils.link import Link
2018
from poetry.core.utils.helpers import temporary_directory
2119
from poetry.core.version.markers import parse_marker
2220

@@ -33,6 +31,7 @@
3331

3432
if TYPE_CHECKING:
3533
from packaging.utils import NormalizedName
34+
from poetry.core.packages.utils.link import Link
3635

3736
from poetry.config.config import Config
3837
from poetry.repositories.link_sources.base import LinkSource
@@ -86,41 +85,77 @@ def _cached_or_downloaded_file(self, link: Link) -> Iterator[Path]:
8685
self._download(link.url, filepath)
8786
yield filepath
8887

89-
def _get_info_from_wheel(self, url: str) -> PackageInfo:
88+
def _get_info_from_wheel(self, link: Link) -> PackageInfo:
9089
from poetry.inspection.info import PackageInfo
9190

92-
with self._cached_or_downloaded_file(Link(url)) as filepath:
91+
with self._cached_or_downloaded_file(link) as filepath:
9392
return PackageInfo.from_wheel(filepath)
9493

95-
def _get_info_from_sdist(self, url: str) -> PackageInfo:
94+
def _get_info_from_sdist(self, link: Link) -> PackageInfo:
9695
from poetry.inspection.info import PackageInfo
9796

98-
with self._cached_or_downloaded_file(Link(url)) as filepath:
97+
with self._cached_or_downloaded_file(link) as filepath:
9998
return PackageInfo.from_sdist(filepath)
10099

101-
@staticmethod
102-
def _get_info_from_metadata(
103-
url: str, metadata: dict[str, pkginfo.Distribution]
104-
) -> PackageInfo | None:
105-
if url in metadata:
106-
dist = metadata[url]
107-
return PackageInfo(
108-
name=dist.name,
109-
version=dist.version,
110-
summary=dist.summary,
111-
requires_dist=list(dist.requires_dist),
112-
requires_python=dist.requires_python,
113-
)
100+
def _get_info_from_metadata(self, link: Link) -> PackageInfo | None:
101+
if link.has_metadata:
102+
try:
103+
assert link.metadata_url is not None
104+
response = self.session.get(link.metadata_url)
105+
distribution = pkginfo.Distribution()
106+
if link.metadata_hash_name is not None:
107+
metadata_hash = getattr(hashlib, link.metadata_hash_name)(
108+
response.text.encode()
109+
).hexdigest()
110+
111+
if metadata_hash != link.metadata_hash:
112+
self._log(
113+
f"Metadata file hash ({metadata_hash}) does not match"
114+
f" expected hash ({link.metadata_hash})."
115+
f" Metadata file for {link.filename} will be ignored.",
116+
level="warning",
117+
)
118+
return None
119+
120+
distribution.parse(response.content)
121+
return PackageInfo(
122+
name=distribution.name,
123+
version=distribution.version,
124+
summary=distribution.summary,
125+
requires_dist=list(distribution.requires_dist),
126+
requires_python=distribution.requires_python,
127+
)
128+
129+
except requests.HTTPError:
130+
self._log(
131+
f"Failed to retrieve metadata at {link.metadata_url}",
132+
level="warning",
133+
)
134+
114135
return None
115136

116-
def _get_info_from_urls(
137+
def _get_info_from_links(
117138
self,
118-
urls: dict[str, list[str]],
119-
metadata: dict[str, pkginfo.Distribution] | None = None,
139+
links: list[Link],
140+
*,
141+
ignore_yanked: bool = True,
120142
) -> PackageInfo:
121-
metadata = metadata or {}
143+
# Sort links by distribution type
144+
wheels: list[Link] = []
145+
sdists: list[Link] = []
146+
for link in links:
147+
if link.yanked and ignore_yanked:
148+
# drop yanked files unless the entire release is yanked
149+
continue
150+
if link.is_wheel:
151+
wheels.append(link)
152+
elif link.filename.endswith(
153+
(".tar.gz", ".zip", ".bz2", ".xz", ".Z", ".tar")
154+
):
155+
sdists.append(link)
156+
122157
# Prefer to read data from wheels: this is faster and more reliable
123-
if wheels := urls.get("bdist_wheel"):
158+
if wheels:
124159
# We ought just to be able to look at any of the available wheels to read
125160
# metadata, they all should give the same answer.
126161
#
@@ -135,8 +170,7 @@ def _get_info_from_urls(
135170
universal_python3_wheel = None
136171
platform_specific_wheels = []
137172
for wheel in wheels:
138-
link = Link(wheel)
139-
m = wheel_file_re.match(link.filename)
173+
m = wheel_file_re.match(wheel.filename)
140174
if not m:
141175
continue
142176

@@ -157,17 +191,17 @@ def _get_info_from_urls(
157191

158192
if universal_wheel is not None:
159193
return self._get_info_from_metadata(
160-
universal_wheel, metadata
194+
universal_wheel
161195
) or self._get_info_from_wheel(universal_wheel)
162196

163197
info = None
164198
if universal_python2_wheel and universal_python3_wheel:
165199
info = self._get_info_from_metadata(
166-
universal_python2_wheel, metadata
200+
universal_python2_wheel
167201
) or self._get_info_from_wheel(universal_python2_wheel)
168202

169203
py3_info = self._get_info_from_metadata(
170-
universal_python3_wheel, metadata
204+
universal_python3_wheel
171205
) or self._get_info_from_wheel(universal_python3_wheel)
172206

173207
if info.requires_python or py3_info.requires_python:
@@ -219,71 +253,23 @@ def _get_info_from_urls(
219253
# Prefer non platform specific wheels
220254
if universal_python3_wheel:
221255
return self._get_info_from_metadata(
222-
universal_python3_wheel, metadata
256+
universal_python3_wheel
223257
) or self._get_info_from_wheel(universal_python3_wheel)
224258

225259
if universal_python2_wheel:
226260
return self._get_info_from_metadata(
227-
universal_python2_wheel, metadata
261+
universal_python2_wheel
228262
) or self._get_info_from_wheel(universal_python2_wheel)
229263

230264
if platform_specific_wheels:
231265
first_wheel = platform_specific_wheels[0]
232266
return self._get_info_from_metadata(
233-
first_wheel, metadata
267+
first_wheel
234268
) or self._get_info_from_wheel(first_wheel)
235269

236-
return self._get_info_from_metadata(
237-
urls["sdist"][0], metadata
238-
) or self._get_info_from_sdist(urls["sdist"][0])
239-
240-
def _get_info_from_links(
241-
self,
242-
links: list[Link],
243-
*,
244-
ignore_yanked: bool = True,
245-
) -> PackageInfo:
246-
urls = defaultdict(list)
247-
metadata: dict[str, pkginfo.Distribution] = {}
248-
for link in links:
249-
if link.yanked and ignore_yanked:
250-
# drop yanked files unless the entire release is yanked
251-
continue
252-
if link.has_metadata:
253-
try:
254-
assert link.metadata_url is not None
255-
response = self.session.get(link.metadata_url)
256-
distribution = pkginfo.Distribution()
257-
if link.metadata_hash_name is not None:
258-
metadata_hash = getattr(hashlib, link.metadata_hash_name)(
259-
response.text.encode()
260-
).hexdigest()
261-
262-
if metadata_hash != link.metadata_hash:
263-
self._log(
264-
f"Metadata file hash ({metadata_hash}) does not match"
265-
f" expected hash ({link.metadata_hash})."
266-
f" Metadata file for {link.filename} will be ignored.",
267-
level="warning",
268-
)
269-
continue
270-
271-
distribution.parse(response.content)
272-
metadata[link.url] = distribution
273-
except requests.HTTPError:
274-
self._log(
275-
f"Failed to retrieve metadata at {link.metadata_url}",
276-
level="warning",
277-
)
278-
279-
if link.is_wheel:
280-
urls["bdist_wheel"].append(link.url)
281-
elif link.filename.endswith(
282-
(".tar.gz", ".zip", ".bz2", ".xz", ".Z", ".tar")
283-
):
284-
urls["sdist"].append(link.url)
285-
286-
return self._get_info_from_urls(urls, metadata)
270+
return self._get_info_from_metadata(sdists[0]) or self._get_info_from_sdist(
271+
sdists[0]
272+
)
287273

288274
def _links_to_data(self, links: list[Link], data: PackageInfo) -> dict[str, Any]:
289275
if not links:

0 commit comments

Comments
 (0)