@@ -2099,134 +2099,15 @@ def python_run_mx_filetests(args):
2099
2099
2100
2100
2101
2101
def _python_checkpatchfiles ():
2102
- listfilename = tempfile .mktemp ()
2103
- # additionally, we want to check if the packages we are patching all have a permissive license
2104
- with open (listfilename , "w" ) as listfile :
2105
- mx .run (["git" , "ls-tree" , "-r" , "HEAD" , "--name-only" ], out = listfile )
2106
- try :
2107
- # TODO our mirror doesn't handle the json API
2108
- # pypi_base_url = mx_urlrewrites.rewriteurl("https://pypi.org/packages/").replace("packages/", "")
2109
- pypi_base_url = "https://pypi.org"
2110
- with open (listfilename , "r" ) as listfile :
2111
- content = listfile .read ()
2112
- patchfile_pattern = re .compile (r"lib-graalpython/patches/([^/]+)/.*?([^/]*\.patch)" )
2113
- checked = {
2114
- # meson-python puts the whole license text in the field. It's MIT
2115
- 'meson-python.patch' ,
2116
- # scipy puts the whole license text in the field, skip it. It's new BSD
2117
- 'scipy-1.9.3.patch' ,
2118
- 'scipy-1.10.1.patch' ,
2119
- # pandas puts the whole license text in the field. Its BSD-3-Clause
2120
- 'pandas-1.5.2.patch' ,
2121
- 'pandas-2.0.3.patch' ,
2122
- 'pandas-2.2.2.patch' ,
2123
- # numpy started putting the whole license text in the field. Its BSD-3-Clause
2124
- 'numpy-1.23.2.patch' ,
2125
- 'numpy-1.23.5.patch' ,
2126
- 'numpy-1.24.3.patch' ,
2127
- 'numpy-1.26.4.patch' ,
2128
- 'numpy-2.0.0.patch' ,
2129
- # libcst is MIT
2130
- 'libcst-1.0.1.patch' ,
2131
- # Empty license field, skip it. It's MIT
2132
- 'setuptools-60.patch' ,
2133
- 'setuptools-60.9.patch' ,
2134
- 'setuptools-63.patch' ,
2135
- 'setuptools-65.patch' ,
2136
- # Empty license field. It's MIT
2137
- 'urllib3-2.patch' ,
2138
- # Empty license field. It's MIT
2139
- 'wheel-0.43.patch' ,
2140
- 'wheel-0.41.2.patch' ,
2141
- 'wheel-0.40.patch' ,
2142
- 'wheel-0.38.patch' ,
2143
- 'wheel-0.37.patch' ,
2144
- 'wheel-0.35.patch' ,
2145
- 'wheel-pre-0.35.patch' ,
2146
- # Empty license field. It's ASL 2.0 or BSD 2-Clause
2147
- 'packaging.patch' ,
2148
- # pymongo puts the whole license in the field. It's ASL 2.0
2149
- 'pymongo.patch' ,
2150
- # Empty license field. It's ASL 2.0
2151
- 'tokenizers-0.13.3.patch' ,
2152
- 'tokenizers-0.15.0.patch' ,
2153
- # Empty license field. It's Apache 2
2154
- 'safetensors-0.3.3.patch' ,
2155
- 'tensorflow-io-0.34.0.patch' ,
2156
- 'tensorflow-io-gcs-filesystem-0.34.0.patch' ,
2157
- # Puts whole license into the field. It's BSD 3-Clause
2158
- 'pythran-0.12.0.patch' ,
2159
- 'pythran-0.13.patch' ,
2160
- 'pyzmq.patch' ,
2161
- 'jupyter_server.patch' ,
2162
- # Empty license field. It's BSD-3-Clause
2163
- 'prompt_toolkit.patch' ,
2164
- # Whole license in the field. It's BSD-3-Clause
2165
- 'pyzmq.patch' ,
2166
- # Whole license in the field. It's PSF
2167
- 'matplotlib-3.5.3.patch' ,
2168
- 'matplotlib-3.6.3.patch' ,
2169
- 'matplotlib-3.7.0.patch' ,
2170
- # Empty license field. It's MIT
2171
- 'autopep8.patch' ,
2172
- # Whole license in the field. It's MIT
2173
- 'tiktoken-0.7.0.patch' ,
2174
- # License field is null. It's PSF
2175
- 'typing_extensions.patch' ,
2176
- }
2177
- allowed_licenses = [
2178
- "MIT" ,
2179
- "BSD" ,
2180
- "BSD-3-Clause" ,
2181
- "3-Clause BSD License" ,
2182
- "Apache License, Version 2.0" ,
2183
- "http://www.apache.org/licenses/LICENSE-2.0" ,
2184
- "PSF" ,
2185
- "Apache" ,
2186
- "new BSD" ,
2187
- "Apache-2.0" ,
2188
- "MPL-2.0" ,
2189
- "LGPL" ,
2190
- ]
2191
-
2192
- def as_license_regex (name ):
2193
- subregex = re .escape (name ).replace (r'\-' , '[- ]' )
2194
- return f'(?:{ subregex } (?: license)?)'
2195
-
2196
- allowed_licenses_regex = re .compile ('|' .join (map (as_license_regex , allowed_licenses )), re .IGNORECASE )
2197
-
2198
- for line in content .split ("\n " ):
2199
- if not line or os .stat (line ).st_size == 0 :
2200
- # empty files are just markers and do not need to be license checked
2201
- continue
2202
- match = patchfile_pattern .search (line )
2203
- if match :
2204
- package_name = match .group (1 )
2205
- patch_name = match .group (2 )
2206
- if patch_name in checked :
2207
- continue
2208
- checked .add (patch_name )
2209
- package_url = "/" .join ([pypi_base_url , "pypi" , package_name , "json" ])
2210
- mx .log ("Checking license of patchfile for " + package_url )
2211
- response = urllib_request .urlopen (package_url )
2212
- try :
2213
- data = json .loads (response .read ())
2214
- license_field = data ["info" ]["license" ]
2215
- license_field_no_parens = re .sub (r'[()]' , '' , license_field )
2216
- license_tokens = re .split (r' AND | OR ' , license_field_no_parens )
2217
- for license_token in license_tokens :
2218
- if not allowed_licenses_regex .match (license_token ):
2219
- mx .abort (
2220
- f"The license for the original project of patch file { patch_name !r} is { license_field !r} . "
2221
- f"We cannot include a patch for it. Allowed licenses are: { allowed_licenses } "
2222
- )
2223
- except Exception as e : # pylint: disable=broad-except;
2224
- mx .abort ("Error getting %r.\n %r" % (package_url , e ))
2225
- finally :
2226
- if response :
2227
- response .close ()
2228
- finally :
2229
- os .unlink (listfilename )
2102
+ exe = os .environ .get ("PYTHON3_HOME" , sys .executable )
2103
+ env = os .environ .copy ()
2104
+ env ['PYTHONPATH' ] = 'graalpython/lib-python/3/ensurepip/_bundled/pip-23.2.1-py3-none-any.whl'
2105
+ mx_dir = Path (__file__ ).parent
2106
+ mx .run (
2107
+ [exe , str (mx_dir / 'verify_patches.py' ), str (mx_dir .parent / 'graalpython/lib-graalpython/patches' )],
2108
+ env = env ,
2109
+ nonZeroIsFatal = True ,
2110
+ )
2230
2111
2231
2112
2232
2113
# ----------------------------------------------------------------------------------------------------------------------
0 commit comments