diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 8d705bd621..0000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,210 +0,0 @@ -version: 2.1 -orbs: - codecov: codecov/codecov@3.2.4 - -commands: - setup: - steps: - - run: - name: Install dependencies and set path - command: | - sudo apt-get update - sudo apt-get install -y ninja-build libcunit1-dev valgrind clang doxygen python3-pip - # Install meson to the system packages so we can run it as root - pip install --upgrade pip wheel - sudo pip install meson - # Install uv for dependency management - pip install --user uv - # Install dependencies from pyproject.toml, no blas as expensive to - # build on 32 bit - pip install --user numpy --config-settings=setup-args="-Dallow-noblas=true" - cd python && uv pip install --system -r pyproject.toml --extra test --config-settings=setup-args="-Dallow-noblas=true" - # Remove tskit installed by msprime - pip uninstall tskit -y - echo 'export PATH=/home/circleci/.local/bin:$PATH' >> $BASH_ENV - - compile_and_test: - steps: - - run: - name: Compile Python - command: | - cd python && make allchecks - - - run: - name: Compile C with gcc - command: | - meson build-gcc c -D b_coverage=true - ninja -C build-gcc - - - run: - name: Compile C with clang - command: | - CC=clang CXX=clang++ meson build-clang c - ninja -C build-clang - - - run: - name: Compile C with gcc in 64 bit mode - command: | - CFLAGS=-D_TSK_BIG_TABLES CPPFLAGS=-D_TSK_BIG_TABLES meson build-gcc-bt c - ninja -C build-gcc-bt - - - run: - name: Run C tests - command: | - ninja -C build-gcc test - - - run: - name: Run gcov - command: | - cd build-gcc - find ../c/tskit/*.c -type f -printf "%f\n" | xargs -i gcov -pb libtskit.a.p/tskit_{}.gcno ../c/tskit/{} - - - codecov/upload: - flags: c-tests - token: CODECOV_TOKEN - - - run: - name: Valgrind for C tests. - command: | - valgrind --leak-check=full --error-exitcode=1 ./build-gcc/test_core - valgrind --leak-check=full --error-exitcode=1 ./build-gcc/test_tables - valgrind --leak-check=full --error-exitcode=1 ./build-gcc/test_trees - valgrind --leak-check=full --error-exitcode=1 ./build-gcc/test_genotypes - valgrind --leak-check=full --error-exitcode=1 ./build-gcc/test_convert - valgrind --leak-check=full --error-exitcode=1 ./build-gcc/test_stats - valgrind --leak-check=full --error-exitcode=1 ./build-gcc/test_haplotype_matching - valgrind --leak-check=full --error-exitcode=1 ./build-gcc/test_file_format - valgrind --leak-check=full --error-exitcode=1 ./build-gcc/test_minimal_cpp - - - run: - name: Valgrind for BIG_TABLES C tests. - command: | - valgrind --leak-check=full --error-exitcode=1 ./build-gcc-bt/test_core - valgrind --leak-check=full --error-exitcode=1 ./build-gcc-bt/test_tables - valgrind --leak-check=full --error-exitcode=1 ./build-gcc-bt/test_trees - valgrind --leak-check=full --error-exitcode=1 ./build-gcc-bt/test_genotypes - valgrind --leak-check=full --error-exitcode=1 ./build-gcc-bt/test_convert - valgrind --leak-check=full --error-exitcode=1 ./build-gcc-bt/test_stats - valgrind --leak-check=full --error-exitcode=1 ./build-gcc-bt/test_haplotype_matching - valgrind --leak-check=full --error-exitcode=1 ./build-gcc-bt/test_file_format - valgrind --leak-check=full --error-exitcode=1 ./build-gcc-bt/test_minimal_cpp - - - run: - name: Run clang-compiled C tests - command: | - ninja -C build-clang test - - - run: - name: Test building with meson subproject - command: | - meson build-subproject c/tests/meson-subproject - ninja -C build-subproject - ./build-subproject/example - - - run: - name: Install shared library and hand-compile program. - command: | - meson build-install c --prefix=/usr - sudo ninja -C build-install install - clang c/examples/api_structure.c -I c/subprojects/kastore -o api_structure -ltskit - ./api_structure - - - run: - name: Run example make file - command: | - make -C c/examples - - - run: - name: Build example LWT interface code and test - command: | - # We're assuming that the tskit C module has already - # been built, as we're testing against the local tskit version. - cd python/lwt_interface - make allchecks - python -m pytest -n2 - - - run: - name: Build cython example LWT interface code and run - command: | - cd python/lwt_interface/cython_example - make - - - run: - name: Generate coverage - command: | - # Make sure the C coverage reports aren't lying around - rm -fR build-gcc - ls -R - cd python/lwt_interface - gcov -pb -o ./build/temp.linux*/*.gcno example_c_module.c - - - codecov/upload: - flags: lwt-tests - token: CODECOV_TOKEN - - - run: - name: Run Python tests - command: | - cd python - python -m pytest --cov=tskit --cov-report=xml --cov-branch -n2 tests/test_lowlevel.py tests/test_tables.py tests/test_file_format.py - - - run: - name: Generate Python coverage - command: | - # Make sure the C coverage reports aren't lying around - rm -fR build-gcc - rm -f python/lwt_interface/*.gcov - cd python - gcov -pb -o ./build/temp.linux*/*.gcno _tskitmodule.c - - - codecov/upload: - flags: python-c-tests - token: CODECOV_TOKEN - -jobs: - build: - docker: - - image: cimg/python:3.10 - working_directory: /home/circleci/tskit - steps: - - checkout - - run: sudo chown -R circleci:circleci * - - restore_cache: - # It's sometimes necessary to nuke the cache, and the simplest - # way to do it is to change the key. We can increment this - # version number when we want to do this. - key: tskit-{{ .Branch }}-v8 - - setup - - save_cache: - key: tskit-{{ .Branch }}-v8 - paths: - - "/home/circleci/.local" - - compile_and_test - - build-32: - docker: - - image: tskitimages/testing-32bit:4.0 - working_directory: /home/circleci/tskit - steps: - - checkout - - run: sudo chown -R circleci:circleci * - - restore_cache: - key: tskit-32-{{ .Branch }}-v8 - - setup - - save_cache: - key: tskit-32-{{ .Branch }}-v8 - paths: - - "/home/circleci/.local" - # We need to install curl for the codecov upload. - - run: | - sudo apt-get install -y curl wget - - compile_and_test - -workflows: - test: - jobs: - - build - #Temporarily disabled due avoid compiling numpy on 32bit - # - build-32 - - diff --git a/.circleci/images/32bit/Dockerfile b/.circleci/images/32bit/Dockerfile deleted file mode 100644 index 1d414061f4..0000000000 --- a/.circleci/images/32bit/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM i386/python:3.10-slim-bullseye - -RUN apt-get update && apt-get install -y sudo rustc cargo libhdf5-dev libgsl-dev pkg-config libssl-dev llvm build-essential -RUN adduser --disabled-password --gecos "" circleci -RUN echo 'circleci ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers - -USER circleci diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a9d4ec9bd4..0846488b48 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -141,3 +141,70 @@ jobs: verbose: true flags: python-tests-no-jit + - name: Build example LWT interface code and test + working-directory: python/lwt_interface/ + run: | + make allchecks + uv run --project=../ --group=test pytest -vs + + - name: Build cython example LWT interface code and run + working-directory: python/lwt_interface/cython_example + run: make + + + bespoke-c-test: + name: Bespoke C tests + runs-on: ubuntu-24.04 + + steps: + - name: Cancel Previous Runs + uses: styfle/cancel-workflow-action@0.13.0 + with: + access_token: ${{ github.token }} + + - name: Checkout + uses: actions/checkout@v6.0.2 + with: + submodules: true + + - name: Install system deps + run: | + sudo apt-get update + sudo apt-get install -y libcunit1-dev ninja-build clang + + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + version: "0.10.2" + + - name: Install uv deps + run: | + uv tool install meson==1.10.1 + + - name: Configure code + run: CFLAGS=-D_TSK_BIG_TABLES CPPFLAGS=-D_TSK_BIG_TABLES meson setup build-bt c/ + + - name: Compile + run: ninja -C build-bt + + - name: Run tests + run: ninja -C build-bt test + + + - name: Test building with meson subproject + run: | + meson build-subproject c/tests/meson-subproject + ninja -C build-subproject + ./build-subproject/example + + - name: Install shared library and hand-compile program. + run: | + meson build-install c --prefix=/usr + sudo ninja -C build-install install + clang c/examples/api_structure.c -I c/subprojects/kastore -o api_structure -ltskit + ./api_structure + + - name: Run example make file + run: | + make -C c/examples + diff --git a/c/subprojects/kastore/VERSION.txt b/c/subprojects/kastore/VERSION.txt index 3e3c2f1e5e..eca07e4c1a 100644 --- a/c/subprojects/kastore/VERSION.txt +++ b/c/subprojects/kastore/VERSION.txt @@ -1 +1 @@ -2.1.1 +2.1.2 diff --git a/c/subprojects/kastore/kastore.h b/c/subprojects/kastore/kastore.h index fbd48cec22..3acc01aad1 100644 --- a/c/subprojects/kastore/kastore.h +++ b/c/subprojects/kastore/kastore.h @@ -157,7 +157,7 @@ to the API or ABI are introduced, i.e., the addition of a new function. The library patch version. Incremented when any changes not relevant to the to the API or ABI are introduced, i.e., internal refactors of bugfixes. */ -#define KAS_VERSION_PATCH 1 +#define KAS_VERSION_PATCH 2 /** @} */ #define KAS_HEADER_SIZE 64 diff --git a/c/subprojects/kastore/meson.build b/c/subprojects/kastore/meson.build index 1fd4b1b1d9..e635b7c945 100644 --- a/c/subprojects/kastore/meson.build +++ b/c/subprojects/kastore/meson.build @@ -26,25 +26,29 @@ if not meson.is_subproject() shared_library('kastore', 'kastore.c', install: true) executable('example', ['example.c'], link_with: kastore) - # Note: we don't declare these as meson tests because they depend on - # being run from the current working directory because of the paths - # to example files. cunit_dep = dependency('cunit') - executable('tests', ['tests.c', 'kastore.c'], dependencies: cunit_dep, + src_root = meson.project_source_root() + + tests_exe = executable('tests', ['tests.c', 'kastore.c'], dependencies: cunit_dep, c_args: ['-DMESON_VERSION="@0@"'.format(meson.project_version())]) + test('tests', tests_exe, + env: ['KAS_TEST_DATA_PREFIX=' + src_root + '/test-data/']) - executable('cpp_tests', ['cpp_tests.cpp'], link_with: kastore) + cpp_tests_exe = executable('cpp_tests', ['cpp_tests.cpp'], link_with: kastore) + test('cpp_tests', cpp_tests_exe) - executable('malloc_tests', ['malloc_tests.c', 'kastore.c'], - dependencies: cunit_dep, + malloc_tests_exe = executable('malloc_tests', ['malloc_tests.c', 'kastore.c'], + dependencies: cunit_dep, link_args:['-Wl,--wrap=malloc', '-Wl,--wrap=realloc', '-Wl,--wrap=calloc']) + test('malloc_tests', malloc_tests_exe, workdir: src_root) - executable('io_tests', ['io_tests.c', 'kastore.c'], - dependencies: cunit_dep, + io_tests_exe = executable('io_tests', ['io_tests.c', 'kastore.c'], + dependencies: cunit_dep, link_args:[ - '-Wl,--wrap=fwrite', - '-Wl,--wrap=fread', + '-Wl,--wrap=fwrite', + '-Wl,--wrap=fread', '-Wl,--wrap=fclose', '-Wl,--wrap=ftell', '-Wl,--wrap=fseek']) + test('io_tests', io_tests_exe, workdir: src_root) endif diff --git a/codecov.yml b/codecov.yml index 662bcb2b7f..9399884b23 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,6 +1,6 @@ -# ignore: -# - "lib/tests/" -# - "lib/subprojects/**/*" +ignore: + - "c/tests/" + - "c/subprojects/**/*" codecov: require_ci_to_pass: false @@ -8,9 +8,6 @@ codecov: comment: layout: "header, diff, flags, components" # show component info in the PR comment -# fixes: -# - "tskit/::python/tskit/" -# - "^_tskitmodule.*::python/_tskitmodule.*" component_management: individual_components: @@ -29,39 +26,3 @@ component_management: name: C library paths: - c - -# -# codecov: -# require_ci_to_pass: false -# comment: -# layout: "diff, flags, files" -# fixes: -# - "tskit/::python/tskit/" -# flag_management: -# individual_flags: -# - name: python-tests -# paths: -# - python/tskit/*.py -# statuses: -# - type: project -# target: 95% -# - name: python-c-tests -# paths: -# - python/_tskitmodule.c -# statuses: -# - type: project -# target: 85% -# - name: c-tests -# paths: -# - c/tskit/*.c -# - c/tskit/*.h -# statuses: -# - type: project -# target: 85% -# - name: lwt-tests -# paths: -# - python/lwt_interface/*.c -# - python/lwt_interface/*.h -# statuses: -# - type: project -# target: 80% diff --git a/docs/_config.yml b/docs/_config.yml index 28fba57b58..fb18e6594a 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -65,7 +65,6 @@ sphinx: python: ["https://docs.python.org/3/", null] tutorials: ["https://tskit.dev/tutorials/", null] stdpopsim: ["https://stdpopsim.readthedocs.io/en/stable", null] - pyslim: ["https://tskit.dev/pyslim/docs/latest/", null] msprime: ["https://tskit.dev/msprime/docs/stable/", null] numpy: ["https://numpy.org/doc/stable/", null] diff --git a/python/Makefile b/python/Makefile index a14783ec6b..50d0560686 100644 --- a/python/Makefile +++ b/python/Makefile @@ -1,17 +1,11 @@ -PYTHON := $(shell command -v python 2> /dev/null) -ifndef PYTHON -$(error "python is not available via the `python` executable. If you have python only via `python3` you may need to `apt install python-is-python3`") -endif - all: ext3 allchecks: _tskitmodule.c CFLAGS="-std=c99 --coverage -Wall -Wextra -Werror -Wno-unused-parameter -Wno-cast-function-type" \ - python setup.py build_ext --inplace + uv run python setup.py build_ext --inplace ext3: _tskitmodule.c - - python setup.py build_ext --inplace + uv run python setup.py build_ext --inplace ctags: ctags lib/*.c lib/*.h tskit/*.py diff --git a/python/lwt_interface/Makefile b/python/lwt_interface/Makefile index 66941642b1..9a82ca3b31 100644 --- a/python/lwt_interface/Makefile +++ b/python/lwt_interface/Makefile @@ -3,10 +3,10 @@ all: cmodule allchecks: example_c_module.c CFLAGS="-std=c99 --coverage -Wall -Wextra -Werror -Wno-unused-parameter -Wno-cast-function-type" \ - python3 setup.py build_ext --inplace + uv run --project=../ python setup.py build_ext --inplace cmodule: example_c_module.c - python3 setup.py build_ext --inplace + uv run --project=../ python setup.py build_ext --inplace clean: rm -f *.so *.o tags diff --git a/python/lwt_interface/cython_example/Makefile b/python/lwt_interface/cython_example/Makefile index 7b0350eda9..8e6d261b60 100644 --- a/python/lwt_interface/cython_example/Makefile +++ b/python/lwt_interface/cython_example/Makefile @@ -1,10 +1,10 @@ all: compile run compile: - pip install -e . --use-pep517 + uv run --project=../../ --group=test-lwt setup.py build_ext --inplace run: - PYTHONPATH=../.. python -c "import example; example.main()" + uv run --project=../../ --group=test-lwt python -c "import example; example.main()" clean: rm -rf build/ diff --git a/python/pyproject.toml b/python/pyproject.toml index bdc71b1149..05a021db37 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -82,6 +82,12 @@ test = [ "zarr", ] +test-lwt = [ + "cython", + "pytest", + "pytest-cov", +] + docs = [ "jupyter-book<2", "breathe", @@ -94,7 +100,6 @@ docs = [ "pandas", ] - wheels = [ "cibuildwheel", ] diff --git a/python/tests/test_python_c.py b/python/tests/test_python_c.py index 702010acf7..8bb5fdac1f 100644 --- a/python/tests/test_python_c.py +++ b/python/tests/test_python_c.py @@ -5073,7 +5073,7 @@ class TestModuleFunctions: def test_kastore_version(self): version = _tskit.get_kastore_version() - assert version == (2, 1, 1) + assert version == (2, 1, 2) def test_tskit_version(self): version = _tskit.get_tskit_version() @@ -5365,15 +5365,6 @@ def test_cpy_bad_node_bin_map(self): with pytest.raises(TypeError, match="cast array data"): self.pair_coalescence_quantiles(ts, node_bin_map=np.zeros(num_nodes)) - def test_cpy_bad_quantiles(self): - ts = self.example_ts() - quantiles = np.zeros(0) - with pytest.raises(ValueError, match="at least one quantile"): - self.pair_coalescence_quantiles(ts, quantiles=quantiles) - quantiles = np.zeros((3, 3)) - with pytest.raises(ValueError, match="object too deep"): - self.pair_coalescence_quantiles(ts, quantiles=quantiles) - def test_cpy_bad_inputs(self): ts = self.example_ts() with pytest.raises(TypeError, match="at most 6 keyword"): @@ -5387,6 +5378,15 @@ def test_cpy_bad_inputs(self): foo="bar", ) + def test_cpy_bad_quantiles(self): + ts = self.example_ts() + quantiles = np.zeros(0) + with pytest.raises(ValueError, match="at least one quantile"): + self.pair_coalescence_quantiles(ts, quantiles=quantiles) + quantiles = np.zeros((3, 3)) + with pytest.raises(ValueError, match="object too deep"): + self.pair_coalescence_quantiles(ts, quantiles=quantiles) + class TestPairCoalescenceRatesErrors: def example_ts(self, sample_size=10): diff --git a/python/uv.lock b/python/uv.lock index ec23dbc595..bf2f8f830b 100644 --- a/python/uv.lock +++ b/python/uv.lock @@ -493,6 +493,40 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ae/11/7e500d2dd3ba891197b9efd2da5454b74336d64a7cc419aa7327ab74e5f6/cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257", size = 4381252, upload-time = "2026-02-10T19:18:27.496Z" }, ] +[[package]] +name = "cython" +version = "3.2.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/85/7574c9cd44b69a27210444b6650f6477f56c75fee1b70d7672d3e4166167/cython-3.2.4.tar.gz", hash = "sha256:84226ecd313b233da27dc2eb3601b4f222b8209c3a7216d8733b031da1dc64e6", size = 3280291, upload-time = "2026-01-04T14:14:14.473Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/cc/8f06145ec3efa121c8b1b67f06a640386ddacd77ee3e574da582a21b14ee/cython-3.2.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff9af2134c05e3734064808db95b4dd7341a39af06e8945d05ea358e1741aaed", size = 2953769, upload-time = "2026-01-04T14:15:00.361Z" }, + { url = "https://files.pythonhosted.org/packages/55/b0/706cf830eddd831666208af1b3058c2e0758ae157590909c1f634b53bed9/cython-3.2.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67922c9de058a0bfb72d2e75222c52d09395614108c68a76d9800f150296ddb3", size = 3243841, upload-time = "2026-01-04T14:15:02.066Z" }, + { url = "https://files.pythonhosted.org/packages/ac/25/58893afd4ef45f79e3d4db82742fa4ff874b936d67a83c92939053920ccd/cython-3.2.4-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b362819d155fff1482575e804e43e3a8825332d32baa15245f4642022664a3f4", size = 3378083, upload-time = "2026-01-04T14:15:04.248Z" }, + { url = "https://files.pythonhosted.org/packages/32/e4/424a004d7c0d8a4050c81846ebbd22272ececfa9a498cb340aa44fccbec2/cython-3.2.4-cp311-cp311-win_amd64.whl", hash = "sha256:1a64a112a34ec719b47c01395647e54fb4cf088a511613f9a3a5196694e8e382", size = 2769990, upload-time = "2026-01-04T14:15:06.53Z" }, + { url = "https://files.pythonhosted.org/packages/91/4d/1eb0c7c196a136b1926f4d7f0492a96c6fabd604d77e6cd43b56a3a16d83/cython-3.2.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:64d7f71be3dd6d6d4a4c575bb3a4674ea06d1e1e5e4cd1b9882a2bc40ed3c4c9", size = 2970064, upload-time = "2026-01-04T14:15:08.567Z" }, + { url = "https://files.pythonhosted.org/packages/03/1c/46e34b08bea19a1cdd1e938a4c123e6299241074642db9d81983cef95e9f/cython-3.2.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:869487ea41d004f8b92171f42271fbfadb1ec03bede3158705d16cd570d6b891", size = 3226757, upload-time = "2026-01-04T14:15:10.812Z" }, + { url = "https://files.pythonhosted.org/packages/12/33/3298a44d201c45bcf0d769659725ae70e9c6c42adf8032f6d89c8241098d/cython-3.2.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:55b6c44cd30821f0b25220ceba6fe636ede48981d2a41b9bbfe3c7902ce44ea7", size = 3388969, upload-time = "2026-01-04T14:15:12.45Z" }, + { url = "https://files.pythonhosted.org/packages/bb/f3/4275cd3ea0a4cf4606f9b92e7f8766478192010b95a7f516d1b7cf22cb10/cython-3.2.4-cp312-cp312-win_amd64.whl", hash = "sha256:767b143704bdd08a563153448955935844e53b852e54afdc552b43902ed1e235", size = 2756457, upload-time = "2026-01-04T14:15:14.67Z" }, + { url = "https://files.pythonhosted.org/packages/18/b5/1cfca43b7d20a0fdb1eac67313d6bb6b18d18897f82dd0f17436bdd2ba7f/cython-3.2.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:28e8075087a59756f2d059273184b8b639fe0f16cf17470bd91c39921bc154e0", size = 2960506, upload-time = "2026-01-04T14:15:16.733Z" }, + { url = "https://files.pythonhosted.org/packages/71/bb/8f28c39c342621047fea349a82fac712a5e2b37546d2f737bbde48d5143d/cython-3.2.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:03893c88299a2c868bb741ba6513357acd104e7c42265809fd58dce1456a36fc", size = 3213148, upload-time = "2026-01-04T14:15:18.804Z" }, + { url = "https://files.pythonhosted.org/packages/7a/d2/16fa02f129ed2b627e88d9d9ebd5ade3eeb66392ae5ba85b259d2d52b047/cython-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8", size = 3375764, upload-time = "2026-01-04T14:15:20.817Z" }, + { url = "https://files.pythonhosted.org/packages/91/3f/deb8f023a5c10c0649eb81332a58c180fad27c7533bb4aae138b5bc34d92/cython-3.2.4-cp313-cp313-win_amd64.whl", hash = "sha256:83266c356c13c68ffe658b4905279c993d8a5337bb0160fa90c8a3e297ea9a2e", size = 2754238, upload-time = "2026-01-04T14:15:23.001Z" }, + { url = "https://files.pythonhosted.org/packages/ee/d7/3bda3efce0c5c6ce79cc21285dbe6f60369c20364e112f5a506ee8a1b067/cython-3.2.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d4b4fd5332ab093131fa6172e8362f16adef3eac3179fd24bbdc392531cb82fa", size = 2971496, upload-time = "2026-01-04T14:15:25.038Z" }, + { url = "https://files.pythonhosted.org/packages/89/ed/1021ffc80b9c4720b7ba869aea8422c82c84245ef117ebe47a556bdc00c3/cython-3.2.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3b5ac54e95f034bc7fb07313996d27cbf71abc17b229b186c1540942d2dc28e", size = 3256146, upload-time = "2026-01-04T14:15:26.741Z" }, + { url = "https://files.pythonhosted.org/packages/0c/51/ca221ec7e94b3c5dc4138dcdcbd41178df1729c1e88c5dfb25f9d30ba3da/cython-3.2.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90f43be4eaa6afd58ce20d970bb1657a3627c44e1760630b82aa256ba74b4acb", size = 3383458, upload-time = "2026-01-04T14:15:28.425Z" }, + { url = "https://files.pythonhosted.org/packages/79/2e/1388fc0243240cd54994bb74f26aaaf3b2e22f89d3a2cf8da06d75d46ca2/cython-3.2.4-cp314-cp314-win_amd64.whl", hash = "sha256:983f9d2bb8a896e16fa68f2b37866ded35fa980195eefe62f764ddc5f9f5ef8e", size = 2791241, upload-time = "2026-01-04T14:15:30.448Z" }, + { url = "https://files.pythonhosted.org/packages/0a/8b/fd393f0923c82be4ec0db712fffb2ff0a7a131707b842c99bf24b549274d/cython-3.2.4-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:36bf3f5eb56d5281aafabecbaa6ed288bc11db87547bba4e1e52943ae6961ccf", size = 2875622, upload-time = "2026-01-04T14:15:39.749Z" }, + { url = "https://files.pythonhosted.org/packages/73/48/48530d9b9d64ec11dbe0dd3178a5fe1e0b27977c1054ecffb82be81e9b6a/cython-3.2.4-cp39-abi3-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6d5267f22b6451eb1e2e1b88f6f78a2c9c8733a6ddefd4520d3968d26b824581", size = 3210669, upload-time = "2026-01-04T14:15:41.911Z" }, + { url = "https://files.pythonhosted.org/packages/5e/91/4865fbfef1f6bb4f21d79c46104a53d1a3fa4348286237e15eafb26e0828/cython-3.2.4-cp39-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3b6e58f73a69230218d5381817850ce6d0da5bb7e87eb7d528c7027cbba40b06", size = 2856835, upload-time = "2026-01-04T14:15:43.815Z" }, + { url = "https://files.pythonhosted.org/packages/fa/39/60317957dbef179572398253f29d28f75f94ab82d6d39ea3237fb6c89268/cython-3.2.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e71efb20048358a6b8ec604a0532961c50c067b5e63e345e2e359fff72feaee8", size = 2994408, upload-time = "2026-01-04T14:15:45.422Z" }, + { url = "https://files.pythonhosted.org/packages/8d/30/7c24d9292650db4abebce98abc9b49c820d40fa7c87921c0a84c32f4efe7/cython-3.2.4-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:28b1e363b024c4b8dcf52ff68125e635cb9cb4b0ba997d628f25e32543a71103", size = 2891478, upload-time = "2026-01-04T14:15:47.394Z" }, + { url = "https://files.pythonhosted.org/packages/86/70/03dc3c962cde9da37a93cca8360e576f904d5f9beecfc9d70b1f820d2e5f/cython-3.2.4-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:31a90b4a2c47bb6d56baeb926948348ec968e932c1ae2c53239164e3e8880ccf", size = 3225663, upload-time = "2026-01-04T14:15:49.446Z" }, + { url = "https://files.pythonhosted.org/packages/b1/97/10b50c38313c37b1300325e2e53f48ea9a2c078a85c0c9572057135e31d5/cython-3.2.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e65e4773021f8dc8532010b4fbebe782c77f9a0817e93886e518c93bd6a44e9d", size = 3115628, upload-time = "2026-01-04T14:15:51.323Z" }, + { url = "https://files.pythonhosted.org/packages/8f/b1/d6a353c9b147848122a0db370863601fdf56de2d983b5c4a6a11e6ee3cd7/cython-3.2.4-cp39-abi3-win32.whl", hash = "sha256:2b1f12c0e4798293d2754e73cd6f35fa5bbdf072bdc14bc6fc442c059ef2d290", size = 2437463, upload-time = "2026-01-04T14:15:53.787Z" }, + { url = "https://files.pythonhosted.org/packages/2d/d8/319a1263b9c33b71343adfd407e5daffd453daef47ebc7b642820a8b68ed/cython-3.2.4-cp39-abi3-win_arm64.whl", hash = "sha256:3b8e62049afef9da931d55de82d8f46c9a147313b69d5ff6af6e9121d545ce7a", size = 2442754, upload-time = "2026-01-04T14:15:55.382Z" }, + { url = "https://files.pythonhosted.org/packages/ff/fa/d3c15189f7c52aaefbaea76fb012119b04b9013f4bf446cb4eb4c26c4e6b/cython-3.2.4-py3-none-any.whl", hash = "sha256:732fc93bc33ae4b14f6afaca663b916c2fdd5dcbfad7114e17fb2434eeaea45c", size = 1257078, upload-time = "2026-01-04T14:14:12.373Z" }, +] + [[package]] name = "debugpy" version = "1.8.20" @@ -2829,6 +2863,11 @@ test = [ { name = "xmlunittest" }, { name = "zarr" }, ] +test-lwt = [ + { name = "cython" }, + { name = "pytest" }, + { name = "pytest-cov" }, +] wheels = [ { name = "cibuildwheel" }, ] @@ -2913,6 +2952,11 @@ test = [ { name = "xmlunittest" }, { name = "zarr" }, ] +test-lwt = [ + { name = "cython" }, + { name = "pytest" }, + { name = "pytest-cov" }, +] wheels = [{ name = "cibuildwheel" }] [[package]]