From 4e30420ff2a6a12d7a50009da1219a79cd0e3e9f Mon Sep 17 00:00:00 2001 From: Jeremy Howard Date: Sun, 23 Aug 2026 14:33:05 +1000 Subject: [PATCH] Support complete sdist and Python 3.14 installs --- .github/workflows/ci.yml | 10 +++++++++- DEV.md | 3 +++ build_backend.py | 22 ++++++++++++++++++++++ pyproject.toml | 3 ++- tests/test_install.py | 8 ++++---- 5 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 build_backend.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a34370..6c1fdf8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: python tools/stage_binaries.py - uses: PyO3/maturin-action@v1 with: - args: --release --out dist -i python3.10 -i python3.11 -i python3.12 -i python3.13 + args: --release --out dist -i python3.10 -i python3.11 -i python3.12 -i python3.13 -i python3.14 manylinux: auto before-script-linux: cargo build --release --bins && python3.10 tools/stage_binaries.py - uses: actions/upload-artifact@v7 @@ -53,11 +53,19 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 + - uses: dtolnay/rust-toolchain@stable + - uses: actions/setup-python@v7 + with: + python-version: '3.14' - run: mkdir -p target/wheel-data - uses: PyO3/maturin-action@v1 with: command: sdist args: -o dist + - run: | + python -m venv /tmp/fastbz2-sdist-test + /tmp/fastbz2-sdist-test/bin/pip install pytest dist/*.tar.gz + /tmp/fastbz2-sdist-test/bin/pytest tests/test_install.py - uses: actions/upload-artifact@v7 with: name: wheels-sdist diff --git a/DEV.md b/DEV.md index 9c80e8a..ca7eb40 100644 --- a/DEV.md +++ b/DEV.md @@ -16,6 +16,7 @@ src/indexed.rs seekable decoded view and block cache src/lib.rs public Rust API and private PyO3 binding src/source.rs owned and memory-mapped compressed sources python/fastbz2/ thin Python I/O wrapper over fastbz2._core +build_backend.py stage the native CLI for PEP 517 wheel builds tests/corpus/ selected upstream conformance and corruption fixtures tests/ Rust CLI/corpus and Python API integration tests tools/stage_binaries.py copy the release executable into Maturin wheel data @@ -76,6 +77,8 @@ CI tests and builds Linux on x86-64 and ARM64, and macOS on ARM64. macOS Intel r The canonical version lives in `Cargo.toml`. `pyproject.toml` gets the Python package version from Cargo via `dynamic = ["version"]`. +The thin PEP 517 backend delegates to Maturin after building and staging the native executable. This makes wheels built from the sdist contain the same native CLI as CI-built wheels. Release CI verifies that path from a fresh Python 3.14 environment before publishing. + ## Release 1. Run `cargo build --release --bins && python tools/stage_binaries.py`. diff --git a/build_backend.py b/build_backend.py new file mode 100644 index 0000000..f14d9ec --- /dev/null +++ b/build_backend.py @@ -0,0 +1,22 @@ +import subprocess, sys + +import maturin + +def _stage_cli(): + subprocess.run(["cargo", "build", "--release", "--bin", "fastbz2"], check=True) + subprocess.run([sys.executable, "tools/stage_binaries.py"], check=True) + +def build_wheel(wheel_directory, config_settings=None, metadata_directory=None): + _stage_cli() + return maturin.build_wheel(wheel_directory, config_settings, metadata_directory) + +def build_editable(wheel_directory, config_settings=None, metadata_directory=None): + _stage_cli() + return maturin.build_editable(wheel_directory, config_settings, metadata_directory) + +build_sdist = maturin.build_sdist +get_requires_for_build_wheel = maturin.get_requires_for_build_wheel +get_requires_for_build_editable = maturin.get_requires_for_build_editable +get_requires_for_build_sdist = maturin.get_requires_for_build_sdist +prepare_metadata_for_build_wheel = maturin.prepare_metadata_for_build_wheel +prepare_metadata_for_build_editable = maturin.prepare_metadata_for_build_editable diff --git a/pyproject.toml b/pyproject.toml index a04f392..49f464b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,7 @@ [build-system] requires = ["maturin>=1.0,<2.0"] -build-backend = "maturin" +build-backend = "build_backend" +backend-path = ["."] [project] name = "fastbz2" diff --git a/tests/test_install.py b/tests/test_install.py index 9f753d0..0484b63 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -1,11 +1,11 @@ -import shutil, subprocess +import os, subprocess, sysconfig from pathlib import Path import fastbz2 def test_pip_installs_native_cli(): - executable = shutil.which("fastbz2") - assert executable is not None - assert not Path(executable).read_bytes().startswith(b"#!") + executable = Path(sysconfig.get_path("scripts")) / ("fastbz2.exe" if os.name == "nt" else "fastbz2") + assert executable.exists() + assert not executable.read_bytes().startswith(b"#!") result = subprocess.run([executable, "--version"], check=True, capture_output=True, text=True) assert result.stdout.strip() == f"fastbz2 {fastbz2.__version__}"