feat: support GraalPy (#1538)
* Properly close files used for testing * Add support for GraalPy * Help GraalPy discover build tools on Windows * Expect manylinux-interpreters ensure graalpy* warning in pip * Workaround GraalPy bugs on Windows * Workaround oracle/graalpython#491 also when uv is not available * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update azure-pipelines.yml * Update azure-pipelines.yml * refacotor: use pathlib.write_text Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * Include GraalPy in docker_warmup and remove workaround for installing it late --------- Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Henry Schreiner <HenrySchreinerIII@gmail.com>
This commit is contained in:
co-authored by
pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Henry Schreiner
parent
5f8d06ff55
commit
020a91baa8
+1
-2
@@ -56,9 +56,8 @@ def docker_warmup(request: pytest.FixtureRequest) -> None:
|
||||
images = [build_options.manylinux_images[arch] for arch in archs] + [
|
||||
build_options.musllinux_images[arch] for arch in archs
|
||||
]
|
||||
# exclude GraalPy as it's not a target for cibuildwheel
|
||||
command = (
|
||||
"manylinux-interpreters ensure $(manylinux-interpreters list 2>/dev/null | grep -v graalpy) &&"
|
||||
"manylinux-interpreters ensure-all &&"
|
||||
"cpython3.13 -m pip download -d /tmp setuptools wheel pytest"
|
||||
)
|
||||
for image in images:
|
||||
|
||||
@@ -41,9 +41,9 @@ def test_abi3(tmp_path):
|
||||
actual_wheels = utils.cibuildwheel_run(
|
||||
project_dir,
|
||||
add_env={
|
||||
# free_threaded and PyPy do not have a Py_LIMITED_API equivalent, just build one of those
|
||||
# free_threaded, GraalPy, and PyPy do not have a Py_LIMITED_API equivalent, just build one of those
|
||||
# also limit the number of builds for test performance reasons
|
||||
"CIBW_BUILD": f"cp39-* cp310-* pp310-* {single_python_tag}-* cp313t-*"
|
||||
"CIBW_BUILD": f"cp39-* cp310-* pp310-* gp242-* {single_python_tag}-* cp313t-*"
|
||||
},
|
||||
)
|
||||
|
||||
@@ -59,7 +59,11 @@ def test_abi3(tmp_path):
|
||||
expected_wheels = [
|
||||
w.replace("cp310-cp310", "cp310-abi3")
|
||||
for w in expected_wheels
|
||||
if "-cp39" in w or "-cp310" in w or "-pp310" in w or "-cp313t" in w
|
||||
if "-cp39" in w
|
||||
or "-cp310" in w
|
||||
or "-pp310" in w
|
||||
or "-graalpy242" in w
|
||||
or "-cp313t" in w
|
||||
]
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
|
||||
|
||||
@@ -38,8 +38,8 @@ def test(tmp_path):
|
||||
|
||||
# build the wheels
|
||||
before_all_command = (
|
||||
"""python -c "import os, sys;open('{project}/text_info.txt', 'w').write('sample text '+os.environ.get('TEST_VAL', ''))" && """
|
||||
'''python -c "import sys; open('{project}/python_prefix.txt', 'w').write(sys.prefix)"'''
|
||||
"""python -c "import os, pathlib, sys; pathlib.Path('{project}/text_info.txt').write_text('sample text '+os.environ.get('TEST_VAL', ''))" && """
|
||||
'''python -c "import pathlib, sys; pathlib.Path('{project}/python_prefix.txt').write_text(sys.prefix)"'''
|
||||
)
|
||||
actual_wheels = utils.cibuildwheel_run(
|
||||
project_dir,
|
||||
|
||||
@@ -41,8 +41,8 @@ def test(tmp_path):
|
||||
project_with_before_build_asserts.generate(project_dir)
|
||||
|
||||
before_build = (
|
||||
"""python -c "import sys; open('{project}/pythonversion_bb.txt', 'w').write(sys.version)" && """
|
||||
f'''python -c "import sys; open('{{project}}/pythonprefix_bb.txt', 'w').write({SYS_PREFIX})"'''
|
||||
"""python -c "import pathlib, sys; pathlib.Path('{project}/pythonversion_bb.txt').write_text(sys.version)" && """
|
||||
f'''python -c "import pathlib, sys; pathlib.Path('{{project}}/pythonprefix_bb.txt').write_text({SYS_PREFIX})"'''
|
||||
)
|
||||
frontend = "build"
|
||||
if utils.platform != "pyodide":
|
||||
|
||||
@@ -7,7 +7,7 @@ import os
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
|
||||
PROJECT_DIR = Path(__file__).joinpath("..", "..").resolve()
|
||||
PROJECT_DIR = Path(__file__).parent.parent.resolve()
|
||||
|
||||
|
||||
class TestBeforeTest(TestCase):
|
||||
@@ -39,8 +39,8 @@ def test(tmp_path, build_frontend_env):
|
||||
test_projects.new_c_project().generate(test_project_dir)
|
||||
|
||||
before_test_steps = [
|
||||
'''python -c "import os, sys; open('{project}/pythonversion_bt.txt', 'w').write(sys.version)"''',
|
||||
'''python -c "import os, sys; open('{project}/pythonprefix_bt.txt', 'w').write(sys.prefix)"''',
|
||||
'''python -c "import pathlib, sys; pathlib.Path('{project}/pythonversion_bt.txt').write_text(sys.version)"''',
|
||||
'''python -c "import pathlib, sys; pathlib.Path('{project}/pythonprefix_bt.txt').write_text(sys.prefix)"''',
|
||||
]
|
||||
|
||||
if utils.platform == "pyodide":
|
||||
@@ -63,7 +63,9 @@ def test(tmp_path, build_frontend_env):
|
||||
# the 'false ||' bit is to ensure this command runs in a shell on
|
||||
# mac/linux.
|
||||
"CIBW_TEST_COMMAND": f"false || {utils.invoke_pytest()} ./test",
|
||||
"CIBW_TEST_COMMAND_WINDOWS": "pytest ./test",
|
||||
# pytest fails on GraalPy 24.2.0 on Windows so we skip it there
|
||||
# until https://github.com/oracle/graalpython/issues/490 is fixed
|
||||
"CIBW_TEST_COMMAND_WINDOWS": "where graalpy || pytest ./test",
|
||||
**build_frontend_env,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -128,6 +128,17 @@ def test_dependency_constraints(method, tmp_path, build_frontend_env_nouv):
|
||||
|
||||
build_environment = {}
|
||||
|
||||
if (
|
||||
utils.platform == "windows"
|
||||
and method == "file"
|
||||
and build_frontend_env_nouv["CIBW_BUILD_FRONTEND"] == "build"
|
||||
):
|
||||
# GraalPy fails to discover its standard library when a venv is created
|
||||
# from a virtualenv seeded executable. See
|
||||
# https://github.com/oracle/graalpython/issues/491 and remove this once
|
||||
# fixed upstream.
|
||||
build_frontend_env_nouv["CIBW_SKIP"] = "gp*"
|
||||
|
||||
for package_name, version in tool_versions.items():
|
||||
env_name = f"EXPECTED_{package_name.upper()}_VERSION"
|
||||
build_environment[env_name] = version
|
||||
@@ -147,4 +158,13 @@ def test_dependency_constraints(method, tmp_path, build_frontend_env_nouv):
|
||||
# also check that we got the right wheels
|
||||
expected_wheels = utils.expected_wheels("spam", "0.1.0")
|
||||
|
||||
if (
|
||||
utils.platform == "windows"
|
||||
and method == "file"
|
||||
and build_frontend_env_nouv["CIBW_BUILD_FRONTEND"] == "build"
|
||||
):
|
||||
# See reference to https://github.com/oracle/graalpython/issues/491
|
||||
# above
|
||||
expected_wheels = [w for w in expected_wheels if "graalpy" not in w]
|
||||
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
|
||||
@@ -33,11 +33,26 @@ def test_pep518(tmp_path, build_frontend_env):
|
||||
project_dir = tmp_path / "project"
|
||||
basic_project.generate(project_dir)
|
||||
|
||||
# GraalPy fails to discover its standard library when a venv is created
|
||||
# from a virtualenv seeded executable. See
|
||||
# https://github.com/oracle/graalpython/issues/491 and remove this once
|
||||
# fixed upstream.
|
||||
if build_frontend_env["CIBW_BUILD_FRONTEND"] == "build" and utils.platform == "windows":
|
||||
build_frontend_env["CIBW_SKIP"] = "gp*"
|
||||
|
||||
# build the wheels
|
||||
actual_wheels = utils.cibuildwheel_run(project_dir, add_env=build_frontend_env)
|
||||
|
||||
# check that the expected wheels are produced
|
||||
expected_wheels = utils.expected_wheels("spam", "0.1.0")
|
||||
|
||||
# GraalPy fails to discover its standard library when a venv is created
|
||||
# from a virtualenv seeded executable. See
|
||||
# https://github.com/oracle/graalpython/issues/491 and remove this once
|
||||
# fixed upstream.
|
||||
if build_frontend_env["CIBW_BUILD_FRONTEND"] == "build" and utils.platform == "windows":
|
||||
expected_wheels = [w for w in expected_wheels if "graalpy" not in w]
|
||||
|
||||
assert set(actual_wheels) == set(expected_wheels)
|
||||
|
||||
# These checks ensure an extra file is not created when using custom
|
||||
|
||||
+15
-5
@@ -81,7 +81,9 @@ def test(tmp_path):
|
||||
# the 'false ||' bit is to ensure this command runs in a shell on
|
||||
# mac/linux.
|
||||
"CIBW_TEST_COMMAND": f"false || {utils.invoke_pytest()} ./test",
|
||||
"CIBW_TEST_COMMAND_WINDOWS": "COLOR 00 || pytest ./test",
|
||||
# pytest fails on GraalPy 24.2.0 on Windows so we skip it there
|
||||
# until https://github.com/oracle/graalpython/issues/490 is fixed
|
||||
"CIBW_TEST_COMMAND_WINDOWS": "COLOR 00 || where graalpy || pytest ./test",
|
||||
},
|
||||
)
|
||||
|
||||
@@ -102,7 +104,9 @@ def test_extras_require(tmp_path):
|
||||
# the 'false ||' bit is to ensure this command runs in a shell on
|
||||
# mac/linux.
|
||||
"CIBW_TEST_COMMAND": f"false || {utils.invoke_pytest()} ./test",
|
||||
"CIBW_TEST_COMMAND_WINDOWS": "COLOR 00 || pytest ./test",
|
||||
# pytest fails on GraalPy 24.2.0 on Windows so we skip it there
|
||||
# until https://github.com/oracle/graalpython/issues/490 is fixed
|
||||
"CIBW_TEST_COMMAND_WINDOWS": "COLOR 00 || where graalpy || pytest ./test",
|
||||
},
|
||||
single_python=True,
|
||||
)
|
||||
@@ -134,7 +138,9 @@ def test_dependency_groups(tmp_path):
|
||||
# the 'false ||' bit is to ensure this command runs in a shell on
|
||||
# mac/linux.
|
||||
"CIBW_TEST_COMMAND": f"false || {utils.invoke_pytest()} ./test",
|
||||
"CIBW_TEST_COMMAND_WINDOWS": "COLOR 00 || pytest ./test",
|
||||
# pytest fails on GraalPy 24.2.0 on Windows so we skip it there
|
||||
# until https://github.com/oracle/graalpython/issues/490 is fixed
|
||||
"CIBW_TEST_COMMAND_WINDOWS": "COLOR 00 || where graalpy || pytest ./test",
|
||||
},
|
||||
single_python=True,
|
||||
)
|
||||
@@ -189,7 +195,9 @@ def test_bare_pytest_invocation(tmp_path: Path, test_runner: str) -> None:
|
||||
add_env={
|
||||
"CIBW_TEST_REQUIRES": "pytest" if test_runner == "pytest" else "",
|
||||
"CIBW_TEST_COMMAND": (
|
||||
"python -m pytest"
|
||||
# pytest fails on GraalPy 24.2.0 on Windows so we skip it there
|
||||
# until https://github.com/oracle/graalpython/issues/490 fixed
|
||||
"graalpy.exe -c 1 || python -m pytest"
|
||||
if test_runner == "pytest"
|
||||
else "python -m unittest discover test spam_test.py"
|
||||
),
|
||||
@@ -211,7 +219,9 @@ def test_test_sources(tmp_path):
|
||||
add_env={
|
||||
"CIBW_TEST_REQUIRES": "pytest",
|
||||
"CIBW_TEST_COMMAND": "pytest",
|
||||
"CIBW_TEST_COMMAND_WINDOWS": "pytest",
|
||||
# pytest fails on GraalPy 24.2.0 on Windows so we skip it there
|
||||
# until https://github.com/oracle/graalpython/issues/490 is fixed
|
||||
"CIBW_TEST_COMMAND_WINDOWS": "where graalpy || pytest",
|
||||
"CIBW_TEST_SOURCES": "test",
|
||||
},
|
||||
)
|
||||
|
||||
+6
-2
@@ -55,7 +55,7 @@ def cibuildwheel_get_build_identifiers(
|
||||
cmd = [sys.executable, "-m", "cibuildwheel", "--print-build-identifiers", str(project_path)]
|
||||
if env is None:
|
||||
env = os.environ.copy()
|
||||
env["CIBW_ENABLE"] = "cpython-freethreading pypy"
|
||||
env["CIBW_ENABLE"] = "cpython-freethreading pypy graalpy"
|
||||
if prerelease_pythons:
|
||||
env["CIBW_ENABLE"] += " cpython-prerelease"
|
||||
|
||||
@@ -257,6 +257,10 @@ def _expected_wheels(
|
||||
"pp310-pypy310_pp73",
|
||||
"pp311-pypy311_pp73",
|
||||
]
|
||||
if machine_arch in ["x86_64", "AMD64", "aarch64", "arm64"]:
|
||||
python_abi_tags += [
|
||||
"graalpy311-graalpy242_311_native",
|
||||
]
|
||||
|
||||
if single_python:
|
||||
python_tag = "cp{}{}-".format(*SINGLE_PYTHON_VERSION)
|
||||
@@ -286,7 +290,7 @@ def _expected_wheels(
|
||||
for manylinux_version in manylinux_versions
|
||||
)
|
||||
]
|
||||
if len(musllinux_versions) > 0 and not python_abi_tag.startswith("pp"):
|
||||
if len(musllinux_versions) > 0 and not python_abi_tag.startswith(("pp", "graalpy")):
|
||||
platform_tags.append(
|
||||
".".join(
|
||||
f"{musllinux_version}_{machine_arch}"
|
||||
|
||||
Reference in New Issue
Block a user