@@ -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 :
0 commit comments