8
8
# See https://github.com/nexB/skeleton for support or download.
9
9
# See https://aboutcode.org for more information about nexB OSS projects.
10
10
#
11
- from collections import defaultdict
12
11
import email
12
+ import functools
13
13
import itertools
14
14
import os
15
15
import re
18
18
import tempfile
19
19
import time
20
20
import urllib
21
+ from collections import defaultdict
22
+ from urllib .parse import quote_plus
21
23
22
24
import attr
23
25
import license_expression
29
31
from commoncode .text import python_safe_name
30
32
from packaging import tags as packaging_tags
31
33
from packaging import version as packaging_version
32
- from urllib .parse import quote_plus
33
34
34
35
import utils_pip_compatibility_tags
35
36
from utils_requirements import load_requirements
111
112
112
113
"""
113
114
114
- TRACE = True
115
+ TRACE = False
115
116
TRACE_DEEP = False
116
117
TRACE_ULTRA_DEEP = False
117
118
@@ -233,7 +234,7 @@ def download_wheel(
233
234
tuple of lists of (fetched_wheel_filenames, existing_wheel_filenames)
234
235
"""
235
236
if TRACE_DEEP :
236
- print (f" download_wheel: { name } =={ version } : { environment } " )
237
+ print (f" download_wheel: { name } =={ version } : { environment } and index_urls: { index_urls } " )
237
238
238
239
fetched_wheel_filenames = []
239
240
existing_wheel_filenames = []
@@ -311,6 +312,7 @@ def download_sdist(
311
312
raise DistributionNotFound (f"Failed to fetch sdist: { name } =={ version } : No sources found" )
312
313
313
314
315
+ @functools .cache
314
316
def get_package_versions (
315
317
name ,
316
318
version = None ,
@@ -321,15 +323,28 @@ def get_package_versions(
321
323
repository ``index_urls`` list of URLs.
322
324
If ``version`` is not provided, return the latest available versions.
323
325
"""
326
+ found = []
327
+ not_found = []
324
328
for index_url in index_urls :
325
329
try :
326
330
repo = get_pypi_repo (index_url )
327
331
package = repo .get_package (name , version )
332
+
328
333
if package :
329
- yield package
334
+ found .append ((package , index_url ))
335
+ else :
336
+ not_found .append ((name , version , index_url ))
330
337
except RemoteNotFetchedException as e :
331
- print (f"Failed to fetch PyPI package { name } @ { version } info from { index_url } : { e } " )
338
+ if TRACE_ULTRA_DEEP :
339
+ print (f"Failed to fetch PyPI package { name } @ { version } info from { index_url } : { e } " )
340
+ not_found .append ((name , version , index_url ))
341
+
342
+ if not found :
343
+ raise Exception (f"No PyPI package { name } @ { version } found!" )
332
344
345
+ for package , index_url in found :
346
+ print (f"Fetched PyPI package { package .name } @ { package .version } info from { index_url } " )
347
+ yield package
333
348
334
349
################################################################################
335
350
#
@@ -546,14 +561,14 @@ def get_best_download_url(
546
561
If none is found, return a synthetic remote URL.
547
562
"""
548
563
for index_url in index_urls :
549
- pypi_package = get_pypi_package (
564
+ pypi_package = get_pypi_package_data (
550
565
name = self .normalized_name ,
551
566
version = self .version ,
552
567
index_url = index_url ,
553
568
)
554
569
if pypi_package :
555
570
if isinstance (pypi_package , tuple ):
556
- raise Exception ("############" , repr (pypi_package ))
571
+ raise Exception ("############" , repr (pypi_package ), self . normalized_name , self . version , index_url )
557
572
try :
558
573
pypi_url = pypi_package .get_url_for_filename (self .filename )
559
574
except Exception as e :
@@ -1450,7 +1465,7 @@ def get_name_version(cls, name, version, packages):
1450
1465
nvs = [p for p in cls .get_versions (name , packages ) if p .version == version ]
1451
1466
1452
1467
if not nvs :
1453
- return name , version
1468
+ return
1454
1469
1455
1470
if len (nvs ) == 1 :
1456
1471
return nvs [0 ]
@@ -1494,8 +1509,8 @@ def dists_from_paths_or_urls(cls, paths_or_urls):
1494
1509
>>> assert expected == result
1495
1510
"""
1496
1511
dists = []
1497
- if TRACE_DEEP :
1498
- print (" ###paths_or_urls:" , paths_or_urls )
1512
+ if TRACE_ULTRA_DEEP :
1513
+ print (" ###paths_or_urls:" , paths_or_urls )
1499
1514
installable = [f for f in paths_or_urls if f .endswith (EXTENSIONS_INSTALLABLE )]
1500
1515
for path_or_url in installable :
1501
1516
try :
@@ -1618,7 +1633,6 @@ def tags(self):
1618
1633
)
1619
1634
)
1620
1635
1621
-
1622
1636
################################################################################
1623
1637
#
1624
1638
# PyPI repo and link index for package wheels and sources
@@ -1657,7 +1671,10 @@ def get_versions(self, name):
1657
1671
The list may be empty.
1658
1672
"""
1659
1673
name = name and NameVer .normalize_name (name )
1660
- self ._populate_links_and_packages (name )
1674
+ try :
1675
+ self ._populate_links_and_packages (name )
1676
+ except Exception as e :
1677
+ print (f" ==> Cannot find versions of { name } : { e } " )
1661
1678
return self .packages_by_normalized_name .get (name , [])
1662
1679
1663
1680
def get_latest_version (self , name ):
@@ -1703,7 +1720,7 @@ def _fetch_links(self, name, _LINKS={}):
1703
1720
_LINKS [index_url ] = [l for l in links if l .endswith (EXTENSIONS )]
1704
1721
1705
1722
links = _LINKS [index_url ]
1706
- if TRACE_DEEP :
1723
+ if TRACE_ULTRA_DEEP :
1707
1724
print (f" Found links { links !r} " )
1708
1725
return links
1709
1726
@@ -1803,7 +1820,6 @@ def from_url(cls, url=ABOUT_BASE_URL, _LINKS_REPO={}):
1803
1820
_LINKS_REPO [url ] = cls (url = url )
1804
1821
return _LINKS_REPO [url ]
1805
1822
1806
-
1807
1823
################################################################################
1808
1824
# Globals for remote repos to be lazily created and cached on first use for the
1809
1825
# life of the session together with some convenience functions.
@@ -1824,19 +1840,21 @@ def get_pypi_repo(index_url, _PYPI_REPO={}):
1824
1840
return _PYPI_REPO [index_url ]
1825
1841
1826
1842
1827
- def get_pypi_package (name , version , index_url , verbose = TRACE_DEEP ):
1843
+ @functools .cache
1844
+ def get_pypi_package_data (name , version , index_url , verbose = TRACE_DEEP ):
1828
1845
"""
1829
1846
Return a PypiPackage or None.
1830
1847
"""
1831
1848
try :
1849
+ if verbose :
1850
+ print (f" get_pypi_package_data: Fetching { name } @ { version } info from { index_url } " )
1832
1851
package = get_pypi_repo (index_url ).get_package (name , version )
1833
1852
if verbose :
1834
- print (f" get_pypi_package: { name } @ { version } info from { index_url } : { package } " )
1853
+ print (f" get_pypi_package_data: Fetched : { package } " )
1835
1854
return package
1836
1855
1837
1856
except RemoteNotFetchedException as e :
1838
- print (f"Failed to fetch PyPI package { name } @ { version } info from { index_url } : { e } " )
1839
-
1857
+ print (f" get_pypi_package_data: Failed to fetch PyPI package { name } @ { version } info from { index_url } : { e } " )
1840
1858
1841
1859
################################################################################
1842
1860
#
@@ -1998,7 +2016,6 @@ def fetch_and_save_path_or_url(
1998
2016
fo .write (content )
1999
2017
return content
2000
2018
2001
-
2002
2019
################################################################################
2003
2020
# Requirements processing
2004
2021
################################################################################
@@ -2036,7 +2053,6 @@ def get_required_packages(
2036
2053
print (" get_required_packages: name:" , name , "version:" , version )
2037
2054
yield repo .get_package (name , version )
2038
2055
2039
-
2040
2056
################################################################################
2041
2057
# Functions to update or fetch ABOUT and license files
2042
2058
################################################################################
@@ -2115,7 +2131,6 @@ def get_other_dists(_package, _dist):
2115
2131
for p in packages_by_name [local_package .name ]
2116
2132
if p .version != local_package .version
2117
2133
]
2118
-
2119
2134
other_local_version = other_local_packages and other_local_packages [- 1 ]
2120
2135
if other_local_version :
2121
2136
latest_local_dists = list (other_local_version .get_distributions ())
@@ -2187,7 +2202,6 @@ def get_other_dists(_package, _dist):
2187
2202
lic_errs = "\n " .join (lic_errs )
2188
2203
print (f"Failed to fetch some licenses:: { lic_errs } " )
2189
2204
2190
-
2191
2205
################################################################################
2192
2206
#
2193
2207
# Functions to build new Python wheels including native on multiple OSes
@@ -2318,9 +2332,9 @@ def build_wheels_locally_if_pure_python(
2318
2332
"--wheel-dir" ,
2319
2333
wheel_dir ,
2320
2334
]
2321
- + deps
2322
- + verbose
2323
- + [requirements_specifier ]
2335
+ + deps
2336
+ + verbose
2337
+ + [requirements_specifier ]
2324
2338
)
2325
2339
2326
2340
print (f"Building local wheels for: { requirements_specifier } " )
0 commit comments