1
1
#!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
2
3
#
3
4
# Copyright (c) nexB Inc. and others. All rights reserved.
4
5
# ScanCode is a trademark of nexB Inc.
24
25
import packageurl
25
26
import requests
26
27
import saneyaml
27
- import utils_pip_compatibility_tags
28
28
from commoncode import fileutils
29
29
from commoncode .hash import multi_checksums
30
30
from commoncode .text import python_safe_name
31
31
from packvers import tags as packaging_tags
32
32
from packvers import version as packaging_version
33
33
34
+ import utils_pip_compatibility_tags
35
+
34
36
"""
35
37
Utilities to manage Python thirparty libraries source, binaries and metadata in
36
38
local directories and remote repositories.
91
93
92
94
- parse requirement file
93
95
- create a TODO queue of requirements to process
94
- - done: create an empty map of processed binary requirements as
95
- {package name: (list of versions/tags}
96
+ - done: create an empty map of processed binary requirements as {package name: (list of versions/tags}
96
97
97
98
98
99
- while we have package reqs in TODO queue, process one requirement:
114
115
TRACE_ULTRA_DEEP = False
115
116
116
117
# Supported environments
117
- PYTHON_VERSIONS = "37 " , "38 " , "39 " , "310 "
118
+ PYTHON_VERSIONS = "39 " , "310 " , "311 " , "312" , "313 "
118
119
119
120
PYTHON_DOT_VERSIONS_BY_VER = {
120
- "37" : "3.7" ,
121
- "38" : "3.8" ,
122
121
"39" : "3.9" ,
123
122
"310" : "3.10" ,
123
+ "311" : "3.11" ,
124
+ "312" : "3.12" ,
125
+ "313" : "3.13" ,
124
126
}
125
127
126
128
@@ -132,10 +134,11 @@ def get_python_dot_version(version):
132
134
133
135
134
136
ABIS_BY_PYTHON_VERSION = {
135
- "37" : ["cp37" , "cp37m" , "abi3" ],
136
- "38" : ["cp38" , "cp38m" , "abi3" ],
137
137
"39" : ["cp39" , "cp39m" , "abi3" ],
138
138
"310" : ["cp310" , "cp310m" , "abi3" ],
139
+ "311" : ["cp311" , "cp311m" , "abi3" ],
140
+ "312" : ["cp312" , "cp312m" , "abi3" ],
141
+ "313" : ["cp313" , "cp313m" , "abi3" ],
139
142
}
140
143
141
144
PLATFORMS_BY_OS = {
@@ -553,8 +556,7 @@ def download(self, dest_dir=THIRDPARTY_DIR):
553
556
Download this distribution into `dest_dir` directory.
554
557
Return the fetched filename.
555
558
"""
556
- if not self .filename :
557
- raise ValueError (f"self.filename has no value but is required: { self .filename !r} " )
559
+ assert self .filename
558
560
if TRACE_DEEP :
559
561
print (
560
562
f"Fetching distribution of { self .name } =={ self .version } :" ,
@@ -822,9 +824,9 @@ def fetch_license_files(self, dest_dir=THIRDPARTY_DIR, use_cached_index=False):
822
824
"""
823
825
urls = LinksRepository .from_url (use_cached_index = use_cached_index ).links
824
826
errors = []
825
- extra_lic_names = [lic .get ("file" ) for lic in self .extra_data .get ("licenses" , {})]
827
+ extra_lic_names = [l .get ("file" ) for l in self .extra_data .get ("licenses" , {})]
826
828
extra_lic_names += [self .extra_data .get ("license_file" )]
827
- extra_lic_names = [eln for eln in extra_lic_names if eln ]
829
+ extra_lic_names = [ln for ln in extra_lic_names if ln ]
828
830
lic_names = [f"{ key } .LICENSE" for key in self .get_license_keys ()]
829
831
for filename in lic_names + extra_lic_names :
830
832
floc = os .path .join (dest_dir , filename )
@@ -844,7 +846,7 @@ def fetch_license_files(self, dest_dir=THIRDPARTY_DIR, use_cached_index=False):
844
846
if TRACE :
845
847
print (f"Fetched license from remote: { lic_url } " )
846
848
847
- except Exception :
849
+ except :
848
850
try :
849
851
# try licensedb second
850
852
lic_url = f"{ LICENSEDB_API_URL } /{ filename } "
@@ -857,9 +859,8 @@ def fetch_license_files(self, dest_dir=THIRDPARTY_DIR, use_cached_index=False):
857
859
if TRACE :
858
860
print (f"Fetched license from licensedb: { lic_url } " )
859
861
860
- except Exception :
861
- msg = f"No text for license { filename } in expression "
862
- f"{ self .license_expression !r} from { self } "
862
+ except :
863
+ msg = f'No text for license { filename } in expression "{ self .license_expression } " from { self } '
863
864
print (msg )
864
865
errors .append (msg )
865
866
@@ -999,7 +1000,7 @@ def get_license_link_for_filename(filename, urls):
999
1000
exception if no link is found or if there are more than one link for that
1000
1001
file name.
1001
1002
"""
1002
- path_or_url = [url for url in urls if url .endswith (f"/{ filename } " )]
1003
+ path_or_url = [l for l in urls if l .endswith (f"/{ filename } " )]
1003
1004
if not path_or_url :
1004
1005
raise Exception (f"Missing link to file: { filename } " )
1005
1006
if not len (path_or_url ) == 1 :
@@ -1288,7 +1289,7 @@ def is_pure(self):
1288
1289
def is_pure_wheel (filename ):
1289
1290
try :
1290
1291
return Wheel .from_filename (filename ).is_pure ()
1291
- except Exception :
1292
+ except :
1292
1293
return False
1293
1294
1294
1295
@@ -1484,7 +1485,8 @@ def get_distributions(self):
1484
1485
"""
1485
1486
if self .sdist :
1486
1487
yield self .sdist
1487
- yield from self .wheels
1488
+ for wheel in self .wheels :
1489
+ yield wheel
1488
1490
1489
1491
def get_url_for_filename (self , filename ):
1490
1492
"""
@@ -1613,8 +1615,7 @@ class PypiSimpleRepository:
1613
1615
type = dict ,
1614
1616
default = attr .Factory (lambda : defaultdict (dict )),
1615
1617
metadata = dict (
1616
- help = "Mapping of {name: {version: PypiPackage, version: PypiPackage, etc} "
1617
- "available in this repo"
1618
+ help = "Mapping of {name: {version: PypiPackage, version: PypiPackage, etc} available in this repo"
1618
1619
),
1619
1620
)
1620
1621
@@ -1628,8 +1629,7 @@ class PypiSimpleRepository:
1628
1629
type = bool ,
1629
1630
default = False ,
1630
1631
metadata = dict (
1631
- help = "If True, use any existing on-disk cached PyPI index files. "
1632
- "Otherwise, fetch and cache."
1632
+ help = "If True, use any existing on-disk cached PyPI index files. Otherwise, fetch and cache."
1633
1633
),
1634
1634
)
1635
1635
@@ -1638,8 +1638,7 @@ def _get_package_versions_map(self, name):
1638
1638
Return a mapping of all available PypiPackage version for this package name.
1639
1639
The mapping may be empty. It is ordered by version from oldest to newest
1640
1640
"""
1641
- if not name :
1642
- raise ValueError (f"name is required: { name !r} " )
1641
+ assert name
1643
1642
normalized_name = NameVer .normalize_name (name )
1644
1643
versions = self .packages [normalized_name ]
1645
1644
if not versions and normalized_name not in self .fetched_package_normalized_names :
@@ -1694,7 +1693,7 @@ def fetch_links(self, normalized_name):
1694
1693
)
1695
1694
links = collect_urls (text )
1696
1695
# TODO: keep sha256
1697
- links = [link .partition ("#sha256=" ) for link in links ]
1696
+ links = [l .partition ("#sha256=" ) for l in links ]
1698
1697
links = [url for url , _ , _sha256 in links ]
1699
1698
return links
1700
1699
@@ -1915,7 +1914,7 @@ def get_remote_file_content(
1915
1914
# several redirects and that we can ignore content there. A HEAD request may
1916
1915
# not get us this last header
1917
1916
print (f" DOWNLOADING: { url } " )
1918
- with requests .get (url , allow_redirects = True , stream = True , headers = headers ) as response : # noqa: S113
1917
+ with requests .get (url , allow_redirects = True , stream = True , headers = headers ) as response :
1919
1918
status = response .status_code
1920
1919
if status != requests .codes .ok : # NOQA
1921
1920
if status == 429 and _delay < 20 :
@@ -2134,7 +2133,7 @@ def call(args, verbose=TRACE):
2134
2133
"""
2135
2134
if TRACE_DEEP :
2136
2135
print ("Calling:" , " " .join (args ))
2137
- with subprocess .Popen ( # noqa: S603
2136
+ with subprocess .Popen (
2138
2137
args , stdout = subprocess .PIPE , stderr = subprocess .PIPE , encoding = "utf-8"
2139
2138
) as process :
2140
2139
stdouts = []
@@ -2199,7 +2198,7 @@ def download_wheels_with_pip(
2199
2198
cli_args .extend (["--requirement" , req_file ])
2200
2199
2201
2200
if TRACE :
2202
- print ("Downloading wheels using command:" , " " .join (cli_args ))
2201
+ print (f "Downloading wheels using command:" , " " .join (cli_args ))
2203
2202
2204
2203
existing = set (os .listdir (dest_dir ))
2205
2204
error = False
@@ -2232,7 +2231,7 @@ def download_wheels_with_pip(
2232
2231
2233
2232
def check_about (dest_dir = THIRDPARTY_DIR ):
2234
2233
try :
2235
- subprocess .check_output (f"venv/bin/about check { dest_dir } " .split ()) # noqa: S603
2234
+ subprocess .check_output (f"venv/bin/about check { dest_dir } " .split ())
2236
2235
except subprocess .CalledProcessError as cpe :
2237
2236
print ()
2238
2237
print ("Invalid ABOUT files:" )
@@ -2283,5 +2282,5 @@ def get_license_expression(declared_licenses):
2283
2282
return get_only_expression_from_extracted_license (declared_licenses )
2284
2283
except ImportError :
2285
2284
# Scancode is not installed, clean and join all the licenses
2286
- lics = [python_safe_name (lic ).lower () for lic in declared_licenses ]
2285
+ lics = [python_safe_name (l ).lower () for l in declared_licenses ]
2287
2286
return " AND " .join (lics ).lower ()
0 commit comments