name: Python Wheels
on:
push:
tags: ["py-v*"]
pull_request:
paths:
- "bindings/python/**"
- "docs/guides/python.md"
- "docs/tutorials/**"
- "src/**"
- "Cargo.toml"
- "Cargo.lock"
- ".github/workflows/python.yml"
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
jobs:
build:
name: wheels-${{ matrix.platform.os }}-${{ matrix.platform.target }}
runs-on: ${{ matrix.platform.runner }}
strategy:
fail-fast: false
matrix:
platform:
- { os: linux, runner: ubuntu-latest, target: x86_64, features: --features gpu }
- { os: linux, runner: ubuntu-24.04-arm, target: aarch64, features: --features gpu }
- { os: macos, runner: macos-latest, target: aarch64, features: "" }
- { os: windows, runner: windows-latest, target: x64, features: --features gpu }
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: "3.12"
- uses: dtolnay/rust-toolchain@1.99.0
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
command: build
target: ${{ matrix.platform.target }}
args: --profile python-release --manifest-path bindings/python/Cargo.toml --out dist ${{ matrix.platform.features }}
manylinux: auto
- name: Smoke test and pytest
shell: bash
run: |
python -m pip install --upgrade pip
python -m pip install numpy pytest
python -m pip install --no-index --find-links dist prism-q
pytest bindings/python/tests -q
- name: Stub check
if: matrix.platform.os == 'linux' && matrix.platform.target == 'x86_64'
shell: bash
run: |
python -m pip install mypy==1.19.1
python -m mypy.stubtest prism_q._prism_q --allowlist bindings/python/stubtest-allowlist.txt
- uses: actions/upload-artifact@v7
with:
name: wheels-${{ matrix.platform.os }}-${{ matrix.platform.target }}
path: dist
wheel-compatibility:
name: Test wheel (Python ${{ matrix.python }})
needs: build
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python: ["3.11", "3.13", "3.14"]
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python }}
- uses: actions/download-artifact@v8
with:
name: wheels-linux-x86_64
path: dist
- name: Test the ABI3 wheel across Python versions
run: |
python -m pip install --upgrade pip
python -m pip install numpy pytest
python -m pip install --no-index --find-links dist prism-q
python -m pytest bindings/python/tests -q
sdist:
name: sdist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --manifest-path bindings/python/Cargo.toml --out dist
- uses: actions/upload-artifact@v7
with:
name: sdist
path: dist
sdist-validation:
name: Test source distribution
needs: sdist
runs-on: ubuntu-latest
steps:
- uses: actions/setup-python@v7
with:
python-version: "3.12"
- uses: dtolnay/rust-toolchain@1.99.0
- uses: actions/download-artifact@v8
with:
name: sdist
path: ${{ runner.temp }}/sdist
- name: Install and test outside the checkout
working-directory: ${{ runner.temp }}
run: |
python -m pip install --upgrade pip
python -m pip install "$RUNNER_TEMP"/sdist/*.tar.gz
python - <<'PY'
import numpy as np
import prism_q
circuit = prism_q.CircuitBuilder(2).h(0).cx(0, 1).build()
probabilities = prism_q.simulate(circuit).seed(42).run().probabilities
assert isinstance(probabilities, np.ndarray)
assert probabilities.dtype == np.float64
assert probabilities.shape == (4,)
np.testing.assert_allclose(probabilities, [0.5, 0.0, 0.0, 0.5], atol=1e-12)
state = prism_q.simulate(circuit).seed(42).state_vector()
assert isinstance(state, np.ndarray)
assert state.dtype == np.complex128
assert state.shape == (4,)
np.testing.assert_allclose(state, np.sqrt([0.5, 0.0, 0.0, 0.5]), atol=1e-12)
PY
publish:
name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags/py-v')
needs: [build, wheel-compatibility, sdist-validation]
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v8
with:
path: dist
merge-multiple: true
- name: Publish
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist