Skip to content

Commit d0074ce

Browse files
committed
Replace patch license check with patch metadata verification
1 parent 4e8db34 commit d0074ce

File tree

4 files changed

+141
-259
lines changed

4 files changed

+141
-259
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_patch_metadata.py

Lines changed: 0 additions & 130 deletions
This file was deleted.

graalpython/lib-graalpython/patches/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Configuration files are named `metadata.toml` and can contain the following:
1212
# Optional. Relative path to a patch file. May be omitted when the entry just specifies `install-priority`
1313
patch = 'foo-1.0.0.patch'
1414
# Required if 'patch' is specified. SPDX license expression for the package (allows parentheses, 'AND', 'OR', 'WITH').
15-
# Allowed licenses are enumerated in test_patch_metadata.py
15+
# Allowed licenses are enumerated in mx.graalpython/verify_patches.py
1616
license = 'MIT'
1717
# Optional. Version specifier according to https://peps.python.org/pep-0440/#version-specifiers. If omitted, it will
1818
# match any version

mx.graalpython/mx_graalpython.py

Lines changed: 9 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,134 +2099,15 @@ def python_run_mx_filetests(args):
20992099

21002100

21012101
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+
)
22302111

22312112

22322113
# ----------------------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)