diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73ab37e1..1b717f3f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,13 +45,18 @@ jobs: pixi run -e lint pyright checks: - name: Check ${{ matrix.environment }} + name: Test ${{ matrix.environment }} runs-on: ${{ matrix.runs-on }} needs: [pre-commit-and-lint] strategy: fail-fast: false matrix: - environment: [tests-py310, tests-py313, tests-numpy1, tests-backends] + environment: + - tests-py310 + - tests-py313 + - tests-numpy1 + - tests-backends + - tests-nogil runs-on: [ubuntu-latest] steps: @@ -66,9 +71,16 @@ jobs: environments: ${{ matrix.environment }} - name: Test package + # Save some time; also at the moment of writing coverage crashes on python 3.13t + if: ${{ matrix.environment != 'tests-nogil' }} run: pixi run -e ${{ matrix.environment }} tests-ci + - name: Test free-threading + if: ${{ matrix.environment == 'tests-nogil' }} + run: pixi run -e tests-nogil tests --parallel-threads=4 + - name: Upload coverage report + if: ${{ matrix.environment != 'tests-nogil' }} uses: codecov/codecov-action@ad3126e916f78f00edff4ed0317cf185271ccc2d # v5.4.2 with: token: ${{ secrets.CODECOV_TOKEN }} diff --git a/pixi.lock b/pixi.lock index 03cc1128..49aba377 100644 --- a/pixi.lock +++ b/pixi.lock @@ -1542,7 +1542,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/myst-parser-4.0.1-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.3.0-py313h17eae1a_0.conda - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda @@ -1629,7 +1629,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/myst-parser-4.0.1-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - - conda: https://prefix.dev/conda-forge/osx-64/numpy-2.2.6-py313hc518a0f_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/numpy-2.3.0-py313hc518a0f_0.conda - conda: https://prefix.dev/conda-forge/osx-64/openssl-3.5.0-hc426f3f_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda @@ -1716,7 +1716,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/noarch/myst-parser-4.0.1-pyhd8ed1ab_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.6-py313h41a2e72_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.3.0-py313h41a2e72_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.0-h81ee809_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda @@ -1803,7 +1803,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda - conda: https://prefix.dev/conda-forge/noarch/myst-parser-4.0.1-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.6-py313hefb8edb_0.conda + - conda: https://prefix.dev/conda-forge/win-64/numpy-2.3.0-py313hefb8edb_0.conda - conda: https://prefix.dev/conda-forge/win-64/openssl-3.5.0-ha4e3fda_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda @@ -1921,7 +1921,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/linux-64/nodejs-22.13.0-hf235a45_0.conda - conda: https://prefix.dev/conda-forge/noarch/nodejs-wheel-22.16.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.3.0-py313h17eae1a_0.conda - conda: https://prefix.dev/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda @@ -2030,7 +2030,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/osx-64/nodejs-22.13.0-hffbc63d_0.conda - conda: https://prefix.dev/conda-forge/noarch/nodejs-wheel-22.16.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/osx-64/numpy-2.2.6-py313hc518a0f_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/numpy-2.3.0-py313hc518a0f_0.conda - conda: https://prefix.dev/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/osx-64/openssl-3.5.0-hc426f3f_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda @@ -2139,7 +2139,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/nodejs-22.13.0-h02a13b7_0.conda - conda: https://prefix.dev/conda-forge/noarch/nodejs-wheel-22.16.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.6-py313h41a2e72_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.3.0-py313h41a2e72_0.conda - conda: https://prefix.dev/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.0-h81ee809_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda @@ -2246,7 +2246,7 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/nodeenv-1.9.1-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/win-64/nodejs-22.13.0-hfeaa22a_0.conda - conda: https://prefix.dev/conda-forge/noarch/nodejs-wheel-22.16.0-pyhd8ed1ab_0.conda - - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.6-py313hefb8edb_0.conda + - conda: https://prefix.dev/conda-forge/win-64/numpy-2.3.0-py313hefb8edb_0.conda - conda: https://prefix.dev/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda - conda: https://prefix.dev/conda-forge/win-64/openssl-3.5.0-ha4e3fda_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda @@ -2337,7 +2337,7 @@ environments: - conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.3.0-py313h17eae1a_0.conda - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda @@ -2382,7 +2382,7 @@ environments: - conda: https://prefix.dev/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - conda: https://prefix.dev/conda-forge/osx-64/llvm-openmp-20.1.6-ha54dae1_0.conda - conda: https://prefix.dev/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - - conda: https://prefix.dev/conda-forge/osx-64/numpy-2.2.6-py313hc518a0f_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/numpy-2.3.0-py313hc518a0f_0.conda - conda: https://prefix.dev/conda-forge/osx-64/openssl-3.5.0-hc426f3f_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda @@ -2427,7 +2427,7 @@ environments: - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-20.1.6-hdb05f8b_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.6-py313h41a2e72_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.3.0-py313h41a2e72_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.0-h81ee809_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda @@ -2472,7 +2472,7 @@ environments: - conda: https://prefix.dev/conda-forge/win-64/libxml2-2.13.8-h442d1da_0.conda - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda - - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.6-py313hefb8edb_0.conda + - conda: https://prefix.dev/conda-forge/win-64/numpy-2.3.0-py313hefb8edb_0.conda - conda: https://prefix.dev/conda-forge/win-64/openssl-3.5.0-ha4e3fda_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda @@ -3291,6 +3291,254 @@ environments: - conda: https://prefix.dev/conda-forge/win-64/yaml-0.2.5-h8ffe710_2.tar.bz2 - conda: https://prefix.dev/conda-forge/noarch/zipp-3.22.0-pyhd8ed1ab_0.conda - pypi: ./ + tests-nogil: + channels: + - url: https://prefix.dev/conda-forge/ + indexes: + - https://pypi.org/simple + packages: + linux-64: + - conda: https://prefix.dev/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 + - conda: https://prefix.dev/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 + - conda: https://prefix.dev/conda-forge/noarch/array-api-compat-1.12.0-pyhe01879c_0.conda + - conda: https://prefix.dev/conda-forge/noarch/array-api-strict-2.3.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/attrs-25.3.0-pyh71513ae_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb_0.conda + - conda: https://prefix.dev/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cloudpickle-3.1.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/coverage-7.8.2-pyhe1237c8_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cpython-3.13.3-py313hd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/dask-core-2025.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/fsspec-2025.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.135.4-pyha770c72_0.conda + - conda: https://prefix.dev/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda + - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda + - conda: https://prefix.dev/conda-forge/linux-64/libblas-3.9.0-31_h59b9bed_openblas.conda + - conda: https://prefix.dev/conda-forge/linux-64/libcblas-3.9.0-31_he106b2a_openblas.conda + - conda: https://prefix.dev/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.1.0-h767d61c_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/liblapack-3.9.0-31_h7ac8fdf_openblas.conda + - conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libopenblas-0.3.29-pthreads_h94d23a6_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.50.1-hee588c1_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda + - conda: https://prefix.dev/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.3.0-py313h103f029_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda + - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda + - conda: https://prefix.dev/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-8.4.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-run-parallel-0.4.3-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.3-h4724d56_1_cp313t.conda + - conda: https://prefix.dev/conda-forge/noarch/python-freethreading-3.13.3-h92d6c8b_1.conda + - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.13-7_cp313t.conda + - conda: https://prefix.dev/conda-forge/noarch/pyyaml-6.0.2-pyhe1237c8_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda + - conda: https://prefix.dev/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda + - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda + - conda: https://prefix.dev/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/toolz-1.0.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.14.0-pyhe01879c_0.conda + - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 + - conda: https://prefix.dev/conda-forge/noarch/zipp-3.23.0-pyhd8ed1ab_0.conda + - pypi: ./ + osx-64: + - conda: https://prefix.dev/conda-forge/noarch/array-api-compat-1.12.0-pyhe01879c_0.conda + - conda: https://prefix.dev/conda-forge/noarch/array-api-strict-2.3.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/attrs-25.3.0-pyh71513ae_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb_0.conda + - conda: https://prefix.dev/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cloudpickle-3.1.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/coverage-7.8.2-pyhe1237c8_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cpython-3.13.3-py313hd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/dask-core-2025.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/fsspec-2025.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.135.4-pyha770c72_0.conda + - conda: https://prefix.dev/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda + - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/osx-64/libblas-3.9.0-31_h7f60823_openblas.conda + - conda: https://prefix.dev/conda-forge/osx-64/libcblas-3.9.0-31_hff6cab4_openblas.conda + - conda: https://prefix.dev/conda-forge/osx-64/libcxx-20.1.6-hf95d169_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libexpat-2.7.0-h240833e_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libffi-3.4.6-h281671d_1.conda + - conda: https://prefix.dev/conda-forge/osx-64/libgfortran-14.2.0-hef36b68_105.conda + - conda: https://prefix.dev/conda-forge/osx-64/libgfortran5-14.2.0-h58528f3_105.conda + - conda: https://prefix.dev/conda-forge/osx-64/liblapack-3.9.0-31_h236ab99_openblas.conda + - conda: https://prefix.dev/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda + - conda: https://prefix.dev/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libopenblas-0.3.29-openmp_hbf64a52_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libsqlite-3.50.1-hdb6dae5_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda + - conda: https://prefix.dev/conda-forge/osx-64/llvm-openmp-20.1.6-ha54dae1_0.conda + - conda: https://prefix.dev/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://prefix.dev/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda + - conda: https://prefix.dev/conda-forge/osx-64/numpy-2.3.0-py313h6699f8c_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/openssl-3.5.0-hc426f3f_1.conda + - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda + - conda: https://prefix.dev/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-8.4.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-run-parallel-0.4.3-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/python-3.13.3-h2267d90_1_cp313t.conda + - conda: https://prefix.dev/conda-forge/noarch/python-freethreading-3.13.3-h92d6c8b_1.conda + - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.13-7_cp313t.conda + - conda: https://prefix.dev/conda-forge/noarch/pyyaml-6.0.2-pyhe1237c8_2.conda + - conda: https://prefix.dev/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda + - conda: https://prefix.dev/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda + - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/osx-64/tk-8.6.13-hf689a15_2.conda + - conda: https://prefix.dev/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/toolz-1.0.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.14.0-pyhe01879c_0.conda + - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2 + - conda: https://prefix.dev/conda-forge/noarch/zipp-3.23.0-pyhd8ed1ab_0.conda + - pypi: ./ + osx-arm64: + - conda: https://prefix.dev/conda-forge/noarch/array-api-compat-1.12.0-pyhe01879c_0.conda + - conda: https://prefix.dev/conda-forge/noarch/array-api-strict-2.3.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/attrs-25.3.0-pyh71513ae_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb_0.conda + - conda: https://prefix.dev/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cloudpickle-3.1.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/coverage-7.8.2-pyhe1237c8_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cpython-3.13.3-py313hd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/dask-core-2025.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/fsspec-2025.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.135.4-pyha770c72_0.conda + - conda: https://prefix.dev/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda + - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libblas-3.9.0-31_h10e41b3_openblas.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libcblas-3.9.0-31_hb3479ef_openblas.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-20.1.6-ha82da77_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.7.0-h286801f_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.6-h1da3d7d_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libgfortran-14.2.0-heb5dd2a_105.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libgfortran5-14.2.0-h2c44a93_105.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/liblapack-3.9.0-31_hc9a63f6_openblas.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libopenblas-0.3.29-openmp_hf332438_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.50.1-h3f77e49_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-20.1.6-hdb05f8b_0.conda + - conda: https://prefix.dev/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.3.0-py313h991d4a7_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.0-h81ee809_1.conda + - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda + - conda: https://prefix.dev/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-8.4.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-run-parallel-0.4.3-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.3-hfd29fff_1_cp313t.conda + - conda: https://prefix.dev/conda-forge/noarch/python-freethreading-3.13.3-h92d6c8b_1.conda + - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.13-7_cp313t.conda + - conda: https://prefix.dev/conda-forge/noarch/pyyaml-6.0.2-pyhe1237c8_2.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda + - conda: https://prefix.dev/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda + - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda + - conda: https://prefix.dev/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/toolz-1.0.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.14.0-pyhe01879c_0.conda + - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2 + - conda: https://prefix.dev/conda-forge/noarch/zipp-3.23.0-pyhd8ed1ab_0.conda + - pypi: ./ + win-64: + - conda: https://prefix.dev/conda-forge/noarch/array-api-compat-1.12.0-pyhe01879c_0.conda + - conda: https://prefix.dev/conda-forge/noarch/array-api-strict-2.3.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/attrs-25.3.0-pyh71513ae_0.conda + - conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.4.26-h4c7d964_0.conda + - conda: https://prefix.dev/conda-forge/noarch/click-8.2.1-pyh7428d3b_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cloudpickle-3.1.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/coverage-7.8.2-pyhe1237c8_0.conda + - conda: https://prefix.dev/conda-forge/noarch/cpython-3.13.3-py313hd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/dask-core-2025.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/fsspec-2025.5.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.135.4-pyha770c72_0.conda + - conda: https://prefix.dev/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda + - conda: https://prefix.dev/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/win-64/intel-openmp-2024.2.1-h57928b3_1083.conda + - conda: https://prefix.dev/conda-forge/win-64/libblas-3.9.0-31_h641d27c_mkl.conda + - conda: https://prefix.dev/conda-forge/win-64/libcblas-3.9.0-31_h5e41251_mkl.conda + - conda: https://prefix.dev/conda-forge/win-64/libexpat-2.7.0-he0c23c2_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda + - conda: https://prefix.dev/conda-forge/win-64/libhwloc-2.11.2-default_ha69328c_1001.conda + - conda: https://prefix.dev/conda-forge/win-64/libiconv-1.18-h135ad9c_1.conda + - conda: https://prefix.dev/conda-forge/win-64/liblapack-3.9.0-31_h1aa476e_mkl.conda + - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda + - conda: https://prefix.dev/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.50.1-h67fdade_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda + - conda: https://prefix.dev/conda-forge/win-64/libxml2-2.13.8-h442d1da_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda + - conda: https://prefix.dev/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 + - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda + - conda: https://prefix.dev/conda-forge/win-64/numpy-2.3.0-py313hd96daed_0.conda + - conda: https://prefix.dev/conda-forge/win-64/openssl-3.5.0-ha4e3fda_1.conda + - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda + - conda: https://prefix.dev/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-8.4.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/noarch/pytest-run-parallel-0.4.3-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/win-64/python-3.13.3-hd7c436d_1_cp313t.conda + - conda: https://prefix.dev/conda-forge/noarch/python-freethreading-3.13.3-h92d6c8b_1.conda + - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.13-7_cp313t.conda + - conda: https://prefix.dev/conda-forge/noarch/pyyaml-6.0.2-pyhe1237c8_2.conda + - conda: https://prefix.dev/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda + - conda: https://prefix.dev/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/win-64/tbb-2021.13.0-h62715c5_1.conda + - conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda + - conda: https://prefix.dev/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/toolz-1.0.0-pyhd8ed1ab_1.conda + - conda: https://prefix.dev/conda-forge/noarch/typing_extensions-4.14.0-pyhe01879c_0.conda + - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda + - conda: https://prefix.dev/conda-forge/win-64/vc-14.3-h2b53caa_26.conda + - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.42.34438-hfd919c2_26.conda + - conda: https://prefix.dev/conda-forge/win-64/vs2015_runtime-14.42.34438-h7142326_26.conda + - conda: https://prefix.dev/conda-forge/win-64/yaml-0.2.5-h8ffe710_2.tar.bz2 + - conda: https://prefix.dev/conda-forge/noarch/zipp-3.23.0-pyhd8ed1ab_0.conda + - pypi: ./ tests-numpy1: channels: - url: https://prefix.dev/conda-forge/ @@ -3718,7 +3966,7 @@ environments: - conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/numpy-2.3.0-py313h17eae1a_0.conda - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda @@ -3763,7 +4011,7 @@ environments: - conda: https://prefix.dev/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - conda: https://prefix.dev/conda-forge/osx-64/llvm-openmp-20.1.6-ha54dae1_0.conda - conda: https://prefix.dev/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - - conda: https://prefix.dev/conda-forge/osx-64/numpy-2.2.6-py313hc518a0f_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/numpy-2.3.0-py313hc518a0f_0.conda - conda: https://prefix.dev/conda-forge/osx-64/openssl-3.5.0-hc426f3f_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda @@ -3808,7 +4056,7 @@ environments: - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - conda: https://prefix.dev/conda-forge/osx-arm64/llvm-openmp-20.1.6-hdb05f8b_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.6-py313h41a2e72_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.3.0-py313h41a2e72_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.0-h81ee809_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda @@ -3853,7 +4101,7 @@ environments: - conda: https://prefix.dev/conda-forge/win-64/libxml2-2.13.8-h442d1da_0.conda - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - conda: https://prefix.dev/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda - - conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.6-py313hefb8edb_0.conda + - conda: https://prefix.dev/conda-forge/win-64/numpy-2.3.0-py313hefb8edb_0.conda - conda: https://prefix.dev/conda-forge/win-64/openssl-3.5.0-ha4e3fda_1.conda - conda: https://prefix.dev/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda - conda: https://prefix.dev/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda @@ -3948,7 +4196,7 @@ packages: - pypi: ./ name: array-api-extra version: 0.8.1.dev0 - sha256: 026f2389147e594fb81cfd47423eb90f6d7253d12ea1e0e0ea739e6aa4dd2e63 + sha256: b18fc8298d171a9cdb01c938905cbab87f77ca2d76497505c79c46e5f4770d74 requires_dist: - array-api-compat>=1.12.0,<2 requires_python: '>=3.10' @@ -4599,6 +4847,20 @@ packages: - pkg:pypi/coverage?source=hash-mapping size: 379067 timestamp: 1748048940298 +- conda: https://prefix.dev/conda-forge/noarch/coverage-7.8.2-pyhe1237c8_0.conda + sha256: a88f65a8e79045454be5c714bfa08530d1bf96fd8ce2d3dee7d3cda58a08d7e3 + md5: 6d1d4aee3c89b52b8a46ee28854e7c20 + depends: + - python >=3.9 + - tomli + track_features: + - coverage_no_compile + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/coverage?source=hash-mapping + size: 168830 + timestamp: 1748048870605 - conda: https://prefix.dev/conda-forge/osx-64/coverage-7.8.2-py310h8e2f543_0.conda sha256: 45882f723c09ec059000f54ac3e2329b94057ecf909ea068d63913a11620dbe4 md5: f07a792c442b3b3aa890175a990814d4 @@ -4700,6 +4962,17 @@ packages: purls: [] size: 50554 timestamp: 1744323109983 +- conda: https://prefix.dev/conda-forge/noarch/cpython-3.13.3-py313hd8ed1ab_1.conda + noarch: generic + sha256: 02147913b77a10f32b3aa6940af4003c86c3323401caae44da8f5f7f68650453 + md5: 6ba9ba47b91b7758cb963d0f0eaf3422 + depends: + - python >=3.13,<3.14.0a0 + - python_abi * *_cp313t + license: Python-2.0 + purls: [] + size: 47939 + timestamp: 1744663487710 - conda: https://prefix.dev/conda-forge/noarch/cuda-cccl_linux-64-12.9.27-ha770c72_0.conda sha256: 2ee3b9564ca326226e5cda41d11b251482df8e7c757e333d28ec75213c75d126 md5: 87ff6381e33b76e5b9b179a2cdd005ec @@ -5376,6 +5649,22 @@ packages: - pkg:pypi/hypothesis?source=hash-mapping size: 363329 timestamp: 1748926459156 +- conda: https://prefix.dev/conda-forge/noarch/hypothesis-6.135.4-pyha770c72_0.conda + sha256: d53f9f6722817f8c60d6043e06c219acb9785830b39e6d4a6b60ac830572296b + md5: dde3b6dbdf86b3351f8c1db027dafad6 + depends: + - attrs >=22.2.0 + - click >=7.0 + - exceptiongroup >=1.0.0 + - python >=3.9 + - setuptools + - sortedcontainers >=2.1.0,<3.0.0 + license: MPL-2.0 + license_family: MOZILLA + purls: + - pkg:pypi/hypothesis?source=hash-mapping + size: 367768 + timestamp: 1749461444685 - conda: https://prefix.dev/conda-forge/linux-64/icu-75.1-he02047a_0.conda sha256: 71e750d509f5fa3421087ba88ef9a7b9be11c53174af3aa4d06aff4c18b38e8e md5: 8b189310083baabfb622af68fd9d3ae3 @@ -6787,6 +7076,18 @@ packages: purls: [] size: 112845 timestamp: 1746531470399 +- conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 + md5: 1a580f7796c7bf6393fddb8bbbde58dc + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + constrains: + - xz 5.8.1.* + license: 0BSD + purls: [] + size: 112894 + timestamp: 1749230047870 - conda: https://prefix.dev/conda-forge/osx-64/liblzma-5.8.1-hd471939_1.conda sha256: 20a4c5291f3e338548013623bb1dc8ee2fba5dbac8f77acaddd730ed2a7d29b6 md5: f87e8821e0e38a4140a7ed4f52530053 @@ -6799,6 +7100,17 @@ packages: purls: [] size: 104814 timestamp: 1746531577001 +- conda: https://prefix.dev/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda + sha256: 7e22fd1bdb8bf4c2be93de2d4e718db5c548aa082af47a7430eb23192de6bb36 + md5: 8468beea04b9065b9807fc8b9cdc5894 + depends: + - __osx >=10.13 + constrains: + - xz 5.8.1.* + license: 0BSD + purls: [] + size: 104826 + timestamp: 1749230155443 - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_1.conda sha256: 5ab62c179229640c34491a7de806ad4ab7bec47ea2b5fc2136e3b8cf5ef26a57 md5: 4e8ef3d79c97c9021b34d682c24c2044 @@ -6811,6 +7123,17 @@ packages: purls: [] size: 92218 timestamp: 1746531818330 +- conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda + sha256: 0cb92a9e026e7bd4842f410a5c5c665c89b2eb97794ffddba519a626b8ce7285 + md5: d6df911d4564d77c4374b02552cb17d1 + depends: + - __osx >=11.0 + constrains: + - xz 5.8.1.* + license: 0BSD + purls: [] + size: 92286 + timestamp: 1749230283517 - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.1-h2466b09_1.conda sha256: adbf6c7bde70536ada734a81b8b5aa23654f2b95445204404622e0cc40e921a0 md5: 14a1042c163181e143a7522dfb8ad6ab @@ -6825,6 +7148,19 @@ packages: purls: [] size: 104699 timestamp: 1746531718026 +- conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda + sha256: 55764956eb9179b98de7cc0e55696f2eff8f7b83fc3ebff5e696ca358bca28cc + md5: c15148b2e18da456f5108ccb5e411446 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - xz 5.8.1.* + license: 0BSD + purls: [] + size: 104935 + timestamp: 1749230611612 - conda: https://prefix.dev/conda-forge/linux-64/libmagma-2.9.0-h19665d7_1.conda sha256: 13d50a4f7da02e6acce4b5b6df82072c0f447a2c5ba1f4a3190dfec3a9174965 md5: 38b3447782263c96b0c0a7b92c97575e @@ -7110,6 +7446,17 @@ packages: purls: [] size: 918995 timestamp: 1748549888459 +- conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.50.1-hee588c1_0.conda + sha256: cd15ab1b9f0d53507e7ad7a01e52f6756ab3080bf623ab0e438973b6e4dba3c0 + md5: 96a7e36bff29f1d0ddf5b771e0da373a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libzlib >=1.3.1,<2.0a0 + license: Unlicense + purls: [] + size: 919819 + timestamp: 1749232795476 - conda: https://prefix.dev/conda-forge/osx-64/libsqlite-3.50.0-hdb6dae5_0.conda sha256: e88ea982455060b96fdab3d360b947389248bf2139e3b17576e4c72e139526fc md5: caf16742f7e16475603cd9981ef36195 @@ -7120,6 +7467,16 @@ packages: purls: [] size: 979930 timestamp: 1748549977346 +- conda: https://prefix.dev/conda-forge/osx-64/libsqlite-3.50.1-hdb6dae5_0.conda + sha256: 619fbc556a621beafc7ec712f16648ee30bf2d029b6d7aea2c84839fbb2b4e14 + md5: 00116248e7b4025ae01632472b300d29 + depends: + - __osx >=10.13 + - libzlib >=1.3.1,<2.0a0 + license: Unlicense + purls: [] + size: 979974 + timestamp: 1749232778874 - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.50.0-h3f77e49_0.conda sha256: 80bbe9c53d4bf2e842eccdd089653d0659972deba7057cda3ebaebaf43198f79 md5: cda0ec640bc4698d0813a8fb459aee58 @@ -7130,6 +7487,16 @@ packages: purls: [] size: 901545 timestamp: 1748550158812 +- conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.50.1-h3f77e49_0.conda + sha256: f39e22a00396c048dcfcb5d8c9dbedb2d69f06edcd8dba98b87f263eeb6d2049 + md5: 73df23998b27dd6774d03db626d031d3 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: Unlicense + purls: [] + size: 901258 + timestamp: 1749232800279 - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.50.0-h67fdade_0.conda sha256: 92546e3ea213ee7b11385b22ea4e7c69bbde1c25586288765b37bc5e96b20dd9 md5: 92b11b0b2120d563caa1629928122cee @@ -7141,6 +7508,17 @@ packages: purls: [] size: 1082124 timestamp: 1748550277035 +- conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.50.1-h67fdade_0.conda + sha256: 0dda5b3f21ad2c7e823f21b0e173194347fbfccb73a06ddc9366da1877020bda + md5: 0e11a893eeeb46510520fd3fdd9c346a + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: Unlicense + purls: [] + size: 1082758 + timestamp: 1749233212790 - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda sha256: 6ae3d153e78f6069d503d9309f2cac6de5b93d067fc6433160a4c05226a5dad4 md5: 1cb1c67961f6dd257eae9e9691b341aa @@ -8484,9 +8862,9 @@ packages: - pkg:pypi/numpy?source=hash-mapping size: 7893263 timestamp: 1747545075833 -- conda: https://prefix.dev/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda - sha256: 7da9ebd80a7311e0482c4c6393be0eddf0012b3846df528e375037409b3d2b3d - md5: 7a2d2f9adecd86ed5c29c2115354f615 +- conda: https://prefix.dev/conda-forge/linux-64/numpy-2.3.0-py313h103f029_0.conda + sha256: a646e7e284dff94e1ef2dc816a5a61ac069907ea97192159da32ee190c56f64a + md5: d24d95f39ffa3c70827df0183b01df04 depends: - __glibc >=2.17,<3.0.a0 - libblas >=3.9.0,<4.0a0 @@ -8495,15 +8873,35 @@ packages: - liblapack >=3.9.0,<4.0a0 - libstdcxx >=13 - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python_abi 3.13.* *_cp313t constrains: - numpy-base <0a0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/numpy?source=hash-mapping - size: 8517250 - timestamp: 1747545080496 + size: 8503297 + timestamp: 1749430966275 +- conda: https://prefix.dev/conda-forge/linux-64/numpy-2.3.0-py313h17eae1a_0.conda + sha256: 8b88ade24df5229c5d76c5ef09568ae4630b1095982e94648fbbeb18f475aa61 + md5: db18a34466bef0863e9301b518a75e8f + depends: + - __glibc >=2.17,<3.0.a0 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libgcc >=13 + - liblapack >=3.9.0,<4.0a0 + - libstdcxx >=13 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy?source=compressed-mapping + size: 8545037 + timestamp: 1749430954481 - conda: https://prefix.dev/conda-forge/osx-64/numpy-1.22.0-py310hfbbbacf_1.tar.bz2 sha256: 314f87226d04969a8cf6444a547b8437c5a45869acedb0d9adca9d18b0b0db80 md5: 6c533068089d17205d21055ed717831e @@ -8541,9 +8939,9 @@ packages: - pkg:pypi/numpy?source=hash-mapping size: 6988856 timestamp: 1747545137089 -- conda: https://prefix.dev/conda-forge/osx-64/numpy-2.2.6-py313hc518a0f_0.conda - sha256: a7994c4968d9cbb12752663e57f600379775b1f032776829068380db9874e449 - md5: 7b80c7ace05b1b9d7ec6f55130776988 +- conda: https://prefix.dev/conda-forge/osx-64/numpy-2.3.0-py313h6699f8c_0.conda + sha256: b7af1f24ee3600d8e8892f9bca8c40d08792714764eaf80926c8fbe18919f92d + md5: dc2afb3c85fbcec2294eef844540c4b5 depends: - __osx >=10.13 - libblas >=3.9.0,<4.0a0 @@ -8551,15 +8949,34 @@ packages: - libcxx >=18 - liblapack >=3.9.0,<4.0a0 - python >=3.13,<3.14.0a0 - - python_abi 3.13.* *_cp313 + - python_abi 3.13.* *_cp313t constrains: - numpy-base <0a0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/numpy?source=hash-mapping - size: 7596354 - timestamp: 1747545051328 + size: 7738014 + timestamp: 1749431078203 +- conda: https://prefix.dev/conda-forge/osx-64/numpy-2.3.0-py313hc518a0f_0.conda + sha256: 6e751f573b6aa727b83bdcb6534c9a4ffe05bcb56a659eb3f1418d28794213cc + md5: 9ff00ee247ea2b114a56de1a31a5d5af + depends: + - __osx >=10.13 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libcxx >=18 + - liblapack >=3.9.0,<4.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy?source=compressed-mapping + size: 7634474 + timestamp: 1749431208151 - conda: https://prefix.dev/conda-forge/osx-arm64/numpy-1.22.0-py310h567df17_1.tar.bz2 sha256: 985e83cdda1fb1d0c3ff813381c258818696985d10fd4ccab2b719ea8fdc8652 md5: 6ecd7326570ae2fb65fa4d8427f64213 @@ -8599,9 +9016,9 @@ packages: - pkg:pypi/numpy?source=hash-mapping size: 5841650 timestamp: 1747545043441 -- conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.2.6-py313h41a2e72_0.conda - sha256: 2206aa59ee700f00896604178864ebe54ab8e87e479a1707def23636a6a62797 - md5: 6a5bd221d600de2bf1b408678dab01b7 +- conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.3.0-py313h41a2e72_0.conda + sha256: d473005786a27cf4e1430d45a99a61626c2fbf61eb25b4d021cee8d217b973d2 + md5: 0dc3aa075f3e64bdda6e779e2cbf5aa9 depends: - __osx >=11.0 - libblas >=3.9.0,<4.0a0 @@ -8616,9 +9033,29 @@ packages: license: BSD-3-Clause license_family: BSD purls: + - pkg:pypi/numpy?source=compressed-mapping + size: 6525213 + timestamp: 1749430964570 +- conda: https://prefix.dev/conda-forge/osx-arm64/numpy-2.3.0-py313h991d4a7_0.conda + sha256: 0dea09495c653c75e2ffda698a5be0aca81667b9f663d9631a95c00eddd88969 + md5: 0d2ceb567a45d4dfe3eb9f2accb982ea + depends: + - __osx >=11.0 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libcxx >=18 + - liblapack >=3.9.0,<4.0a0 + - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313t + - python_abi 3.13.* *_cp313t + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: - pkg:pypi/numpy?source=hash-mapping - size: 6532195 - timestamp: 1747545087365 + size: 8127568 + timestamp: 1749431087698 - conda: https://prefix.dev/conda-forge/win-64/numpy-1.22.0-py310hcae7c84_1.tar.bz2 sha256: c327b5bcc96e9f06147c03eecba689eb3cfe2478d8e68f17b471b273ee60cf45 md5: 07f52c684a2387799426a532170152b6 @@ -8658,9 +9095,29 @@ packages: - pkg:pypi/numpy?source=hash-mapping size: 6596153 timestamp: 1747545352390 -- conda: https://prefix.dev/conda-forge/win-64/numpy-2.2.6-py313hefb8edb_0.conda - sha256: ee193d2cfbf6bc06fb99312ee2555c40b68402cae44cf101f452acb2f1490f98 - md5: ae9a9741b830bbb42f22f80ef4e6a074 +- conda: https://prefix.dev/conda-forge/win-64/numpy-2.3.0-py313hd96daed_0.conda + sha256: 4e720b130b947705c3149256f5ee3391c77d4f8e089d0780fc956116b61789a9 + md5: 87b9d2d5ec66618019cd7ff8d856cce1 + depends: + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - python >=3.13,<3.14.0a0 + - python_abi 3.13.* *_cp313t + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy?source=hash-mapping + size: 6763262 + timestamp: 1749431105515 +- conda: https://prefix.dev/conda-forge/win-64/numpy-2.3.0-py313hefb8edb_0.conda + sha256: b2d8af00021061b43fc43f24ad7f135ff3641bc642e25dab0a175126facb749b + md5: 34a477d1a0c5396c6d82d6f7765ca339 depends: - libblas >=3.9.0,<4.0a0 - libcblas >=3.9.0,<4.0a0 @@ -8676,8 +9133,8 @@ packages: license_family: BSD purls: - pkg:pypi/numpy?source=hash-mapping - size: 7097859 - timestamp: 1747545350386 + size: 6646194 + timestamp: 1749431079208 - conda: https://prefix.dev/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda sha256: d836860163b027622cb59b96b92824dd75196a37d599e8ae69733b31769989a9 md5: 5af206d64d18d6c8dfb3122b4d9e643b @@ -9212,6 +9669,18 @@ packages: - pkg:pypi/pytest-cov?source=hash-mapping size: 27565 timestamp: 1743886993683 +- conda: https://prefix.dev/conda-forge/noarch/pytest-run-parallel-0.4.3-pyhd8ed1ab_0.conda + sha256: 981deb0bad7e92b78ce8c4b3db99f9c008e37ddb666fc117ec28efe7ec8ad7cd + md5: 4974eeb9e368dca027c3e49c58ced417 + depends: + - pytest >=6.2.0 + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pytest-run-parallel?source=hash-mapping + size: 17692 + timestamp: 1748343358484 - conda: https://prefix.dev/conda-forge/linux-64/python-3.10.17-hd6af730_0_cpython.conda sha256: 0ae32507817402bfad08fbf0f4a9b5ae26859d5390b98bc939da85fd0bd4239f md5: 7bb89638dae9ce1b8e051d0b721e83c2 @@ -9239,6 +9708,35 @@ packages: purls: [] size: 25058210 timestamp: 1744324903492 +- conda: https://prefix.dev/conda-forge/linux-64/python-3.13.3-h4724d56_1_cp313t.conda + build_number: 1 + sha256: 0a754546c765d8b0301637012d6a4265f9167e60ebc15d47f9a414b1769096dc + md5: 8193603fe48ace3d8801cfb246f44491 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-64 >=2.36.1 + - libexpat >=2.7.0,<3.0a0 + - libffi >=3.4.6,<3.5.0a0 + - libgcc >=13 + - liblzma >=5.8.1,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.49.1,<4.0a0 + - libuuid >=2.38.1,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.0,<4.0a0 + - python_abi 3.13.* *_cp313t + - readline >=8.2,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + track_features: + - py_freethreading + license: Python-2.0 + purls: [] + size: 41651821 + timestamp: 1744665599069 + python_site_packages_path: lib/python3.13t/site-packages - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.3-hf636f53_101_cp313.conda build_number: 101 sha256: eecb11ea60f8143deeb301eab2e04d04f7acb83659bb20fdfeacd431a5f31168 @@ -9288,6 +9786,32 @@ packages: purls: [] size: 12898620 timestamp: 1744323796398 +- conda: https://prefix.dev/conda-forge/osx-64/python-3.13.3-h2267d90_1_cp313t.conda + build_number: 1 + sha256: a0eb5bfae3e58f46ea6de09bf51e19f9c611e9bb1d63751065f5b48e55a8a0bd + md5: 3a0f325506b25cf554c55795520635ba + depends: + - __osx >=10.13 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.0,<3.0a0 + - libffi >=3.4.6,<3.5.0a0 + - liblzma >=5.8.1,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.49.1,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.0,<4.0a0 + - python_abi 3.13.* *_cp313t + - readline >=8.2,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + track_features: + - py_freethreading + license: Python-2.0 + purls: [] + size: 15799189 + timestamp: 1744664727737 + python_site_packages_path: lib/python3.13t/site-packages - conda: https://prefix.dev/conda-forge/osx-64/python-3.13.3-h534c281_101_cp313.conda build_number: 101 sha256: fe70f145472820922a01279165b96717815dcd4f346ad9a2f2338045d8818930 @@ -9358,6 +9882,32 @@ packages: size: 12136505 timestamp: 1744663807953 python_site_packages_path: lib/python3.13/site-packages +- conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.3-hfd29fff_1_cp313t.conda + build_number: 1 + sha256: 28a0fa63d5557bb1a8818b86cefc10333253e0cd159db2a6f2a130340185d6cf + md5: 8463aa08925f217800fc11136ee748e5 + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.0,<3.0a0 + - libffi >=3.4.6,<3.5.0a0 + - liblzma >=5.8.1,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.49.1,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.0,<4.0a0 + - python_abi 3.13.* *_cp313t + - readline >=8.2,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + track_features: + - py_freethreading + license: Python-2.0 + purls: [] + size: 14836789 + timestamp: 1744663662894 + python_site_packages_path: lib/python3.13t/site-packages - conda: https://prefix.dev/conda-forge/win-64/python-3.10.17-h8c5b53a_0_cpython.conda sha256: 071303a9bcbba4d79ab1ca61f34ec9f4ad65bc15d897828f5006ef9507094557 md5: 0c59918f056ab2e9c7bb45970d32b2ea @@ -9404,6 +9954,42 @@ packages: size: 16614435 timestamp: 1744663103022 python_site_packages_path: Lib/site-packages +- conda: https://prefix.dev/conda-forge/win-64/python-3.13.3-hd7c436d_1_cp313t.conda + build_number: 1 + sha256: 0145db5ded3f15e7bba8873f232c26622df00acda070e9e43b14c6b72c3f3fc1 + md5: bac978c337c76f61eab2f3eb187d6a78 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.0,<3.0a0 + - libffi >=3.4.6,<3.5.0a0 + - liblzma >=5.8.1,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.49.1,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + - python_abi 3.13.* *_cp313t + - tk >=8.6.13,<8.7.0a0 + - tzdata + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + track_features: + - py_freethreading + license: Python-2.0 + purls: [] + size: 16618325 + timestamp: 1744663415142 + python_site_packages_path: Lib/site-packages +- conda: https://prefix.dev/conda-forge/noarch/python-freethreading-3.13.3-h92d6c8b_1.conda + sha256: f5ce208db07f3e910e47ad054e62cd431f8e46e32596bd5431b0b2da99ff0786 + md5: 4fa25290aec662a01642ba4b3c0ff5c1 + depends: + - cpython 3.13.3.* + - python_abi * *_cp313t + license: Python-2.0 + purls: [] + size: 47968 + timestamp: 1744663562078 - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.10-7_cp310.conda build_number: 7 sha256: 1316c66889313d9caebcfa5d5e9e6af25f8ba09396fc1bc196a08a3febbbabb8 @@ -9426,6 +10012,19 @@ packages: purls: [] size: 6988 timestamp: 1745258852285 +- conda: https://prefix.dev/conda-forge/noarch/python_abi-3.13-7_cp313t.conda + build_number: 7 + sha256: fa1705748ea982e20fbd29f9958b368e7c170835d780b500f7f4c3f5cf55fe6e + md5: df81edcc11a1176315e8226acab83eec + constrains: + - python 3.13.* *_cp313t + track_features: + - freethreading + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 7018 + timestamp: 1745258869977 - conda: https://prefix.dev/conda-forge/linux-64/pytorch-2.7.0-cpu_mkl_py310_h8ec2884_100.conda sha256: a91d20ad4a3246ce8e8b90c3498b145b85c30226e3e37e505012d725541b9872 md5: 80db30658f13a31389c00b26bb494555 @@ -9734,6 +10333,20 @@ packages: - pkg:pypi/pyyaml?source=hash-mapping size: 205919 timestamp: 1737454783637 +- conda: https://prefix.dev/conda-forge/noarch/pyyaml-6.0.2-pyhe1237c8_2.conda + sha256: e65194b89607feab1f5fce7a150246572f1c2145af125260eb87bacb5311f3f3 + md5: 97db1b8e8c2ca460dd37d7bf2fb0f174 + depends: + - python >=3.9.* + - yaml + track_features: + - pyyaml_no_compile + license: MIT + license_family: MIT + purls: + - pkg:pypi/pyyaml?source=hash-mapping + size: 44603 + timestamp: 1737454840302 - conda: https://prefix.dev/conda-forge/osx-64/pyyaml-6.0.2-py310h8e2f543_2.conda sha256: ee888a231818e98603439abcad0084ea7600399c4633d3d9415d42a5e7e3aee1 md5: a421bbf2cdd0d7ec3357a01d2d48709e @@ -10794,6 +11407,17 @@ packages: - pkg:pypi/zipp?source=compressed-mapping size: 22691 timestamp: 1748277499928 +- conda: https://prefix.dev/conda-forge/noarch/zipp-3.23.0-pyhd8ed1ab_0.conda + sha256: 7560d21e1b021fd40b65bfb72f67945a3fcb83d78ad7ccf37b8b3165ec3b68ad + md5: df5e78d904988eb55042c0c97446079f + depends: + - python >=3.9 + license: MIT + license_family: MIT + purls: + - pkg:pypi/zipp?source=hash-mapping + size: 22963 + timestamp: 1749421737203 - conda: https://prefix.dev/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda sha256: 5d7c0e5f0005f74112a34a7425179f4eb6e73c92f5d109e6af4ddeca407c92ab md5: c9f075ab2f33b3bbee9e62d4ad0a6cd8 diff --git a/pyproject.toml b/pyproject.toml index 36e25425..c58498c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,6 +23,7 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: Free Threading :: 3 - Stable", "Typing :: Typed", ] dynamic = ["version"] @@ -47,7 +48,6 @@ channels = ["https://prefix.dev/conda-forge"] platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"] [tool.pixi.dependencies] -python = ">=3.10,<3.14" array-api-compat = ">=1.12.0,<2" [tool.pixi.pypi-dependencies] @@ -179,6 +179,15 @@ cupy = ">=13.4.1" # jaxlib = { version = "*", build = "cuda12*" } # unavailable pytorch = { version = ">=2.7.0", build = "cuda12*" } +[tool.pixi.feature.nogil.dependencies] +python-freethreading = "~=3.13.0" +pytest-run-parallel = ">=0.4.3" +numpy = ">=2.3.0" +# pytorch = "*" # Not available on Python 3.13t yet +dask-core = ">=2025.5.1" # No distributed, tornado, etc. +# sparse = "*" # numba not available on Python 3.13t yet +# jax = "*" # ml_dtypes not available on Python 3.13t yet + [tool.pixi.environments] default = { features = ["py313"], solve-group = "py313" } lint = { features = ["py313", "lint"], solve-group = "py313" } @@ -197,7 +206,7 @@ tests-cuda = { features = ["py310", "tests", "backends", "cuda-backends"], solve # Ungrouped environments tests-numpy1 = ["py310", "tests", "numpy1"] tests-py310 = ["py310", "tests"] - +tests-nogil = ["nogil", "tests"] # pytest diff --git a/src/array_api_extra/_lib/_backends.py b/src/array_api_extra/_lib/_backends.py index 68bef24b..936f5dd0 100644 --- a/src/array_api_extra/_lib/_backends.py +++ b/src/array_api_extra/_lib/_backends.py @@ -3,8 +3,14 @@ from __future__ import annotations from enum import Enum +from typing import Any -__all__ = ["Backend"] +import numpy as np +import pytest + +__all__ = ["NUMPY_VERSION", "Backend"] + +NUMPY_VERSION = tuple(int(v) for v in np.__version__.split(".")[:3]) # pyright: ignore[reportUnknownArgumentType] class Backend(Enum): # numpydoc ignore=PR02 @@ -30,12 +36,6 @@ class Backend(Enum): # numpydoc ignore=PR02 JAX = "jax.numpy" JAX_GPU = "jax.numpy:gpu" - def __str__(self) -> str: # pyright: ignore[reportImplicitOverride] # numpydoc ignore=RT01 - """Pretty-print parameterized test names.""" - return ( - self.name.lower().replace("_gpu", ":gpu").replace("_readonly", ":readonly") - ) - @property def modname(self) -> str: # numpydoc ignore=RT01 """Module name to be imported.""" @@ -44,3 +44,29 @@ def modname(self) -> str: # numpydoc ignore=RT01 def like(self, *others: Backend) -> bool: # numpydoc ignore=PR01,RT01 """Check if this backend uses the same module as others.""" return any(self.modname == other.modname for other in others) + + def pytest_param(self) -> Any: + """ + Backend as a pytest parameter + + Returns + ------- + pytest.mark.ParameterSet + """ + id_ = ( + self.name.lower().replace("_gpu", ":gpu").replace("_readonly", ":readonly") + ) + + marks = [] + if self.like(Backend.ARRAY_API_STRICT): + marks.append( + pytest.mark.skipif( + NUMPY_VERSION < (1, 26), + reason="array_api_strict is untested on NumPy <1.26", + ) + ) + if self.like(Backend.DASK, Backend.JAX): + # Monkey-patched by lazy_xp_function + marks.append(pytest.mark.thread_unsafe) + + return pytest.param(self, id=id_, marks=marks) # pyright: ignore[reportUnknownArgumentType] diff --git a/src/array_api_extra/_lib/_lazy.py b/src/array_api_extra/_lib/_lazy.py index dc7c0039..d5095001 100644 --- a/src/array_api_extra/_lib/_lazy.py +++ b/src/array_api_extra/_lib/_lazy.py @@ -343,7 +343,7 @@ def wrapper( if as_numpy: import numpy as np - arg = cast(Array, np.asarray(arg)) # noqa: PLW2901 + arg = cast(Array, np.asarray(arg)) # pyright: ignore[reportInvalidCast] # noqa: PLW2901 args_list.append(arg) assert device is not None diff --git a/src/array_api_extra/testing.py b/src/array_api_extra/testing.py index bb310467..47511c75 100644 --- a/src/array_api_extra/testing.py +++ b/src/array_api_extra/testing.py @@ -9,7 +9,7 @@ import contextlib import enum import warnings -from collections.abc import Callable, Iterator, Sequence +from collections.abc import Callable, Generator, Iterator, Sequence from functools import wraps from types import ModuleType from typing import TYPE_CHECKING, Any, ParamSpec, TypeVar, cast @@ -216,8 +216,11 @@ def test_myfunc(xp): def patch_lazy_xp_functions( - request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch, *, xp: ModuleType -) -> None: + request: pytest.FixtureRequest, + monkeypatch: pytest.MonkeyPatch | None = None, + *, + xp: ModuleType, +) -> contextlib.AbstractContextManager[None]: """ Test lazy execution of functions tagged with :func:`lazy_xp_function`. @@ -233,10 +236,15 @@ def patch_lazy_xp_functions( This function should be typically called by your library's `xp` fixture that runs tests on multiple backends:: - @pytest.fixture(params=[numpy, array_api_strict, jax.numpy, dask.array]) - def xp(request, monkeypatch): - patch_lazy_xp_functions(request, monkeypatch, xp=request.param) - return request.param + @pytest.fixture(params=[ + numpy, + array_api_strict, + pytest.param(jax.numpy, marks=pytest.mark.thread_unsafe), + pytest.param(dask.array, marks=pytest.mark.thread_unsafe), + ]) + def xp(request): + with patch_lazy_xp_functions(request, xp=request.param): + yield request.param but it can be otherwise be called by the test itself too. @@ -245,7 +253,7 @@ def xp(request, monkeypatch): request : pytest.FixtureRequest Pytest fixture, as acquired by the test itself or by one of its fixtures. monkeypatch : pytest.MonkeyPatch - Pytest fixture, as acquired by the test itself or by one of its fixtures. + Deprecated xp : array_namespace Array namespace to be tested. @@ -253,10 +261,42 @@ def xp(request, monkeypatch): -------- lazy_xp_function : Tag a function to be tested on lazy backends. pytest.FixtureRequest : `request` test function parameter. + + Notes + ----- + This context manager monkey-patches modules and as such is thread unsafe + on Dask and JAX. If you run your test suite with + `pytest-run-parallel `_, + you should mark these backends with ``@pytest.mark.thread_unsafe``, as shown in + the example above. """ mod = cast(ModuleType, request.module) mods = [mod, *cast(list[ModuleType], getattr(mod, "lazy_xp_modules", []))] + to_revert: list[tuple[ModuleType, str, object]] = [] + + def temp_setattr(mod: ModuleType, name: str, func: object) -> None: + """ + Variant of monkeypatch.setattr, which allows monkey-patching only selected + parameters of a test so that pytest-run-parallel can run on the remainder. + """ + assert hasattr(mod, name) + to_revert.append((mod, name, getattr(mod, name))) + setattr(mod, name, func) + + if monkeypatch is not None: + warnings.warn( + ( + "The `monkeypatch` parameter is deprecated and will be removed in a " + "future version. " + "Use `patch_lazy_xp_function` as a context manager instead." + ), + DeprecationWarning, + stacklevel=2, + ) + # Enable using patch_lazy_xp_function not as a context manager + temp_setattr = monkeypatch.setattr # type: ignore[assignment] # pyright: ignore[reportAssignmentType] + def iter_tagged() -> ( Iterator[tuple[ModuleType, str, Callable[..., Any], dict[str, Any]]] ): @@ -279,13 +319,26 @@ def iter_tagged() -> ( elif n is False: n = 0 wrapped = _dask_wrap(func, n) - monkeypatch.setattr(mod, name, wrapped) + temp_setattr(mod, name, wrapped) elif is_jax_namespace(xp): for mod, name, func, tags in iter_tagged(): if tags["jax_jit"]: wrapped = jax_autojit(func) - monkeypatch.setattr(mod, name, wrapped) + temp_setattr(mod, name, wrapped) + + # We can't just decorate patch_lazy_xp_functions with + # @contextlib.contextmanager because it would not work with the + # deprecated monkeypatch when not used as a context manager. + @contextlib.contextmanager + def revert_on_exit() -> Generator[None]: + try: + yield + finally: + for mod, name, orig_func in to_revert: + setattr(mod, name, orig_func) + + return revert_on_exit() class CountingDaskScheduler(SchedulerGetCallable): diff --git a/tests/conftest.py b/tests/conftest.py index 82a0acbb..26b9a816 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -18,11 +18,10 @@ T = TypeVar("T") P = ParamSpec("P") -NUMPY_VERSION = tuple(int(v) for v in np.__version__.split(".")[2]) np_compat = array_namespace(np.empty(0)) # type: ignore[arg-type] # pyright: ignore[reportArgumentType] -@pytest.fixture(params=tuple(Backend)) +@pytest.fixture(params=[b.pytest_param() for b in Backend]) def library(request: pytest.FixtureRequest) -> Backend: # numpydoc ignore=PR01,RT03 """ Parameterized fixture that iterates on all libraries. @@ -112,7 +111,7 @@ def wrapper(*args: P.args, **kwargs: P.kwargs) -> T: # numpydoc ignore=GL08 @pytest.fixture def xp( - library: Backend, request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch + library: Backend, request: pytest.FixtureRequest ) -> Generator[ModuleType]: # numpydoc ignore=PR01,RT03 """ Parameterized fixture that iterates on all libraries. @@ -125,9 +124,6 @@ def xp( yield NumPyReadOnly() # type: ignore[misc] # pyright: ignore[reportReturnType] return - if library.like(Backend.ARRAY_API_STRICT) and NUMPY_VERSION < (1, 26): - pytest.skip("array_api_strict is untested on NumPy <1.26") - xp = pytest.importorskip(library.modname) # Possibly wrap module with array_api_compat xp = array_namespace(xp.empty(0)) @@ -143,16 +139,15 @@ def xp( yield xp return - # On Dask and JAX, monkey-patch all functions tagged by `lazy_xp_function` - # in the global scope of the module containing the test function. - patch_lazy_xp_functions(request, monkeypatch, xp=xp) - if library.like(Backend.JAX): _setup_jax(library) elif library.like(Backend.TORCH): _setup_torch(library) - yield xp + # On Dask and JAX, monkey-patch all functions tagged by `lazy_xp_function` + # in the global scope of the module containing the test function. + with patch_lazy_xp_functions(request, xp=xp): + yield xp def _setup_jax(library: Backend) -> None: @@ -189,26 +184,27 @@ def _setup_torch(library: Backend) -> None: torch.set_default_device("cpu") -@pytest.fixture(params=[Backend.DASK]) # Can select the test with `pytest -k dask` +# Can select the test with `pytest -k dask` +@pytest.fixture(params=[Backend.DASK.pytest_param()]) def da( - request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch -) -> ModuleType: # numpydoc ignore=PR01,RT01 + request: pytest.FixtureRequest, +) -> Generator[ModuleType]: # numpydoc ignore=PR01,RT01 """Variant of the `xp` fixture that only yields dask.array.""" xp = pytest.importorskip("dask.array") xp = array_namespace(xp.empty(0)) - patch_lazy_xp_functions(request, monkeypatch, xp=xp) - return xp + with patch_lazy_xp_functions(request, xp=xp): + yield xp -@pytest.fixture(params=[Backend.JAX, Backend.JAX_GPU]) +@pytest.fixture(params=[Backend.JAX.pytest_param(), Backend.JAX_GPU.pytest_param()]) def jnp( - request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch -) -> ModuleType: # numpydoc ignore=PR01,RT01 + request: pytest.FixtureRequest, +) -> Generator[ModuleType]: # numpydoc ignore=PR01,RT01 """Variant of the `xp` fixture that only yields jax.numpy.""" xp = pytest.importorskip("jax.numpy") _setup_jax(request.param) - patch_lazy_xp_functions(request, monkeypatch, xp=xp) - return xp + with patch_lazy_xp_functions(request, xp=xp): + yield xp @pytest.fixture(params=[Backend.TORCH, Backend.TORCH_GPU]) diff --git a/tests/test_at.py b/tests/test_at.py index 04b71b70..d9e1bdf9 100644 --- a/tests/test_at.py +++ b/tests/test_at.py @@ -178,7 +178,7 @@ def test_copy_invalid(): def test_xp(): - a = cast(Array, np.asarray([1, 2, 3])) + a = cast(Array, np.asarray([1, 2, 3])) # pyright: ignore[reportInvalidCast] _ = at(a, 0).set(4, xp=np) _ = at(a, 0).add(4, xp=np) _ = at(a, 0).subtract(4, xp=np) diff --git a/tests/test_funcs.py b/tests/test_funcs.py index 6e80a61d..dc0658ab 100644 --- a/tests/test_funcs.py +++ b/tests/test_funcs.py @@ -27,15 +27,13 @@ setdiff1d, sinc, ) -from array_api_extra._lib._backends import Backend +from array_api_extra._lib._backends import NUMPY_VERSION, Backend from array_api_extra._lib._testing import xp_assert_close, xp_assert_equal from array_api_extra._lib._utils._compat import device as get_device from array_api_extra._lib._utils._helpers import eager_shape, ndindex from array_api_extra._lib._utils._typing import Array, Device from array_api_extra.testing import lazy_xp_function -from .conftest import NUMPY_VERSION - lazy_xp_function(apply_where) lazy_xp_function(atleast_nd) lazy_xp_function(cov) diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 275ca519..43ad5dc7 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -24,7 +24,7 @@ from .conftest import np_compat -if TYPE_CHECKING: +if TYPE_CHECKING: # pragma: no cover # TODO import from typing (requires Python >=3.12) from typing_extensions import override else: diff --git a/tests/test_lazy.py b/tests/test_lazy.py index 503e180f..056d608b 100644 --- a/tests/test_lazy.py +++ b/tests/test_lazy.py @@ -141,7 +141,7 @@ def f(x: Array) -> Array: xp = array_namespace(x) return xp.sum(x, axis=0) + x - x_np = cast(Array, np.arange(15).reshape(5, 3)) + x_np = cast(Array, np.arange(15).reshape(5, 3)) # pyright: ignore[reportInvalidCast] expect = da.asarray(f(x_np)) x_da = da.asarray(x_np).rechunk(3) @@ -230,7 +230,7 @@ def test_lazy_apply_none_shape_in_args(xp: ModuleType, library: Backend): # Single output with ctx: values = lazy_apply(mxp.unique_values, x, shape=(None,)) - xp_assert_equal(values, xp.asarray([1, 2])) + xp_assert_equal(xp.sort(values), xp.asarray([1, 2])) with ctx: # Multi output diff --git a/tests/test_testing.py b/tests/test_testing.py index 33c36c12..7eda3fb6 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -18,7 +18,7 @@ is_jax_namespace, ) from array_api_extra._lib._utils._typing import Array, Device -from array_api_extra.testing import lazy_xp_function +from array_api_extra.testing import lazy_xp_function, patch_lazy_xp_functions # pyright: reportUnknownParameterType=false,reportMissingParameterType=false @@ -448,3 +448,23 @@ def test_lazy_xp_modules(xp: ModuleType, library: Backend): else: y = wrapped.f(x) xp_assert_equal(y, x) + + +def test_patch_lazy_xp_functions_deprecated_monkeypatch( + request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch +): + xp = pytest.importorskip("dask.array") + + x = xp.asarray([1.0, 2.0]) + y = non_materializable5(x) + xp_assert_equal(y, x) + + with pytest.warns(DeprecationWarning): + _ = patch_lazy_xp_functions(request, monkeypatch, xp=xp) + + with pytest.raises(AssertionError, match=r"dask\.compute.* 1 times"): + _ = non_materializable5(x) + + monkeypatch.undo() + y = non_materializable5(x) + xp_assert_equal(y, x)