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_DEEP = True
115
+ TRACE = False
116
+ TRACE_DEEP = False
116
117
TRACE_ULTRA_DEEP = False
117
118
118
119
# Supported environments
@@ -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 ))
332
341
342
+ if not found :
343
+ raise Exception (f"No PyPI package { name } @ { version } found!" )
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
#
@@ -553,7 +568,7 @@ def get_best_download_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 ]
@@ -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 ):
@@ -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,6 +1840,7 @@ def get_pypi_repo(index_url, _PYPI_REPO={}):
1824
1840
return _PYPI_REPO [index_url ]
1825
1841
1826
1842
1843
+ @functools .cache
1827
1844
def get_pypi_package_data (name , version , index_url , verbose = TRACE_DEEP ):
1828
1845
"""
1829
1846
Return a PypiPackage or None.
@@ -1833,13 +1850,12 @@ def get_pypi_package_data(name, version, index_url, verbose=TRACE_DEEP):
1833
1850
print (f" get_pypi_package_data: Fetching { name } @ { version } info from { index_url } " )
1834
1851
package = get_pypi_repo (index_url ).get_package (name , version )
1835
1852
if verbose :
1836
- print (f" get_pypi_package_data: Fetched" ) # {package}")
1853
+ print (f" get_pypi_package_data: Fetched: { package } " )
1837
1854
return package
1838
1855
1839
1856
except RemoteNotFetchedException as e :
1840
1857
print (f" get_pypi_package_data: Failed to fetch PyPI package { name } @ { version } info from { index_url } : { e } " )
1841
1858
1842
-
1843
1859
################################################################################
1844
1860
#
1845
1861
# Basic file and URL-based operations using a persistent file-based Cache
@@ -2000,7 +2016,6 @@ def fetch_and_save_path_or_url(
2000
2016
fo .write (content )
2001
2017
return content
2002
2018
2003
-
2004
2019
################################################################################
2005
2020
# Requirements processing
2006
2021
################################################################################
@@ -2038,7 +2053,6 @@ def get_required_packages(
2038
2053
print (" get_required_packages: name:" , name , "version:" , version )
2039
2054
yield repo .get_package (name , version )
2040
2055
2041
-
2042
2056
################################################################################
2043
2057
# Functions to update or fetch ABOUT and license files
2044
2058
################################################################################
@@ -2117,7 +2131,6 @@ def get_other_dists(_package, _dist):
2117
2131
for p in packages_by_name [local_package .name ]
2118
2132
if p .version != local_package .version
2119
2133
]
2120
-
2121
2134
other_local_version = other_local_packages and other_local_packages [- 1 ]
2122
2135
if other_local_version :
2123
2136
latest_local_dists = list (other_local_version .get_distributions ())
@@ -2189,7 +2202,6 @@ def get_other_dists(_package, _dist):
2189
2202
lic_errs = "\n " .join (lic_errs )
2190
2203
print (f"Failed to fetch some licenses:: { lic_errs } " )
2191
2204
2192
-
2193
2205
################################################################################
2194
2206
#
2195
2207
# Functions to build new Python wheels including native on multiple OSes
@@ -2320,9 +2332,9 @@ def build_wheels_locally_if_pure_python(
2320
2332
"--wheel-dir" ,
2321
2333
wheel_dir ,
2322
2334
]
2323
- + deps
2324
- + verbose
2325
- + [requirements_specifier ]
2335
+ + deps
2336
+ + verbose
2337
+ + [requirements_specifier ]
2326
2338
)
2327
2339
2328
2340
print (f"Building local wheels for: { requirements_specifier } " )
0 commit comments