diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index dfc5862..0f4eb19 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -10,8 +10,11 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - python-version: ["3.12"] + python-version: ["3.12", "3.13", "3.14"] os: [ubuntu-latest, windows-latest, macos-latest] + exclude: + - os: windows-latest + python-version: "3.14" steps: - name: Checkout code @@ -38,7 +41,7 @@ jobs: cache: 'pip' # Enable caching for pip dependencies - name: Install dependencies - run: pip install -e ".[stim,dev]" + run: pip install -e ".[stim]" --group dev - name: Run tests run: pytest # Or your preferred testing command diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0fa1aca --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,173 @@ +# This file is autogenerated by maturin v1.12.4 +# To update, run +# +# maturin generate-ci github +# +name: Release Python Package + +env: + DEFAULT_PYTHON_VERSIONS: "3.8 3.9 3.10 3.11 3.12 3.13 3.14" + +on: + push: + tags: + - '*' + workflow_dispatch: + +permissions: + contents: read + +jobs: + linux: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: ubuntu-22.04 + target: x86_64 + - runner: ubuntu-22.04 + target: aarch64 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: 3.x + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --interpreter ${{ matrix.platform.interpreter || env.DEFAULT_PYTHON_VERSIONS }} + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + manylinux: auto + - name: Upload wheels + uses: actions/upload-artifact@v5 + with: + name: wheels-linux-${{ matrix.platform.target }} + path: dist + + musllinux: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: ubuntu-22.04 + target: x86_64 + - runner: ubuntu-22.04 + target: aarch64 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: 3.x + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --interpreter ${{ matrix.platform.interpreter || env.DEFAULT_PYTHON_VERSIONS}} + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + manylinux: musllinux_1_2 + - name: Upload wheels + uses: actions/upload-artifact@v5 + with: + name: wheels-musllinux-${{ matrix.platform.target }} + path: dist + + windows: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: windows-latest + target: x64 + python_arch: x64 + interpreter: "3.11 3.12 3.13 3.14" + - runner: windows-11-arm + target: aarch64 + python_arch: arm64 + interpreter: "3.12 3.13 3.14" + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: 3.13 + architecture: ${{ matrix.platform.python_arch }} + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --interpreter ${{ matrix.platform.interpreter || env.DEFAULT_PYTHON_VERSIONS}} + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + - name: Upload wheels + uses: actions/upload-artifact@v5 + with: + name: wheels-windows-${{ matrix.platform.target }} + path: dist + + macos: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: macos-15-intel + target: x86_64 + - runner: macos-latest + target: aarch64 + interpreter: "3.10 3.11 3.12 3.13 3.14" + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: 3.x + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --interpreter ${{ matrix.platform.interpreter || env.DEFAULT_PYTHON_VERSIONS}} + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + - name: Upload wheels + uses: actions/upload-artifact@v5 + with: + name: wheels-macos-${{ matrix.platform.target }} + path: dist + + sdist: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - name: Build sdist + uses: PyO3/maturin-action@v1 + with: + command: sdist + args: --out dist + - name: Upload sdist + uses: actions/upload-artifact@v5 + with: + name: wheels-sdist + path: dist + + # release: + # name: Release + # runs-on: ubuntu-latest + # if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }} + # needs: [linux, musllinux, windows, macos, sdist] + # permissions: + # # Use to sign the release artifacts + # id-token: write + # # Used to upload release artifacts + # contents: write + # # Used to generate artifact attestation + # attestations: write + # steps: + # - uses: actions/download-artifact@v6 + # - name: Generate artifact attestation + # uses: actions/attest-build-provenance@v3 + # with: + # subject-path: 'wheels-*/*' + # - name: Install uv + # if: ${{ startsWith(github.ref, 'refs/tags/') }} + # uses: astral-sh/setup-uv@v7 + # - name: Publish to PyPI + # if: ${{ startsWith(github.ref, 'refs/tags/') }} + # run: uv publish 'wheels-*/*' + # env: + # UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }} diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 5b3fee1..ffa8c5c 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -41,7 +41,7 @@ jobs: cache: 'pip' # cache pip downloads - name: Install Python deps (dev) - run: pip install -U pip && pip install -e ".[dev]" + run: pip install -U pip && pip install -e . --group dev - name: Install pre-commit (if not in dev extras) run: pip install pre-commit diff --git a/Cargo.lock b/Cargo.lock index df91e85..5cad04c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -482,12 +482,6 @@ dependencies = [ "web-time", ] -[[package]] -name = "indoc" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" - [[package]] name = "is-terminal" version = "0.4.16" @@ -573,15 +567,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - [[package]] name = "miniz_oxide" version = "0.8.8" @@ -688,9 +673,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "numpy" -version = "0.23.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94caae805f998a07d33af06e6a3891e38556051b8045c615470a71590e13e78" +checksum = "778da78c64ddc928ebf5ad9df5edf0789410ff3bdbf3619aed51cd789a6af1e2" dependencies = [ "libc", "ndarray", @@ -698,6 +683,7 @@ dependencies = [ "num-integer", "num-traits", "pyo3", + "pyo3-build-config", "rustc-hash", ] @@ -840,37 +826,32 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.23.5" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7778bffd85cf38175ac1f545509665d0b9b92a198ca7941f131f85f7a4f9a872" +checksum = "cf85e27e86080aafd5a22eae58a162e133a589551542b3e5cee4beb27e54f8e1" dependencies = [ - "cfg-if", - "indoc", "libc", - "memoffset", "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", "pyo3-macros", - "unindent", ] [[package]] name = "pyo3-build-config" -version = "0.23.5" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f6cbe86ef3bf18998d9df6e0f3fc1050a8c5efa409bf712e661a4366e010fb" +checksum = "8bf94ee265674bf76c09fa430b0e99c26e319c945d96ca0d5a8215f31bf81cf7" dependencies = [ - "once_cell", "target-lexicon", ] [[package]] name = "pyo3-ffi" -version = "0.23.5" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f1b4c431c0bb1c8fb0a338709859eed0d030ff6daa34368d3b152a63dfdd8d" +checksum = "491aa5fc66d8059dd44a75f4580a2962c1862a1c2945359db36f6c2818b748dc" dependencies = [ "libc", "pyo3-build-config", @@ -878,9 +859,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.23.5" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc2201328f63c4710f68abdf653c89d8dbc2858b88c5d88b0ff38a75288a9da" +checksum = "f5d671734e9d7a43449f8480f8b38115df67bef8d21f76837fa75ee7aaa5e52e" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -890,9 +871,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.23.5" +version = "0.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fca6726ad0f3da9c9de093d6f116a93c1a38e417ed73bf138472cf4064f72028" +checksum = "22faaa1ce6c430a1f71658760497291065e6450d7b5dc2bcf254d49f66ee700a" dependencies = [ "heck", "proc-macro2", @@ -1137,9 +1118,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.16" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca" [[package]] name = "thiserror" @@ -1195,12 +1176,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" -[[package]] -name = "unindent" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3" - [[package]] name = "utf8parse" version = "0.2.2" diff --git a/Cargo.toml b/Cargo.toml index 8ec528b..e7ad17b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,9 +13,9 @@ readme = "./README.md" [workspace.dependencies] ndarray = {version = ">= 0.15, < 0.17", features = ["serde"]} ndarray-npy = "0.9.1" -numpy = "0.23" +numpy = "0.28" serde = {version = ">=1.0", features = ["derive"]} -pyo3 = "^0.23.5" +pyo3 = "~0.28" rayon = "1.10.0" sprs = {version = ">= 0.11"} indicatif = {version = ">=0.17", features = ["rayon"]} diff --git a/crates/relay_bp_py/src/decoder.rs b/crates/relay_bp_py/src/decoder.rs index 6e8a0c1..a442078 100644 --- a/crates/relay_bp_py/src/decoder.rs +++ b/crates/relay_bp_py/src/decoder.rs @@ -24,7 +24,7 @@ pub fn get_sprs_bit_matrix_from_python( ) -> PyResult { let matrix = matrix.call_method1("astype", ("uint8",))?; - if let Ok(dense) = matrix.downcast::>() { + if let Ok(dense) = matrix.cast::>() { let dense = dense.to_owned_array(); Ok(SparseBitMatrix::from_dense(dense)) } else { @@ -70,7 +70,7 @@ pub fn get_sprs_bit_matrix_from_python( } } -#[pyclass(subclass, module = "decoder")] +#[pyclass(from_py_object, subclass, module = "decoder")] #[derive(Clone)] pub struct DynDecoder(pub Box); diff --git a/pyproject.toml b/pyproject.toml index 3927d31..af088c2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", "Programming Language :: Rust", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", @@ -54,6 +55,13 @@ dependencies = [ ] [project.optional-dependencies] +stim = [ + "stim>=1.15", + "beliefmatching", + "numpy<2.3" # Resolves type issue in sinter, see https://github.com/quantumlib/Stim/issues/1000. +] + +[dependency-groups] dev = [ "matplotlib", "nevergrad", @@ -63,11 +71,7 @@ dev = [ "pre-commit-hooks", "black", "tomlcheck", - "pytest", -] -stim = [ - "stim>=1.15", - "beliefmatching" + "maturin", ] [tool.maturin]