3
3
import functools
4
4
import hashlib
5
5
6
- from collections import defaultdict
7
6
from contextlib import contextmanager
8
7
from pathlib import Path
9
8
from typing import TYPE_CHECKING
16
15
17
16
from poetry .core .constraints .version import parse_constraint
18
17
from poetry .core .packages .dependency import Dependency
19
- from poetry .core .packages .utils .link import Link
20
18
from poetry .core .utils .helpers import temporary_directory
21
19
from poetry .core .version .markers import parse_marker
22
20
38
36
39
37
if TYPE_CHECKING :
40
38
from packaging .utils import NormalizedName
39
+ from poetry .core .packages .utils .link import Link
41
40
42
41
from poetry .repositories .link_sources .base import LinkSource
43
42
from poetry .utils .authenticator import RepositoryCertificateConfig
@@ -110,10 +109,9 @@ def _cached_or_downloaded_file(
110
109
)
111
110
yield filepath
112
111
113
- def _get_info_from_wheel (self , url : str ) -> PackageInfo :
112
+ def _get_info_from_wheel (self , link : Link ) -> PackageInfo :
114
113
from poetry .inspection .info import PackageInfo
115
114
116
- link = Link (url )
117
115
netloc = link .netloc
118
116
119
117
# If "lazy-wheel" is enabled and the domain supports range requests
@@ -149,37 +147,73 @@ def _get_info_from_wheel(self, url: str) -> PackageInfo:
149
147
level = "debug" ,
150
148
)
151
149
self ._supports_range_requests [netloc ] = True
152
- return self ._get_info_from_wheel (link . url )
150
+ return self ._get_info_from_wheel (link )
153
151
154
- def _get_info_from_sdist (self , url : str ) -> PackageInfo :
152
+ def _get_info_from_sdist (self , link : Link ) -> PackageInfo :
155
153
from poetry .inspection .info import PackageInfo
156
154
157
- with self ._cached_or_downloaded_file (Link ( url ) ) as filepath :
155
+ with self ._cached_or_downloaded_file (link ) as filepath :
158
156
return PackageInfo .from_sdist (filepath )
159
157
160
- @staticmethod
161
- def _get_info_from_metadata (
162
- url : str , metadata : dict [str , pkginfo .Distribution ]
163
- ) -> PackageInfo | None :
164
- if url in metadata :
165
- dist = metadata [url ]
166
- return PackageInfo (
167
- name = dist .name ,
168
- version = dist .version ,
169
- summary = dist .summary ,
170
- requires_dist = list (dist .requires_dist ),
171
- requires_python = dist .requires_python ,
172
- )
158
+ def _get_info_from_metadata (self , link : Link ) -> PackageInfo | None :
159
+ if link .has_metadata :
160
+ try :
161
+ assert link .metadata_url is not None
162
+ response = self .session .get (link .metadata_url )
163
+ distribution = pkginfo .Distribution ()
164
+ if link .metadata_hash_name is not None :
165
+ metadata_hash = getattr (hashlib , link .metadata_hash_name )(
166
+ response .text .encode ()
167
+ ).hexdigest ()
168
+
169
+ if metadata_hash != link .metadata_hash :
170
+ self ._log (
171
+ f"Metadata file hash ({ metadata_hash } ) does not match"
172
+ f" expected hash ({ link .metadata_hash } )."
173
+ f" Metadata file for { link .filename } will be ignored." ,
174
+ level = "warning" ,
175
+ )
176
+ return None
177
+
178
+ distribution .parse (response .content )
179
+ return PackageInfo (
180
+ name = distribution .name ,
181
+ version = distribution .version ,
182
+ summary = distribution .summary ,
183
+ requires_dist = list (distribution .requires_dist ),
184
+ requires_python = distribution .requires_python ,
185
+ )
186
+
187
+ except requests .HTTPError :
188
+ self ._log (
189
+ f"Failed to retrieve metadata at { link .metadata_url } " ,
190
+ level = "warning" ,
191
+ )
192
+
173
193
return None
174
194
175
- def _get_info_from_urls (
195
+ def _get_info_from_links (
176
196
self ,
177
- urls : dict [str , list [str ]],
178
- metadata : dict [str , pkginfo .Distribution ] | None = None ,
197
+ links : list [Link ],
198
+ * ,
199
+ ignore_yanked : bool = True ,
179
200
) -> PackageInfo :
180
- metadata = metadata or {}
201
+ # Sort links by distribution type
202
+ wheels : list [Link ] = []
203
+ sdists : list [Link ] = []
204
+ for link in links :
205
+ if link .yanked and ignore_yanked :
206
+ # drop yanked files unless the entire release is yanked
207
+ continue
208
+ if link .is_wheel :
209
+ wheels .append (link )
210
+ elif link .filename .endswith (
211
+ (".tar.gz" , ".zip" , ".bz2" , ".xz" , ".Z" , ".tar" )
212
+ ):
213
+ sdists .append (link )
214
+
181
215
# Prefer to read data from wheels: this is faster and more reliable
182
- if wheels := urls . get ( "bdist_wheel" ) :
216
+ if wheels :
183
217
# We ought just to be able to look at any of the available wheels to read
184
218
# metadata, they all should give the same answer.
185
219
#
@@ -194,8 +228,7 @@ def _get_info_from_urls(
194
228
universal_python3_wheel = None
195
229
platform_specific_wheels = []
196
230
for wheel in wheels :
197
- link = Link (wheel )
198
- m = wheel_file_re .match (link .filename )
231
+ m = wheel_file_re .match (wheel .filename )
199
232
if not m :
200
233
continue
201
234
@@ -216,17 +249,17 @@ def _get_info_from_urls(
216
249
217
250
if universal_wheel is not None :
218
251
return self ._get_info_from_metadata (
219
- universal_wheel , metadata
252
+ universal_wheel
220
253
) or self ._get_info_from_wheel (universal_wheel )
221
254
222
255
info = None
223
256
if universal_python2_wheel and universal_python3_wheel :
224
257
info = self ._get_info_from_metadata (
225
- universal_python2_wheel , metadata
258
+ universal_python2_wheel
226
259
) or self ._get_info_from_wheel (universal_python2_wheel )
227
260
228
261
py3_info = self ._get_info_from_metadata (
229
- universal_python3_wheel , metadata
262
+ universal_python3_wheel
230
263
) or self ._get_info_from_wheel (universal_python3_wheel )
231
264
232
265
if info .requires_python or py3_info .requires_python :
@@ -278,71 +311,23 @@ def _get_info_from_urls(
278
311
# Prefer non platform specific wheels
279
312
if universal_python3_wheel :
280
313
return self ._get_info_from_metadata (
281
- universal_python3_wheel , metadata
314
+ universal_python3_wheel
282
315
) or self ._get_info_from_wheel (universal_python3_wheel )
283
316
284
317
if universal_python2_wheel :
285
318
return self ._get_info_from_metadata (
286
- universal_python2_wheel , metadata
319
+ universal_python2_wheel
287
320
) or self ._get_info_from_wheel (universal_python2_wheel )
288
321
289
322
if platform_specific_wheels :
290
323
first_wheel = platform_specific_wheels [0 ]
291
324
return self ._get_info_from_metadata (
292
- first_wheel , metadata
325
+ first_wheel
293
326
) or self ._get_info_from_wheel (first_wheel )
294
327
295
- return self ._get_info_from_metadata (
296
- urls ["sdist" ][0 ], metadata
297
- ) or self ._get_info_from_sdist (urls ["sdist" ][0 ])
298
-
299
- def _get_info_from_links (
300
- self ,
301
- links : list [Link ],
302
- * ,
303
- ignore_yanked : bool = True ,
304
- ) -> PackageInfo :
305
- urls = defaultdict (list )
306
- metadata : dict [str , pkginfo .Distribution ] = {}
307
- for link in links :
308
- if link .yanked and ignore_yanked :
309
- # drop yanked files unless the entire release is yanked
310
- continue
311
- if link .has_metadata :
312
- try :
313
- assert link .metadata_url is not None
314
- response = self .session .get (link .metadata_url )
315
- distribution = pkginfo .Distribution ()
316
- if link .metadata_hash_name is not None :
317
- metadata_hash = getattr (hashlib , link .metadata_hash_name )(
318
- response .text .encode ()
319
- ).hexdigest ()
320
-
321
- if metadata_hash != link .metadata_hash :
322
- self ._log (
323
- f"Metadata file hash ({ metadata_hash } ) does not match"
324
- f" expected hash ({ link .metadata_hash } )."
325
- f" Metadata file for { link .filename } will be ignored." ,
326
- level = "warning" ,
327
- )
328
- continue
329
-
330
- distribution .parse (response .content )
331
- metadata [link .url ] = distribution
332
- except requests .HTTPError :
333
- self ._log (
334
- f"Failed to retrieve metadata at { link .metadata_url } " ,
335
- level = "warning" ,
336
- )
337
-
338
- if link .is_wheel :
339
- urls ["bdist_wheel" ].append (link .url )
340
- elif link .filename .endswith (
341
- (".tar.gz" , ".zip" , ".bz2" , ".xz" , ".Z" , ".tar" )
342
- ):
343
- urls ["sdist" ].append (link .url )
344
-
345
- return self ._get_info_from_urls (urls , metadata )
328
+ return self ._get_info_from_metadata (sdists [0 ]) or self ._get_info_from_sdist (
329
+ sdists [0 ]
330
+ )
346
331
347
332
def _links_to_data (self , links : list [Link ], data : PackageInfo ) -> dict [str , Any ]:
348
333
if not links :
0 commit comments