Add a Python matrix to ensure the bindings build on all supported versions (#1871)

Also contains a run of `pre-commit autoupdate`, and a bump of cibuildwheel
to its latest tag for CPython 3.13 support.

But, since we build for 3.10+ with SABI from 3.12 onwards, we don't even
need a dedicated Python 3.13 build job or toolchain - the wheels from 3.12
can be reused.

Simplifies some version-dependent logic around assembling the bazel
build command in setup.py, and fixes a possible unbound local error in
the toolchain patch context manager.
This commit is contained in:
Nicholas Junge 2024-11-06 14:15:22 +01:00 committed by GitHub
parent d99cdd7356
commit a6af6eeb6a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 24 additions and 18 deletions

View File

@ -8,23 +8,23 @@ on:
jobs: jobs:
python_bindings: python_bindings:
name: Test GBM Python bindings on ${{ matrix.os }} name: Test GBM Python ${{ matrix.python-version }} bindings on ${{ matrix.os }}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ ubuntu-latest, macos-latest, windows-latest ] os: [ ubuntu-latest, macos-latest, windows-latest ]
python-version: [ "3.10", "3.11", "3.12", "3.13" ]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up Python 3.11 - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
python-version: 3.11 python-version: ${{ matrix.python-version }}
- name: Install GBM Python bindings on ${{ matrix.os }} - name: Install GBM Python bindings on ${{ matrix.os }}
run: python -m pip install . run: python -m pip install .
- name: Run bindings example on ${{ matrix.os }} - name: Run example on ${{ matrix.os }} under Python ${{ matrix.python-version }}
run: run: python bindings/python/google_benchmark/example.py
python bindings/python/google_benchmark/example.py

View File

@ -53,7 +53,7 @@ jobs:
platforms: all platforms: all
- name: Build wheels on ${{ matrix.os }} using cibuildwheel - name: Build wheels on ${{ matrix.os }} using cibuildwheel
uses: pypa/cibuildwheel@v2.20 uses: pypa/cibuildwheel@v2.21.3
env: env:
CIBW_BUILD: "cp310-* cp311-* cp312-*" CIBW_BUILD: "cp310-* cp311-* cp312-*"
CIBW_BUILD_FRONTEND: "build[uv]" CIBW_BUILD_FRONTEND: "build[uv]"

View File

@ -1,17 +1,17 @@
repos: repos:
- repo: https://github.com/keith/pre-commit-buildifier - repo: https://github.com/keith/pre-commit-buildifier
rev: 7.1.2 rev: 7.3.1
hooks: hooks:
- id: buildifier - id: buildifier
- id: buildifier-lint - id: buildifier-lint
- repo: https://github.com/pre-commit/mirrors-mypy - repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.1 rev: v1.13.0
hooks: hooks:
- id: mypy - id: mypy
types_or: [ python, pyi ] types_or: [ python, pyi ]
args: [ "--ignore-missing-imports", "--scripts-are-modules" ] args: [ "--ignore-missing-imports", "--scripts-are-modules" ]
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.1 rev: v0.7.2
hooks: hooks:
- id: ruff - id: ruff
args: [ --fix, --exit-non-zero-on-fix ] args: [ --fix, --exit-non-zero-on-fix ]

View File

@ -3,6 +3,7 @@ import os
import platform import platform
import re import re
import shutil import shutil
import sys
from pathlib import Path from pathlib import Path
from typing import Any, Generator from typing import Any, Generator
@ -15,8 +16,7 @@ IS_LINUX = platform.system() == "Linux"
# hardcoded SABI-related options. Requires that each Python interpreter # hardcoded SABI-related options. Requires that each Python interpreter
# (hermetic or not) participating is of the same major-minor version. # (hermetic or not) participating is of the same major-minor version.
version_tuple = tuple(int(i) for i in platform.python_version_tuple()) py_limited_api = sys.version_info >= (3, 12)
py_limited_api = version_tuple >= (3, 12)
options = {"bdist_wheel": {"py_limited_api": "cp312"}} if py_limited_api else {} options = {"bdist_wheel": {"py_limited_api": "cp312"}} if py_limited_api else {}
@ -43,10 +43,10 @@ def _maybe_patch_toolchains() -> Generator[None, None, None]:
return "python.toolchain(" + callargs + ")" return "python.toolchain(" + callargs + ")"
CIBW_LINUX = is_cibuildwheel() and IS_LINUX CIBW_LINUX = is_cibuildwheel() and IS_LINUX
module_bazel = Path("MODULE.bazel")
content: str = module_bazel.read_text()
try: try:
if CIBW_LINUX: if CIBW_LINUX:
module_bazel = Path("MODULE.bazel")
content: str = module_bazel.read_text()
module_bazel.write_text( module_bazel.write_text(
re.sub( re.sub(
r"python.toolchain\(([\w\"\s,.=]*)\)", r"python.toolchain\(([\w\"\s,.=]*)\)",
@ -92,10 +92,16 @@ class BuildBazelExtension(build_ext.build_ext):
def bazel_build(self, ext: BazelExtension) -> None: def bazel_build(self, ext: BazelExtension) -> None:
"""Runs the bazel build to create the package.""" """Runs the bazel build to create the package."""
temp_path = Path(self.build_temp) temp_path = Path(self.build_temp)
# omit the patch version to avoid build errors if the toolchain is not if py_limited_api:
# yet registered in the current @rules_python version. # We only need to know the minimum ABI version,
# patch version differences should be fine. # since it is stable across minor versions by definition.
python_version = ".".join(platform.python_version_tuple()[:2]) # The value here is calculated as the minimum of a) the minimum
# Python version required, and b) the stable ABI version target.
# NB: This needs to be kept in sync with [project.requires-python]
# in pyproject.toml.
python_version = "3.12"
else:
python_version = "{0}.{1}".format(*sys.version_info[:2])
bazel_argv = [ bazel_argv = [
"bazel", "bazel",