Skip to content

Commit 0ebd476

Browse files
committed
Enhance build workflow to validate interpreter and wheel mode compatibility; update README for clarity on free-threaded builds and limited API usage
1 parent c03f56d commit 0ebd476

File tree

3 files changed

+114
-8
lines changed

3 files changed

+114
-8
lines changed

.github/workflows/build.yml

Lines changed: 110 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,45 @@ jobs:
143143
with:
144144
enable-cache: true
145145

146+
- name: Validate interpreter/wheel mode
147+
shell: bash
148+
env:
149+
WHEEL_MODE: ${{ endsWith(matrix.python-version, 't') && 'freethreaded' || 'abi3' }}
150+
MATURIN_FEATURES: ${{ endsWith(matrix.python-version, 't') && 'substrait' || 'substrait,py-limited-api' }}
151+
run: |
152+
python - <<'PY'
153+
import os
154+
import sys
155+
import sysconfig
156+
157+
mode = os.environ["WHEEL_MODE"]
158+
features = os.environ["MATURIN_FEATURES"]
159+
is_free_threaded = bool(sysconfig.get_config_var("Py_GIL_DISABLED"))
160+
161+
print(sys.version)
162+
print(f"Py_GIL_DISABLED={int(is_free_threaded)}")
163+
print(f"wheel_mode={mode}")
164+
print(f"maturin_features={features}")
165+
166+
if mode == "abi3" and is_free_threaded:
167+
raise SystemExit("Invalid matrix: free-threaded interpreter cannot build abi3 wheels")
168+
if mode == "freethreaded" and not is_free_threaded:
169+
raise SystemExit("Invalid matrix: freethreaded wheel mode requires a free-threaded interpreter")
170+
PY
171+
172+
- name: Show resolved PyO3 versions
173+
shell: bash
174+
run: |
175+
cargo tree -e no-dev -i pyo3
176+
cargo tree -e no-dev -i pyo3-build-config
177+
146178
- name: Build Python package
179+
shell: bash
180+
env:
181+
MATURIN_FEATURES: ${{ endsWith(matrix.python-version, 't') && 'substrait' || 'substrait,py-limited-api' }}
147182
run: |
148183
uv sync --dev --no-install-package datafusion
149-
uv run --no-project maturin build --release --strip --features substrait --interpreter python
184+
uv run --no-project maturin build --release --strip --features "${MATURIN_FEATURES}" --interpreter python
150185
151186
- name: List Windows wheels
152187
if: matrix.os == 'windows-latest'
@@ -213,10 +248,45 @@ jobs:
213248
with:
214249
enable-cache: true
215250

251+
- name: Validate interpreter/wheel mode
252+
shell: bash
253+
env:
254+
WHEEL_MODE: ${{ endsWith(matrix.python-version, 't') && 'freethreaded' || 'abi3' }}
255+
MATURIN_FEATURES: ${{ endsWith(matrix.python-version, 't') && 'substrait' || 'substrait,py-limited-api' }}
256+
run: |
257+
python - <<'PY'
258+
import os
259+
import sys
260+
import sysconfig
261+
262+
mode = os.environ["WHEEL_MODE"]
263+
features = os.environ["MATURIN_FEATURES"]
264+
is_free_threaded = bool(sysconfig.get_config_var("Py_GIL_DISABLED"))
265+
266+
print(sys.version)
267+
print(f"Py_GIL_DISABLED={int(is_free_threaded)}")
268+
print(f"wheel_mode={mode}")
269+
print(f"maturin_features={features}")
270+
271+
if mode == "abi3" and is_free_threaded:
272+
raise SystemExit("Invalid matrix: free-threaded interpreter cannot build abi3 wheels")
273+
if mode == "freethreaded" and not is_free_threaded:
274+
raise SystemExit("Invalid matrix: freethreaded wheel mode requires a free-threaded interpreter")
275+
PY
276+
277+
- name: Show resolved PyO3 versions
278+
shell: bash
279+
run: |
280+
cargo tree -e no-dev -i pyo3
281+
cargo tree -e no-dev -i pyo3-build-config
282+
216283
- name: Build Python package
284+
shell: bash
285+
env:
286+
MATURIN_FEATURES: ${{ endsWith(matrix.python-version, 't') && 'substrait' || 'substrait,py-limited-api' }}
217287
run: |
218288
uv sync --dev --no-install-package datafusion
219-
uv run --no-project maturin build --release --strip --features substrait --interpreter python
289+
uv run --no-project maturin build --release --strip --features "${MATURIN_FEATURES}" --interpreter python
220290
221291
- name: List Mac wheels
222292
run: find target/wheels/
@@ -237,8 +307,12 @@ jobs:
237307
include:
238308
- interpreter: "3.10 3.11 3.12 3.13 3.14"
239309
artifact-label: cp310-314
310+
wheel-mode: abi3
311+
maturin-features: protoc,substrait,py-limited-api
240312
- interpreter: "3.13t 3.14t"
241313
artifact-label: cp313t-314t
314+
wheel-mode: freethreaded
315+
maturin-features: protoc,substrait
242316
steps:
243317
- uses: actions/checkout@v5
244318
- run: rm LICENSE.txt
@@ -248,6 +322,20 @@ jobs:
248322
name: python-wheel-license
249323
path: .
250324
- run: cat LICENSE.txt
325+
- name: Validate wheel mode matrix
326+
shell: bash
327+
run: |
328+
echo "interpreter=${{ matrix.interpreter }}"
329+
echo "wheel_mode=${{ matrix.wheel-mode }}"
330+
echo "maturin_features=${{ matrix.maturin-features }}"
331+
if [[ "${{ matrix.wheel-mode }}" == "abi3" && "${{ matrix.interpreter }}" == *t* ]]; then
332+
echo "Invalid matrix: abi3 mode cannot use free-threaded interpreters"
333+
exit 1
334+
fi
335+
if [[ "${{ matrix.wheel-mode }}" == "freethreaded" && "${{ matrix.interpreter }}" != *t* ]]; then
336+
echo "Invalid matrix: freethreaded mode requires free-threaded interpreters"
337+
exit 1
338+
fi
251339
- name: Build wheels
252340
uses: PyO3/maturin-action@v1
253341
env:
@@ -258,7 +346,7 @@ jobs:
258346
manylinux: auto
259347
rustup-components: rust-std rustfmt # Keep them in one line due to https://github.com/PyO3/maturin-action/issues/153
260348
interpreter: ${{ matrix.interpreter }}
261-
args: --release --manylinux 2014 --features protoc,substrait
349+
args: --release --manylinux 2014 --features ${{ matrix.maturin-features }}
262350
- name: Archive wheels
263351
uses: actions/upload-artifact@v4
264352
with:
@@ -275,8 +363,12 @@ jobs:
275363
include:
276364
- interpreter: "3.10 3.11 3.12 3.13 3.14"
277365
artifact-label: cp310-314
366+
wheel-mode: abi3
367+
maturin-features: protoc,substrait,py-limited-api
278368
- interpreter: "3.13t 3.14t"
279369
artifact-label: cp313t-314t
370+
wheel-mode: freethreaded
371+
maturin-features: protoc,substrait
280372
steps:
281373
- uses: actions/checkout@v5
282374
- run: rm LICENSE.txt
@@ -286,6 +378,20 @@ jobs:
286378
name: python-wheel-license
287379
path: .
288380
- run: cat LICENSE.txt
381+
- name: Validate wheel mode matrix
382+
shell: bash
383+
run: |
384+
echo "interpreter=${{ matrix.interpreter }}"
385+
echo "wheel_mode=${{ matrix.wheel-mode }}"
386+
echo "maturin_features=${{ matrix.maturin-features }}"
387+
if [[ "${{ matrix.wheel-mode }}" == "abi3" && "${{ matrix.interpreter }}" == *t* ]]; then
388+
echo "Invalid matrix: abi3 mode cannot use free-threaded interpreters"
389+
exit 1
390+
fi
391+
if [[ "${{ matrix.wheel-mode }}" == "freethreaded" && "${{ matrix.interpreter }}" != *t* ]]; then
392+
echo "Invalid matrix: freethreaded mode requires free-threaded interpreters"
393+
exit 1
394+
fi
289395
- name: Build wheels
290396
uses: PyO3/maturin-action@v1
291397
env:
@@ -297,7 +403,7 @@ jobs:
297403
manylinux: 2_28
298404
rustup-components: rust-std rustfmt # Keep them in one line due to https://github.com/PyO3/maturin-action/issues/153
299405
interpreter: ${{ matrix.interpreter }}
300-
args: --release --features protoc,substrait
406+
args: --release --features ${{ matrix.maturin-features }}
301407
- name: Archive wheels
302408
uses: actions/upload-artifact@v4
303409
with:

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ include = [
4040
default = ["mimalloc"]
4141
protoc = ["datafusion-substrait/protoc"]
4242
substrait = ["dep:datafusion-substrait"]
43+
py-limited-api = ["pyo3/abi3-py310"]
4344

4445
[dependencies]
4546
tokio = { version = "1.47", features = [
@@ -50,7 +51,6 @@ tokio = { version = "1.47", features = [
5051
] }
5152
pyo3 = { version = "0.26", features = [
5253
"extension-module",
53-
"abi3-py310",
5454
] }
5555
pyo3-async-runtimes = { version = "0.26", features = ["tokio-runtime"] }
5656
pyo3-log = "0.13.2"

dev/release/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,9 @@ datafusion-22.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
130130
datafusion-22.0.0-cp37-abi3-win_amd64.whl
131131
```
132132

133-
Note: PyO3's free-threaded CPython builds (3.13t/3.14t) use a distinct ABI and ignore the `abi3` setting. We keep
134-
the `abi3-py310` feature enabled to preserve the stable-ABI wheels for GIL-enabled Python, and we additionally ship
135-
version-specific `cp313t`/`cp314t` wheels for the free-threaded builds.
133+
Note: PyO3's free-threaded CPython builds (3.13t/3.14t) use a distinct ABI and cannot use the limited API (`abi3`).
134+
The release workflow enables Cargo feature `py-limited-api` for GIL-enabled wheels and disables it for free-threaded
135+
builds, producing version-specific `cp313t`/`cp314t` wheels.
136136

137137
Upload the wheels to testpypi.
138138

0 commit comments

Comments
 (0)