diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 849d44efc9..0c794d9b08 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -31,14 +31,3 @@ updates:
- "*"
cooldown:
default-days: 7
- - package-ecosystem: "github-actions"
- directory: "/"
- target-branch: "support/v2"
- schedule:
- interval: "weekly"
- groups:
- actions:
- patterns:
- - "*"
- cooldown:
- default-days: 7
diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml
index a77e99bc28..1d8e847ec5 100644
--- a/.github/workflows/codspeed.yml
+++ b/.github/workflows/codspeed.yml
@@ -32,7 +32,7 @@ jobs:
with:
version: '1.16.5'
- name: Run the benchmarks
- uses: CodSpeedHQ/action@63f3e98b61959fe67f146a3ff022e4136fe9bb9c # v4.17.6
+ uses: CodSpeedHQ/action@a4a36bb07c0638b0b4ca52bf1f3dad1b4289e52f # v4.18.1
with:
mode: walltime
run: hatch run test.py3.12-minimal:pytest tests/benchmarks --codspeed
diff --git a/.github/workflows/downstream.yml b/.github/workflows/downstream.yml
index c592fb3cd6..d8aa2907be 100644
--- a/.github/workflows/downstream.yml
+++ b/.github/workflows/downstream.yml
@@ -40,7 +40,7 @@ jobs:
# `meson-python: error: Unknown option "pixi-conda-environment"`, breaking
# the job before any test runs. Tests that need a backend we don't install
# are skipped via xarray's `requires_*` markers, not failed.
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.13'
@@ -97,7 +97,7 @@ jobs:
submodules: recursive
persist-credentials: false
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.13'
diff --git a/.github/workflows/gpu_test.yml b/.github/workflows/gpu_test.yml
index 60c871cb15..f2bf4907fa 100644
--- a/.github/workflows/gpu_test.yml
+++ b/.github/workflows/gpu_test.yml
@@ -57,7 +57,7 @@ jobs:
echo $LD_LIBRARY_PATH
nvcc -V
- name: Set up Python
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
diff --git a/.github/workflows/hypothesis.yaml b/.github/workflows/hypothesis.yaml
index b1262cee06..01212dfb56 100644
--- a/.github/workflows/hypothesis.yaml
+++ b/.github/workflows/hypothesis.yaml
@@ -52,7 +52,7 @@ jobs:
echo "HYPOTHESIS_PROFILE=ci" >> $GITHUB_ENV
fi
- name: Set up Python
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
@@ -71,7 +71,7 @@ jobs:
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#update-a-cache
- name: Restore cached hypothesis directory
id: restore-hypothesis-cache
- uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: .hypothesis/
key: cache-hypothesis-${{ runner.os }}-${{ github.run_id }}
@@ -91,7 +91,7 @@ jobs:
- name: Save cached hypothesis directory
id: save-hypothesis-cache
if: always() && steps.status.outcome != 'skipped'
- uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
+ uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: .hypothesis/
key: cache-hypothesis-${{ runner.os }}-${{ github.run_id }}
@@ -109,7 +109,7 @@ jobs:
&& steps.status.outcome == 'failure'
&& github.event_name == 'schedule'
&& github.repository_owner == 'zarr-developers'
- uses: scientific-python/issue-from-pytest-log-action@8e905db353437cda1d6a773de245343fbfc940dd # v1.5.0
+ uses: scientific-python/issue-from-pytest-log-action@87351a8f864e969567cda22a25a2f214cbe2340f # v1.6.0
with:
log-path: output-${{ matrix.python-version }}-log.jsonl
issue-title: "Nightly Hypothesis tests failed"
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index d60c9f59b4..8190b1e061 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -23,11 +23,11 @@ jobs:
with:
persist-credentials: false
- name: Set up Python
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- name: Install uv
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
with:
enable-cache: true
- - uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4
+ - uses: j178/prek-action@e98a699c41eb69ab013a45817a0406469a748f8d # v2.0.5
diff --git a/.github/workflows/nightly_wheels.yml b/.github/workflows/nightly_wheels.yml
index 85f07cc8a1..0a0cafd425 100644
--- a/.github/workflows/nightly_wheels.yml
+++ b/.github/workflows/nightly_wheels.yml
@@ -28,7 +28,7 @@ jobs:
fetch-depth: 0
persist-credentials: false
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
name: Install Python
with:
python-version: '3.14'
diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
index c930eea689..4d460f4a56 100644
--- a/.github/workflows/releases.yml
+++ b/.github/workflows/releases.yml
@@ -32,7 +32,7 @@ jobs:
fetch-depth: 0
persist-credentials: false
- - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
name: Install Python
with:
python-version: '3.12'
@@ -81,7 +81,7 @@ jobs:
name: releases
path: dist
- name: Generate artifact attestation
- uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
+ uses: actions/attest@a1948c3f048ba23858d222213b7c278aabede763 # v4.1.1
with:
subject-path: dist/*
- name: Publish package to PyPI
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index a75974f6c9..7bc43512b5 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -61,7 +61,7 @@ jobs:
fetch-depth: 0 # grab all branches and tags
persist-credentials: false
- name: Set up Python
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
@@ -110,7 +110,7 @@ jobs:
fetch-depth: 0
persist-credentials: false
- name: Set up Python
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
@@ -145,7 +145,7 @@ jobs:
fetch-depth: 0 # required for hatch version discovery, which is needed for numcodecs.zarr3
persist-credentials: false
- name: Set up Python
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.13'
cache: 'pip'
@@ -169,7 +169,7 @@ jobs:
fetch-depth: 0
persist-credentials: false
- name: Set up Python
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.13'
cache: 'pip'
diff --git a/.github/workflows/zarr-metadata-release.yml b/.github/workflows/zarr-metadata-release.yml
index 689d3392ba..db05489798 100644
--- a/.github/workflows/zarr-metadata-release.yml
+++ b/.github/workflows/zarr-metadata-release.yml
@@ -82,7 +82,7 @@ jobs:
path: dist
- name: Generate artifact attestation
- uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
+ uses: actions/attest@a1948c3f048ba23858d222213b7c278aabede763 # v4.1.1
with:
subject-path: dist/*
@@ -107,7 +107,7 @@ jobs:
path: dist
- name: Generate artifact attestation
- uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
+ uses: actions/attest@a1948c3f048ba23858d222213b7c278aabede763 # v4.1.1
with:
subject-path: dist/*
diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml
index 2b08f619f0..6250426bae 100644
--- a/.github/workflows/zizmor.yml
+++ b/.github/workflows/zizmor.yml
@@ -32,4 +32,4 @@ jobs:
persist-credentials: false
- name: Run zizmor
- uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6
+ uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index fb2e8c3c6f..e08c98abca 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -15,7 +15,7 @@ default_language_version:
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
- rev: v0.15.15
+ rev: v0.15.20
hooks:
- id: ruff-check
args: ["--fix", "--show-fixes"]
@@ -41,11 +41,11 @@ repos:
always_run: true
types_or: [python, pyi]
- repo: https://github.com/scientific-python/cookie
- rev: 2026.04.04
+ rev: 2026.06.18
hooks:
- id: sp-repo-review
- repo: https://github.com/numpy/numpydoc
- rev: v1.10.0
+ rev: v1.11.0rc0
hooks:
- id: numpydoc-validation
- repo: local
@@ -58,7 +58,7 @@ repos:
types: [python]
files: ^(src|tests)/
- repo: https://github.com/zizmorcore/zizmor-pre-commit
- rev: v1.25.2
+ rev: v1.26.1
hooks:
- id: zizmor
- repo: https://github.com/twisted/towncrier
diff --git a/README.md b/README.md
index 45410eeb7b..fb0890d18c 100644
--- a/README.md
+++ b/README.md
@@ -4,97 +4,14 @@
# Zarr
-
-
- | Latest Release |
-
-
-
-
- |
-
-
- |
-
-
-
-
- |
-
-
- | Package Status |
-
-
-
-
- |
-
-
- | License |
-
-
-
-
- |
-
-
- | Build Status |
-
-
-
-
- |
-
-
- | Pre-commit Status |
-
-
-
-
- |
-
-
- | Coverage |
-
-
-
-
- |
-
-
- | Downloads |
-
-
-
-
- |
-
-
- | Developer Chat |
-
-
-
-
- |
-
-
- | Funding |
-
-
-
-
- |
-
-
- | Citation |
-
-
-
-
- |
-
-
-
+[](https://pypi.org/project/zarr/)
+[](https://anaconda.org/anaconda/zarr/)
+[](https://pypi.org/project/zarr/)
+[](https://github.com/zarr-developers/zarr-python/blob/main/LICENSE.txt)
+[](https://codecov.io/gh/zarr-developers/zarr-python)
+[](https://zarr.readthedocs.io)
+[](https://ossci.zulipchat.com/#narrow/channel/423692-Zarr-Python)
+[](https://doi.org/10.5281/zenodo.3773450)
## What is it?
diff --git a/changes/215.misc.md b/changes/215.misc.md
new file mode 100644
index 0000000000..f8df7cc632
--- /dev/null
+++ b/changes/215.misc.md
@@ -0,0 +1 @@
+Enable pytest's `strict = true` config option (strict config, markers, xfail, and parametrization ids), replacing the `--strict-config`/`--strict-markers` addopts flags that pytest silently ignored before 9.1, and fix the seven duplicate parametrization ids it surfaced — including restoring float-JSON roundtrip cases that were meant to cover numpy scalars but ran plain-float cases twice instead. Also arm pytest's faulthandler watchdog (`faulthandler_timeout = 600` with `faulthandler_exit_on_timeout`) so a deadlocked test dumps every thread's traceback and fails the run instead of hanging indefinitely.
diff --git a/changes/3009.doc.md b/changes/3009.doc.md
new file mode 100644
index 0000000000..777672b77b
--- /dev/null
+++ b/changes/3009.doc.md
@@ -0,0 +1 @@
+Document the changes to `zarr.errors` in the 3.0 migration guide, including the removal of v2 exception classes and the introduction of `NodeNotFoundError`.
diff --git a/changes/3984.doc.md b/changes/3984.doc.md
new file mode 100644
index 0000000000..1b92fb8e74
--- /dev/null
+++ b/changes/3984.doc.md
@@ -0,0 +1,4 @@
+Clarify the difference between `zarr.load` and `zarr.open` in their docstrings.
+`load` eagerly reads data into an in-memory array, while `open` returns a
+lazy `Array` or `Group` backed by the store, with `See Also` cross-references
+linking the two.
diff --git a/changes/4116.bugfix.md b/changes/4116.bugfix.md
new file mode 100644
index 0000000000..e99eac8c95
--- /dev/null
+++ b/changes/4116.bugfix.md
@@ -0,0 +1 @@
+Fixed writing Fortran-ordered (F-contiguous) arrays through the variable-length string and bytes codecs and through numcodecs array-array filters such as `Delta`, `FixedScaleOffset` and `PackBits`. Chunks are now passed to numcodecs as C-contiguous arrays, so elements are no longer stored in transposed order.
diff --git a/changes/4132.doc.md b/changes/4132.doc.md
new file mode 100644
index 0000000000..3325c82f43
--- /dev/null
+++ b/changes/4132.doc.md
@@ -0,0 +1,6 @@
+Fixed many documentation errors found in a full review of the user guide, including
+prose contradicted by rendered example output on the performance page, invisible
+code blocks, an incorrect S3 example, stale "not yet implemented" claims in the
+v3 migration guide, and undocumented optional dependency groups. Also improved
+navigation order, cross-linking between pages, and coverage of group member
+enumeration, bulk attribute updates, and the `use_consolidated` keyword.
diff --git a/changes/4133.doc.md b/changes/4133.doc.md
new file mode 100644
index 0000000000..9690318b46
--- /dev/null
+++ b/changes/4133.doc.md
@@ -0,0 +1 @@
+Fixed the documented default of ``max_age_seconds`` in the ``CacheStore`` docstring: the default is ``"infinity"`` (no expiration), not ``None``, which is rejected. Also noted that ``cache_store`` must support deletes.
diff --git a/changes/4138.misc.md b/changes/4138.misc.md
new file mode 100644
index 0000000000..2cf0365bb9
--- /dev/null
+++ b/changes/4138.misc.md
@@ -0,0 +1 @@
+Pass a list rather than a generator to `pytest.mark.parametrize` in `tests/test_docs.py`, so the test suite collects cleanly under pytest 9.1 (which deprecates non-Collection iterables and, under `filterwarnings = error`, turns that into a collection error).
diff --git a/docs/api/zarr/abc/index.md b/docs/api/zarr/abc/index.md
index 7c2fb2ef13..7e15cb2a51 100644
--- a/docs/api/zarr/abc/index.md
+++ b/docs/api/zarr/abc/index.md
@@ -1,7 +1,13 @@
-## Abstract base classes
+---
+title: zarr.abc
+---
-- **[buffer](./buffer.md)** - Providing access to underlying memory via [buffers](https://docs.python.org/3/c-api/buffer.html)
-- **[codec](./codec.md)** - Expressing [zarr codecs](https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html#chunk-encoding)
-- **[metadata](./metadata.md)** - Creating metadata classes compatible with the Zarr API
-- **[numcodec](./numcodec.md)** - Protocols and classes for modeling codec interface used by numcodecs
-- **[store](./store.md)** - ABC for implementing Zarr stores and managing getting and setting bytes in a store
\ No newline at end of file
+# zarr.abc
+
+Abstract base classes for extending Zarr-Python.
+
+- **[zarr.abc.buffer](./buffer.md)** - Providing access to underlying memory via [buffers](https://docs.python.org/3/c-api/buffer.html)
+- **[zarr.abc.codec](./codec.md)** - Expressing [zarr codecs](https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html#chunk-encoding)
+- **[zarr.abc.metadata](./metadata.md)** - Creating metadata classes compatible with the Zarr API
+- **[zarr.abc.numcodec](./numcodec.md)** - Protocols and classes for modeling codec interface used by numcodecs
+- **[zarr.abc.store](./store.md)** - ABC for implementing Zarr stores and managing getting and setting bytes in a store
diff --git a/docs/api/zarr/api/index.md b/docs/api/zarr/api/index.md
index 75b4fff62b..7fac5e766a 100644
--- a/docs/api/zarr/api/index.md
+++ b/docs/api/zarr/api/index.md
@@ -1,5 +1,7 @@
---
-title: API
+title: zarr.api
---
+# zarr.api
+
Zarr provides both an [async](./asynchronous.md) and a [sync](./synchronous.md) API. See those pages for more details.
diff --git a/docs/api/zarr/buffer/index.md b/docs/api/zarr/buffer/index.md
index 0b303781e1..ebbb9e1c99 100644
--- a/docs/api/zarr/buffer/index.md
+++ b/docs/api/zarr/buffer/index.md
@@ -1,3 +1,7 @@
+---
+title: zarr.buffer
+---
+
Zarr provides buffer classes for both the [cpu](./cpu.md) and [gpu](./gpu.md). Generic buffer functionality is also detailed below.
::: zarr.buffer
diff --git a/docs/api/zarr/create.md b/docs/api/zarr/create.md
deleted file mode 100644
index 971e9c293c..0000000000
--- a/docs/api/zarr/create.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: create
----
-
-::: zarr.array
-::: zarr.create
-::: zarr.create_array
-::: zarr.create_group
-::: zarr.create_hierarchy
-::: zarr.empty
-::: zarr.empty_like
-::: zarr.full
-::: zarr.full_like
-::: zarr.from_array
-::: zarr.group
-::: zarr.ones
-::: zarr.ones_like
-::: zarr.zeros
-::: zarr.zeros_like
diff --git a/docs/api/zarr/functions/array.md b/docs/api/zarr/functions/array.md
new file mode 100644
index 0000000000..ff7242005c
--- /dev/null
+++ b/docs/api/zarr/functions/array.md
@@ -0,0 +1,5 @@
+---
+title: zarr.array
+---
+
+::: zarr.array
diff --git a/docs/api/zarr/functions/consolidate_metadata.md b/docs/api/zarr/functions/consolidate_metadata.md
new file mode 100644
index 0000000000..946531f028
--- /dev/null
+++ b/docs/api/zarr/functions/consolidate_metadata.md
@@ -0,0 +1,5 @@
+---
+title: zarr.consolidate_metadata
+---
+
+::: zarr.consolidate_metadata
diff --git a/docs/api/zarr/functions/create.md b/docs/api/zarr/functions/create.md
new file mode 100644
index 0000000000..b43094eaba
--- /dev/null
+++ b/docs/api/zarr/functions/create.md
@@ -0,0 +1,5 @@
+---
+title: zarr.create
+---
+
+::: zarr.create
diff --git a/docs/api/zarr/functions/create_array.md b/docs/api/zarr/functions/create_array.md
new file mode 100644
index 0000000000..a9f4a24bd0
--- /dev/null
+++ b/docs/api/zarr/functions/create_array.md
@@ -0,0 +1,5 @@
+---
+title: zarr.create_array
+---
+
+::: zarr.create_array
diff --git a/docs/api/zarr/functions/create_group.md b/docs/api/zarr/functions/create_group.md
new file mode 100644
index 0000000000..50beb0674c
--- /dev/null
+++ b/docs/api/zarr/functions/create_group.md
@@ -0,0 +1,5 @@
+---
+title: zarr.create_group
+---
+
+::: zarr.create_group
diff --git a/docs/api/zarr/functions/create_hierarchy.md b/docs/api/zarr/functions/create_hierarchy.md
new file mode 100644
index 0000000000..38938ffee2
--- /dev/null
+++ b/docs/api/zarr/functions/create_hierarchy.md
@@ -0,0 +1,5 @@
+---
+title: zarr.create_hierarchy
+---
+
+::: zarr.create_hierarchy
diff --git a/docs/api/zarr/functions/empty.md b/docs/api/zarr/functions/empty.md
new file mode 100644
index 0000000000..aff67bb9ed
--- /dev/null
+++ b/docs/api/zarr/functions/empty.md
@@ -0,0 +1,5 @@
+---
+title: zarr.empty
+---
+
+::: zarr.empty
diff --git a/docs/api/zarr/functions/empty_like.md b/docs/api/zarr/functions/empty_like.md
new file mode 100644
index 0000000000..9e2fbd26a5
--- /dev/null
+++ b/docs/api/zarr/functions/empty_like.md
@@ -0,0 +1,5 @@
+---
+title: zarr.empty_like
+---
+
+::: zarr.empty_like
diff --git a/docs/api/zarr/functions/from_array.md b/docs/api/zarr/functions/from_array.md
new file mode 100644
index 0000000000..7ab8179b05
--- /dev/null
+++ b/docs/api/zarr/functions/from_array.md
@@ -0,0 +1,5 @@
+---
+title: zarr.from_array
+---
+
+::: zarr.from_array
diff --git a/docs/api/zarr/functions/full.md b/docs/api/zarr/functions/full.md
new file mode 100644
index 0000000000..d6c60de2d5
--- /dev/null
+++ b/docs/api/zarr/functions/full.md
@@ -0,0 +1,5 @@
+---
+title: zarr.full
+---
+
+::: zarr.full
diff --git a/docs/api/zarr/functions/full_like.md b/docs/api/zarr/functions/full_like.md
new file mode 100644
index 0000000000..eb5c162f76
--- /dev/null
+++ b/docs/api/zarr/functions/full_like.md
@@ -0,0 +1,5 @@
+---
+title: zarr.full_like
+---
+
+::: zarr.full_like
diff --git a/docs/api/zarr/functions/group.md b/docs/api/zarr/functions/group.md
new file mode 100644
index 0000000000..3048218f6b
--- /dev/null
+++ b/docs/api/zarr/functions/group.md
@@ -0,0 +1,5 @@
+---
+title: zarr.group
+---
+
+::: zarr.group
diff --git a/docs/api/zarr/load.md b/docs/api/zarr/functions/load.md
similarity index 57%
rename from docs/api/zarr/load.md
rename to docs/api/zarr/functions/load.md
index d6463ca976..aa004076ab 100644
--- a/docs/api/zarr/load.md
+++ b/docs/api/zarr/functions/load.md
@@ -1,5 +1,5 @@
---
-title: load
+title: zarr.load
---
::: zarr.load
diff --git a/docs/api/zarr/functions/ones.md b/docs/api/zarr/functions/ones.md
new file mode 100644
index 0000000000..b7757da1bc
--- /dev/null
+++ b/docs/api/zarr/functions/ones.md
@@ -0,0 +1,5 @@
+---
+title: zarr.ones
+---
+
+::: zarr.ones
diff --git a/docs/api/zarr/functions/ones_like.md b/docs/api/zarr/functions/ones_like.md
new file mode 100644
index 0000000000..cffccb10ef
--- /dev/null
+++ b/docs/api/zarr/functions/ones_like.md
@@ -0,0 +1,5 @@
+---
+title: zarr.ones_like
+---
+
+::: zarr.ones_like
diff --git a/docs/api/zarr/functions/open.md b/docs/api/zarr/functions/open.md
new file mode 100644
index 0000000000..3d75977395
--- /dev/null
+++ b/docs/api/zarr/functions/open.md
@@ -0,0 +1,5 @@
+---
+title: zarr.open
+---
+
+::: zarr.open
diff --git a/docs/api/zarr/functions/open_array.md b/docs/api/zarr/functions/open_array.md
new file mode 100644
index 0000000000..f40da1bd5d
--- /dev/null
+++ b/docs/api/zarr/functions/open_array.md
@@ -0,0 +1,5 @@
+---
+title: zarr.open_array
+---
+
+::: zarr.open_array
diff --git a/docs/api/zarr/functions/open_consolidated.md b/docs/api/zarr/functions/open_consolidated.md
new file mode 100644
index 0000000000..de71cf7662
--- /dev/null
+++ b/docs/api/zarr/functions/open_consolidated.md
@@ -0,0 +1,5 @@
+---
+title: zarr.open_consolidated
+---
+
+::: zarr.open_consolidated
diff --git a/docs/api/zarr/functions/open_group.md b/docs/api/zarr/functions/open_group.md
new file mode 100644
index 0000000000..4944e94e06
--- /dev/null
+++ b/docs/api/zarr/functions/open_group.md
@@ -0,0 +1,5 @@
+---
+title: zarr.open_group
+---
+
+::: zarr.open_group
diff --git a/docs/api/zarr/functions/open_like.md b/docs/api/zarr/functions/open_like.md
new file mode 100644
index 0000000000..1aea075a81
--- /dev/null
+++ b/docs/api/zarr/functions/open_like.md
@@ -0,0 +1,5 @@
+---
+title: zarr.open_like
+---
+
+::: zarr.open_like
diff --git a/docs/api/zarr/functions/print_debug_info.md b/docs/api/zarr/functions/print_debug_info.md
new file mode 100644
index 0000000000..c98329f893
--- /dev/null
+++ b/docs/api/zarr/functions/print_debug_info.md
@@ -0,0 +1,5 @@
+---
+title: zarr.print_debug_info
+---
+
+::: zarr.print_debug_info
diff --git a/docs/api/zarr/functions/save.md b/docs/api/zarr/functions/save.md
new file mode 100644
index 0000000000..6c8eae410f
--- /dev/null
+++ b/docs/api/zarr/functions/save.md
@@ -0,0 +1,5 @@
+---
+title: zarr.save
+---
+
+::: zarr.save
diff --git a/docs/api/zarr/functions/save_array.md b/docs/api/zarr/functions/save_array.md
new file mode 100644
index 0000000000..58a6d5143d
--- /dev/null
+++ b/docs/api/zarr/functions/save_array.md
@@ -0,0 +1,5 @@
+---
+title: zarr.save_array
+---
+
+::: zarr.save_array
diff --git a/docs/api/zarr/functions/save_group.md b/docs/api/zarr/functions/save_group.md
new file mode 100644
index 0000000000..ba66a70563
--- /dev/null
+++ b/docs/api/zarr/functions/save_group.md
@@ -0,0 +1,5 @@
+---
+title: zarr.save_group
+---
+
+::: zarr.save_group
diff --git a/docs/api/zarr/functions/zeros.md b/docs/api/zarr/functions/zeros.md
new file mode 100644
index 0000000000..d43e8d913b
--- /dev/null
+++ b/docs/api/zarr/functions/zeros.md
@@ -0,0 +1,5 @@
+---
+title: zarr.zeros
+---
+
+::: zarr.zeros
diff --git a/docs/api/zarr/functions/zeros_like.md b/docs/api/zarr/functions/zeros_like.md
new file mode 100644
index 0000000000..5adf1a23b3
--- /dev/null
+++ b/docs/api/zarr/functions/zeros_like.md
@@ -0,0 +1,5 @@
+---
+title: zarr.zeros_like
+---
+
+::: zarr.zeros_like
diff --git a/docs/api/zarr/index.md b/docs/api/zarr/index.md
index 194edb7913..f691c4599a 100644
--- a/docs/api/zarr/index.md
+++ b/docs/api/zarr/index.md
@@ -14,13 +14,13 @@ Complete reference documentation for the Zarr-Python API.
- **[Array](array.md)** - The main Zarr array class for N-dimensional data
- **[Group](group.md)** - Hierarchical organization of arrays and subgroups
-- **[Create](create.md)** - Functions for creating new arrays and groups
-- **[Open](open.md)** - Opening existing Zarr stores and arrays
+- **[create_array](functions/create_array.md)** and **[create_group](functions/create_group.md)** - Creating new arrays and groups
+- **[open](functions/open.md)**, **[open_array](functions/open_array.md)**, and **[open_group](functions/open_group.md)** - Opening existing Zarr stores, arrays, and groups
### Data Operations
-- **[Load](load.md)** - Loading data from Zarr stores
-- **[Save](save.md)** - Saving data to Zarr format
+- **[load](functions/load.md)** - Loading data from Zarr stores
+- **[save](functions/save.md)** - Saving data to Zarr format
### Data Types and Configuration
diff --git a/docs/api/zarr/open.md b/docs/api/zarr/open.md
deleted file mode 100644
index c59f896129..0000000000
--- a/docs/api/zarr/open.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: open
----
-
-::: zarr.open
-::: zarr.open_array
-::: zarr.open_consolidated
-::: zarr.open_group
-::: zarr.open_like
diff --git a/docs/api/zarr/save.md b/docs/api/zarr/save.md
deleted file mode 100644
index c611d10a4c..0000000000
--- a/docs/api/zarr/save.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: save
----
-
-::: zarr.save
-::: zarr.save_array
-::: zarr.save_group
diff --git a/docs/api/zarr/testing/index.md b/docs/api/zarr/testing/index.md
index ab5dd1daa0..2b48ad349f 100644
--- a/docs/api/zarr/testing/index.md
+++ b/docs/api/zarr/testing/index.md
@@ -1,11 +1,13 @@
---
-title: testing
+title: zarr.testing
---
+# zarr.testing
+
See the following sub-modules:
-- [buffer](./buffer.md)
-- [stateful](./stateful.md)
-- [store](./store.md)
-- [strategies](./strategies.md)
-- [utils](./utils.md)
+- [zarr.testing.buffer](./buffer.md)
+- [zarr.testing.stateful](./stateful.md)
+- [zarr.testing.store](./store.md)
+- [zarr.testing.strategies](./strategies.md)
+- [zarr.testing.utils](./utils.md)
diff --git a/docs/contributing.md b/docs/contributing.md
index 750f7c7a65..eaab26fbc7 100644
--- a/docs/contributing.md
+++ b/docs/contributing.md
@@ -18,9 +18,9 @@ g = zarr.group()
# etc.
```
-2. An explanation of why the current behaviour is wrong/not desired, and what you expect instead.
+2. An explanation of why the current behavior is wrong/not desired, and what you expect instead.
-3. Information about the version of Zarr, along with versions of dependencies and the Python interpreter, and installation information. The version of Zarr can be obtained from the `zarr.__version__` property. Please also state how Zarr was installed, e.g., "installed via pip into a virtual environment", or "installed using conda". Information about other packages installed can be obtained by executing `pip freeze` (if using pip to install packages) or `conda env export` (if using conda to install packages) from the operating system command prompt. The version of the Python interpreter can be obtained by running a Python interactive session, e.g.:
+3. Information about the version of Zarr, along with versions of dependencies and the Python interpreter, and installation information. The version of Zarr can be obtained from the `zarr.__version__` attribute. Please also state how Zarr was installed, e.g., "installed via pip into a virtual environment", or "installed using conda". Information about other packages installed can be obtained by executing `pip freeze` (if using pip to install packages) or `conda env export` (if using conda to install packages) from the operating system command prompt. The version of the Python interpreter can be obtained by running a Python interactive session, e.g.:
```console
python
@@ -133,8 +133,6 @@ hatch env run --env test.py3.12-optional run
All tests are automatically run via GitHub Actions for every pull request and must pass before code can be accepted. Test coverage is also collected automatically via the Codecov service.
-> **Note:** Previous versions of Zarr-Python made extensive use of doctests. These tests were not maintained during the 3.0 refactor but may be brought back in the future. See issue #2614 for more details.
-
### Code standards - using prek
All code must conform to the PEP8 standard. Regarding line length, lines up to 100 characters are allowed, although please try to keep under 90 wherever possible.
@@ -215,9 +213,9 @@ The documentation can be built locally by running:
hatch --env docs run build
```
-The resulting built documentation will be available in the `docs/_build/html` folder.
+The resulting built documentation will be available in the `site` folder.
-Hatch can also be used to serve continuously updating version of the documentation during development at [http://0.0.0.0:8000/](http://0.0.0.0:8000/). This can be done by running:
+Hatch can also be used to serve continuously updating version of the documentation during development at [http://127.0.0.1:8000/](http://127.0.0.1:8000/). This can be done by running:
```bash
hatch --env docs run serve
@@ -292,6 +290,11 @@ that fits the block).
`test="true"`, or `exec="false"` with a reason — so a block can never silently skip
validation. A bare ` ```python ` fence, or a typo like `exec="on"`, fails that test.
+Markdown Exec only renders `exec="true"` fences; the `mkdocs_hooks.py` hook at the
+repository root makes `test="true"` and `exec="false"` fences render as ordinary
+highlighted code blocks. Without it, these fences would fail superfences parsing and
+their contents would spill into the page as raw markdown.
+
##### Marker-bound blocks (GPU, S3)
A `test="true"` block that needs special infrastructure declares a pytest marker with
@@ -382,7 +385,7 @@ Releases are classified by the library changes contained in that release. This c
Minor releases are safe for most users and downstream projects to adopt.
-* **patch** releases (for example, `3.1.0` -> `3.1.1`) are for changes that contain no breaking or behaviour changes for downstream projects or users. Examples of changes suitable for a patch release are bugfixes and documentation improvements.
+* **patch** releases (for example, `3.1.0` -> `3.1.1`) are for changes that contain no breaking or behavior changes for downstream projects or users. Examples of changes suitable for a patch release are bugfixes and documentation improvements.
Users should always feel safe upgrading to the latest patch release.
@@ -396,7 +399,7 @@ Zarr developers should make changes as smooth as possible for users. This means
The Zarr library is an implementation of a file format standard defined externally -- see the [Zarr specifications website](https://zarr-specs.readthedocs.io) for the list of Zarr file format specifications.
-If an existing Zarr format version changes, or a new version of the Zarr format is released, then the Zarr library will generally require changes. It is very likely that a new Zarr format will require extensive breaking changes to the Zarr library, and so support for a new Zarr format in the Zarr library will almost certainly come in new `major` release. When the Zarr library adds support for a new Zarr format, there may be a period of accelerated changes as developers refine newly added APIs and deprecate old APIs. In such a transitional phase breaking changes may be more frequent than usual.
+If an existing Zarr format version changes, or a new version of the Zarr format is released, then the Zarr library will generally require changes. It is very likely that a new Zarr format will require extensive breaking changes to the Zarr library, and so support for a new Zarr format in the Zarr library will almost certainly come in a new `major` release. When the Zarr library adds support for a new Zarr format, there may be a period of accelerated changes as developers refine newly added APIs and deprecate old APIs. In such a transitional phase breaking changes may be more frequent than usual.
## Experimental API policy
diff --git a/docs/index.md b/docs/index.md
index b8c2b07ee7..1ec5e93c75 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -30,7 +30,7 @@ pip install zarr
or `conda`:
```bash
-conda install --channel conda-forge zarr
+conda install -c conda-forge zarr
```
## Navigating the documentation
@@ -45,14 +45,14 @@ conda install --channel conda-forge zarr
introduction to Zarr's main concepts and links to additional tutorials.
-- [:material-book-open:{ .lg .middle } __User guide__](user-guide/installation.md)
+- [:material-book-open:{ .lg .middle } __User guide__](user-guide/index.md)
---
A detailed guide for how to use Zarr-Python.
-- [:material-api:{ .lg .middle } __API Reference__](api/zarr/open.md)
+- [:material-api:{ .lg .middle } __API Reference__](api/zarr/index.md)
---
diff --git a/docs/quick-start.md b/docs/quick-start.md
index 0bad4f2e34..29232d2a04 100644
--- a/docs/quick-start.md
+++ b/docs/quick-start.md
@@ -1,7 +1,11 @@
-This section will help you get up and running with
+# Quick start
+
+This page will help you get up and running with
the Zarr library in Python to efficiently manage and analyze multi-dimensional arrays.
+Zarr must be installed first -- see the [installation guide](user-guide/installation.md)
+if you have not installed it yet.
-### Creating an Array
+## Creating an Array
To get started, you can create a simple Zarr array:
@@ -42,12 +46,12 @@ Here, we created a 2D array of shape `(100, 100)`, chunked into blocks of
`(10, 10)`, and filled it with random floating-point data. This array was
written to a `LocalStore` in the `data/example-1.zarr` directory.
-#### Compression and Filters
+### Compression and Filters
Zarr supports data compression and filters. For example, to use Blosc compression:
-```python exec="true" session="quickstart" source="above" result="code"
+```python exec="true" session="quickstart" source="above" result="ansi"
# Create a 2D Zarr array with Blosc compression
z = zarr.create_array(
@@ -70,7 +74,7 @@ print(z.info)
This compresses the data using the Blosc codec with shuffle enabled for better compression.
-### Hierarchical Groups
+## Hierarchical Groups
Zarr allows you to create hierarchical groups, similar to directories:
@@ -94,12 +98,12 @@ print(root.tree())
This creates a group hierarchy with a group (`foo`) and two arrays (`bar` and `spam`).
-#### Batch Hierarchy Creation
+### Batch Hierarchy Creation
Zarr provides tools for creating a collection of arrays and groups with a single function call.
Suppose we want to copy existing groups and arrays into a new storage backend:
-```python exec="true" session="quickstart" source="above" result="html"
+```python exec="true" session="quickstart" source="above" result="code"
# Create nested groups and add arrays
root = zarr.group("data/example-4.zarr", attributes={'name': 'root'})
@@ -122,7 +126,7 @@ assert new_root.attrs == root.attrs
Note that [`zarr.create_hierarchy`][] will only initialize arrays and groups -- copying array data must
be done in a separate step.
-### Persistent Storage
+## Persistent Storage
Zarr supports persistent storage to disk or cloud-compatible backends. While examples above
utilized a [`zarr.storage.LocalStore`][], a number of other storage options are available.
@@ -150,7 +154,7 @@ store.close()
To open an existing array from a ZIP file:
-```python exec="true" session="quickstart" source="above" result="code"
+```python exec="true" session="quickstart" source="above" result="ansi"
# Open the ZipStore in read-only mode
store = zarr.storage.ZipStore("data/example-5.zip", read_only=True)
@@ -163,7 +167,9 @@ print(z[:])
Zarr also integrates seamlessly with cloud object storage such as Amazon S3 and Google
Cloud Storage using external libraries like [s3fs](https://s3fs.readthedocs.io) or
-[gcsfs](https://gcsfs.readthedocs.io):
+[gcsfs](https://gcsfs.readthedocs.io). Remote storage support requires the `remote`
+optional dependencies (`pip install "zarr[remote]"`) as well as a filesystem library
+for your storage service, such as `s3fs` for S3:
```python test="true" session="s3demo" markers="s3" source="above"
import zarr
@@ -175,4 +181,13 @@ z = zarr.create_array(
z[:, :] = np.random.random((100, 100))
```
-Read more about Zarr's storage options in the [User Guide](user-guide/index.md).
+See the [Remote Store](user-guide/storage.md#remote-store) section of the storage guide
+for more detail, including how to configure the underlying filesystem with `storage_options`.
+
+## Next steps
+
+This page only scratches the surface. Continue with the [User Guide](user-guide/index.md), in particular:
+
+- **[Arrays](user-guide/arrays.md)** - creating, reading, and writing arrays in depth
+- **[Groups](user-guide/groups.md)** - organizing arrays into hierarchies
+- **[Storage](user-guide/storage.md)** - the full range of local, remote, and in-memory storage options
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 4511c9815e..3ba870ac92 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -114,9 +114,9 @@ a `ManagedMemoryStore` is used. ([#3944](https://github.com/zarr-developers/zarr
- [#3562](https://github.com/zarr-developers/zarr-python/issues/3562), [#3605](https://github.com/zarr-developers/zarr-python/issues/3605), [#3619](https://github.com/zarr-developers/zarr-python/issues/3619), [#3623](https://github.com/zarr-developers/zarr-python/issues/3623), [#3636](https://github.com/zarr-developers/zarr-python/issues/3636), [#3648](https://github.com/zarr-developers/zarr-python/issues/3648), [#3656](https://github.com/zarr-developers/zarr-python/issues/3656), [#3658](https://github.com/zarr-developers/zarr-python/issues/3658), [#3673](https://github.com/zarr-developers/zarr-python/issues/3673), [#3704](https://github.com/zarr-developers/zarr-python/issues/3704), [#3706](https://github.com/zarr-developers/zarr-python/issues/3706), [#3708](https://github.com/zarr-developers/zarr-python/issues/3708), [#3712](https://github.com/zarr-developers/zarr-python/issues/3712), [#3713](https://github.com/zarr-developers/zarr-python/issues/3713), [#3717](https://github.com/zarr-developers/zarr-python/issues/3717), [#3721](https://github.com/zarr-developers/zarr-python/issues/3721), [#3728](https://github.com/zarr-developers/zarr-python/issues/3728), [#3778](https://github.com/zarr-developers/zarr-python/issues/3778)
-## zarr 3.1.5 (2025-11-21)
+## 3.1.5 (2025-11-21)
-## Bugfixes
+### Bugfixes
- Fix formatting errors in the release notes section of the docs. ([#3594](https://github.com/zarr-developers/zarr-python/issues/3594))
@@ -153,7 +153,7 @@ a `ManagedMemoryStore` is used. ([#3944](https://github.com/zarr-developers/zarr
- [#3515](https://github.com/zarr-developers/zarr-python/issues/3515), [#3532](https://github.com/zarr-developers/zarr-python/issues/3532), [#3533](https://github.com/zarr-developers/zarr-python/issues/3533), [#3553](https://github.com/zarr-developers/zarr-python/issues/3553)
-## zarr 3.1.3 (2025-09-18)
+## 3.1.3 (2025-09-18)
### Features
@@ -536,18 +536,18 @@ a `ManagedMemoryStore` is used. ([#3944](https://github.com/zarr-developers/zarr
- Test `getsize()` and `getsize_prefix()` in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
- Test that a `ValueError` is raised for invalid byte range syntax in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
- Separate instantiating and opening a store in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
-- Add a test for using Stores as a context managers in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
+- Add a test for using Stores as context managers in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
- Implemented `LoggingStore.open()`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
- `LoggingStore` is now a generic class. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
- Change StoreTest's `test_store_repr`, `test_store_supports_writes`,
`test_store_supports_partial_writes`, and `test_store_supports_listing`
- to to be implemented using `@abstractmethod`, rather raising `NotImplementedError`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
+ to be implemented using `@abstractmethod`, rather than raising `NotImplementedError`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
- Test the error raised for invalid buffer arguments in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
- Test that data can be written to a store that's not yet open using the store.set method in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
- Adds a new function `init_array` for initializing an array in storage, and refactors `create_array`
to use `init_array`. `create_array` takes two new parameters: `data`, an optional array-like object, and `write_data`, a bool which defaults to `True`.
If `data` is given to `create_array`, then the `dtype` and `shape` attributes of `data` are used to define the
- corresponding attributes of the resulting Zarr array. Additionally, if `data` given and `write_data` is `True`,
+ corresponding attributes of the resulting Zarr array. Additionally, if `data` is given and `write_data` is `True`,
then the values in `data` will be written to the newly created array. ([#2761](https://github.com/zarr-developers/zarr-python/issues/2761))
### Bugfixes
@@ -559,7 +559,7 @@ a `ManagedMemoryStore` is used. ([#3944](https://github.com/zarr-developers/zarr
- Use stdout rather than stderr as the default stream for `LoggingStore`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
- Match the errors raised by read only stores in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/issues/2693))
- Fixed `ZipStore` to make sure the correct attributes are saved when instances are pickled.
- This fixes a previous bug that prevent using `ZipStore` with a `ProcessPoolExecutor`. ([#2762](https://github.com/zarr-developers/zarr-python/issues/2762))
+ This fixes a previous bug that prevented using `ZipStore` with a `ProcessPoolExecutor`. ([#2762](https://github.com/zarr-developers/zarr-python/issues/2762))
- Updated the optional test dependencies to include `botocore` and `fsspec`. ([#2768](https://github.com/zarr-developers/zarr-python/issues/2768))
- Fixed the fsspec tests to skip if `botocore` is not installed.
Previously they would have failed with an import error. ([#2768](https://github.com/zarr-developers/zarr-python/issues/2768))
@@ -576,7 +576,7 @@ a `ManagedMemoryStore` is used. ([#3944](https://github.com/zarr-developers/zarr
parameters of those instances. `ChunkKeyEncodingLike` should be used by high-level functions to provide a convenient
way for creating `ChunkKeyEncoding` objects. ([#2763](https://github.com/zarr-developers/zarr-python/issues/2763))
-## 3.0.1 (Jan. 17, 2025)
+## 3.0.1 (2025-01-17)
* Implement `zarr.from_array` using concurrent streaming ([#2622](https://github.com/zarr-developers/zarr-python/issues/2622)).
@@ -604,7 +604,7 @@ a `ManagedMemoryStore` is used. ([#3944](https://github.com/zarr-developers/zarr
* Speed up hypothesis tests ([#2650](https://github.com/zarr-developers/zarr-python/issues/2650)).
* Remove multiple imports for an import name ([#2723](https://github.com/zarr-developers/zarr-python/issues/2723)).
-## 3.0.0 (Jan. 9, 2025)
+## 3.0.0 (2025-01-09)
3.0.0 is a new major release of Zarr-Python, with many breaking changes.
See the [v3 migration guide](user-guide/v3_migration.md) for a listing of what's changed.
diff --git a/docs/user-guide/arrays.md b/docs/user-guide/arrays.md
index dd1788b7d2..51b2fa1a17 100644
--- a/docs/user-guide/arrays.md
+++ b/docs/user-guide/arrays.md
@@ -8,8 +8,6 @@ Zarr has several functions for creating arrays. For example:
import shutil
shutil.rmtree('data', ignore_errors=True)
import numpy as np
-
-np.random.seed(0)
```
```python exec="true" session="arrays" source="above" result="ansi"
@@ -21,12 +19,16 @@ print(z)
The code above creates a 2-dimensional array of 32-bit integers with 10000 rows
and 10000 columns, divided into chunks where each chunk has 1000 rows and 1000
columns (and so there will be 100 chunks in total). The data is written to an
-in-memory store (see [`zarr.storage.MemoryStore`][] for more details). See
-[Persistent arrays](#persistent-arrays) for details on storing arrays in other stores,
-and see [Data types](data_types.md) for an in-depth look at the data types supported
-by Zarr.
-
-See the [creation API documentation](../api/zarr/create.md) for more detailed information about
+in-memory store: when `fsspec` is installed, a `memory://` URL resolves to a
+[`zarr.storage.FsspecStore`][] backed by fsspec's in-memory filesystem; otherwise a
+[`zarr.storage.ManagedMemoryStore`][] is used. See the [Storage guide](storage.md)
+for more details on stores, and
+[Persistent arrays](#persistent-arrays) for details on storing arrays in other stores.
+See [Data types](data_types.md) for an in-depth look at the data types supported
+by Zarr, and [Chunk size and shape](performance.md#chunk-size-and-shape) in the
+performance guide for guidance on choosing chunk shapes.
+
+See the [`zarr.create_array`][] API documentation for more detailed information about
creating arrays.
## Reading and writing data
@@ -128,7 +130,7 @@ A Zarr array can be resized, which means that any of its dimensions can be
increased or decreased in length. For example:
```python exec="true" session="arrays" source="above" result="ansi"
-z = zarr.create_array(store='data/example-3.zarr', shape=(10000, 10000), dtype='int32',chunks=(1000, 1000))
+z = zarr.create_array(store='data/example-3.zarr', shape=(10000, 10000), dtype='int32', chunks=(1000, 1000))
z[:] = 42
print(f"Original shape: {z.shape}")
z.resize((20000, 10000))
@@ -157,13 +159,15 @@ print(f"Shape after second append: {z.shape}")
Zarr arrays are parametrized with a configuration that determines certain aspects of array behavior.
-We currently support three configuration options for arrays: `write_empty_chunks`, `read_missing_chunks`, and `order`.
+We currently support five configuration options for arrays: `order`, `write_empty_chunks`, `read_missing_chunks`, `sharding_coalesce_max_gap_bytes`, and `sharding_coalesce_max_bytes`.
| field | type | default | description |
| - | - | - | - |
+| `order` | `Literal["C", "F"]` | `"C"` | The memory layout of arrays returned when reading data from the store.
| `write_empty_chunks` | `bool` | `False` | Controls whether empty chunks are written to storage. See [Empty chunks](performance.md#empty-chunks).
| `read_missing_chunks` | `bool` | `True` | Controls whether missing chunks are filled with the array's fill value on read. If `False`, reading missing chunks raises a [`ChunkNotFoundError`][zarr.errors.ChunkNotFoundError].
-| `order` | `Literal["C", "F"]` | `"C"` | The memory layout of arrays returned when reading data from the store.
+| `sharding_coalesce_max_gap_bytes` | `int` | `1048576` (1 MiB) | When reading multiple chunks from the same shard, nearby byte ranges separated by no more than this many bytes are coalesced into a single request to the store.
+| `sharding_coalesce_max_bytes` | `int` | `16777216` (16 MiB) | Requests will not be coalesced if doing so would exceed this byte size.
!!! info
The Zarr V3 spec states that readers should interpret an uninitialized chunk as containing the
@@ -266,19 +270,6 @@ z = zarr.create_array(store='data/example-7.zarr', shape=data.shape, dtype=data.
print(f"Compressors: {z.compressors}")
```
-To disable compression, set `compressors=None` when creating an array, e.g.:
-
-```python exec="true" session="arrays" source="above" result="ansi"
-z = zarr.create_array(
- store='data/example-8.zarr',
- shape=(100000000,),
- chunks=(1000000,),
- dtype='int32',
- compressors=None
-)
-print(f"Compressors: {z.compressors}")
-```
-
## Filters
In some cases, compression can be improved by transforming the data in some
@@ -461,11 +452,11 @@ print(z.get_orthogonal_selection(([0, 2], slice(None)))) # select first and thi
```
```python exec="true" session="arrays" source="above" result="ansi"
-print(z.get_orthogonal_selection((slice(None), [1, 3]))) # select second and fourth columns)
+print(z.get_orthogonal_selection((slice(None), [1, 3]))) # select second and fourth columns
```
```python exec="true" session="arrays" source="above" result="ansi"
-print(z.get_orthogonal_selection(([0, 2], [1, 3]))) # select rows [0, 2] and columns [1, 4]
+print(z.get_orthogonal_selection(([0, 2], [1, 3]))) # select rows [0, 2] and columns [1, 3]
```
Data can also be modified, e.g.:
@@ -489,7 +480,7 @@ print(z.oindex[:, [1, 3]]) # select second and fourth columns
```
```python exec="true" session="arrays" source="above" result="ansi"
-print(z.oindex[[0, 2], [1, 3]]) # select rows [0, 2] and columns [1, 4]
+print(z.oindex[[0, 2], [1, 3]]) # select rows [0, 2] and columns [1, 3]
```
```python exec="true" session="arrays" source="above" result="ansi"
@@ -510,7 +501,7 @@ z[:] = data
print(np.all(z.oindex[[0, 2], :] == z[[0, 2], :]))
```
-### Block Indexing
+### Block indexing
Zarr also supports block indexing, which allows selections of whole chunks based on their
logical indices along each dimension of an array. For example, this allows selecting
@@ -575,15 +566,6 @@ Any combination of integer and slice can be used for block indexing:
print(z.blocks[2, 1:3])
```
-```python exec="true" session="arrays" source="above" result="ansi"
-root = zarr.create_group('data/example-19.zarr')
-foo = root.create_array(name='foo', shape=(1000, 100), chunks=(10, 10), dtype='float32')
-bar = root.create_array(name='bar', shape=(100,), dtype='int32')
-foo[:, :] = np.random.random((1000, 100))
-bar[:] = np.arange(100)
-print(root.tree())
-```
-
## Sharding
Using small chunk shapes in very large arrays can lead to a very large number of chunks.
@@ -596,7 +578,9 @@ This allows individual chunks to be read independently.
However, when writing data, a full shard must be written in one go for optimal
performance and to avoid concurrency issues.
That means that shards are the units of writing and chunks are the units of reading.
-Users need to configure the chunk and shard shapes accordingly.
+Users need to configure the chunk and shard shapes accordingly. For guidance on
+choosing chunk and shard shapes, see [Sharding](performance.md#sharding) in the
+performance guide.
Sharded arrays can be created by providing the `shards` parameter to [`zarr.create_array`][].
@@ -619,7 +603,7 @@ Without the `shards` argument, there would be 10,000 chunks stored as individual
Because the feature is still stabilizing, it is disabled by default and
must be explicitly enabled:
- ```python exec="true" session="arrays-rectilinear"
+ ```python exec="true" session="arrays" source="above"
import zarr
zarr.config.set({"array.rectilinear_chunks": True})
```
@@ -641,7 +625,6 @@ To create an array with rectilinear chunks, pass a nested list to the `chunks`
parameter where each inner list gives the chunk sizes along one dimension:
```python exec="true" session="arrays" source="above" result="ansi"
-zarr.config.set({"array.rectilinear_chunks": True})
z = zarr.create_array(
store=zarr.storage.MemoryStore(),
shape=(60, 100),
@@ -775,9 +758,9 @@ pairs are accepted:
When writing, Zarr automatically compresses repeated values into RLE format.
-## Missing features in 3.0
+## Features not yet ported to Zarr-Python 3
-The following features have not been ported to 3.0 yet.
+The following Zarr-Python 2 features are not yet available in Zarr-Python 3.
### Copying and migrating data
diff --git a/docs/user-guide/attributes.md b/docs/user-guide/attributes.md
index d5961ed38a..96a5d67584 100644
--- a/docs/user-guide/attributes.md
+++ b/docs/user-guide/attributes.md
@@ -32,5 +32,29 @@ print(z.attrs['baz'])
print(z.attrs['qux'])
```
-Internally Zarr uses JSON to store array attributes, so attribute values must be
-JSON serializable.
+Attributes can be deleted with the `del` operator:
+
+```python exec="true" session="attributes" source="above" result="ansi"
+del z.attrs['baz']
+print(sorted(z.attrs))
+```
+
+Note that each attribute assignment or deletion writes the node's metadata
+document back to the store. To change several attributes in a single write,
+use [`zarr.Array.update_attributes`][] (or [`zarr.Group.update_attributes`][]
+for groups), which merges the given dict into the existing attributes and
+returns the updated array or group:
+
+```python exec="true" session="attributes" source="above" result="ansi"
+z = z.update_attributes({'baz': 43, 'quux': True})
+print(sorted(z.attrs))
+```
+
+Internally Zarr uses JSON to store array and group attributes, so attribute
+values must be JSON serializable.
+
+When working with hierarchies that contain many arrays and groups, reading the
+attributes of each node separately can be slow. See
+[Consolidated metadata](consolidated_metadata.md) for a way to store the
+metadata (including attributes) of all nodes in a hierarchy in a single
+document.
diff --git a/docs/user-guide/cli.md b/docs/user-guide/cli.md
index 13fcb6f1b6..77f50f5eaf 100644
--- a/docs/user-guide/cli.md
+++ b/docs/user-guide/cli.md
@@ -2,9 +2,22 @@
Zarr-Python provides a command-line interface that enables:
-- migration of Zarr v2 metadata to v3
+- migration of Zarr v2 metadata to v3 (see the [3.0 Migration Guide](v3_migration.md) for
+ migrating your *code* from the Zarr-Python 2 API to the Zarr-Python 3 API)
- removal of v2 or v3 metadata
+## Installation
+
+The command-line interface requires the `cli` optional dependencies. Install them with:
+
+```bash
+pip install "zarr[cli]"
+```
+
+Without this extra, running `zarr` in a terminal will fail with `ModuleNotFoundError`.
+
+## Getting help
+
To see available commands run the following in a terminal:
```bash
@@ -83,7 +96,7 @@ zarr remove-metadata v3 path/to/input.zarr
By default, this will only allow removal of metadata if a valid alternative exists. For example, you can't
remove v2 metadata unless v3 metadata exists at that location.
-To override this behaviour use `--force`:
+To override this behavior use `--force`:
```bash
zarr remove-metadata v3 path/to/input.zarr --force
@@ -98,7 +111,7 @@ or modifying any files.
zarr migrate v3 path/to/input.zarr --dry-run
Dry run enabled - no new files will be created or changed. Log of files that would be created on a real run:
-Saving metadata to path/to/input.zarr/zarr.json
+Saving metadata to file://path/to/input.zarr/zarr.json
```
## Verbose
@@ -113,5 +126,8 @@ zarr --verbose remove-metadata v2 path/to/input.zarr
## Equivalent functions
-All features of the command-line interface are also available via functions under
-`zarr.metadata`.
\ No newline at end of file
+All features of the command-line interface are also available as functions in the
+`zarr.metadata.migrate_v3` module:
+[`migrate_v2_to_v3`][zarr.metadata.migrate_v3.migrate_v2_to_v3] and
+[`remove_metadata`][zarr.metadata.migrate_v3.remove_metadata].
+See the [`zarr.metadata` API reference](../api/zarr/metadata.md) for details.
diff --git a/docs/user-guide/config.md b/docs/user-guide/config.md
index 71c021b070..d1a70a14b0 100644
--- a/docs/user-guide/config.md
+++ b/docs/user-guide/config.md
@@ -6,14 +6,22 @@ is based on the [donfig](https://github.com/pytroll/donfig) Python library.
Configuration values can be set using code like the following:
```python exec="true" session="config" source="above" result="ansi"
-
import zarr
+zarr.config.set({'array.order': 'F'})
+
print(zarr.config.get('array.order'))
```
+`zarr.config.set` can also be used as a context manager, which restores the
+previous configuration on exit, and `zarr.config.reset` restores the default
+configuration:
+
```python exec="true" session="config" source="above" result="ansi"
-zarr.config.set({'array.order': 'F'})
+zarr.config.reset()
+
+with zarr.config.set({'array.order': 'F'}):
+ print(zarr.config.get('array.order'))
print(zarr.config.get('array.order'))
```
@@ -34,13 +42,13 @@ Configuration options include the following:
- Whether missing chunks are filled with the array's fill value on read `array.read_missing_chunks` (default `True`). Set to `False` to raise a [`ChunkNotFoundError`][zarr.errors.ChunkNotFoundError] instead.
- Async and threading options, e.g. `async.concurrency` and `threading.max_workers`
- Selections of implementations of codecs, codec pipelines and buffers
-- Enabling GPU support with `zarr.config.enable_gpu()`. See GPU support for more.
+- Enabling GPU support with `zarr.config.enable_gpu()`. See [GPU support](gpu.md) for more.
- Control request merging when reading multiple chunks from the same shard with `array.sharding_coalesce_max_gap_bytes` and `array.sharding_coalesce_max_bytes`. Reads of nearby chunks are coalesced into a single request to the store when separated by at most `sharding_coalesce_max_gap_bytes` and the resulting merged read is no larger than `sharding_coalesce_max_bytes`.
For selecting custom implementations of codecs, pipelines, buffers and ndbuffers,
first register the implementations in the registry and then select them in the config.
For example, an implementation of the bytes codec in a class `'custompackage.NewBytesCodec'`,
-requires the value of `codecs.bytes.name` to be `'custompackage.NewBytesCodec'`.
+requires the value of `codecs.bytes` to be `'custompackage.NewBytesCodec'`.
This is the current default configuration:
diff --git a/docs/user-guide/consolidated_metadata.md b/docs/user-guide/consolidated_metadata.md
index d8066b6846..7030ed6cbc 100644
--- a/docs/user-guide/consolidated_metadata.md
+++ b/docs/user-guide/consolidated_metadata.md
@@ -5,7 +5,7 @@
stores. [zarr-specs#309](https://github.com/zarr-developers/zarr-specs/pull/309)
has proposed a formal extension to the v3 specification to support consolidated metadata.
-Zarr-Python implements the [Consolidated Metadata](https://github.com/zarr-developers/zarr-specs/pull/309) for v2 and v3 stores.
+Zarr-Python implements the Consolidated Metadata feature for both the v2 and v3 formats.
Consolidated metadata can reduce the time needed to load the metadata for an
entire hierarchy, especially when the metadata is being served over a network.
Consolidated metadata essentially stores all the metadata for a hierarchy in the
@@ -48,8 +48,8 @@ result = zarr.consolidate_metadata("memory://consolidated-metadata-demo")
print(result)
```
-If we open that group, the Group's metadata has a `zarr.core.group.ConsolidatedMetadata`
-that can be used:
+If we open that group, the Group's metadata includes a `ConsolidatedMetadata` object
+holding the metadata for every child node, which can be used:
```python exec="true" session="consolidated_metadata" source="above" result="ansi"
from pprint import pprint
@@ -58,7 +58,6 @@ import io
consolidated = zarr.open_group(store="memory://consolidated-metadata-demo")
consolidated_metadata = consolidated.metadata.consolidated_metadata.metadata
-# Note: pprint can be used without capturing the output regularly
output = io.StringIO()
pprint(dict(sorted(consolidated_metadata.items())), stream=output, width=60)
print(output.getvalue())
@@ -74,7 +73,7 @@ With nested groups, the consolidated metadata is available on the children, recu
```python exec="true" session="consolidated_metadata" source="above" result="ansi"
child = group.create_group('child', attributes={'kind': 'child'})
-grandchild = child.create_group('child', attributes={'kind': 'grandchild'})
+grandchild = child.create_group('grandchild', attributes={'kind': 'grandchild'})
consolidated = zarr.consolidate_metadata("memory://consolidated-metadata-demo")
output = io.StringIO()
@@ -86,9 +85,26 @@ print(output.getvalue())
The keys in the consolidated metadata are sorted prior to writing. Keys are
sorted in ascending order by path depth, where a path is defined as a sequence
of strings joined by `"/"`. For keys with the same path length, lexicographic
- order is used to break the tie. This behaviour ensures deterministic metadata
+ order is used to break the tie. This behavior ensures deterministic metadata
output for a given group.
+### Controlling the use of consolidated metadata
+
+By default, [`zarr.open_group`][] uses consolidated metadata if it is present, and
+falls back to reading metadata from the store otherwise. This behavior can be
+controlled with the `use_consolidated` keyword. Pass `use_consolidated=False` to
+ignore consolidated metadata and always read the metadata of child nodes directly
+from the store:
+
+```python exec="true" session="consolidated_metadata" source="above" result="ansi"
+group = zarr.open_group(store="memory://consolidated-metadata-demo", use_consolidated=False)
+print(group.metadata.consolidated_metadata)
+```
+
+Passing `use_consolidated=True` instead raises an error if consolidated metadata is
+not found, which is useful when reading over a network, where relying on many
+per-node metadata requests would be slow.
+
## Synchronization and Concurrency
Consolidated metadata is intended for read-heavy use cases on slowly changing
@@ -99,7 +115,9 @@ removed, or modified, consolidated metadata may not be desirable.
would need to be re-consolidated to keep it in sync with the store.
2. Readers using consolidated metadata will regularly see a "past" version
of the metadata, at the time they read the root node with its consolidated
- metadata.
+ metadata. Readers who need the latest view of a changing hierarchy can pass
+ `use_consolidated=False` to [`zarr.open_group`][] to always read child
+ metadata directly from the store.
## Stores Without Support for Consolidated Metadata
diff --git a/docs/user-guide/data_types.md b/docs/user-guide/data_types.md
index 6f6bb05033..642a09d714 100644
--- a/docs/user-guide/data_types.md
+++ b/docs/user-guide/data_types.md
@@ -1,6 +1,6 @@
# Array data types
-## Zarr's Data Type Model
+## Zarr's data type model
Zarr is designed for interoperability with NumPy, so if you are familiar with NumPy or any other
N-dimensional array library, Zarr's model for array data types should seem familiar. However, Zarr
@@ -14,7 +14,7 @@ which adds some unique aspects to the Zarr data type model.
The following sections explain Zarr's data type model in greater detail and demonstrate the
Zarr Python APIs for working with Zarr data types.
-### Array Data Types
+### Array data types
Every Zarr array has a data type, which defines the meaning of the array's elements. An array's data
type is encoded in the JSON metadata for the array. This means that the data type of an array must be
@@ -38,10 +38,10 @@ For the boolean data type, the scalar encoding is simple—booleans are natively
JSON, so Zarr saves booleans as JSON booleans. Other scalars, like floats or raw bytes, have
more elaborate encoding schemes, and in some cases, this scheme depends on the Zarr format version.
-## Data Types in Zarr Version 2
+## Data types in Zarr version 2
Version 2 of the Zarr format defined its data types relative to
-[NumPy's data types](https://numpy.org/doc/2.1/reference/arrays.dtypes.html#data-type-objects-dtype),
+[NumPy's data types](https://numpy.org/doc/stable/reference/arrays.dtypes.html#data-type-objects-dtype),
and added a few non-NumPy data types as well. With one exception ([structured data types](#structured-data-type)), the Zarr
V2 JSON identifier for a data type is just the NumPy `str` attribute of that data type:
@@ -64,7 +64,7 @@ print(dtype_meta)
!!! note
The `<` character in the data type metadata encodes the
- [endianness](https://numpy.org/doc/2.2/reference/generated/numpy.dtype.byteorder.html),
+ [endianness](https://numpy.org/doc/stable/reference/generated/numpy.dtype.byteorder.html),
or "byte order," of the data type. As per the NumPy model,
in Zarr version 2 each data type has an endianness where applicable.
However, Zarr version 3 data types do not store endianness information.
@@ -72,7 +72,7 @@ print(dtype_meta)
There are two special cases to consider: ["structured" data types](#structured-data-type), and
["object"](#object-data-type) data types.
-### Structured Data Type
+### Structured data type
NumPy allows the construction of a so-called "structured" data types comprised of ordered collections
of named fields, where each field is itself a distinct NumPy data type. See the NumPy documentation
@@ -101,7 +101,7 @@ dtype_meta = json.loads(store['.zarray'].to_bytes())["dtype"]
print(dtype_meta)
```
-### Object Data Type
+### Object data type
The NumPy "object" type is essentially an array of references to arbitrary Python objects.
It can model arrays of variable-length UTF-8 strings, arrays of variable-length byte strings, or
@@ -129,7 +129,7 @@ Although this fact can be ignored for many simple numeric data types, any compre
Zarr V2 data types must either reject the "object" data types or include the "object codec"
identifier in the JSON form of the basic data type model.
-## Data Types in Zarr Version 3
+## Data types in Zarr version 3
The NumPy-based Zarr V2 data type representation was effective for simple data types but struggled
with more complex data types, like "object" and "structured" data types. To address these limitations,
@@ -159,7 +159,7 @@ Zarr V3 introduced several key changes to how data types are represented:
For more about data types in Zarr V3, see the
[V3 specification](https://zarr-specs.readthedocs.io/en/latest/v3/data-types/index.html).
-## Data Types in Zarr Python
+## Data types in Zarr Python
The two Zarr formats that Zarr Python supports specify data types in different ways: data types in
Zarr version 2 are encoded as NumPy-compatible strings (or lists, in the case of structured data
@@ -191,7 +191,7 @@ API for the following operations:
The following section lists the data types built in to Zarr Python. With a few exceptions, Zarr
Python supports nearly all of the data types in NumPy. If you need a data type that is not listed
-here, it's possible to create it yourself: see [Adding New Data Types](#adding-new-data-types).
+here, it's possible to create it yourself: see [Adding new data types](#adding-new-data-types).
#### Boolean
- [Boolean][zarr.dtype.Bool]
@@ -260,14 +260,14 @@ here, it's possible to create it yourself: see [Adding New Data Types](#adding-n
explicit `endian` parameter. If omitted, Zarr Python assumes little-endian for legacy
compatibility but emits a warning.
-### Example Usage
+### Example usage
This section will demonstrate the basic usage of Zarr data types.
Create a `ZDType` from a native data type:
```python exec="true" session="data_types" source="above"
-from zarr.core.dtype import Int8
+from zarr.dtype import Int8
import numpy as np
int8 = Int8.from_native_dtype(np.dtype('int8'))
```
@@ -291,7 +291,6 @@ Serialize to JSON for Zarr V2:
```python exec="true" session="data_types" source="above" result="ansi"
json_v2 = int8.to_json(zarr_format=2)
print(json_v2)
-{'name': '|i1', 'object_codec_id': None}
```
!!! note
@@ -324,7 +323,7 @@ scalar_value = int8.from_json_scalar(42, zarr_format=3)
assert scalar_value == np.int8(42)
```
-### Adding New Data Types
+### Adding new data types
Each Zarr data type is a separate Python class that inherits from
[ZDType][zarr.dtype.ZDType]. You can define a custom data type by
@@ -332,7 +331,7 @@ writing your own subclass of [ZDType][zarr.dtype.ZDType] and adding
your data type to the data type registry. To see an executable demonstration
of this process, see the [`custom_dtype` example](../user-guide/examples/custom_dtype.md).
-### Data Type Resolution
+### Data type resolution
Although Zarr Python uses a different data type model from NumPy, you can still define a Zarr array
with a NumPy data type object:
@@ -375,16 +374,14 @@ For simple data types like `int`, the solution could be extremely simple: just
maintain a lookup table that maps a NumPy data type to the Zarr data type equivalent. But not all
data types are so simple. Consider this case:
-```python exec="true" session="data_types" source="above"
+```python exec="true" session="data_types" source="above" result="ansi"
from zarr import create_array
-import warnings
import numpy as np
-warnings.simplefilter("ignore", category=FutureWarning)
a = create_array({}, shape=(10,), dtype=[('a', 'f8'), ('b', 'i8')])
print(a.dtype) # this is the NumPy data type
```
-```python exec="true" session="data_types" source="above"
+```python exec="true" session="data_types" source="above" result="ansi"
print(a.metadata.data_type) # this is the Zarr data type
```
diff --git a/docs/user-guide/examples/rectilinear_chunks.ipynb b/docs/user-guide/examples/rectilinear_chunks.ipynb
deleted file mode 100644
index a2dd636ee8..0000000000
--- a/docs/user-guide/examples/rectilinear_chunks.ipynb
+++ /dev/null
@@ -1,428 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "da9139cc",
- "metadata": {
- "execution": {
- "iopub.execute_input": "2026-03-30T13:18:20.792275Z",
- "iopub.status.busy": "2026-03-30T13:18:20.792050Z",
- "iopub.status.idle": "2026-03-30T13:18:20.801655Z",
- "shell.execute_reply": "2026-03-30T13:18:20.797952Z",
- "shell.execute_reply.started": "2026-03-30T13:18:20.792253Z"
- }
- },
- "outputs": [],
- "source": [
- "# /// script\n",
- "# requires-python = \">=3.12\"\n",
- "# dependencies = [\n",
- "# \"dask\",\n",
- "# \"healpix-geo\",\n",
- "# \"matplotlib\",\n",
- "# \"numpy\",\n",
- "# \"obstore\",\n",
- "# \"xarray\",\n",
- "# \"zarr\",\n",
- "# ]\n",
- "#\n",
- "# [tool.uv.sources]\n",
- "# zarr = { git = \"https://github.com/zarr-developers/zarr-python\", branch = \"main\" }\n",
- "# xarray = { git = \"https://github.com/maxrjones/xarray\", branch = \"poc/unified-zarr-chunk-grid\" }\n",
- "# ///"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "71gnhfq4pfe",
- "metadata": {},
- "source": [
- "# Rectilinear Chunk Grids\n",
- "\n",
- "This notebook demonstrates the unified chunk grid implementation from [#3802](https://github.com/zarr-developers/zarr-python/pull/3802), which adds support for rectilinear (variable) chunk grids.\n",
- "\n",
- "Note that it requires installing from a fork of Xarray; this will ideally be incorporated in the codebase and included in a future Xarray release.\n",
- "\n",
- "Rectilinear grids allow different chunk sizes along each dimension, which is useful for data that doesn't partition evenly. For example, sparse HEALPix cells grouped by parent tile, boundary-padded HPC arrays, or ingesting existing variable-chunked datasets via VirtualiZarr."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "9e9nyjdx06f",
- "metadata": {
- "execution": {
- "iopub.execute_input": "2026-03-30T13:18:20.802629Z",
- "iopub.status.busy": "2026-03-30T13:18:20.802471Z",
- "iopub.status.idle": "2026-03-30T13:18:21.183147Z",
- "shell.execute_reply": "2026-03-30T13:18:21.182751Z",
- "shell.execute_reply.started": "2026-03-30T13:18:20.802615Z"
- }
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- ""
- ]
- },
- "execution_count": 2,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "import tempfile\n",
- "from pathlib import Path\n",
- "import json\n",
- "\n",
- "import numpy as np\n",
- "import xarray as xr\n",
- "from healpix_geo import nested\n",
- "from obstore.store import HTTPStore\n",
- "\n",
- "import zarr\n",
- "from zarr.storage import ObjectStore\n",
- "\n",
- "zarr.config.set({'async.concurrency': 128}) # Increase concurrency for better performance with obstore\n",
- "zarr.config.set({\"array.rectilinear_chunks\": True}) # Opt-in to rectilinear chunks\n"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "kj1o9xik9l",
- "metadata": {},
- "source": [
- "## 1. Inspect HEALPix dataset\n",
- "\n",
- "Load the remote Zarr store to understand the data structure before chunking it."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "v6cot74r1gq",
- "metadata": {
- "execution": {
- "iopub.execute_input": "2026-03-30T13:18:21.183653Z",
- "iopub.status.busy": "2026-03-30T13:18:21.183505Z",
- "iopub.status.idle": "2026-03-30T13:18:22.028419Z",
- "shell.execute_reply": "2026-03-30T13:18:22.027356Z",
- "shell.execute_reply.started": "2026-03-30T13:18:21.183644Z"
- }
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Members: [('cell_ids', ), ('da', )]\n",
- "Attrs: {}\n",
- "Write chunk sizes: ((55611, 55611, 55611, 55609),)\n"
- ]
- }
- ],
- "source": [
- "ob_store = HTTPStore.from_url(\"https://data-taos.ifremer.fr/GRID4EARTH/no_chunk_healpix.zarr\")\n",
- "store = ObjectStore(ob_store)\n",
- "g = zarr.open_group(store, mode=\"r\", zarr_format=2, use_consolidated=True)\n",
- "arr = g['da']\n",
- "\n",
- "print(\"Members:\", list(g.members()))\n",
- "print(\"Attrs:\", dict(g.attrs))\n",
- "print(\"Write chunk sizes:\", arr.write_chunk_sizes)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "wmuqi66d46",
- "metadata": {},
- "source": [
- "## 2. HEALPix-style variable chunking\n",
- "\n",
- "Inspired by [this use case](https://github.com/zarr-developers/zarr-python/pull/3534#issuecomment-3848669859): HEALPix grids where cells are grouped by parent tile at a coarser resolution level, producing variable-sized chunks along the cell dimension when accounting for sparsity."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "90bc91b9",
- "metadata": {
- "execution": {
- "iopub.execute_input": "2026-03-30T13:18:22.029842Z",
- "iopub.status.busy": "2026-03-30T13:18:22.029258Z",
- "iopub.status.idle": "2026-03-30T13:18:23.629597Z",
- "shell.execute_reply": "2026-03-30T13:18:23.628896Z",
- "shell.execute_reply.started": "2026-03-30T13:18:22.029824Z"
- }
- },
- "outputs": [],
- "source": [
- "da = xr.open_zarr(\n",
- " store,\n",
- " zarr_format=2,\n",
- " consolidated=True,\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "0d7785b0-d72f-4ef8-8a57-91d61f07be96",
- "metadata": {
- "execution": {
- "iopub.execute_input": "2026-03-30T13:18:23.630244Z",
- "iopub.status.busy": "2026-03-30T13:18:23.629978Z",
- "iopub.status.idle": "2026-03-30T13:18:23.633850Z",
- "shell.execute_reply": "2026-03-30T13:18:23.632930Z",
- "shell.execute_reply.started": "2026-03-30T13:18:23.630232Z"
- }
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "10"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "depth = da.cell_ids.attrs['level']\n",
- "depth"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "72c80224-dcac-4724-8caf-5717b29a25d5",
- "metadata": {
- "execution": {
- "iopub.execute_input": "2026-03-30T13:18:23.634211Z",
- "iopub.status.busy": "2026-03-30T13:18:23.634119Z",
- "iopub.status.idle": "2026-03-30T13:18:23.642291Z",
- "shell.execute_reply": "2026-03-30T13:18:23.641668Z",
- "shell.execute_reply.started": "2026-03-30T13:18:23.634203Z"
- }
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "array([ 25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603,\n",
- " 2450, 4096, 4096, 3327, 4047, 4096, 4096, 1278, 2113, 4096, 3879,\n",
- " 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, 4096, 4096, 4096,\n",
- " 4096, 3515, 1395, 4096, 3622, 4096, 4096, 3875, 4096, 4096, 4096,\n",
- " 4096, 4096, 2034, 4096, 358, 3991, 4096, 4096, 4096, 4096, 2714,\n",
- " 1210, 4096, 4096, 4096, 4096, 92, 3826, 4096, 2629, 4096, 1438,\n",
- " 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23])"
- ]
- },
- "execution_count": 6,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "new_depth = depth-6\n",
- "parents = nested.zoom_to(da.cell_ids, depth=depth, new_depth=new_depth)\n",
- "_, chunk_sizes =np.unique(parents, return_counts=True)\n",
- "chunk_sizes"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "id": "a79a281b-ca74-49c3-a467-60490a4ad63e",
- "metadata": {
- "execution": {
- "iopub.execute_input": "2026-03-30T13:18:23.642721Z",
- "iopub.status.busy": "2026-03-30T13:18:23.642622Z",
- "iopub.status.idle": "2026-03-30T13:18:23.649165Z",
- "shell.execute_reply": "2026-03-30T13:18:23.648723Z",
- "shell.execute_reply.started": "2026-03-30T13:18:23.642712Z"
- }
- },
- "outputs": [
- {
- "data": {
- "text/plain": [
- "Frozen({'cell_ids': (25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, 4096, 4096, 3327, 4047, 4096, 4096, 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, 4096, 4096, 4096, 4096, 3515, 1395, 4096, 3622, 4096, 4096, 3875, 4096, 4096, 4096, 4096, 4096, 2034, 4096, 358, 3991, 4096, 4096, 4096, 4096, 2714, 1210, 4096, 4096, 4096, 4096, 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23)})"
- ]
- },
- "execution_count": 7,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "da = da.chunk({\"cell_ids\": tuple(chunk_sizes.tolist())})\n",
- "da.chunks"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bsp6y7otkzb",
- "metadata": {},
- "source": [
- "## 3. Write as rectilinear Zarr V3\n",
- "\n",
- "Write the variable-chunked dataset to a local Zarr V3 store with rectilinear chunk grids enabled."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "id": "ribguojdr0s",
- "metadata": {
- "execution": {
- "iopub.execute_input": "2026-03-30T13:18:23.649823Z",
- "iopub.status.busy": "2026-03-30T13:18:23.649737Z",
- "iopub.status.idle": "2026-03-30T13:18:24.089390Z",
- "shell.execute_reply": "2026-03-30T13:18:24.088640Z",
- "shell.execute_reply.started": "2026-03-30T13:18:23.649815Z"
- }
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Written to: /var/folders/70/hc_nynms54d8lp67z4rsfctc0000gp/T/tmp6dibcrho/healpix_rectilinear.zarr\n"
- ]
- }
- ],
- "source": [
- "output_path = Path(tempfile.mkdtemp()) / \"healpix_rectilinear.zarr\"\n",
- "\n",
- "encoding = {\n",
- " \"da\": {\"chunks\": [chunk_sizes.tolist()]},\n",
- " \"cell_ids\": {\"chunks\": [chunk_sizes.tolist()]},\n",
- "}\n",
- "\n",
- "da.to_zarr(output_path, zarr_format=3, mode=\"w\", encoding=encoding, consolidated=False)\n",
- "\n",
- "print(f\"Written to: {output_path}\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "rbfm1hn63g9",
- "metadata": {},
- "source": [
- "## 4. Verify rectilinear metadata\n",
- "\n",
- "Inspect the output store to confirm the chunk grid is serialized as `\"rectilinear\"` in `zarr.json`,\n",
- "following the [rectilinear chunk grid extension spec](https://github.com/zarr-developers/zarr-extensions/tree/main/chunk-grids/rectilinear).\n",
- "\n",
- "Key things to look for in `chunk_grid`:\n",
- "- **`name`**: `\"rectilinear\"` (the extension identifier)\n",
- "- **`configuration.kind`**: `\"inline\"` (edge lengths stored directly in metadata)\n",
- "- **`configuration.chunk_shapes`**: one entry per dimension — here a single list for the 1D `cell_ids` axis. Each element is either:\n",
- " - a **bare integer** for a unique edge length (e.g., `25`, `645`)\n",
- " - a **`[value, count]` array** using [run-length encoding](https://github.com/zarr-developers/zarr-extensions/tree/main/chunk-grids/rectilinear#run-length-encoding) for consecutive repeated sizes (e.g., `[4096, 4]` means four consecutive chunks of size 4096)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "id": "mpdn5hxp7lp",
- "metadata": {
- "execution": {
- "iopub.execute_input": "2026-03-30T13:18:24.090312Z",
- "iopub.status.busy": "2026-03-30T13:18:24.090192Z",
- "iopub.status.idle": "2026-03-30T13:18:24.093595Z",
- "shell.execute_reply": "2026-03-30T13:18:24.092908Z",
- "shell.execute_reply.started": "2026-03-30T13:18:24.090303Z"
- }
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "{'name': 'rectilinear', 'configuration': {'kind': 'inline', 'chunk_shapes': [[25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, [4096, 2], 3327, 4047, [4096, 2], 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, [4096, 4], 3515, 1395, 4096, 3622, [4096, 2], 3875, [4096, 5], 2034, 4096, 358, 3991, [4096, 4], 2714, 1210, [4096, 4], 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23]]}}\n"
- ]
- }
- ],
- "source": [
- "\n",
- "# Read the zarr.json for the 'da' array\n",
- "da_meta_path = output_path / \"da\" / \"zarr.json\"\n",
- "meta = json.loads(da_meta_path.read_text())\n",
- "print(meta['chunk_grid'])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "inz7s8ugu2c",
- "metadata": {},
- "source": [
- "## 5. Round-trip verification\n",
- "\n",
- "Read the rectilinear store back and confirm the chunk sizes are preserved."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "id": "308gxly6r3j",
- "metadata": {
- "execution": {
- "iopub.execute_input": "2026-03-30T13:18:24.094252Z",
- "iopub.status.busy": "2026-03-30T13:18:24.094013Z",
- "iopub.status.idle": "2026-03-30T13:18:24.117313Z",
- "shell.execute_reply": "2026-03-30T13:18:24.116670Z",
- "shell.execute_reply.started": "2026-03-30T13:18:24.094242Z"
- }
- },
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Round-trip chunk sizes: Frozen({'cell_ids': (25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, 4096, 4096, 3327, 4047, 4096, 4096, 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, 4096, 4096, 4096, 4096, 3515, 1395, 4096, 3622, 4096, 4096, 3875, 4096, 4096, 4096, 4096, 4096, 2034, 4096, 358, 3991, 4096, 4096, 4096, 4096, 2714, 1210, 4096, 4096, 4096, 4096, 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23)})\n"
- ]
- }
- ],
- "source": [
- "roundtrip = xr.open_zarr(output_path, zarr_format=3, consolidated=False)\n",
- "\n",
- "print(\"Round-trip chunk sizes:\", roundtrip.chunks)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "e8d42341-c242-44f5-ad6a-491370e3ffab",
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.12.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/docs/user-guide/examples/rectilinear_chunks.md b/docs/user-guide/examples/rectilinear_chunks.md
new file mode 100644
index 0000000000..098cdf1e2f
--- /dev/null
+++ b/docs/user-guide/examples/rectilinear_chunks.md
@@ -0,0 +1,173 @@
+# Rectilinear Chunk Grids
+
+This example demonstrates rectilinear (variable-sized) chunk grids, introduced in
+[#3802](https://github.com/zarr-developers/zarr-python/pull/3802). Rectilinear grids
+allow different chunk sizes along each dimension, which is useful for data that
+doesn't partition evenly — for example, sparse HEALPix cells grouped by parent tile,
+boundary-padded HPC arrays, or ingesting existing variable-chunked datasets via
+VirtualiZarr. See [Rectilinear (variable) chunk grids](../arrays.md#rectilinear-variable-chunk-grids)
+in the arrays guide for an introduction to the feature.
+
+The example chunks a HEALPix dataset by parent tile, writes it as a Zarr v3 array
+with a rectilinear chunk grid, and verifies the round trip through
+[Xarray](https://xarray.dev).
+
+!!! warning "Experimental"
+ Rectilinear chunk grids are an experimental feature and may change in future
+ releases. In addition, this example currently requires
+ [a fork of Xarray](https://github.com/maxrjones/xarray/tree/poc/unified-zarr-chunk-grid)
+ with rectilinear chunk grid support (this will ideally be incorporated into a
+ future Xarray release), as well as the `dask`, `healpix-geo`, and `obstore`
+ packages, and it reads an example dataset from a remote server. For these
+ reasons the code on this page is not executed when the documentation is built;
+ the outputs shown were captured from a live run.
+
+## Setup
+
+Rectilinear chunk grids are disabled by default and must be explicitly enabled via
+the `array.rectilinear_chunks` configuration option:
+
+```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data"
+import json
+import tempfile
+from pathlib import Path
+
+import numpy as np
+import xarray as xr
+from healpix_geo import nested
+from obstore.store import HTTPStore
+
+import zarr
+from zarr.storage import ObjectStore
+
+# Increase concurrency for better performance with obstore
+zarr.config.set({'async.concurrency': 128})
+# Opt in to rectilinear chunks
+zarr.config.set({'array.rectilinear_chunks': True})
+```
+
+## Inspect the HEALPix dataset
+
+Load the remote Zarr store to understand the data structure before chunking it:
+
+```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data"
+ob_store = HTTPStore.from_url("https://data-taos.ifremer.fr/GRID4EARTH/no_chunk_healpix.zarr")
+store = ObjectStore(ob_store)
+g = zarr.open_group(store, mode="r", zarr_format=2, use_consolidated=True)
+arr = g['da']
+
+print("Members:", list(g.members()))
+print("Attrs:", dict(g.attrs))
+print("Write chunk sizes:", arr.write_chunk_sizes)
+```
+
+```text
+Members: [('cell_ids', ), ('da', )]
+Attrs: {}
+Write chunk sizes: ((55611, 55611, 55611, 55609),)
+```
+
+## HEALPix-style variable chunking
+
+Inspired by [this use case](https://github.com/zarr-developers/zarr-python/pull/3534#issuecomment-3848669859):
+HEALPix grids where cells are grouped by parent tile at a coarser resolution level,
+producing variable-sized chunks along the cell dimension when accounting for sparsity.
+
+```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data"
+da = xr.open_zarr(
+ store,
+ zarr_format=2,
+ consolidated=True,
+)
+
+depth = da.cell_ids.attrs['level']
+new_depth = depth - 6
+parents = nested.zoom_to(da.cell_ids, depth=depth, new_depth=new_depth)
+_, chunk_sizes = np.unique(parents, return_counts=True)
+print(chunk_sizes)
+```
+
+```text
+[ 25 645 1510 2363 3203 74 769 3963 4096 233 1603 2450 4096 4096
+ 3327 4047 4096 4096 1278 2113 4096 3879 4096 3842 2173 983 4046 2187
+ 4095 1369 4096 4096 4096 4096 3515 1395 4096 3622 4096 4096 3875 4096
+ 4096 4096 4096 4096 2034 4096 358 3991 4096 4096 4096 4096 2714 1210
+ 4096 4096 4096 4096 92 3826 4096 2629 4096 1438 4096 353 4078 3410
+ 2407 226 132 2738 1223 23]
+```
+
+Rechunk the dataset with these variable-sized chunks:
+
+```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data"
+da = da.chunk({"cell_ids": tuple(chunk_sizes.tolist())})
+print(da.chunks)
+```
+
+```text
+Frozen({'cell_ids': (25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, 4096, 4096, 3327, 4047, 4096, 4096, 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, 4096, 4096, 4096, 4096, 3515, 1395, 4096, 3622, 4096, 4096, 3875, 4096, 4096, 4096, 4096, 4096, 2034, 4096, 358, 3991, 4096, 4096, 4096, 4096, 2714, 1210, 4096, 4096, 4096, 4096, 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23)})
+```
+
+## Write as rectilinear Zarr v3
+
+Write the variable-chunked dataset to a local Zarr v3 store with rectilinear chunk
+grids enabled:
+
+```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data"
+output_path = Path(tempfile.mkdtemp()) / "healpix_rectilinear.zarr"
+
+encoding = {
+ "da": {"chunks": [chunk_sizes.tolist()]},
+ "cell_ids": {"chunks": [chunk_sizes.tolist()]},
+}
+
+da.to_zarr(output_path, zarr_format=3, mode="w", encoding=encoding, consolidated=False)
+
+print(f"Written to: {output_path}")
+```
+
+```text
+Written to: /var/folders/.../T/tmp6dibcrho/healpix_rectilinear.zarr
+```
+
+## Verify the rectilinear metadata
+
+Inspect the output store to confirm the chunk grid is serialized as `"rectilinear"`
+in `zarr.json`, following the
+[rectilinear chunk grid extension spec](https://github.com/zarr-developers/zarr-extensions/tree/main/chunk-grids/rectilinear).
+
+Key things to look for in `chunk_grid`:
+
+- **`name`**: `"rectilinear"` (the extension identifier)
+- **`configuration.kind`**: `"inline"` (edge lengths stored directly in metadata)
+- **`configuration.chunk_shapes`**: one entry per dimension — here a single list for
+ the 1D `cell_ids` axis. Each element is either:
+ - a **bare integer** for a unique edge length (e.g., `25`, `645`)
+ - a **`[value, count]` array** using
+ [run-length encoding](https://github.com/zarr-developers/zarr-extensions/tree/main/chunk-grids/rectilinear#run-length-encoding)
+ for consecutive repeated sizes (e.g., `[4096, 4]` means four consecutive chunks
+ of size 4096)
+
+```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data"
+# Read the zarr.json for the 'da' array
+da_meta_path = output_path / "da" / "zarr.json"
+meta = json.loads(da_meta_path.read_text())
+print(meta['chunk_grid'])
+```
+
+```text
+{'name': 'rectilinear', 'configuration': {'kind': 'inline', 'chunk_shapes': [[25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, [4096, 2], 3327, 4047, [4096, 2], 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, [4096, 4], 3515, 1395, 4096, 3622, [4096, 2], 3875, [4096, 5], 2034, 4096, 358, 3991, [4096, 4], 2714, 1210, [4096, 4], 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23]]}}
+```
+
+## Round-trip verification
+
+Read the rectilinear store back and confirm the chunk sizes are preserved:
+
+```python exec="false" reason="requires an xarray fork with rectilinear chunk grid support and remote example data"
+roundtrip = xr.open_zarr(output_path, zarr_format=3, consolidated=False)
+
+print("Round-trip chunk sizes:", roundtrip.chunks)
+```
+
+```text
+Round-trip chunk sizes: Frozen({'cell_ids': (25, 645, 1510, 2363, 3203, 74, 769, 3963, 4096, 233, 1603, 2450, 4096, 4096, 3327, 4047, 4096, 4096, 1278, 2113, 4096, 3879, 4096, 3842, 2173, 983, 4046, 2187, 4095, 1369, 4096, 4096, 4096, 4096, 3515, 1395, 4096, 3622, 4096, 4096, 3875, 4096, 4096, 4096, 4096, 4096, 2034, 4096, 358, 3991, 4096, 4096, 4096, 4096, 2714, 1210, 4096, 4096, 4096, 4096, 92, 3826, 4096, 2629, 4096, 1438, 4096, 353, 4078, 3410, 2407, 226, 132, 2738, 1223, 23)})
+```
diff --git a/docs/user-guide/experimental.md b/docs/user-guide/experimental.md
index 1c6d952c7c..a50be394c2 100644
--- a/docs/user-guide/experimental.md
+++ b/docs/user-guide/experimental.md
@@ -1,6 +1,8 @@
# Experimental features
-This section contains documentation for experimental Zarr Python features. The features described here are exciting and potentially useful, but also volatile -- we might change them at any time. Take this into account if you consider depending on these features.
+This section contains documentation for experimental Zarr Python features. The features described here are exciting and potentially useful, but also volatile -- we might change them at any time. Take this into account if you consider depending on these features. See the
+[experimental API policy](../contributing.md#experimental-api-policy) for the stability
+guarantees (or lack thereof) that apply to everything documented on this page.
## `CacheStore`
@@ -16,10 +18,11 @@ when the cache reaches its maximum size.
Because the `CacheStore` uses an ordinary Zarr `Store` object as the caching layer, you can reuse the data stored in the cache later.
-> **Note:** The CacheStore is a wrapper store that maintains compatibility with the full
-> `zarr.abc.store.Store` API while adding transparent caching functionality.
+!!! note
+ The CacheStore is a wrapper store that maintains compatibility with the full
+ `zarr.abc.store.Store` API while adding transparent caching functionality.
-## Basic Usage
+### Basic Usage
Creating a CacheStore requires both a source store and a cache store. The cache store
can be any Store implementation, providing flexibility in cache persistence:
@@ -51,7 +54,7 @@ zarr_array[:] = np.random.random((100, 100))
The dual-store architecture allows you to use different store types for source and cache,
such as a remote store for source data and a local store for persistent caching.
-## Performance Benefits
+### Performance Benefits
The CacheStore provides significant performance improvements for repeated data access:
@@ -79,20 +82,15 @@ print(f"Speedup is {speedup}")
Cache effectiveness is particularly pronounced with repeated access to the same data chunks.
-## Cache Configuration
+### Cache Configuration
The CacheStore can be configured with several parameters:
-**max_size**: Controls the maximum size of cached data in bytes
+**max_size**: Controls the maximum size of cached data in bytes. The
+[Basic Usage](#basic-usage) example above sets a 256MB limit with
+`max_size=256*1024*1024`:
```python exec="true" session="experimental" source="above"
-# 256MB cache with size limit
-cache = CacheStore(
- store=source_store,
- cache_store=cache_store,
- max_size=256*1024*1024
-)
-
# Unlimited cache size (use with caution)
cache = CacheStore(
store=source_store,
@@ -137,14 +135,15 @@ cache = CacheStore(
)
```
-## Cache Statistics
+### Cache Statistics
The CacheStore provides statistics to monitor cache performance and state:
```python exec="true" session="experimental" source="above"
# Access some data to generate cache activity
-data = zarr_array[0:50, 0:50] # First access - cache miss
-data = zarr_array[0:50, 0:50] # Second access - cache hit
+# (these chunks were already cached by the reads above, so both accesses are cache hits)
+data = zarr_array[0:50, 0:50]
+data = zarr_array[0:50, 0:50]
# Get comprehensive cache information
info = cached_store.cache_info()
@@ -159,7 +158,7 @@ print(info['cache_set_data'])
The `cache_info()` method returns a dictionary with detailed information about the cache state.
-## Cache Management
+### Cache Management
The CacheStore provides methods for manual cache management:
@@ -177,7 +176,7 @@ assert info['current_size'] == 0
The `clear_cache()` method is an async method that clears both the cache store
(if it supports the `clear` method) and all internal tracking data.
-## Best Practices
+### Best Practices
1. **Choose appropriate cache store**: Use MemoryStore for fast temporary caching or LocalStore for persistent caching
2. **Size the cache appropriately**: Set `max_size` based on available storage and expected data access patterns
@@ -186,12 +185,12 @@ The `clear_cache()` method is an async method that clears both the cache store
5. **Consider data locality**: Group related data accesses together to improve cache efficiency
6. **Set appropriate expiration**: Use `max_age_seconds` for time-sensitive data or "infinity" for static data
-## Working with Different Store Types
+### Working with Different Store Types
The CacheStore can wrap any store that implements the `zarr.abc.store.Store` interface
and use any store type for the cache backend:
-### Local Store with Memory Cache
+#### Local Store with Memory Cache
```python exec="true" session="experimental-memory-cache" source="above"
from zarr.storage import LocalStore, MemoryStore
@@ -208,7 +207,7 @@ cached_store = CacheStore(
)
```
-### Memory Store with Persistent Cache
+#### Memory Store with Persistent Cache
```python exec="true" session="experimental-local-cache" source="above"
from tempfile import mkdtemp
@@ -228,7 +227,7 @@ cached_store = CacheStore(
The dual-store architecture provides flexibility in choosing the best combination
of source and cache stores for your specific use case.
-## Examples from Real Usage
+### Examples from Real Usage
Here's a complete example demonstrating cache effectiveness:
diff --git a/docs/user-guide/extending.md b/docs/user-guide/extending.md
index cefeb114c5..8602ec8c3b 100644
--- a/docs/user-guide/extending.md
+++ b/docs/user-guide/extending.md
@@ -50,8 +50,8 @@ Custom codecs should also implement the following methods:
To use custom codecs in Zarr, they need to be registered using the
[entrypoint mechanism](https://packaging.python.org/en/latest/specifications/entry-points/).
Commonly, entrypoints are declared in the `pyproject.toml` of your package under the
-`[project.entry-points."zarr.codecs"]` section. Zarr will automatically discover and
-load all codecs registered with the entrypoint mechanism from imported modules.
+`[project.entry-points."zarr.codecs"]` section. Zarr will automatically discover
+all codecs registered via the entrypoint mechanism in installed packages.
```toml
[project.entry-points."zarr.codecs"]
@@ -74,7 +74,8 @@ implementation.
## Custom stores
-Coming soon.
+Custom stores can be created by implementing the [`zarr.abc.store.Store`][] interface.
+See [developing custom stores](storage.md#developing-custom-stores) for more information.
## Custom array buffers
@@ -82,7 +83,16 @@ Zarr-python provides control over where and how arrays are stored in memory thro
[`zarr.abc.buffer.Buffer`][]. Currently both CPU (the default) and GPU implementations are
provided (see [Using GPUs with Zarr](gpu.md) for more information). You can implement your own buffer
classes by implementing the interface defined in [`zarr.abc.buffer.BufferPrototype`][].
+Like codecs, custom buffer implementations can be registered via entrypoints, using the
+`zarr.buffer` and `zarr.ndbuffer` entrypoint groups.
+
+## Custom data types
+
+Zarr supports user-defined data types. See the
+[data types documentation](data_types.md) for an explanation of how Zarr Python
+models data types and how to write your own, and the
+[custom data type example](examples/custom_dtype.md) for a complete worked example.
## Other extensions
-In the future, Zarr will support writing custom data types and chunk grids.
+In the future, Zarr will support writing custom chunk grids.
diff --git a/docs/user-guide/glossary.md b/docs/user-guide/glossary.md
index 3eb63925cc..dde08388a1 100644
--- a/docs/user-guide/glossary.md
+++ b/docs/user-guide/glossary.md
@@ -9,12 +9,18 @@ This page defines key terms used throughout the zarr-python documentation and AP
An N-dimensional typed array stored in a Zarr [store](#store). An array's
[metadata](#metadata) defines its shape, data type, chunk layout, and codecs.
+### Group
+
+A container for [arrays](#array) and other groups, enabling hierarchical
+organization of data — similar to directories in a file system, or groups in
+HDF5. Like arrays, each group has its own [metadata](#metadata) and
+[attributes](#attributes). See the [groups documentation](groups.md).
+
### Chunk
The fundamental unit of data in a Zarr array. An array is divided into chunks
-along each dimension according to the [chunk grid](#chunk-grid), which is currently
-part of Zarr's private API. Each chunk is independently compressed and encoded
-through the array's [codec](#codec) pipeline.
+along each dimension according to the [chunk grid](#chunk-grid). Each chunk is
+independently compressed and encoded through the array's [codec](#codec) pipeline.
When [sharding](#shard) is used, "chunk" refers to the inner chunks within each
shard, because those are the compressible units. The chunks are the smallest units
@@ -52,7 +58,8 @@ not the inner chunk boundaries. The inner chunk shape is defined within the
grid. [`Array.chunks`][zarr.Array.chunks] returns the chunk shape for regular
grids. For all grid types, `Array.read_chunk_sizes` and `Array.write_chunk_sizes`
return the per-dimension chunk sizes in dask-style `tuple[tuple[int, ...], ...]`
-format.
+format. Note that while the chunk grid is a public concept of the Zarr format,
+the classes zarr-python uses to model chunk grids are currently private API.
### Shard
@@ -88,12 +95,28 @@ file) in the store, addressed by a key derived from its grid coordinates.
### Metadata
-The JSON document (`zarr.json`) that describes an [array](#array) or group. For
-arrays, metadata includes the shape, data type, [chunk grid](#chunk-grid), fill
+The JSON document that describes an [array](#array) or [group](#group). In Zarr
+format 3 this is a single `zarr.json` document; Zarr format 2 stores the
+equivalent information in separate `.zarray`, `.zgroup`, and `.zattrs` documents.
+For arrays, metadata includes the shape, data type, [chunk grid](#chunk-grid), fill
value, and [codec](#codec) pipeline. Metadata is stored alongside the data in
the [store](#store). Zarr-Python does not yet expose its internal metadata
representation as part of its public API.
+### Attributes
+
+User-defined key-value pairs (any JSON-serializable values) attached to an
+[array](#array) or [group](#group). Attributes are stored in the
+[metadata](#metadata) document. See the
+[attributes documentation](attributes.md).
+
+### Consolidated Metadata
+
+A copy of the [metadata](#metadata) of every array and group in a hierarchy,
+stored in the metadata of the root group so that the entire hierarchy can be
+inspected with a single read from the [store](#store). See the
+[consolidated metadata documentation](consolidated_metadata.md).
+
## Codecs
### Codec
diff --git a/docs/user-guide/gpu.md b/docs/user-guide/gpu.md
index 6c26c3e564..26d1c114b0 100644
--- a/docs/user-guide/gpu.md
+++ b/docs/user-guide/gpu.md
@@ -1,6 +1,6 @@
# Using GPUs with Zarr
-Zarr can use GPUs to accelerate your workload by running `zarr.Config.enable_gpu`.
+Zarr can use GPUs to accelerate your workload by running `zarr.config.enable_gpu()`.
!!! note
`zarr-python` currently supports reading the ndarray data into device (GPU)
@@ -11,20 +11,50 @@ Zarr can use GPUs to accelerate your workload by running `zarr.Config.enable_gpu
the GPU, avoiding the need to move data between the host and device for
compression and decompression.
+## Installation
+
+Zarr's GPU support requires [CuPy](https://cupy.dev), which in turn requires a
+CUDA-compatible NVIDIA GPU. CuPy can be installed alongside Zarr with the `gpu`
+extra (see [Installation](installation.md) for the other optional dependency groups):
+
+```console
+pip install "zarr[gpu]"
+```
+
+This installs the `cupy-cuda12x` package. If you need a CuPy build for a different
+CUDA version, see the [CuPy installation guide](https://docs.cupy.dev/en/stable/install.html)
+and install the appropriate package yourself.
+
## Reading data into device memory
-[`zarr.config`][] configures Zarr to use GPU memory for the data
-buffers used internally by Zarr via `enable_gpu()`.
+Calling `zarr.config.enable_gpu()` configures Zarr to use GPU memory for the data
+buffers used internally by Zarr:
```python test="true" session="gpu-demo" markers="gpu" source="above"
import zarr
import cupy as cp
+
zarr.config.enable_gpu()
z = zarr.create_array(
store="memory://gpu-demo", shape=(100, 100), chunks=(10, 10), dtype="float32",
)
-type(z[:10, :10])
-# cupy.ndarray
+assert isinstance(z[:10, :10], cp.ndarray)
+```
+
+Note that the arrays returned by reads are of type `cupy.ndarray` rather than
+NumPy arrays.
+
+`zarr.config.enable_gpu()` returns a [donfig](https://donfig.readthedocs.io/en/latest/)
+`ConfigSet`, which can be used as a context manager to enable GPU support for a
+limited scope:
+
+```python test="true" session="gpu-demo" markers="gpu" source="above"
+with zarr.config.enable_gpu():
+ data = z[:10, :10]
+assert isinstance(data, cp.ndarray)
```
-Note that the output type is a `cupy.ndarray` rather than a NumPy array.
+Under the hood, `enable_gpu()` selects the GPU-backed buffer classes
+`zarr.buffer.gpu.Buffer` and `zarr.buffer.gpu.NDBuffer` via the `buffer` and
+`ndbuffer` configuration keys. See [Custom array buffers](extending.md#custom-array-buffers)
+for more on Zarr's buffer classes, including how to implement your own.
diff --git a/docs/user-guide/groups.md b/docs/user-guide/groups.md
index 5faa26a281..a2b40dfe8a 100644
--- a/docs/user-guide/groups.md
+++ b/docs/user-guide/groups.md
@@ -4,7 +4,7 @@ Zarr supports hierarchical organization of arrays via groups. As with arrays,
groups can be stored in memory, on disk, or via other storage systems that
support a similar interface.
-To create a group, use the [`zarr.group`][] function:
+To create a group, use the [`zarr.create_group`][] function:
```python exec="true" session="groups" source="above" result="ansi"
import zarr
@@ -12,6 +12,13 @@ root = zarr.create_group(store="memory://groups-demo")
print(root)
```
+Zarr-Python provides three related functions for making groups:
+[`zarr.create_group`][] creates a new group; [`zarr.open_group`][] creates or
+re-opens a group depending on its `mode` argument (see below); and
+[`zarr.group`][], which is kept for compatibility with Zarr-Python 2, is
+equivalent to calling [`zarr.open_group`][] with `mode='a'` (or `mode='w'`
+when `overwrite=True`).
+
Groups have a similar API to the Group class from [h5py](https://www.h5py.org/). For example, groups can contain other groups:
```python exec="true" session="groups" source="above"
@@ -26,7 +33,8 @@ z1 = bar.create_array(name='baz', shape=(10000, 10000), chunks=(1000, 1000), dty
print(z1)
```
-Members of a group can be accessed via the suffix notation, e.g.:
+Members of a group can be accessed with square-bracket item access, like a
+Python `dict`, e.g.:
```python exec="true" session="groups" source="above" result="ansi"
print(root['foo'])
@@ -66,10 +74,46 @@ print(z)
For more information on groups see the [`zarr.Group` API docs](../api/zarr/group.md).
-## Batch Group Creation
+## Exploring group contents
+
+Groups also support a dict-like interface for enumerating their contents. The
+[`zarr.Group.keys`][] method iterates over member names, and the `in` operator
+tests for membership:
+
+```python exec="true" session="groups" source="above" result="ansi"
+print(list(root.keys()))
+print('foo' in root)
+```
+
+The [`zarr.Group.members`][] method returns `(name, member)` pairs for the
+arrays and groups contained in a group:
+
+```python exec="true" session="groups" source="above" result="ansi"
+for name, member in root.members():
+ print(name, member)
+```
+
+By default only immediate members are returned. Pass `max_depth=None` to
+recursively traverse the whole hierarchy below a group:
+
+```python exec="true" session="groups" source="above" result="ansi"
+for name, member in root.members(max_depth=None):
+ print(name, member)
+```
+
+Members can be deleted with the `del` operator, which removes the member's
+metadata and data from the store:
+
+```python exec="true" session="groups" source="above" result="ansi"
+del root['foo/bar/baz']
+for name, member in root.members(max_depth=None):
+ print(name, member)
+```
+
+## Batch group creation
You can also create multiple groups concurrently with a single function call. [`zarr.create_hierarchy`][] takes
-a [`zarr Storage`](../api/zarr/storage.md) instance and a dict of `key : metadata` pairs, parses that dict, and
+a [`Store`](../api/zarr/storage.md) instance and a dict of `key : metadata` pairs, parses that dict, and
writes metadata documents to storage:
```python exec="true" session="groups" source="above" result="ansi"
diff --git a/docs/user-guide/index.md b/docs/user-guide/index.md
index ff6e354d80..6b9a547776 100644
--- a/docs/user-guide/index.md
+++ b/docs/user-guide/index.md
@@ -7,7 +7,7 @@ Welcome to the user guide, where you can learn more about using Zarr-Python!
New to Zarr-Python? Start here:
- **[Installation](installation.md)** - Install Zarr-Python
-- **[Quick-start](../quick-start.md)** - Quick overview of core functionality
+- **[Quick start](../quick-start.md)** - Quick overview of core functionality
## Core Concepts
@@ -15,7 +15,7 @@ Learn the essential building blocks:
- **[Arrays](arrays.md)** - Learn the fundamentals of working with arrays
- **[Groups](groups.md)** - Organize your data with groups
-- **[Attributes](attributes.md)** - Configure metadata to your data structures
+- **[Attributes](attributes.md)** - Attach metadata to your arrays and groups
- **[Storage](storage.md)** - Learn how data is stored and accessed
## Configuration & Setup
@@ -23,6 +23,7 @@ Learn the essential building blocks:
Customize your experience:
- **[Runtime Configuration](config.md)** - Configure Zarr-Python for your needs
+- **[Command-Line Interface](cli.md)** - Migrate and manage Zarr metadata from the terminal
- **[V3 Migration](v3_migration.md)** - Upgrading from version 2 to version 3
## Advanced Topics
@@ -34,6 +35,14 @@ Take your skills to the next level:
- **[GPU](gpu.md)** - Leverage GPU acceleration
- **[Extending](extending.md)** - Extend functionality with custom code
- **[Consolidated Metadata](consolidated_metadata.md)** - Advanced metadata management
+- **[Experimental Features](experimental.md)** - Preview features that may change at any time
+
+## Examples
+
+Worked, end-to-end examples:
+
+- **[Custom Data Type](examples/custom_dtype.md)** - Extend Zarr-Python with a user-defined data type
+- **[Rectilinear Chunk Grids](examples/rectilinear_chunks.md)** - Use variable-sized chunks along each dimension
## Reference
diff --git a/docs/user-guide/installation.md b/docs/user-guide/installation.md
index c902acf171..4af7667a44 100644
--- a/docs/user-guide/installation.md
+++ b/docs/user-guide/installation.md
@@ -9,7 +9,7 @@ Required dependencies include:
- [numpy](https://numpy.org) (2.0 or later)
- [numcodecs](https://numcodecs.readthedocs.io) (0.14 or later)
- [google-crc32c](https://github.com/googleapis/python-crc32c) (1.5 or later)
-- [typing_extensions](https://typing-extensions.readthedocs.io) (4.9 or later)
+- [typing_extensions](https://typing-extensions.readthedocs.io) (4.14 or later)
- [donfig](https://donfig.readthedocs.io) (0.8 or later)
## pip
@@ -23,10 +23,11 @@ pip install zarr
There are a number of optional dependency groups you can install for extra functionality.
These can be installed using `pip install "zarr[]"`, e.g. `pip install "zarr[gpu]"`
-- `gpu`: support for GPUs
-- `remote`: support for reading/writing to remote data stores
-
-Additional optional dependencies include `universal_pathlib`. These must be installed separately.
+- `remote`: support for reading/writing to remote data stores (fsspec, obstore)
+- `gpu`: support for GPUs (cupy)
+- `cli`: support for the `zarr` [command-line interface](cli.md) (typer)
+- `optional`: support for path-like access to local and remote stores (universal-pathlib)
+- `cast-value-rs`: support for the `cast_value` codec (cast-value-rs)
## conda
@@ -39,7 +40,7 @@ conda install -c conda-forge zarr
Conda does not support optional dependencies, so you will have to manually install any packages
needed to enable extra functionality.
-# Nightly wheels
+## Nightly wheels
Development wheels are built nightly and published to the [scientific-python-nightly-wheels](https://anaconda.org/scientific-python-nightly-wheels) index. To install the latest nightly build:
@@ -48,6 +49,7 @@ pip install --pre --extra-index-url https://pypi.anaconda.org/scientific-python-
```
Note that nightly wheels may be unstable and are intended for testing purposes.
+
## Dependency support
Zarr has endorsed [Scientific-Python SPEC 0](https://scientific-python.org/specs/spec-0000/) and now follows the version support window as outlined below:
@@ -57,4 +59,4 @@ Zarr has endorsed [Scientific-Python SPEC 0](https://scientific-python.org/specs
## Development
-To install the latest development version of Zarr, see the contributing guide.
+To install the latest development version of Zarr, see the [contributing guide](../contributing.md).
diff --git a/docs/user-guide/performance.md b/docs/user-guide/performance.md
index 685ce7fe7e..818386578c 100644
--- a/docs/user-guide/performance.md
+++ b/docs/user-guide/performance.md
@@ -81,37 +81,38 @@ z6 = zarr.create_array(store={}, shape=(10000, 10000, 1000), shards=(1000, 1000,
print(z6.info)
```
-`shards` can be `"auto"` as well, in which case the `array.target_shard_size_bytes` setting can be used to control the size of shards (i.e., the size of the chunks cumulatively and uncompressed within the shard will be as close to, without being bigger than, `array.target_shard_size_bytes`); otherwise, a default is used.
+`shards` can be `"auto"` as well, in which case Zarr chooses a shard shape for you.
+The `array.target_shard_size_bytes` configuration setting controls this choice: the
+cumulative uncompressed size of the chunks within each shard will be as close as
+possible to, without exceeding, that target. If the setting is `None` (the default),
+Zarr falls back to a built-in heuristic for choosing the shard shape.
### Chunk memory layout
-The order of bytes **within each chunk** of an array can be changed via the
-`order` config option, to use either C or Fortran layout. For
-multi-dimensional arrays, these two layouts may provide different compression
-ratios, depending on the correlation structure within the data. E.g.:
+The memory layout of the in-memory arrays that Zarr produces and consumes can be
+changed via the `order` config option, to use either C or Fortran layout. This can
+matter for performance when the data is passed to other libraries that expect a
+particular memory layout. E.g.:
```python exec="true" session="performance" source="above" result="ansi"
import numpy as np
-a = np.arange(100000000, dtype='int32').reshape(10000, 10000).T
-c = zarr.create_array(store={}, shape=a.shape, chunks=(1000, 1000), dtype=a.dtype, config={'order': 'C'})
-c[:] = a
-print(c.info_complete())
+c = zarr.create_array(store={}, shape=(10000, 10000), chunks=(1000, 1000), dtype='int32', config={'order': 'C'})
+print(c[:100, :100].flags.c_contiguous)
```
```python exec="true" session="performance" source="above" result="ansi"
with zarr.config.set({'array.order': 'F'}):
- f = zarr.create_array(store={}, shape=a.shape, chunks=(1000, 1000), dtype=a.dtype)
- f[:] = a
-print(f.info_complete())
-
+ f = zarr.create_array(store={}, shape=(10000, 10000), chunks=(1000, 1000), dtype='int32')
+print(f[:100, :100].flags.f_contiguous)
```
-In the above example, Fortran order gives a better compression ratio. This is an
-artificial example but illustrates the general point that changing the order of
-bytes within chunks of an array may improve the compression ratio, depending on
-the structure of the data, the compression algorithm used, and which compression
-filters (e.g., byte-shuffle) have been applied.
+Note that for Zarr format 3 arrays the `order` option only affects the in-memory
+layout: the bytes written to storage are identical for both settings. The layout of
+the serialized data is instead determined by the array's codecs (e.g. the transpose
+codec), which can change how well the data compresses depending on the correlation
+structure within the data and which compression filters (e.g., byte-shuffle) have
+been applied.
### Subchunk memory layout
@@ -142,7 +143,7 @@ assert arr.config.write_empty_chunks == False
```
The following example illustrates the effect of the `write_empty_chunks` flag on
-the time required to write an array with different values.:
+the time required to write an array with different values:
```python exec="true" session="performance" source="above" result="ansi"
import zarr
@@ -182,12 +183,17 @@ for write_empty_chunks in (True, False):
print(f'\nwrite_empty_chunks={write_empty_chunks}:\n\tRandom Data: {full[0]:.4f}s, {full[1]} objects stored\n\t Empty Data: {empty[0]:.4f}s, {empty[1]} objects stored\n')
```
-In this example, writing random data is slightly slower with `write_empty_chunks=True`,
-but writing empty data is substantially faster and generates far fewer objects in storage.
+In this example, writing random data is slightly slower with `write_empty_chunks=False`,
+because every chunk must be checked for emptiness before it is stored. Writing empty
+data with `write_empty_chunks=False` is substantially faster, however, and stores no
+objects at all.
### Changing chunk shapes (rechunking)
-Coming soon.
+Zarr-Python does not yet provide a built-in way to change the chunk shape of an
+existing array in place. Arrays can, however, be resized and appended to along any
+dimension — see [Resizing and appending](arrays.md#resizing-and-appending) — and data
+can be copied to a new array created with the desired chunk shape.
## Parallel computing and synchronization
@@ -204,7 +210,7 @@ determines the maximum number of concurrent I/O operations.
The default value is 10, which is a conservative value. You may get improved performance by tuning
the concurrency limit. You can adjust this value based on your specific needs:
-```python exec="true" session="perf-concurrency"
+```python exec="true" session="perf-concurrency" source="above"
import zarr
# Set concurrency for the current session
@@ -234,7 +240,7 @@ By default it is `None`, which lets Python choose the pool size (typically
You can set it explicitly when you want more predictable resource usage:
-```python exec="true" session="perf-workers"
+```python exec="true" session="perf-workers" source="above"
import zarr
zarr.config.set({'threading.max_workers': 8})
@@ -256,7 +262,7 @@ concurrently.
total_concurrency ≈ dask_threads × zarr_async_concurrency
```
-For example, if you're running Dask with 10 threads and Zarr's default concurrency of 64, you could potentially have up to 640 concurrent operations, which may overwhelm your storage system or cause memory issues.
+For example, if you're running Dask with 10 threads and Zarr's default concurrency of 10, you could potentially have up to 100 concurrent operations, which may overwhelm your storage system or cause memory issues.
**Recommendation**: When using Dask with many threads, configure Zarr's concurrency settings:
@@ -283,7 +289,7 @@ result = arr.mean(axis=0).compute()
**Configuration guidelines for Dask workloads**:
- `async.concurrency`: Controls the maximum number of concurrent async I/O operations. Start with a lower value (e.g., 4-8) when using many Dask threads.
-- `threading.max_workers`: Controls Zarr's internal thread pool size for blocking operations (defaults to CPU count). Reduce this to avoid thread contention with Dask's scheduler.
+- `threading.max_workers`: Controls Zarr's internal thread pool size for blocking operations (defaults to `None`, letting Python choose the pool size). Reduce this to avoid thread contention with Dask's scheduler.
You may need to experiment with different values to find the optimal balance for your workload. Monitor your system's resource usage and adjust these settings based on whether your storage system or CPU is the bottleneck.
@@ -300,14 +306,17 @@ When writing to the same chunks from multiple processes, you should use external
## Pickle support
Zarr arrays and groups can be pickled, as long as the underlying store object can be
-pickled. With the exception of the `zarr.storage.MemoryStore`, any of the
-storage classes provided in the `zarr.storage` module can be pickled.
+pickled. All of the storage classes provided in the `zarr.storage` module can be pickled.
If an array or group is backed by a persistent store such as a `zarr.storage.LocalStore`,
`zarr.storage.ZipStore` or `zarr.storage.FsspecStore` then the store data
**are not** pickled. The only thing that is pickled is the necessary parameters to allow the store
to re-open any underlying files or databases upon being unpickled.
+Note that pickling a `zarr.storage.MemoryStore` copies the data it holds into the
+pickle stream: unpickling produces an independent in-memory copy, so a `MemoryStore`
+cannot be used to share data between processes.
+
E.g., pickle/unpickle a local store array:
```python exec="true" session="performance" source="above" result="ansi"
@@ -320,7 +329,3 @@ z2 = pickle.loads(s)
assert z1 == z2
print(np.all(z1[:] == z2[:]))
```
-
-## Configuring Blosc
-
-Coming soon.
diff --git a/docs/user-guide/storage.md b/docs/user-guide/storage.md
index d5f840ab4b..d32fe217c9 100644
--- a/docs/user-guide/storage.md
+++ b/docs/user-guide/storage.md
@@ -18,13 +18,13 @@ being created automatically:
```python exec="true" session="storage" source="above" result="ansi"
import zarr
-# Implicitly create a writable LocalStore
+# Implicitly creates a writable LocalStore
group = zarr.create_group(store='data/foo/bar')
print(group)
```
```python exec="true" session="storage" source="above" result="ansi"
-# Implicitly create a read-only FsspecStore
+# Implicitly creates a read-only FsspecStore
# Note: requires s3fs to be installed
group = zarr.open_group(
store='s3://noaa-nwm-retro-v2-zarr-pds',
@@ -138,24 +138,25 @@ print(group)
```
The type of filesystem (e.g. S3, https, etc..) is inferred from the scheme of the url (e.g. s3 for "**s3**://noaa-nwm-retro-v2-zarr-pds").
-In case a specific filesystem is needed, one can explicitly create it. For example to create an S3 filesystem:
+In case a specific filesystem is needed, one can explicitly create it. For example to create an S3 filesystem
+(note that the filesystem must be created with `asynchronous=True`):
```python exec="true" session="storage" source="above" result="ansi"
# Note: requires s3fs to be installed
import fsspec
-fs = fsspec.filesystem(
- 's3', anon=True, asynchronous=True,
- client_kwargs={'endpoint_url': "https://noaa-nwm-retro-v2-zarr-pds.s3.amazonaws.com"}
-)
-store = zarr.storage.FsspecStore(fs)
+fs = fsspec.filesystem('s3', anon=True, asynchronous=True)
+store = zarr.storage.FsspecStore(fs, path='noaa-nwm-retro-v2-zarr-pds', read_only=True)
print(store)
```
+When using an S3-compatible service other than AWS, pass the service endpoint to the
+filesystem via `client_kwargs={'endpoint_url': 'https://...'}`.
+
### Memory Store
-The [`zarr.storage.MemoryStore`][] is an in-memory store that allows for serialization of
-Zarr data (metadata and chunks) to a dictionary:
+The [`zarr.storage.MemoryStore`][] stores Zarr data (metadata and chunks) in an
+in-memory dictionary:
```python exec="true" session="storage" source="above" result="ansi"
data = {}
@@ -199,3 +200,5 @@ print(group.info)
Zarr-Python [`zarr.abc.store.Store`][] API is meant to be extended. The Store Abstract Base
Class includes all of the methods needed to be a fully operational store in Zarr Python.
Zarr also provides a test harness for custom stores: [`zarr.testing.store.StoreTests`][].
+See the [Custom stores](extending.md#custom-stores) section of the extending guide for
+more on implementing your own store.
diff --git a/docs/user-guide/v3_migration.md b/docs/user-guide/v3_migration.md
index 1680547d93..6d9d516ebe 100644
--- a/docs/user-guide/v3_migration.md
+++ b/docs/user-guide/v3_migration.md
@@ -16,6 +16,12 @@ migrate your code from version 2 to version 3. If we have missed anything, pleas
open a [GitHub issue](https://github.com/zarr-developers/zarr-python/issues/new)
so we can improve this guide.
+!!! tip
+ This page is about migrating your *code* from the Zarr-Python 2 API to the
+ Zarr-Python 3 API. If you want to migrate the *metadata* of stored data from
+ Zarr format 2 to Zarr format 3, see the `zarr migrate` command described in
+ the [command-line interface documentation](cli.md).
+
## Compatibility target
The goals described above necessitated some breaking changes to the API (hence the
@@ -47,6 +53,12 @@ the following actions in order:
- The `zarr.v3_api_available` feature flag is being removed. In Zarr-Python 3
the v3 API is always available, so you shouldn't need to use this flag.
+ - `zarr.errors` has been consolidated. Several exception classes from
+ Zarr-Python 2 (such as `zarr.errors.PathNotFoundError`) have been removed
+ or replaced. For example, missing nodes now raise `zarr.errors.NodeNotFoundError`
+ (which subclasses both `BaseZarrError` and `FileNotFoundError`) instead of
+ `zarr.errors.PathNotFoundError`. Review any code that catches exceptions
+ from `zarr.errors` after migrating.
- The following internal modules are being removed or significantly changed. If
your application relies on imports from any of the below modules, you will need
to either a) modify your application to no longer rely on these imports or b)
@@ -56,14 +68,14 @@ the following actions in order:
* `zarr.codecs` has changed, see "Codecs" section below for more information
* `zarr.context` has gone, with no replacement
* `zarr.core` remains but should be considered private API
- * `zarr.hierarchy` has gone, with no replacement (use `zarr.Group` inplace of `zarr.hierarchy.Group`)
+ * `zarr.hierarchy` has gone, with no replacement (use `zarr.Group` in place of `zarr.hierarchy.Group`)
* `zarr.indexing` has gone, with no replacement
* `zarr.meta` has gone, with no replacement
* `zarr.meta_v1` has gone, with no replacement
* `zarr.sync` has gone, with no replacement
* `zarr.types` has gone, with no replacement
* `zarr.util` has gone, with no replacement
- * `zarr.n5` has gone, see below for an alternative N5 options
+ * `zarr.n5` has gone, see below for an alternative N5 option
3. Test that your package works with version 3.
4. Update the pin to include `zarr>=3,<4`.
@@ -71,8 +83,9 @@ the following actions in order:
## Zarr-Python 2 support window
Zarr-Python 2.x is still available, though we recommend migrating to Zarr-Python 3 for
-its performance improvements and new features. Security and bug fixes will be made to
-the 2.x series for at least six months following the first Zarr-Python 3 release.
+its performance improvements and new features. Security and bug fixes were made to
+the 2.x series for six months following the first Zarr-Python 3 release (January 2025);
+the 2.x series is no longer actively maintained.
If you need to use the latest Zarr-Python 2 release, you can install it with:
```console
@@ -151,11 +164,9 @@ The following stores have been renamed or changed:
| `DirectoryStore` | [`zarr.storage.LocalStore`][] |
| `FSStore` | [`zarr.storage.FsspecStore`][] |
| `TempStore` | Use [`tempfile.TemporaryDirectory`][] with [`LocalStore`][zarr.storage.LocalStore] |
-| `zarr.
-
A number of deprecated stores were also removed.
-See issue #1274 for more details on the removal of these stores.
+See [issue #1274](https://github.com/zarr-developers/zarr-python/issues/1274) for more details on the removal of these stores.
- `N5Store` - see https://github.com/zarr-developers/n5py for an alternative interface to
N5 formatted data.
@@ -169,7 +180,7 @@ See issue #1274 for more details on the removal of these stores.
The latter five stores in this list do not have an equivalent in Zarr-Python 3.
If you are interested in developing a custom store that targets these backends, see
-[developing custom stores](storage.md/#developing-custom-stores) or open an
+[developing custom stores](storage.md#developing-custom-stores) or open an
[issue](https://github.com/zarr-developers/zarr-python/issues) to discuss your use case.
### Codecs
@@ -199,23 +210,21 @@ When installing using `pip`:
(e.g. [`zarr.create`][], [`zarr.open`][], [`zarr.group`][], [`zarr.array`][]) has
been removed. Use `zarr_format` instead.
-## 🚧 Work in Progress 🚧
+## Unimplemented Zarr-Python 2 features
-Zarr-Python 3 is still under active development, and is not yet fully complete.
-The following list summarizes areas of the codebase that we expect to build out
-after the 3.0.0 release. If features listed below are important to your use case
+A few features of Zarr-Python 2 remain unimplemented in Zarr-Python 3.
+If any of the features listed below are important to your use case
of Zarr-Python, please open (or comment on) a
[GitHub issue](https://github.com/zarr-developers/zarr-python/issues/new).
-The following functions / methods have not been ported to Zarr-Python 3 yet:
+The following functions / methods have not been ported to Zarr-Python 3:
- `zarr.copy` ([issue #2407](https://github.com/zarr-developers/zarr-python/issues/2407))
- `zarr.copy_all` ([issue #2407](https://github.com/zarr-developers/zarr-python/issues/2407))
- `zarr.copy_store` ([issue #2407](https://github.com/zarr-developers/zarr-python/issues/2407))
-- `zarr.Group.move` ([issue #2108](https://github.com/zarr-developers/zarr-python/issues/2108))
The following features (corresponding to function arguments to functions in
- `zarr`) have not been ported to Zarr-Python 3 yet. Using these features
+ `zarr`) have not been ported to Zarr-Python 3. Using these features
will raise a warning or a `NotImplementedError`:
- `cache_attrs`
@@ -224,10 +233,9 @@ The following features (corresponding to function arguments to functions in
- `meta_array`
- `object_codec` ([issue #2617](https://github.com/zarr-developers/zarr-python/issues/2617))
- `synchronizer` ([issue #1596](https://github.com/zarr-developers/zarr-python/issues/1596))
-- `dimension_separator`
The following features that were supported by Zarr-Python 2 have not been ported
- to Zarr-Python 3 yet:
+ to Zarr-Python 3:
- Object dtypes ([issue #2616](https://github.com/zarr-developers/zarr-python/issues/2616))
- Ragged arrays ([issue #2618](https://github.com/zarr-developers/zarr-python/issues/2618))
diff --git a/examples/custom_dtype/README.md b/examples/custom_dtype/README.md
index c0722d0661..266f398ca8 100644
--- a/examples/custom_dtype/README.md
+++ b/examples/custom_dtype/README.md
@@ -1,4 +1,4 @@
-# Custom Data Type Example
+# Custom Data Type
This example demonstrates how to extend Zarr Python by defining a new data type.
@@ -11,12 +11,17 @@ The example shows how to:
## Running the Example
+The script declares its dependencies inline
+([PEP 723](https://peps.python.org/pep-0723/)), so the easiest way to run it is
+with [uv](https://docs.astral.sh/uv/), which installs them automatically:
+
```bash
-python examples/custom_dtype/custom_dtype.py
+uv run examples/custom_dtype/custom_dtype.py
```
-Or run with uv:
+Alternatively, run it with plain Python, in which case you must first install
+`zarr`, `ml_dtypes`, and `pytest` yourself:
```bash
-uv run examples/custom_dtype/custom_dtype.py
+python examples/custom_dtype/custom_dtype.py
```
diff --git a/mkdocs.yml b/mkdocs.yml
index e4e757e630..46bfc1764c 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -17,61 +17,86 @@ nav:
- user-guide/arrays.md
- user-guide/groups.md
- user-guide/attributes.md
+ - user-guide/data_types.md
- user-guide/storage.md
- user-guide/config.md
- - user-guide/cli.md
- - user-guide/v3_migration.md
- - user-guide/data_types.md
- user-guide/performance.md
+ - user-guide/cli.md
- user-guide/extending.md
- user-guide/gpu.md
- user-guide/consolidated_metadata.md
- user-guide/experimental.md
+ - user-guide/v3_migration.md
- user-guide/glossary.md
- Examples:
- user-guide/examples/custom_dtype.md
- - user-guide/examples/rectilinear_chunks.ipynb
+ - user-guide/examples/rectilinear_chunks.md
- API Reference:
- api/zarr/index.md
- - api/zarr/array.md
- - api/zarr/group.md
- - api/zarr/create.md
- - api/zarr/dtype.md
- - api/zarr/load.md
- - api/zarr/open.md
- - api/zarr/save.md
- - api/zarr/codecs.md
- - api/zarr/codecs/numcodecs.md
- - api/zarr/config.md
- - api/zarr/errors.md
- - api/zarr/metadata.md
- - api/zarr/registry.md
- - api/zarr/storage.md
- - api/zarr/experimental.md
- - ABC:
+ - ' zarr.abc':
- api/zarr/abc/index.md
- - api/zarr/abc/buffer.md
- - api/zarr/abc/codec.md
- - api/zarr/abc/numcodec.md
- - api/zarr/abc/metadata.md
- - api/zarr/abc/store.md
- - API:
+ - ' zarr.abc.buffer': api/zarr/abc/buffer.md
+ - ' zarr.abc.codec': api/zarr/abc/codec.md
+ - ' zarr.abc.metadata': api/zarr/abc/metadata.md
+ - ' zarr.abc.numcodec': api/zarr/abc/numcodec.md
+ - ' zarr.abc.store': api/zarr/abc/store.md
+ - ' zarr.api':
- api/zarr/api/index.md
- - api/zarr/api/asynchronous.md
- - api/zarr/api/synchronous.md
- - Buffer:
+ - ' zarr.api.asynchronous': api/zarr/api/asynchronous.md
+ - ' zarr.api.synchronous': api/zarr/api/synchronous.md
+ - ' zarr.Array': api/zarr/array.md
+ - ' zarr.array': api/zarr/functions/array.md
+ - ' zarr.buffer':
- api/zarr/buffer/index.md
- - api/zarr/buffer/cpu.md
- - api/zarr/buffer/gpu.md
- - Testing:
+ - ' zarr.buffer.cpu': api/zarr/buffer/cpu.md
+ - ' zarr.buffer.gpu': api/zarr/buffer/gpu.md
+ - ' zarr.codecs': api/zarr/codecs.md
+ - ' zarr.codecs.numcodecs': api/zarr/codecs/numcodecs.md
+ - ' zarr.config': api/zarr/config.md
+ - ' zarr.consolidate_metadata': api/zarr/functions/consolidate_metadata.md
+ - ' zarr.create': api/zarr/functions/create.md
+ - ' zarr.create_array': api/zarr/functions/create_array.md
+ - ' zarr.create_group': api/zarr/functions/create_group.md
+ - ' zarr.create_hierarchy': api/zarr/functions/create_hierarchy.md
+ - ' zarr.dtype': api/zarr/dtype.md
+ - ' zarr.empty': api/zarr/functions/empty.md
+ - ' zarr.empty_like': api/zarr/functions/empty_like.md
+ - ' zarr.errors': api/zarr/errors.md
+ - ' zarr.experimental': api/zarr/experimental.md
+ - ' zarr.from_array': api/zarr/functions/from_array.md
+ - ' zarr.full': api/zarr/functions/full.md
+ - ' zarr.full_like': api/zarr/functions/full_like.md
+ - ' zarr.Group': api/zarr/group.md
+ - ' zarr.group': api/zarr/functions/group.md
+ - ' zarr.load': api/zarr/functions/load.md
+ - ' zarr.metadata': api/zarr/metadata.md
+ - ' zarr.ones': api/zarr/functions/ones.md
+ - ' zarr.ones_like': api/zarr/functions/ones_like.md
+ - ' zarr.open': api/zarr/functions/open.md
+ - ' zarr.open_array': api/zarr/functions/open_array.md
+ - ' zarr.open_consolidated': api/zarr/functions/open_consolidated.md
+ - ' zarr.open_group': api/zarr/functions/open_group.md
+ - ' zarr.open_like': api/zarr/functions/open_like.md
+ - ' zarr.print_debug_info': api/zarr/functions/print_debug_info.md
+ - ' zarr.registry': api/zarr/registry.md
+ - ' zarr.save': api/zarr/functions/save.md
+ - ' zarr.save_array': api/zarr/functions/save_array.md
+ - ' zarr.save_group': api/zarr/functions/save_group.md
+ - ' zarr.storage': api/zarr/storage.md
+ - ' zarr.testing':
- api/zarr/testing/index.md
- - api/zarr/testing/buffer.md
- - api/zarr/testing/stateful.md
- - api/zarr/testing/store.md
- - api/zarr/testing/strategies.md
- - api/zarr/testing/utils.md
+ - ' zarr.testing.buffer': api/zarr/testing/buffer.md
+ - ' zarr.testing.stateful': api/zarr/testing/stateful.md
+ - ' zarr.testing.store': api/zarr/testing/store.md
+ - ' zarr.testing.strategies': api/zarr/testing/strategies.md
+ - ' zarr.testing.utils': api/zarr/testing/utils.md
+ - ' zarr.zeros': api/zarr/functions/zeros.md
+ - ' zarr.zeros_like': api/zarr/functions/zeros_like.md
- release-notes.md
- contributing.md
+hooks:
+ - mkdocs_hooks.py
+
watch:
- src/zarr
- docs
@@ -128,11 +153,6 @@ extra_css:
plugins:
- autorefs
- search
- - mkdocs-jupyter:
- include: ["docs/user-guide/examples/*.ipynb"]
- execute: false
- ignore_h1_titles: true
- show_input: true
- markdown-exec
- mkdocstrings:
enable_inventory: true
@@ -217,6 +237,10 @@ plugins:
'developers/index.html.md': 'contributing.md'
'developers/roadmap.html.md': 'https://zarr.readthedocs.io/en/v3.0.8/developers/roadmap.html'
'api.md': 'api/zarr/index.md'
+ 'api/zarr/create.md': 'api/zarr/functions/create.md'
+ 'api/zarr/open.md': 'api/zarr/functions/open.md'
+ 'api/zarr/save.md': 'api/zarr/functions/save.md'
+ 'api/zarr/load.md': 'api/zarr/functions/load.md'
'api/zarr/metadata/migrate_v3.md': 'api/zarr/metadata.md'
# Based on https://github.com/developmentseed/titiler/blob/50934c929cca2fa8d3c408d239015f8da429c6a8/docs/mkdocs.yml#L115-L140
diff --git a/mkdocs_hooks.py b/mkdocs_hooks.py
new file mode 100644
index 0000000000..88368926b9
--- /dev/null
+++ b/mkdocs_hooks.py
@@ -0,0 +1,82 @@
+"""MkDocs hook that renders validation-marked code fences as ordinary code blocks.
+
+The docs validation convention (see ``tests/test_docs.py`` and the contributing
+guide) requires every python fence to carry ``exec="true"``, ``test="true"``, or
+``exec="false" reason="..."``. Markdown Exec's superfences fence only claims
+``exec="true"`` blocks; without this hook the remaining marked fences fail
+superfences validation and their contents spill into the page as raw markdown
+(e.g. the PEP 723 header of the custom dtype example rendered as headings).
+
+This hook registers a second ``python`` fence, tried when Markdown Exec's
+declines, that strips the validation attributes and delegates to the standard
+superfences highlighter so the block renders exactly like a plain code fence.
+"""
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, Any
+
+if TYPE_CHECKING:
+ from markdown import Markdown
+ from mkdocs.config.defaults import MkDocsConfig
+
+# Mirrors markdown_exec's _to_bool: everything but these means "true".
+_FALSY = {"", "no", "off", "false", "0"}
+
+
+def _validator(
+ language: str,
+ inputs: dict[str, str],
+ options: dict[str, Any],
+ attrs: dict[str, Any],
+ md: Markdown,
+) -> bool:
+ """Claim fences marked test="true" or exec="false"; leave the rest alone."""
+ if "exec" not in inputs and "test" not in inputs:
+ # Plain fence: let the default superfences pathway highlight it.
+ return False
+ if str(inputs.get("exec", "false")).lower() not in _FALSY:
+ # Executable fence: Markdown Exec's own custom fence handles it.
+ return False
+ # Consume the validation attributes so they don't leak into the output.
+ inputs.clear()
+ return True
+
+
+def _formatter(
+ source: str,
+ language: str,
+ css_class: str,
+ options: dict[str, Any],
+ md: Markdown,
+ classes: list[str] | None = None,
+ id_value: str = "",
+ attrs: dict[str, Any] | None = None,
+ **kwargs: Any,
+) -> str:
+ """Render with the same highlighter superfences uses for plain fences."""
+ fenced = md.preprocessors["fenced_code_block"]
+ fenced.get_hl_settings()
+ return fenced.highlight(
+ src=source,
+ language=language,
+ options={},
+ md=md,
+ classes=classes,
+ id_value=id_value,
+ attrs=attrs or {},
+ )
+
+
+def on_config(config: MkDocsConfig) -> MkDocsConfig:
+ superfences = config.setdefault("mdx_configs", {}).setdefault("pymdownx.superfences", {})
+ custom_fences = superfences.setdefault("custom_fences", [])
+ custom_fences.append(
+ {
+ "name": "python",
+ "class": "python",
+ "validator": _validator,
+ "format": _formatter,
+ }
+ )
+ return config
diff --git a/pyproject.toml b/pyproject.toml
index 6a7238ff8f..081ddefdfb 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -94,18 +94,18 @@ homepage = "https://github.com/zarr-developers/zarr-python"
# pins deliberately, e.g. via dependabot or `uv lock --upgrade`.
[dependency-groups]
test = [
- "coverage==7.14.1",
- "pytest==9.0.3",
+ "coverage==7.14.3",
+ "pytest==9.1.1",
"pytest-asyncio==1.4.0",
"pytest-cov==7.1.0",
- "pytest-accept==0.2.3",
+ "pytest-accept==0.3.0",
"numpydoc==1.10.0",
- "hypothesis==6.155.2",
+ "hypothesis==6.155.7",
"pytest-xdist==3.8.0",
"pytest-benchmark==5.2.3",
"pytest-codspeed==5.0.3",
"tomlkit==0.15.0",
- "uv==0.11.20",
+ "uv==0.11.26",
]
remote-tests = [
{include-group = "test"},
@@ -124,20 +124,19 @@ docs = [
"mkdocs-material[imaging]==9.7.6",
"mkdocs==1.6.1",
"mkdocstrings==1.0.4",
- "mkdocstrings-python==2.0.4",
+ "mkdocstrings-python==2.0.5",
"mike==2.2.0",
- "mkdocs-jupyter==0.26.3",
"mkdocs-redirects==1.2.3",
"markdown-exec[ansi]==1.12.1",
"griffe-inherited-docstrings==1.1.3",
- "ruff==0.15.16",
+ "ruff==0.15.20",
# Changelog generation
{include-group = "release"},
# Optional dependencies to run examples
"numcodecs[msgpack]",
"s3fs>=2023.10.0",
"astroid==4.1.2",
- "pytest==9.0.3",
+ "pytest==9.1.1",
]
dev = [
{include-group = "test"},
@@ -427,11 +426,21 @@ module = [
ignore_errors = true
[tool.pytest.ini_options]
-minversion = "7"
+minversion = "9"
testpaths = ["src", "tests", "docs/user-guide"]
log_cli_level = "INFO"
log_level = "INFO"
-xfail_strict = true
+# Enables strict_config, strict_markers, strict_xfail, strict_parametrization_ids, and
+# any strictness options added in future pytest releases. Note that the equivalent
+# `--strict-config`/`--strict-markers` flags were silently ignored when passed via
+# addopts before pytest 9.1 (pytest#14442), so this option is the reliable spelling.
+strict = true
+# Turn deadlocks into loud failures: if a single test exceeds this many seconds, dump
+# every thread's traceback and kill the run (exit_on_timeout is new in pytest 9). Sized
+# far above the slowest legitimate test (~20s locally; slower under coverage/Windows/
+# nightly stateful-hypothesis runs) so only a genuine hang can trip it.
+faulthandler_timeout = 600
+faulthandler_exit_on_timeout = true
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
doctest_optionflags = [
@@ -443,7 +452,7 @@ addopts = [
"--benchmark-columns", "min,mean,stddev,outliers,rounds,iterations",
"--benchmark-disable", # benchmark routines run as tests without benchmarking instrumentation
"--durations", "10",
- "-ra", "--strict-config", "--strict-markers",
+ "-ra",
"--doctest-modules",
"--ignore=tests/test_regression/scripts",
"--ignore=src/zarr/_cli",
diff --git a/src/zarr/api/asynchronous.py b/src/zarr/api/asynchronous.py
index 1908a1a11e..c751d6a31c 100644
--- a/src/zarr/api/asynchronous.py
+++ b/src/zarr/api/asynchronous.py
@@ -108,6 +108,19 @@ def _infer_overwrite(mode: AccessModeLiteral) -> bool:
return mode in _OVERWRITE_MODES
+def _warn_unimplemented_kwargs(kwargs: dict[str, Any]) -> None:
+ """
+ Emit a "not yet implemented" warning for each provided keyword argument that is not None.
+
+ ``kwargs`` maps a keyword argument name to its supplied value. The ``stacklevel`` is chosen
+ so the warning points at the caller of the public API function (the same location as an
+ inline ``warnings.warn(..., stacklevel=2)`` would).
+ """
+ for name, value in kwargs.items():
+ if value is not None:
+ warnings.warn(f"{name} is not yet implemented", ZarrRuntimeWarning, stacklevel=3)
+
+
def _get_shape_chunks(a: ArrayLike | Any) -> tuple[tuple[int, ...] | None, tuple[int, ...] | None]:
"""Helper function to get the shape and chunks from an array-like object"""
shape = None
@@ -134,6 +147,7 @@ class _LikeArgs(TypedDict):
filters: NotRequired[tuple[Numcodec, ...] | None]
compressor: NotRequired[CompressorLikev2]
codecs: NotRequired[tuple[Codec, ...]]
+ fill_value: NotRequired[Any]
def _like_args(a: ArrayLike) -> _LikeArgs:
@@ -151,6 +165,7 @@ def _like_args(a: ArrayLike) -> _LikeArgs:
new["dtype"] = a.dtype
if isinstance(a, AsyncArray | Array):
+ new["fill_value"] = a.metadata.fill_value
if isinstance(a.metadata, ArrayV2Metadata):
new["order"] = a.order
new["compressor"] = a.metadata.compressor
@@ -294,12 +309,20 @@ async def load(
See Also
--------
- save
+ save, open
Notes
-----
If loading data from a group of arrays, data will not be immediately loaded into
memory. Rather, arrays will be loaded into memory as they are requested.
+
+ Unlike [`open`][zarr.open], which returns a lazy [`Array`][zarr.Array] or
+ [`Group`][zarr.Group] backed by the store, `load` eagerly reads the data and
+ returns it as an in-memory array (or a dict of arrays for a group).
+ The array type is NumPy by default, but follows the configured
+ buffer prototype (for example, CuPy for GPU use cases).
+ Use `open` when you want to read or write data incrementally without loading it
+ all into memory.
"""
obj = await open(store=store, path=path, zarr_format=zarr_format)
@@ -347,6 +370,17 @@ async def open(
-------
z : array or group
Return type depends on what exists in the given store.
+
+ See Also
+ --------
+ load
+
+ Notes
+ -----
+ `open` returns a lazy [`Array`][zarr.Array] or [`Group`][zarr.Group] backed by
+ the store, so data is read and written incrementally. Use [`load`][zarr.load]
+ instead when you want the data eagerly read into an in-memory array (a
+ NumPy array by default).
"""
if mode is None:
@@ -813,14 +847,14 @@ async def open_group(
The new group.
"""
- if cache_attrs is not None:
- warnings.warn("cache_attrs is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
- if synchronizer is not None:
- warnings.warn("synchronizer is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
- if meta_array is not None:
- warnings.warn("meta_array is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
- if chunk_store is not None:
- warnings.warn("chunk_store is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
+ _warn_unimplemented_kwargs(
+ {
+ "cache_attrs": cache_attrs,
+ "synchronizer": synchronizer,
+ "meta_array": meta_array,
+ "chunk_store": chunk_store,
+ }
+ )
store_path = await make_store_path(store, mode=mode, storage_options=storage_options, path=path)
if attributes is None:
@@ -1010,20 +1044,17 @@ async def create(
if zarr_format is None:
zarr_format = _default_zarr_format()
- if synchronizer is not None:
- warnings.warn("synchronizer is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
- if chunk_store is not None:
- warnings.warn("chunk_store is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
- if cache_metadata is not None:
- warnings.warn("cache_metadata is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
- if cache_attrs is not None:
- warnings.warn("cache_attrs is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
- if object_codec is not None:
- warnings.warn("object_codec is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
- if read_only is not None:
- warnings.warn("read_only is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
- if meta_array is not None:
- warnings.warn("meta_array is not yet implemented", ZarrRuntimeWarning, stacklevel=2)
+ _warn_unimplemented_kwargs(
+ {
+ "synchronizer": synchronizer,
+ "chunk_store": chunk_store,
+ "cache_metadata": cache_metadata,
+ "cache_attrs": cache_attrs,
+ "object_codec": object_codec,
+ "read_only": read_only,
+ "meta_array": meta_array,
+ }
+ )
if write_empty_chunks is not None:
_warn_write_empty_chunks_kwarg()
@@ -1111,8 +1142,6 @@ async def empty_like(a: ArrayLike, **kwargs: Any) -> AnyAsyncArray:
and these are not guaranteed to be stable from one access to the next.
"""
like_kwargs = _like_args(a) | kwargs
- if isinstance(a, (AsyncArray | Array)):
- like_kwargs.setdefault("fill_value", a.metadata.fill_value)
return await empty(**like_kwargs) # type: ignore[arg-type]
@@ -1155,8 +1184,6 @@ async def full_like(a: ArrayLike, **kwargs: Any) -> AnyAsyncArray:
The new array.
"""
like_kwargs = _like_args(a) | kwargs
- if isinstance(a, (AsyncArray | Array)):
- like_kwargs.setdefault("fill_value", a.metadata.fill_value)
return await full(**like_kwargs) # type: ignore[arg-type]
@@ -1194,7 +1221,10 @@ async def ones_like(a: ArrayLike, **kwargs: Any) -> AnyAsyncArray:
Array
The new array.
"""
- like_kwargs = _like_args(a) | kwargs
+ like_args = _like_args(a)
+ # `ones` supplies its own fill_value, so drop any inherited from `a`.
+ like_args.pop("fill_value", None)
+ like_kwargs = like_args | kwargs
return await ones(**like_kwargs) # type: ignore[arg-type]
@@ -1270,8 +1300,6 @@ async def open_like(a: ArrayLike, path: str, **kwargs: Any) -> AnyAsyncArray:
The opened array.
"""
like_kwargs = _like_args(a) | kwargs
- if isinstance(a, (AsyncArray | Array)):
- like_kwargs.setdefault("fill_value", a.metadata.fill_value)
return await open_array(path=path, **like_kwargs) # type: ignore[arg-type]
@@ -1309,5 +1337,8 @@ async def zeros_like(a: ArrayLike, **kwargs: Any) -> AnyAsyncArray:
Array
The new array.
"""
- like_kwargs = _like_args(a) | kwargs
+ like_args = _like_args(a)
+ # `zeros` supplies its own fill_value, so drop any inherited from `a`.
+ like_args.pop("fill_value", None)
+ like_kwargs = like_args | kwargs
return await zeros(**like_kwargs) # type: ignore[arg-type]
diff --git a/src/zarr/api/synchronous.py b/src/zarr/api/synchronous.py
index 8386427b3f..3231837a04 100644
--- a/src/zarr/api/synchronous.py
+++ b/src/zarr/api/synchronous.py
@@ -161,12 +161,20 @@ def load(
See Also
--------
- save, savez
+ save, savez, open
Notes
-----
If loading data from a group of arrays, data will not be immediately loaded into
memory. Rather, arrays will be loaded into memory as they are requested.
+
+ Unlike [`open`][zarr.open], which returns a lazy [`Array`][zarr.Array] or
+ [`Group`][zarr.Group] backed by the store, `load` eagerly reads the data and
+ returns it as an in-memory array (or a dict of arrays for a group).
+ The array type is NumPy by default, but follows the configured
+ buffer prototype (for example, CuPy for GPU use cases).
+ Use `open` when you want to read or write data incrementally without loading it
+ all into memory.
"""
return sync(async_api.load(store=store, zarr_format=zarr_format, path=path))
@@ -209,6 +217,17 @@ def open(
-------
z : array or group
Return type depends on what exists in the given store.
+
+ See Also
+ --------
+ load
+
+ Notes
+ -----
+ `open` returns a lazy [`Array`][zarr.Array] or [`Group`][zarr.Group] backed by
+ the store, so data is read and written incrementally. Use [`load`][zarr.load]
+ instead when you want the data eagerly read into an in-memory array (a
+ NumPy array by default).
"""
obj = sync(
async_api.open(
diff --git a/src/zarr/codecs/numcodecs/_codecs.py b/src/zarr/codecs/numcodecs/_codecs.py
index 1be1381a08..9c967fdbdd 100644
--- a/src/zarr/codecs/numcodecs/_codecs.py
+++ b/src/zarr/codecs/numcodecs/_codecs.py
@@ -162,7 +162,9 @@ async def _decode_single(self, chunk_data: NDBuffer, chunk_spec: ArraySpec) -> N
return chunk_spec.prototype.nd_buffer.from_ndarray_like(out.reshape(chunk_spec.shape))
async def _encode_single(self, chunk_data: NDBuffer, chunk_spec: ArraySpec) -> NDBuffer:
- chunk_ndarray = chunk_data.as_ndarray_like()
+ # numcodecs codecs flatten with order="A", so an F-contiguous chunk
+ # would be encoded in transposed element order (gh-3558)
+ chunk_ndarray = np.ascontiguousarray(chunk_data.as_ndarray_like())
out = await asyncio.to_thread(self._codec.encode, chunk_ndarray)
return chunk_spec.prototype.nd_buffer.from_ndarray_like(out)
@@ -177,7 +179,9 @@ async def _decode_single(self, chunk_data: Buffer, chunk_spec: ArraySpec) -> NDB
return chunk_spec.prototype.nd_buffer.from_ndarray_like(out.reshape(chunk_spec.shape))
async def _encode_single(self, chunk_data: NDBuffer, chunk_spec: ArraySpec) -> Buffer:
- chunk_ndarray = chunk_data.as_ndarray_like()
+ # numcodecs codecs flatten with order="A", so an F-contiguous chunk
+ # would be encoded in transposed element order (gh-3558)
+ chunk_ndarray = np.ascontiguousarray(chunk_data.as_ndarray_like())
out = await asyncio.to_thread(self._codec.encode, chunk_ndarray)
return chunk_spec.prototype.buffer.from_bytes(out)
diff --git a/src/zarr/codecs/vlen_utf8.py b/src/zarr/codecs/vlen_utf8.py
index a10cb7c335..078e6032fc 100644
--- a/src/zarr/codecs/vlen_utf8.py
+++ b/src/zarr/codecs/vlen_utf8.py
@@ -67,8 +67,10 @@ def _encode_sync(
chunk_spec: ArraySpec,
) -> Buffer | None:
assert isinstance(chunk_array, NDBuffer)
+ # numcodecs vlen codecs flatten with order="A", so an F-contiguous chunk
+ # would be encoded in transposed element order (gh-3558)
return chunk_spec.prototype.buffer.from_bytes(
- _vlen_utf8_codec.encode(chunk_array.as_numpy_array())
+ _vlen_utf8_codec.encode(np.ascontiguousarray(chunk_array.as_numpy_array()))
)
async def _encode_single(
@@ -125,8 +127,10 @@ def _encode_sync(
chunk_spec: ArraySpec,
) -> Buffer | None:
assert isinstance(chunk_array, NDBuffer)
+ # numcodecs vlen codecs flatten with order="A", so an F-contiguous chunk
+ # would be encoded in transposed element order (gh-3558)
return chunk_spec.prototype.buffer.from_bytes(
- _vlen_bytes_codec.encode(chunk_array.as_numpy_array())
+ _vlen_bytes_codec.encode(np.ascontiguousarray(chunk_array.as_numpy_array()))
)
async def _encode_single(
diff --git a/src/zarr/core/array.py b/src/zarr/core/array.py
index 977520b12e..ea7d125b10 100644
--- a/src/zarr/core/array.py
+++ b/src/zarr/core/array.py
@@ -299,6 +299,22 @@ async def get_array_metadata(
return metadata_dict
+async def _prepare_overwrite(
+ store_path: StorePath, *, zarr_format: ZarrFormat, overwrite: bool
+) -> None:
+ """
+ Prepare a store path for writing a new node.
+
+ If ``overwrite`` is true and the store supports deletes, any existing node at
+ ``store_path`` is deleted. Otherwise, the absence of an existing node is enforced
+ (raising if one is present).
+ """
+ if overwrite and store_path.store.supports_deletes:
+ await store_path.delete_dir()
+ else:
+ await ensure_no_existing_node(store_path, zarr_format=zarr_format)
+
+
@dataclass(frozen=True)
class AsyncArray[T_ArrayMetadata: (ArrayV2Metadata, ArrayV3Metadata)]:
"""
@@ -524,7 +540,8 @@ def _create_metadata_v3(
shape = parse_shapelike(shape)
if codecs is None:
- filters = default_filters_v3(dtype)
+ # no data types have default filters
+ filters = ()
serializer = default_serializer_v3(dtype)
compressors = default_compressors_v3(dtype)
@@ -577,13 +594,7 @@ async def _create_v3(
attributes: dict[str, JSON] | None = None,
overwrite: bool = False,
) -> AsyncArrayV3:
- if overwrite:
- if store_path.store.supports_deletes:
- await store_path.delete_dir()
- else:
- await ensure_no_existing_node(store_path, zarr_format=3)
- else:
- await ensure_no_existing_node(store_path, zarr_format=3)
+ await _prepare_overwrite(store_path, zarr_format=3, overwrite=overwrite)
if isinstance(chunk_key_encoding, tuple):
chunk_key_encoding = (
@@ -658,13 +669,7 @@ async def _create_v2(
attributes: dict[str, JSON] | None = None,
overwrite: bool = False,
) -> AsyncArrayV2:
- if overwrite:
- if store_path.store.supports_deletes:
- await store_path.delete_dir()
- else:
- await ensure_no_existing_node(store_path, zarr_format=2)
- else:
- await ensure_no_existing_node(store_path, zarr_format=2)
+ await _prepare_overwrite(store_path, zarr_format=2, overwrite=overwrite)
compressor_parsed: CompressorLikev2
if compressor == "auto":
@@ -970,10 +975,9 @@ def _zdtype(self) -> ZDType[TBaseDType, TBaseScalar]:
"""
The zarr-specific representation of the array data type
"""
- if self.metadata.zarr_format == 2:
- return self.metadata.dtype
- else:
- return self.metadata.data_type
+ # `dtype` returns the zarr dtype object for both v2 and v3 metadata
+ # (on v3 it is an alias for `data_type`).
+ return self.metadata.dtype
@property
def dtype(self) -> TBaseDType:
@@ -1490,13 +1494,16 @@ async def get_orthogonal_selection(
fields: Fields | None = None,
prototype: BufferPrototype | None = None,
) -> NDArrayLikeOrScalar:
- return await _get_orthogonal_selection(
+ if prototype is None:
+ prototype = default_buffer_prototype()
+ indexer = OrthogonalIndexer(selection, self.metadata.shape, self._chunk_grid)
+ return await _get_selection(
self.store_path,
self.metadata,
self.codec_pipeline,
self.config,
self._chunk_grid,
- selection,
+ indexer=indexer,
out=out,
fields=fields,
prototype=prototype,
@@ -1510,13 +1517,16 @@ async def get_mask_selection(
fields: Fields | None = None,
prototype: BufferPrototype | None = None,
) -> NDArrayLikeOrScalar:
- return await _get_mask_selection(
+ if prototype is None:
+ prototype = default_buffer_prototype()
+ indexer = MaskIndexer(mask, self.metadata.shape, self._chunk_grid)
+ return await _get_selection(
self.store_path,
self.metadata,
self.codec_pipeline,
self.config,
self._chunk_grid,
- mask,
+ indexer=indexer,
out=out,
fields=fields,
prototype=prototype,
@@ -1530,17 +1540,24 @@ async def get_coordinate_selection(
fields: Fields | None = None,
prototype: BufferPrototype | None = None,
) -> NDArrayLikeOrScalar:
- return await _get_coordinate_selection(
+ if prototype is None:
+ prototype = default_buffer_prototype()
+ indexer = CoordinateIndexer(selection, self.metadata.shape, self._chunk_grid)
+ out_array = await _get_selection(
self.store_path,
self.metadata,
self.codec_pipeline,
self.config,
self._chunk_grid,
- selection,
+ indexer=indexer,
out=out,
fields=fields,
prototype=prototype,
)
+ if hasattr(out_array, "shape"):
+ # restore shape
+ out_array = cast("NDArrayLikeOrScalar", np.array(out_array).reshape(indexer.sel_shape))
+ return out_array
async def _save_metadata(self, metadata: ArrayMetadata, ensure_parents: bool = False) -> None:
"""
@@ -2166,7 +2183,7 @@ def cdata_shape(self) -> tuple[int, ...]:
When sharding is used, this counts inner chunks (not shards) per dimension.
"""
- return self.async_array._chunk_grid_shape
+ return self._chunk_grid_shape
@property
def _chunk_grid_shape(self) -> tuple[int, ...]:
@@ -4402,10 +4419,7 @@ async def init_array(
chunk_key_encoding, zarr_format=zarr_format
)
- if overwrite and store_path.store.supports_deletes:
- await store_path.delete_dir()
- else:
- await ensure_no_existing_node(store_path, zarr_format=zarr_format)
+ await _prepare_overwrite(store_path, zarr_format=zarr_format, overwrite=overwrite)
# Validate rectilinear chunks constraints
if _is_rectilinear_chunks(chunks):
@@ -4832,15 +4846,6 @@ def _parse_chunk_key_encoding(
return result
-def default_filters_v3(dtype: ZDType[Any, Any]) -> tuple[ArrayArrayCodec, ...]:
- """
- Given a data type, return the default filters for that data type.
-
- This is an empty tuple. No data types have default filters.
- """
- return ()
-
-
def default_compressors_v3(dtype: ZDType[Any, Any]) -> tuple[BytesBytesCodec, ...]:
"""
Given a data type, return the default compressors for that data type.
@@ -4993,7 +4998,8 @@ def _parse_chunk_encoding_v3(
if filters is None:
out_array_array: tuple[ArrayArrayCodec, ...] = ()
elif filters == "auto":
- out_array_array = default_filters_v3(dtype)
+ # no data types have default filters
+ out_array_array = ()
else:
maybe_array_array: Iterable[Codec | dict[str, JSON]]
if isinstance(filters, dict | Codec):
@@ -5388,11 +5394,8 @@ async def _get_selection(
NDArrayLikeOrScalar
The selected data.
"""
- # Get dtype from metadata
- if metadata.zarr_format == 2:
- zdtype = metadata.dtype
- else:
- zdtype = metadata.data_type
+ # `dtype` returns the zarr dtype object for both v2 and v3 metadata.
+ zdtype = metadata.dtype
dtype = zdtype.to_native_dtype()
# Determine memory order
@@ -5522,182 +5525,6 @@ async def _getitem(
)
-async def _get_orthogonal_selection(
- store_path: StorePath,
- metadata: ArrayMetadata,
- codec_pipeline: CodecPipeline,
- config: ArrayConfig,
- chunk_grid: ChunkGrid,
- selection: OrthogonalSelection,
- *,
- out: NDBuffer | None = None,
- fields: Fields | None = None,
- prototype: BufferPrototype | None = None,
-) -> NDArrayLikeOrScalar:
- """
- Get an orthogonal selection from the array.
-
- Parameters
- ----------
- store_path : StorePath
- The store path of the array.
- metadata : ArrayMetadata
- The array metadata.
- codec_pipeline : CodecPipeline
- The codec pipeline for encoding/decoding.
- config : ArrayConfig
- The array configuration.
- chunk_grid : ChunkGrid
- The chunk grid.
- selection : OrthogonalSelection
- The orthogonal selection specification.
- out : NDBuffer | None, optional
- An output buffer to write the data to.
- fields : Fields | None, optional
- Fields to select from structured arrays.
- prototype : BufferPrototype | None, optional
- A buffer prototype to use for the retrieved data.
-
- Returns
- -------
- NDArrayLikeOrScalar
- The selected data.
- """
- if prototype is None:
- prototype = default_buffer_prototype()
- indexer = OrthogonalIndexer(selection, metadata.shape, chunk_grid)
- return await _get_selection(
- store_path,
- metadata,
- codec_pipeline,
- config,
- chunk_grid,
- indexer=indexer,
- out=out,
- fields=fields,
- prototype=prototype,
- )
-
-
-async def _get_mask_selection(
- store_path: StorePath,
- metadata: ArrayMetadata,
- codec_pipeline: CodecPipeline,
- config: ArrayConfig,
- chunk_grid: ChunkGrid,
- mask: MaskSelection,
- *,
- out: NDBuffer | None = None,
- fields: Fields | None = None,
- prototype: BufferPrototype | None = None,
-) -> NDArrayLikeOrScalar:
- """
- Get a mask selection from the array.
-
- Parameters
- ----------
- store_path : StorePath
- The store path of the array.
- metadata : ArrayMetadata
- The array metadata.
- codec_pipeline : CodecPipeline
- The codec pipeline for encoding/decoding.
- config : ArrayConfig
- The array configuration.
- chunk_grid : ChunkGrid
- The chunk grid.
- mask : MaskSelection
- The boolean mask specifying the selection.
- out : NDBuffer | None, optional
- An output buffer to write the data to.
- fields : Fields | None, optional
- Fields to select from structured arrays.
- prototype : BufferPrototype | None, optional
- A buffer prototype to use for the retrieved data.
-
- Returns
- -------
- NDArrayLikeOrScalar
- The selected data.
- """
- if prototype is None:
- prototype = default_buffer_prototype()
- indexer = MaskIndexer(mask, metadata.shape, chunk_grid)
- return await _get_selection(
- store_path,
- metadata,
- codec_pipeline,
- config,
- chunk_grid,
- indexer=indexer,
- out=out,
- fields=fields,
- prototype=prototype,
- )
-
-
-async def _get_coordinate_selection(
- store_path: StorePath,
- metadata: ArrayMetadata,
- codec_pipeline: CodecPipeline,
- config: ArrayConfig,
- chunk_grid: ChunkGrid,
- selection: CoordinateSelection,
- *,
- out: NDBuffer | None = None,
- fields: Fields | None = None,
- prototype: BufferPrototype | None = None,
-) -> NDArrayLikeOrScalar:
- """
- Get a coordinate selection from the array.
-
- Parameters
- ----------
- store_path : StorePath
- The store path of the array.
- metadata : ArrayMetadata
- The array metadata.
- codec_pipeline : CodecPipeline
- The codec pipeline for encoding/decoding.
- config : ArrayConfig
- The array configuration.
- chunk_grid : ChunkGrid
- The chunk grid.
- selection : CoordinateSelection
- The coordinate selection specification.
- out : NDBuffer | None, optional
- An output buffer to write the data to.
- fields : Fields | None, optional
- Fields to select from structured arrays.
- prototype : BufferPrototype | None, optional
- A buffer prototype to use for the retrieved data.
-
- Returns
- -------
- NDArrayLikeOrScalar
- The selected data.
- """
- if prototype is None:
- prototype = default_buffer_prototype()
- indexer = CoordinateIndexer(selection, metadata.shape, chunk_grid)
- out_array = await _get_selection(
- store_path,
- metadata,
- codec_pipeline,
- config,
- chunk_grid,
- indexer=indexer,
- out=out,
- fields=fields,
- prototype=prototype,
- )
-
- if hasattr(out_array, "shape"):
- # restore shape
- out_array = cast("NDArrayLikeOrScalar", np.array(out_array).reshape(indexer.sel_shape))
- return out_array
-
-
async def _set_selection(
store_path: StorePath,
metadata: ArrayMetadata,
@@ -5734,11 +5561,8 @@ async def _set_selection(
fields : Fields | None, optional
Fields to select from structured arrays.
"""
- # Get dtype from metadata
- if metadata.zarr_format == 2:
- zdtype = metadata.dtype
- else:
- zdtype = metadata.data_type
+ # `dtype` returns the zarr dtype object for both v2 and v3 metadata.
+ zdtype = metadata.dtype
dtype = zdtype.to_native_dtype()
# check fields are sensible
diff --git a/src/zarr/core/dtype/npy/bytes.py b/src/zarr/core/dtype/npy/bytes.py
index af8fa7a272..e60f3c6c48 100644
--- a/src/zarr/core/dtype/npy/bytes.py
+++ b/src/zarr/core/dtype/npy/bytes.py
@@ -1069,7 +1069,7 @@ def _from_json_v2(cls, data: DTypeJSON) -> Self:
Raises
------
DataTypeValidationError
- If the input data is not a valid representation of this class class.
+ If the input data is not a valid representation of this class.
"""
if cls._check_json_v2(data):
diff --git a/src/zarr/core/group.py b/src/zarr/core/group.py
index 52eaa3e144..0aaf89234e 100644
--- a/src/zarr/core/group.py
+++ b/src/zarr/core/group.py
@@ -3065,7 +3065,7 @@ async def create_nodes(
"""
# Note: the only way to alter this value is via the config. If that's undesirable for some reason,
- # then we should consider adding a keyword argument this this function
+ # then we should consider adding a keyword argument to this function
semaphore = asyncio.Semaphore(config.get("async.concurrency"))
create_tasks: list[Coroutine[None, None, str]] = []
diff --git a/src/zarr/experimental/cache_store.py b/src/zarr/experimental/cache_store.py
index 1535b42f67..dd50693ad9 100644
--- a/src/zarr/experimental/cache_store.py
+++ b/src/zarr/experimental/cache_store.py
@@ -52,10 +52,11 @@ class CacheStore(WrapperStore[Store]):
store : Store
The underlying store to wrap with caching
cache_store : Store
- The store to use for caching (can be any Store implementation)
- max_age_seconds : int | None, optional
- Maximum age of cached entries in seconds. None means no expiration.
- Default is None.
+ The store to use for caching (can be any Store implementation that
+ supports deletes)
+ max_age_seconds : int or "infinity", optional
+ Maximum age of cached entries in seconds. The string "infinity" means
+ entries never expire. Default is "infinity".
max_size : int | None, optional
Maximum size of the cache in bytes. When exceeded, least recently used
items are evicted. None means unlimited size. Default is None.
diff --git a/src/zarr/storage/_common.py b/src/zarr/storage/_common.py
index 1e13a9ac3f..7e9c035c69 100644
--- a/src/zarr/storage/_common.py
+++ b/src/zarr/storage/_common.py
@@ -1,7 +1,6 @@
from __future__ import annotations
import importlib.util
-import json
from pathlib import Path
from typing import TYPE_CHECKING, Any, Literal, Self
@@ -546,8 +545,10 @@ async def _contains_node_v3(store_path: StorePath) -> Literal["array", "group",
result = "array"
elif extant_meta_json["node_type"] == "group":
result = "group"
- except (KeyError, TypeError, json.JSONDecodeError):
- # any of these errors is consistent with no array or group present.
+ except (KeyError, TypeError, ValueError):
+ # any of these errors is consistent with no array or group present. `ValueError`
+ # covers both malformed JSON (`json.JSONDecodeError`) and non-UTF-8 bytes
+ # (`UnicodeDecodeError`), each a `ValueError` subclass.
pass
return result
@@ -643,18 +644,7 @@ async def contains_group(store_path: StorePath, zarr_format: ZarrFormat) -> bool
"""
if zarr_format == 3:
- extant_meta_bytes = await (store_path / ZARR_JSON).get()
- if extant_meta_bytes is None:
- return False
- else:
- try:
- extant_meta_json = buffer_to_json_object(extant_meta_bytes)
- # we avoid constructing a full metadata document here in the name of speed.
- result: bool = extant_meta_json["node_type"] == "group"
- except (ValueError, KeyError, TypeError):
- return False
- else:
- return result
+ return (await _contains_node_v3(store_path)) == "group"
elif zarr_format == 2:
return await (store_path / ZGROUP_JSON).exists()
msg = f"Invalid zarr_format provided. Got {zarr_format}, expected 2 or 3" # type: ignore[unreachable]
diff --git a/src/zarr/testing/store.py b/src/zarr/testing/store.py
index 11ceeee83a..fb87a69a09 100644
--- a/src/zarr/testing/store.py
+++ b/src/zarr/testing/store.py
@@ -628,9 +628,9 @@ class LatencyStore(WrapperStore[Store]):
set_latency: float
def __init__(self, store: Store, *, get_latency: float = 0, set_latency: float = 0) -> None:
+ super().__init__(store)
self.get_latency = float(get_latency)
self.set_latency = float(set_latency)
- self._store = store
def _with_store(self, store: Store) -> Self:
return type(self)(store, get_latency=self.get_latency, set_latency=self.set_latency)
diff --git a/tests/test_api/test_asynchronous.py b/tests/test_api/test_asynchronous.py
index 362195e858..6ebec36bbd 100644
--- a/tests/test_api/test_asynchronous.py
+++ b/tests/test_api/test_asynchronous.py
@@ -75,6 +75,7 @@ def test_get_shape_chunks(
"chunks": (10,),
"shape": (100,),
"dtype": np.dtype("f8"),
+ "fill_value": np.float64(0.0),
"compressor": None,
"filters": None,
"order": "C",
diff --git a/tests/test_array.py b/tests/test_array.py
index 0d6d2d5906..4faf99eb9e 100644
--- a/tests/test_array.py
+++ b/tests/test_array.py
@@ -1684,7 +1684,7 @@ def test_default_endianness(
store: Store, zarr_format: ZarrFormat, endianness: EndiannessStr
) -> None:
"""
- Test that that endianness is correctly set when creating an array when not specifying a serializer
+ Test that endianness is correctly set when creating an array when not specifying a serializer.
"""
dtype = Int16(endianness=endianness)
arr = zarr.create_array(store=store, shape=(1,), dtype=dtype, zarr_format=zarr_format)
@@ -1693,7 +1693,8 @@ def test_default_endianness(
assert endianness_from_numpy_str(byte_order) == endianness # type: ignore[arg-type]
-@pytest.mark.parametrize("value", [1, 1.4, "a", b"a", np.array(1)])
+# The explicit id for b"a" avoids colliding with the auto-generated id for "a".
+@pytest.mark.parametrize("value", [1, 1.4, "a", pytest.param(b"a", id="a-bytes"), np.array(1)])
@pytest.mark.parametrize("zarr_format", [2, 3])
@pytest.mark.filterwarnings("ignore::zarr.core.dtype.common.UnstableSpecificationWarning")
def test_scalar_array(value: Any, zarr_format: ZarrFormat) -> None:
diff --git a/tests/test_codecs/test_numcodecs.py b/tests/test_codecs/test_numcodecs.py
index 7d5a0c29c4..99cd89492f 100644
--- a/tests/test_codecs/test_numcodecs.py
+++ b/tests/test_codecs/test_numcodecs.py
@@ -163,6 +163,40 @@ def test_generic_filter(
np.testing.assert_array_equal(data, b[:, :])
+@pytest.mark.parametrize(
+ ("codec_class", "codec_config", "dtype"),
+ [
+ (_numcodecs.Delta, {"dtype": "int64"}, "int64"),
+ (_numcodecs.FixedScaleOffset, {"offset": 0, "scale": 1}, "int64"),
+ (_numcodecs.PackBits, {}, "bool"),
+ ],
+ ids=["delta", "fixedscaleoffset", "packbits"],
+)
+def test_generic_filter_f_contiguous(
+ codec_class: type[_numcodecs._NumcodecsArrayArrayCodec],
+ codec_config: dict[str, JSON],
+ dtype: str,
+) -> None:
+ # gh-3558: F-contiguous chunks were handed to numcodecs filters as is, and
+ # numcodecs flattens in memory order, so the elements came back transposed
+ if dtype == "bool":
+ data = np.asfortranarray(np.tril(np.ones((16, 16), dtype=bool)))
+ else:
+ data = np.asfortranarray(np.arange(256, dtype=dtype).reshape(16, 16))
+
+ a = create_array(
+ {},
+ shape=data.shape,
+ chunks=(16, 16),
+ dtype=data.dtype,
+ fill_value=0,
+ filters=[codec_class(**codec_config)],
+ )
+
+ a[:, :] = data
+ np.testing.assert_array_equal(data, a[:, :])
+
+
def test_generic_filter_bitround() -> None:
data = np.linspace(0, 1, 256, dtype="float32").reshape((16, 16))
diff --git a/tests/test_codecs/test_vlen.py b/tests/test_codecs/test_vlen.py
index 3422090a28..b90ad88ddc 100644
--- a/tests/test_codecs/test_vlen.py
+++ b/tests/test_codecs/test_vlen.py
@@ -13,10 +13,12 @@
from zarr.core.metadata.v3 import ArrayV3Metadata
from zarr.storage import StorePath
-numpy_str_dtypes: list[type | str | None] = [
+# The explicit id for the "str" literal avoids colliding with the auto-generated id for
+# the `str` builtin.
+numpy_str_dtypes: list[Any] = [
None,
str,
- "str",
+ pytest.param("str", id="str-literal"),
np.dtypes.StrDType,
"S",
"U",
@@ -67,6 +69,34 @@ def test_vlen_string(
assert a.dtype == data.dtype
+@pytest.mark.filterwarnings("ignore::zarr.core.dtype.common.UnstableSpecificationWarning")
+@pytest.mark.parametrize("store", ["memory"], indirect=["store"])
+@pytest.mark.parametrize(
+ ("dtype", "fill_value", "elements"),
+ [
+ pytest.param("string", "", [f"S{i:05}" for i in range(9)], id="string"),
+ pytest.param("variable_length_bytes", b"", [b"%05d" % i for i in range(9)], id="bytes"),
+ ],
+)
+def test_vlen_f_contiguous(
+ store: Store, dtype: str, fill_value: str | bytes, elements: list[str] | list[bytes]
+) -> None:
+ """An F-contiguous chunk written through a vlen codec round-trips in the original
+ element order rather than the transposed memory order (gh-3558)."""
+ # reshape(order="F") gives an F-contiguous view directly, so the whole-array write
+ # below hands an F-contiguous chunk to the codec; assert it to guard the precondition.
+ data = np.array(elements, dtype=object).reshape((3, 3), order="F")
+ assert data.flags.f_contiguous
+ sp = StorePath(store, path="vlen-f-contiguous")
+ # chunks == shape so the write is a single complete chunk, which the codec pipeline
+ # forwards to the codec untouched; a partial-chunk layout would be recopied to C order.
+ a = zarr.create_array(
+ sp, shape=data.shape, chunks=data.shape, dtype=dtype, fill_value=fill_value
+ )
+ a[:, :] = data
+ assert np.array_equal(data, np.asarray(a[:, :], dtype=object))
+
+
def test_vlen_utf8_codec_supports_sync() -> None:
assert isinstance(VLenUTF8Codec(), SupportsSyncCodec)
diff --git a/tests/test_docs.py b/tests/test_docs.py
index 9c42a0521a..0ed429f173 100644
--- a/tests/test_docs.py
+++ b/tests/test_docs.py
@@ -254,7 +254,7 @@ def test_documentation_examples(
module_globals.update(result)
-@pytest.mark.parametrize("example", find_examples(str(SOURCES_ROOT)), ids=str)
+@pytest.mark.parametrize("example", list(find_examples(str(SOURCES_ROOT))), ids=str)
def test_docstrings(example: CodeExample, eval_example: EvalExample) -> None:
"""Test our docstring examples."""
if example.path.name == "config.py" and "your.module" in example.source:
diff --git a/tests/test_dtype/conftest.py b/tests/test_dtype/conftest.py
index 4c585bfdf6..100b9df226 100644
--- a/tests/test_dtype/conftest.py
+++ b/tests/test_dtype/conftest.py
@@ -1,5 +1,6 @@
# Generate a collection of zdtype instances for use in testing.
import warnings
+from collections import Counter
from typing import Any
import numpy as np
@@ -64,4 +65,19 @@ class TestB(TestExample):
for fixture_name in metafunc.fixturenames:
if hasattr(metafunc.cls, fixture_name):
params = getattr(metafunc.cls, fixture_name)
- metafunc.parametrize(fixture_name, params, scope="class", ids=str)
+ metafunc.parametrize(
+ fixture_name, params, scope="class", ids=_unique_ids([str(p) for p in params])
+ )
+
+
+def _unique_ids(ids: list[str]) -> list[str]:
+ """Suffix repeated ids with their positional index so every id is unique.
+
+ Distinct parameters can stringify identically: for example `np.dtype("i")` and
+ `np.dtype(" 1 else id_ for idx, id_ in enumerate(ids)]
diff --git a/tests/test_dtype/test_npy/test_common.py b/tests/test_dtype/test_npy/test_common.py
index d8912a70ec..b7e4e875ad 100644
--- a/tests/test_dtype/test_npy/test_common.py
+++ b/tests/test_dtype/test_npy/test_common.py
@@ -36,14 +36,17 @@
from zarr.core.common import JSON, ZarrFormat
-json_float_v2_roundtrip_cases: tuple[tuple[JSONFloatV2, float | np.floating[Any]], ...] = (
- ("Infinity", float("inf")),
- ("Infinity", np.inf),
- ("-Infinity", float("-inf")),
- ("-Infinity", -np.inf),
- ("NaN", float("nan")),
- ("NaN", np.nan),
- (1.0, 1.0),
+# Each special value is tested as both a Python float and a numpy scalar. The explicit
+# ids are load-bearing: np.float64("inf") stringifies identically to float("inf"), so
+# without them these parameter sets would produce duplicate test ids.
+json_float_v2_roundtrip_cases: tuple[Any, ...] = (
+ pytest.param("Infinity", float("inf"), id="Infinity-float"),
+ pytest.param("Infinity", np.float64("inf"), id="Infinity-float64"),
+ pytest.param("-Infinity", float("-inf"), id="-Infinity-float"),
+ pytest.param("-Infinity", np.float64("-inf"), id="-Infinity-float64"),
+ pytest.param("NaN", float("nan"), id="NaN-float"),
+ pytest.param("NaN", np.float64("nan"), id="NaN-float64"),
+ pytest.param(1.0, 1.0, id="1.0-1.0"),
)
json_float_v3_cases = json_float_v2_roundtrip_cases
diff --git a/tests/test_group.py b/tests/test_group.py
index bc80e19e86..1acd5551ca 100644
--- a/tests/test_group.py
+++ b/tests/test_group.py
@@ -1713,6 +1713,9 @@ def test_create_nodes_concurrency_limit(store: MemoryStore) -> None:
(zarr.core.group.create_rooted_hierarchy, zarr.core.sync_group.create_rooted_hierarchy),
(zarr.core.group.get_node, zarr.core.sync_group.get_node),
],
+ # The default ids (from __name__) collide: the method pair and the module-level pair
+ # for create_hierarchy would both be id'd "create_hierarchy-create_hierarchy".
+ ids=lambda func: f"{func.__module__.rsplit('.', maxsplit=1)[-1]}.{func.__qualname__}",
)
def test_consistent_signatures(
a_func: Callable[[object], object], b_func: Callable[[object], object]
diff --git a/tests/test_metadata/test_v2.py b/tests/test_metadata/test_v2.py
index d1a1ca00b4..0f280f0401 100644
--- a/tests/test_metadata/test_v2.py
+++ b/tests/test_metadata/test_v2.py
@@ -29,7 +29,8 @@ def test_parse_zarr_format_valid() -> None:
assert parse_zarr_format(2) == 2
-@pytest.mark.parametrize("data", [None, 1, 3, 4, 5, "3"])
+# The explicit id for "3" avoids colliding with the auto-generated id for the int 3.
+@pytest.mark.parametrize("data", [None, 1, 3, 4, 5, pytest.param("3", id="3-str")])
def test_parse_zarr_format_invalid(data: Any) -> None:
with pytest.raises(ValueError, match=f"Invalid value. Expected 2. Got {data}"):
parse_zarr_format(data)
diff --git a/tests/test_store/test_core.py b/tests/test_store/test_core.py
index ae64e17ee0..d2784e1b4b 100644
--- a/tests/test_store/test_core.py
+++ b/tests/test_store/test_core.py
@@ -127,6 +127,16 @@ async def test_contains_missing_node_type_returns_false(
assert await func(store_path, 3) is False
+@pytest.mark.parametrize("func", [contains_array, contains_group])
+async def test_contains_non_utf8_bytes_returns_false(
+ local_store: LocalStore, func: _ContainsFunc
+) -> None:
+ """A v3 metadata document that is not valid UTF-8 reads as 'not present' (not an error)."""
+ store_path = StorePath(local_store, path="foo")
+ await _write_zarr_json(store_path, b"\x80\x81\x82\x83")
+ assert await func(store_path, 3) is False
+
+
async def test_contains_node_v3_malformed_json_returns_nothing(local_store: LocalStore) -> None:
"""`_contains_node_v3` returns 'nothing' when the document is not valid JSON."""
store_path = StorePath(local_store, path="foo")
@@ -148,6 +158,13 @@ async def test_contains_node_v3_missing_node_type_returns_nothing(local_store: L
assert await _contains_node_v3(store_path) == "nothing"
+async def test_contains_node_v3_non_utf8_bytes_returns_nothing(local_store: LocalStore) -> None:
+ """`_contains_node_v3` returns 'nothing' when the document is not valid UTF-8."""
+ store_path = StorePath(local_store, path="foo")
+ await _write_zarr_json(store_path, b"\x80\x81\x82\x83")
+ assert await _contains_node_v3(store_path) == "nothing"
+
+
@pytest.mark.parametrize("path", [None, "", "bar"])
async def test_make_store_path_none(path: str) -> None:
"""
diff --git a/uv.lock b/uv.lock
index 799ea6e45a..7a0d713873 100644
--- a/uv.lock
+++ b/uv.lock
@@ -191,15 +191,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/89/03/a851e84fcbb85214dc637b6378121ef9a0dd61b4c65264675d8a5c9b1ae7/antlr4_python3_runtime-4.13.2-py3-none-any.whl", hash = "sha256:fe3835eb8d33daece0e799090eda89719dbccee7aa39ef94eed3818cafa5a7e8", size = 144462, upload-time = "2024-08-03T19:00:11.134Z" },
]
-[[package]]
-name = "appnope"
-version = "0.1.4"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170, upload-time = "2024-02-06T09:43:11.258Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload-time = "2024-02-06T09:43:09.663Z" },
-]
-
[[package]]
name = "ast-serialize"
version = "0.3.0"
@@ -256,15 +247,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/54/97/4ee9b0438e85bf0a808a89ef0be357319252ab27e1b313ae0aef7aeaa5a6/astroid-4.1.2-py3-none-any.whl", hash = "sha256:21312e682c0866dc5a309ee57e4b88ea92751b9955a58b1c31371cbbeb088707", size = 279956, upload-time = "2026-03-22T19:16:40.062Z" },
]
-[[package]]
-name = "asttokens"
-version = "3.0.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/be/a5/8e3f9b6771b0b408517c82d97aed8f2036509bc247d46114925e32fe33f0/asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7", size = 62308, upload-time = "2025-11-15T16:43:48.578Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a", size = 27047, upload-time = "2025-11-15T16:43:16.109Z" },
-]
-
[[package]]
name = "attrs"
version = "26.1.0"
@@ -324,36 +306,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/3e/5c/fb93d3092640a24dfb7bd7727a24016d7c01774ca013e60efd3f683c8002/backrefs-7.0-py314-none-any.whl", hash = "sha256:a6448b28180e3ca01134c9cf09dcebafad8531072e09903c5451748a05f24bc9", size = 412349, upload-time = "2026-04-28T16:28:02.412Z" },
]
-[[package]]
-name = "beautifulsoup4"
-version = "4.14.3"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "soupsieve" },
- { name = "typing-extensions" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737, upload-time = "2025-11-30T15:08:26.084Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" },
-]
-
-[[package]]
-name = "bleach"
-version = "6.4.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "webencodings" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/48/3c/e12ac860709702bd5ebeb9b56a4fe334f1001246ee1b8f2b7ee28912df7d/bleach-6.4.0.tar.gz", hash = "sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452", size = 204857, upload-time = "2026-06-05T13:01:13.734Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/58/9d/40b6267367182187139a4000b82a3b287d84d745bccd808e75d916920e9d/bleach-6.4.0-py3-none-any.whl", hash = "sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081", size = 165109, upload-time = "2026-06-05T13:01:12.504Z" },
-]
-
-[package.optional-dependencies]
-css = [
- { name = "tinycss2" },
-]
-
[[package]]
name = "blinker"
version = "1.9.0"
@@ -664,97 +616,73 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
]
-[[package]]
-name = "comm"
-version = "0.2.3"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" },
-]
-
[[package]]
name = "coverage"
-version = "7.14.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/54/fd/0ab2772530e946e1be1abd0bc09e647ec9b02e88f0867857601fefca8953/coverage-7.14.1.tar.gz", hash = "sha256:30c08f7d90415aa98b3c990385dea2939b0da55f38515e5b369b83655f8523be", size = 920132, upload-time = "2026-05-26T20:41:36.783Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/3d/b7/bdbb725ba02c5b42825b200c940f38b7a54fcad24627b7192f78f8110d76/coverage-7.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a06c76364a9360e33d6d23769aefdf7f66f38e2ffb60ceb1baaa4989d83b695c", size = 220022, upload-time = "2026-05-26T20:39:03.702Z" },
- { url = "https://files.pythonhosted.org/packages/72/81/fdc0898a55c6219223291ec1a1fe89966ef212ce82276aa0899df84b5de0/coverage-7.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fad54e871165f6ec2f536063ac74c3104508a12963e64072ba44bd822de52b0c", size = 220379, upload-time = "2026-05-26T20:39:05.381Z" },
- { url = "https://files.pythonhosted.org/packages/de/72/de048c4a25e13bce59ac6a339351c10bdf2515e07459afcdaf04dc3143a2/coverage-7.14.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:84b535f00655ecafe1d929d1fb00ed5d6fa3051ea643ab2c161a3887b86f294b", size = 251888, upload-time = "2026-05-26T20:39:07.367Z" },
- { url = "https://files.pythonhosted.org/packages/28/30/300c343f68beb9d4cbb64ec81e58c5b6b80b56927f72d2b38654ac26e013/coverage-7.14.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6b6b0853b895fe0e98cbfc580d1ec3393d9302b4b1e96a77b3f5c91fdab899e6", size = 254624, upload-time = "2026-05-26T20:39:09.037Z" },
- { url = "https://files.pythonhosted.org/packages/b1/ed/7b25642496e8170b6bac14adce00537c6e5fa2d586159401a4de3e8b49e6/coverage-7.14.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:442cc9c952b2df400cda54bb04ab87330cf2cd08a8692cbbea36773531eb6f37", size = 255739, upload-time = "2026-05-26T20:39:10.889Z" },
- { url = "https://files.pythonhosted.org/packages/7f/a2/abd210b8c4e29c24e4624916db97bb519097a91034aaeb767f937e7da794/coverage-7.14.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8270544c361ed405a27a060dbc9ed2c124b084d96dfdc2d9a2510482aef981ad", size = 257998, upload-time = "2026-05-26T20:39:12.722Z" },
- { url = "https://files.pythonhosted.org/packages/7f/24/7c50beed3792fe62f6ce0545c6686ce83379719e2c0276179333d97eae92/coverage-7.14.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:48b283b1dd6372e8de2a7a9a4c4d5dc06f4d4fd209b876f3c88a7a205a0c8f84", size = 252296, upload-time = "2026-05-26T20:39:14.259Z" },
- { url = "https://files.pythonhosted.org/packages/15/05/0f874628ebcbfc77ead559ff210281ef06a97db08481832e7dd39274a135/coverage-7.14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5b0c99ba93a07d56f6df340bb79be53202a082b2fdb81bfe6190b741a3470d54", size = 253658, upload-time = "2026-05-26T20:39:15.923Z" },
- { url = "https://files.pythonhosted.org/packages/99/6f/ca6ad067364b337ef997802115e7ecad2abd2248b05471464b0dea02b4d4/coverage-7.14.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e471bc5769ff073b058cfadb0d736b56ce067c8560eabeb0da88462df98c23e7", size = 251803, upload-time = "2026-05-26T20:39:17.537Z" },
- { url = "https://files.pythonhosted.org/packages/c0/30/b9b4d377cd9f40baf228068f5a81faf8450c6228503011bd499708483a50/coverage-7.14.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f497a1ea81d4cd7c10ddcaa685135b9aabd291af3d55775a9ddf3cb7a364cdd9", size = 255873, upload-time = "2026-05-26T20:39:19.414Z" },
- { url = "https://files.pythonhosted.org/packages/3c/21/7c721a9e5e6bb88547d30a787aefb97512d3f54c1324c7488d9b3743f7f9/coverage-7.14.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:2222be86d0b54f5dd5a38f45f17f315f737245e857bf0bdedc70734f84a13c02", size = 251372, upload-time = "2026-05-26T20:39:21.169Z" },
- { url = "https://files.pythonhosted.org/packages/9d/8c/f8ae5a2200130e1503cd7661a6cd3b2b7bacef98277fbf3571fb13f8b766/coverage-7.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:85e85586565842f6932abebd4c18bcb1074223dc0b3576e7d173ca710622813a", size = 253245, upload-time = "2026-05-26T20:39:23.097Z" },
- { url = "https://files.pythonhosted.org/packages/34/62/70a9024672a5f6910517d9628c52c9afbdd3cf8f46426af52bb148a56fff/coverage-7.14.1-cp312-cp312-win32.whl", hash = "sha256:4a28fd227808366b196a75476dced2eb35b351d6766ba9c858dc93319e87f4f1", size = 222567, upload-time = "2026-05-26T20:39:24.868Z" },
- { url = "https://files.pythonhosted.org/packages/f6/81/8b7cd386839b039ebe1855733b9f9449a8dec5d79564018234f185a7fa70/coverage-7.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:54acdb6674a4661768d7bf7db32dfb9f46ab1d764f8aba6df75ce1a6a088724e", size = 223372, upload-time = "2026-05-26T20:39:26.603Z" },
- { url = "https://files.pythonhosted.org/packages/ae/ba/b44d472022f620d289d95fa830143235c0c36461c6f2437ea8d51e5481ed/coverage-7.14.1-cp312-cp312-win_arm64.whl", hash = "sha256:99cd41ff91afd94896fea3bc002706b6ae4ce95727d06e4a0f39c0a8d8bd8b1a", size = 221989, upload-time = "2026-05-26T20:39:28.242Z" },
- { url = "https://files.pythonhosted.org/packages/8a/9e/5f6d56327c62b185225d145191c607e07515294a0aa6338e58805cd4a5ac/coverage-7.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:be9f2c802dcfce3f71298303aa5dad0dce440a76c52f2f60dacd8656dab78793", size = 220044, upload-time = "2026-05-26T20:39:29.902Z" },
- { url = "https://files.pythonhosted.org/packages/75/92/e82aca356744cbbc0f77a0b623e38918c1872361963413a3bab5d0340393/coverage-7.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6223a72fd0e4c7156353ec0f08a5f93623e1d3034d0e2683b9bb8ea674131b1d", size = 220412, upload-time = "2026-05-26T20:39:31.561Z" },
- { url = "https://files.pythonhosted.org/packages/27/c9/385bde0bf7ed0f4bf3a7ee5367060a86b5d218718cfd6fb943c0f836b34f/coverage-7.14.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7279d2110a28cebc738b6459ecda2771735a4c18465fbbd36b3288fe5ed92247", size = 251412, upload-time = "2026-05-26T20:39:33.337Z" },
- { url = "https://files.pythonhosted.org/packages/51/8c/23faf6a2343a0d17f960a4bd56c43bc7eb4cf312f774dd6ceebd82c7d8fc/coverage-7.14.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9eeb3fcbc13ba40dfbdb22d01d196a28e9cef9ed4c29b60061a1e0e823a9929d", size = 254008, upload-time = "2026-05-26T20:39:35.009Z" },
- { url = "https://files.pythonhosted.org/packages/42/06/36f4aa9ca8a815e6036156e80706a67828bb97bd826948244f6996dda957/coverage-7.14.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f0cfc27c539f07cf5c0a4cfe211d0b6cae039f8f40526dbaa71944e64b50a7b", size = 255241, upload-time = "2026-05-26T20:39:36.71Z" },
- { url = "https://files.pythonhosted.org/packages/ca/79/95266316352f90f6b1c6736bb413302edfde2453fb32422d3911642691b3/coverage-7.14.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:221c70f316241a78e77e607c227cefc8808d4e08f28d99c04f35694690e940be", size = 257373, upload-time = "2026-05-26T20:39:38.412Z" },
- { url = "https://files.pythonhosted.org/packages/e3/9c/58316d1f66c488b5fca8a0eb3e98348807813efa8a0d0833b9021be27488/coverage-7.14.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:da028256b04ec30e5e0114b6f76172938c313991f0a2d3d894271315cf5d5e43", size = 251635, upload-time = "2026-05-26T20:39:40.268Z" },
- { url = "https://files.pythonhosted.org/packages/ef/5a/ca2398a568e16fed7bb713e84ba3603a7164fb65779abe645c565ec890d5/coverage-7.14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76a085d7005236a767e3426148b2c407e53ad61695c562f8a81da2d373324901", size = 253373, upload-time = "2026-05-26T20:39:42.145Z" },
- { url = "https://files.pythonhosted.org/packages/6e/2c/0396562c32deaebe7be51d865b3a41e9a87d7561acafe1a28f53b07e019a/coverage-7.14.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b553d04b5e778a8e56d57eb134aff42a92718ecba45e79c4764ecfa40efd92ff", size = 251341, upload-time = "2026-05-26T20:39:43.907Z" },
- { url = "https://files.pythonhosted.org/packages/fd/8f/a94f9221184c9cae1ee115820e3798e48b6b17777a9f19e46fb9a0c8dc74/coverage-7.14.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:46f714d2fb8ae2f4f29f23ada7f1e79b759fff5a70f94a1dac23af204c3ec9e4", size = 255497, upload-time = "2026-05-26T20:39:46.166Z" },
- { url = "https://files.pythonhosted.org/packages/71/69/505d70e47db1eaebcd002c39759707621ef184cd6b1ae084d9f41293f323/coverage-7.14.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:1896f5e19ff3f0431c7ce2172adc54890fd97f86b59ced8ca1649145d9ffe35d", size = 251159, upload-time = "2026-05-26T20:39:48.03Z" },
- { url = "https://files.pythonhosted.org/packages/e0/aa/58681c383aa33a9d2ed40a02d7a22fbf780d1fa4d575396365777828198c/coverage-7.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:62fd185ef9df3c33d1c8178c5af105f762afbad96038de9a4ae100aa6297ca33", size = 252934, upload-time = "2026-05-26T20:39:49.872Z" },
- { url = "https://files.pythonhosted.org/packages/eb/fd/11c928cd6bdffc7074bb5965c173d9ebf517fb00205e1da524b98d29ef92/coverage-7.14.1-cp313-cp313-win32.whl", hash = "sha256:ab4af6352741a604c431c6072fce5bee33bf0f20dc7a56618d6bf6bb89e9810c", size = 222584, upload-time = "2026-05-26T20:39:51.68Z" },
- { url = "https://files.pythonhosted.org/packages/6f/92/fb416fc26d340dcba19518c418d6048e913186e17243982c5e435e41fa7a/coverage-7.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:7af486dabe8954d03b087f0021540897afe084f04e16ff5579e08cc46f871416", size = 223394, upload-time = "2026-05-26T20:39:53.472Z" },
- { url = "https://files.pythonhosted.org/packages/73/c6/02d56e3867972f77d5036de924643f26c056e848f00452cafb4dbc3c29b4/coverage-7.14.1-cp313-cp313-win_arm64.whl", hash = "sha256:2224f89ffd0c5605ccce1ed7a584da162bc7c55f601ab1c946bc9de31a486b42", size = 222015, upload-time = "2026-05-26T20:39:55.374Z" },
- { url = "https://files.pythonhosted.org/packages/4d/9e/fcc77914050df73f7662fa1f00902774c79c075a8388ab334074574bf77e/coverage-7.14.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de286598cc65d2b489411174b1faec2f5a7775fb3201fd925db2a76b4030f37d", size = 220733, upload-time = "2026-05-26T20:39:57.189Z" },
- { url = "https://files.pythonhosted.org/packages/f7/67/2963cbdaf5cbadec44efa3a1e39eaa1f02df4079585f05387607a221e126/coverage-7.14.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:042c46ded7c288aeb07cf14a28b6c1e10b78fcba40171c3fa1e939377eeef0b5", size = 221086, upload-time = "2026-05-26T20:39:59.019Z" },
- { url = "https://files.pythonhosted.org/packages/c8/c5/8701645574e11881f2f47d8930f98bc48b5d43b25eb5b4430dfc4a2f9f48/coverage-7.14.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f4ddbe407477f04c45115d1a4e5bc480f753553b534d338d4c3358b1cdd0ea52", size = 262381, upload-time = "2026-05-26T20:40:00.822Z" },
- { url = "https://files.pythonhosted.org/packages/7c/28/7a64d73598263e0c5abd5084211a8474488d31b3c552ff531c719dfcff62/coverage-7.14.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d13e6725992e2d2fd7d81d4f5241952d13740121dfd501da09201be39b2c003a", size = 264458, upload-time = "2026-05-26T20:40:02.506Z" },
- { url = "https://files.pythonhosted.org/packages/fa/d8/4969179db9f7eb4df218e69540adf829d1c835f59452513d065d15446802/coverage-7.14.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f747dc8edcfe740130f28f32f3995e955494285717e86ee25af51db2219df08a", size = 266884, upload-time = "2026-05-26T20:40:04.421Z" },
- { url = "https://files.pythonhosted.org/packages/a6/78/a45d5794dbc9bafd97afc96a4377c86c7820d78b6cf51b89bc1d4e919275/coverage-7.14.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ced2f09ef276fd58611a1ef502164ad266d2b75174e5a40cabbdb4033f9f6cf2", size = 268022, upload-time = "2026-05-26T20:40:06.298Z" },
- { url = "https://files.pythonhosted.org/packages/21/cb/4f5e354e9e3e67af96bd4e57113e6db6b22298c7168b13eec408a549903d/coverage-7.14.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b84800013769a78ccb9ef4659402e26d06867e337b61ec365f77ad008adea80e", size = 261631, upload-time = "2026-05-26T20:40:08.226Z" },
- { url = "https://files.pythonhosted.org/packages/ec/49/eced49af4cb996d5d8b7e94e736175c513e4facd3398507b89892b4326d8/coverage-7.14.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ea8cd6ca0ee9f616aaef3afc6882e32c2cbf18b00d96313ffd76af650574034d", size = 264443, upload-time = "2026-05-26T20:40:10.137Z" },
- { url = "https://files.pythonhosted.org/packages/f1/d8/5603a88a7c5913a6b54f6cb1a8c46f7b39cbb30f27cd3f492908da09b2d7/coverage-7.14.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:aa5e304a873fabddc11e484e9b6b738bd38bd7bed17b09aa84eecf5332e8b8bb", size = 262069, upload-time = "2026-05-26T20:40:11.999Z" },
- { url = "https://files.pythonhosted.org/packages/f0/59/2ae3cb79da554a06c8619d6c88ea19dd1e4aed4b834b6a83bb1fa243bdc5/coverage-7.14.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5a1c5215be81035e629d5bc756650634d0bf31991038db7a0eccb90f025ce16d", size = 265780, upload-time = "2026-05-26T20:40:13.858Z" },
- { url = "https://files.pythonhosted.org/packages/af/5f/b130c1dc999031f2648bd25317fbce505ad8d5562079b4ed81e736a84967/coverage-7.14.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:79058c47dae6788504b5effb319961bcd72d7240551464b91d474bc0ed186d69", size = 260970, upload-time = "2026-05-26T20:40:16.142Z" },
- { url = "https://files.pythonhosted.org/packages/87/d1/ec13ccddeb48ec963bdfa72a11224bac2584bd045ba13beca82f8113e9c7/coverage-7.14.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:370c5afae3fa0658e11694a32b24c2778f6bc2d17718121f94ee185e69f26b54", size = 263157, upload-time = "2026-05-26T20:40:18.382Z" },
- { url = "https://files.pythonhosted.org/packages/cf/c2/cd91ead503045161092d3845f7bb95ea2f25131ce96d3e314dd835d91b9c/coverage-7.14.1-cp313-cp313t-win32.whl", hash = "sha256:3758dd0a7f1fa57365ef2e781df0f0731d38b6e3772259d13dae4bd8a958d4b1", size = 223259, upload-time = "2026-05-26T20:40:20.381Z" },
- { url = "https://files.pythonhosted.org/packages/71/9f/1e28d97e6bd2c76b07f38b7c02870f1371255ff6717f54eca578fcbbdd0e/coverage-7.14.1-cp313-cp313t-win_amd64.whl", hash = "sha256:6ff665fb023a77386fe11685190cee1f60a7d635994a30d9b0a061533d470fce", size = 224320, upload-time = "2026-05-26T20:40:22.316Z" },
- { url = "https://files.pythonhosted.org/packages/a9/e0/d936e908f0e1efa55e52b91e01b52f1055cef5e1ab2718493390ed8e2fb8/coverage-7.14.1-cp313-cp313t-win_arm64.whl", hash = "sha256:17a5a241e5997621a956a7f402a7433ef4221e5152809b785bec79e2323799f1", size = 222577, upload-time = "2026-05-26T20:40:24.894Z" },
- { url = "https://files.pythonhosted.org/packages/d6/34/fc2f101b151af3799a101f0550b0454aa008afdc0add677394ec4aa8ea10/coverage-7.14.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d5ed429d0b8edaac649e889b4ffcedb6c80b06629a3f93050e3dddfb99235bee", size = 220091, upload-time = "2026-05-26T20:40:27.249Z" },
- { url = "https://files.pythonhosted.org/packages/3d/a7/1ebae2ab5b961b5c79bb09fe7b3ac99edb190d8be4a8c510b2cf66f46468/coverage-7.14.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8011224a62280e50dab346960c03cf47aca1a1e09e608c0fb33fd6e0cc8e9500", size = 220421, upload-time = "2026-05-26T20:40:30.084Z" },
- { url = "https://files.pythonhosted.org/packages/5e/90/92aca9cf0acc95123c96cd1eb1f08917897a7f5dee01e15738922971ec31/coverage-7.14.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:12c42ec1e14f553c4f817e989365982e646e27211f10a0f717855b94a79c8906", size = 251466, upload-time = "2026-05-26T20:40:32.542Z" },
- { url = "https://files.pythonhosted.org/packages/26/2b/78048cbe3b999f6cbf9cc0d90abba6a88a3e0863a8c1c6cbc762f3f8802f/coverage-7.14.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:06144cd511cf2624873a035c5069cf297144f6e77a73ee3d7a55b605ec5efb42", size = 253973, upload-time = "2026-05-26T20:40:34.473Z" },
- { url = "https://files.pythonhosted.org/packages/8e/21/c2e33b29d1cfde484a19d437afc343c6cd30b08d78cbbf9f5aff14e57b2b/coverage-7.14.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a311d8e1da24be5c1ccf85cbfb06315dbaa1703d5a1eab3f6432c72b837917c8", size = 255318, upload-time = "2026-05-26T20:40:38.154Z" },
- { url = "https://files.pythonhosted.org/packages/8e/ee/aad2f108d63b769121005302f16bf66db8625c88ceaba466942e09a2607e/coverage-7.14.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c79cead5b5bc584d9c71451cb984d0e3a84e0c0937379c8efcbf27c8d661b851", size = 257633, upload-time = "2026-05-26T20:40:40.164Z" },
- { url = "https://files.pythonhosted.org/packages/c2/f8/11a2c29b4fd76d9849f81d0bb812ec0017a9396df3217214e38934a8c837/coverage-7.14.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dcbf65f1f66a26cdd88c35cf68fb4729c5d1cd2e88added72420541dfb212034", size = 251488, upload-time = "2026-05-26T20:40:42.631Z" },
- { url = "https://files.pythonhosted.org/packages/c9/b8/9a5820de4b8ac2b71d85e3b5fb49108d7469c665f0e2ad0dd7569023e305/coverage-7.14.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fd86572566fb40189a8260446158235159bc7a82dfbc87a3b39cf4fb57fcec1c", size = 253329, upload-time = "2026-05-26T20:40:45.208Z" },
- { url = "https://files.pythonhosted.org/packages/6b/ff/f33e4823667e27548e8fd8df44217515303f9808d0ff29817db56f87d990/coverage-7.14.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:7771b601718fdde84832c3a434ca9bbf4ae9adbc49d84198b4110700c3c77c36", size = 251291, upload-time = "2026-05-26T20:40:47.502Z" },
- { url = "https://files.pythonhosted.org/packages/68/9b/489db0ebb209054766b90a9014a45f6d26eb724c02ec21311c3733b5a644/coverage-7.14.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:39b21e212c55af06fa375e3dbf90a8a8e38792f3a910c580066d23563830ddd5", size = 255564, upload-time = "2026-05-26T20:40:49.372Z" },
- { url = "https://files.pythonhosted.org/packages/27/b5/16bc2d4c2409b23c7737edb68c83bc89e345f378050549fe1d75ac7d34d5/coverage-7.14.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f2302660e32562a532b442480121aef8aa61a5bdb20b30bf0adab29f10a5a4b4", size = 251107, upload-time = "2026-05-26T20:40:51.677Z" },
- { url = "https://files.pythonhosted.org/packages/7d/0c/2629997469a00cd069d588a41c9dc887610f2775ae89d250c4791e65272a/coverage-7.14.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:03a6f93c1ec3b7f2e77b5dbcc5573a2c21f12529a5c6bbe0f16f72303cc2fa4d", size = 252764, upload-time = "2026-05-26T20:40:54.267Z" },
- { url = "https://files.pythonhosted.org/packages/d2/ee/f78d63c8f079e0d7211c7e2401fa17e311514534ba61bae03e4b287ce4ab/coverage-7.14.1-cp314-cp314-win32.whl", hash = "sha256:8a3ce026d73290f42f08dafecbd82c193a74df280461fbf97300fec51fd133ee", size = 222837, upload-time = "2026-05-26T20:40:56.496Z" },
- { url = "https://files.pythonhosted.org/packages/dc/b9/be539854f93a70dfbeec69117f33ec70dc42ff0b65b5b07ab8d40d04228e/coverage-7.14.1-cp314-cp314-win_amd64.whl", hash = "sha256:114c95ef29302423b87d159075805f4ab973254a2638a5d7d046c94887cc87d7", size = 223650, upload-time = "2026-05-26T20:40:58.351Z" },
- { url = "https://files.pythonhosted.org/packages/fe/9e/24e2842fef40f35ac82ba3a7719c8023d011bf3bf652d0675316a9d088a1/coverage-7.14.1-cp314-cp314-win_arm64.whl", hash = "sha256:a07891c3f4805442b31b71e84ba3cf29ed1aa9a428284e06deeb4b23e5b46343", size = 222218, upload-time = "2026-05-26T20:41:00.321Z" },
- { url = "https://files.pythonhosted.org/packages/0a/1d/ac0a9df5fe31c1e8bdd658074905fc12844a05c1a7e3fdb8417e97c31e23/coverage-7.14.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1101a5ebb083aecb625ebb6209d4105b58f647b093cb2dc8122d7b33f743cfe1", size = 220822, upload-time = "2026-05-26T20:41:02.281Z" },
- { url = "https://files.pythonhosted.org/packages/32/cf/f964fd9aff20323f9f1a726c97135f8a76bcd87b92dad141a456a43f3c64/coverage-7.14.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:851b9e1e4e8a4608e77c79714b2e77c0970d2ed7202a05e92ae407817481887b", size = 221084, upload-time = "2026-05-26T20:41:04.593Z" },
- { url = "https://files.pythonhosted.org/packages/d8/5e/7e5ef2aba844de2b80d678619fcf0841b42e3f37f16411226f3fe4c1016f/coverage-7.14.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d5b89cdfb2ee051b71e8c3c70bd81a9eff81100f736a269136fe1a68efe00474", size = 262454, upload-time = "2026-05-26T20:41:06.641Z" },
- { url = "https://files.pythonhosted.org/packages/64/62/75809bded87015cc4935524218a2a8ed8dd1a8498bfed30a2f4f7a4b4d34/coverage-7.14.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0177614a0370f227888b4e436a7c55686d6a9f90eb1ade2b624ba685a1686e86", size = 264578, upload-time = "2026-05-26T20:41:08.556Z" },
- { url = "https://files.pythonhosted.org/packages/f3/42/d33392dc14633525012d2d504fa1a33b05538bf535f5c1d64675e5754b78/coverage-7.14.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2d69af5dea2de76fc485a83032a630523f985198b7e25be901ec60181587b01e", size = 266981, upload-time = "2026-05-26T20:41:10.824Z" },
- { url = "https://files.pythonhosted.org/packages/2a/49/0157c4428c2aca7f1e09d5565930586fd5ae36f1655f08b0daa7cf1fcae1/coverage-7.14.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:35ab22d91de736e8966b980dc355cbcdd2c6dbbcfe275f9a2991bc8a91b3df65", size = 268112, upload-time = "2026-05-26T20:41:12.966Z" },
- { url = "https://files.pythonhosted.org/packages/96/26/86b9ce71f4092b1ed325ce1421698081df1286b833400b6836912834d6e0/coverage-7.14.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:357d4e32935c36588aaba057d734fa32428c360c9fc2e4442afbf1b646beee6e", size = 261558, upload-time = "2026-05-26T20:41:15Z" },
- { url = "https://files.pythonhosted.org/packages/20/4c/c311210c5472cf5401d8422b0d7812cdd520f24417673afabda6c323faca/coverage-7.14.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:51bd64741cc6fa065abd300ede1afe5a5291ece9c31da8b24884deda48bcc3f8", size = 264447, upload-time = "2026-05-26T20:41:17.369Z" },
- { url = "https://files.pythonhosted.org/packages/fb/71/59513f8710ed3e6b0ac0a050a5b7e977bb9c9e880354863b5d00d8809256/coverage-7.14.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:9132cd363a68a4c3daa7c8704a654b1e39d3360f6f5b8ddd470608a945236c07", size = 262048, upload-time = "2026-05-26T20:41:19.309Z" },
- { url = "https://files.pythonhosted.org/packages/84/8d/bceed32dc494f5bbf50f775cd2e78ca814953942b5ea28d3c1c3ac316f14/coverage-7.14.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:07c6290b1697b862c0478eab545eec949a0d0e4d6d03497f446d706da3b4f2de", size = 265781, upload-time = "2026-05-26T20:41:21.559Z" },
- { url = "https://files.pythonhosted.org/packages/e7/c5/9348fe40dbfd4991aaf78df2c6c3098bfb2cc834d1fd362a64b4efef855a/coverage-7.14.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:5ea0c297e27133853b4d8a3eb799bff5a2dbd9f2f41537a240d337ac9b4df890", size = 260896, upload-time = "2026-05-26T20:41:23.428Z" },
- { url = "https://files.pythonhosted.org/packages/ca/92/1ea0f03929da7cf87206b1fa24f4c8e9c158be0455481af29ec0a1f3503f/coverage-7.14.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:01b7733daad0237daa01ef80fe2dfceffc911e6a17fa7b55d14aa8214eaaaecd", size = 263214, upload-time = "2026-05-26T20:41:25.419Z" },
- { url = "https://files.pythonhosted.org/packages/f6/a9/b2493c054c0e01a643266742ab45e15744e60743f9260cd930c7142b1124/coverage-7.14.1-cp314-cp314t-win32.whl", hash = "sha256:6adc5a36984624a70bf11d7184e20fa0a49aa7c47ffab43804106a1a695ea22e", size = 223624, upload-time = "2026-05-26T20:41:27.795Z" },
- { url = "https://files.pythonhosted.org/packages/fc/bd/3e1e6a57fccd2d7c83fcdf338e93ba98eb85c6e877dd34731ac585375490/coverage-7.14.1-cp314-cp314t-win_amd64.whl", hash = "sha256:ddf799247318f34dbcd2efa8c95a8d0642674e926bb1774cf9b63dfd2a389d1c", size = 224728, upload-time = "2026-05-26T20:41:30.098Z" },
- { url = "https://files.pythonhosted.org/packages/bb/d7/31066cf1d2f0c6c797fce911bcfa01dd35642dc6da992a950256097c5860/coverage-7.14.1-cp314-cp314t-win_arm64.whl", hash = "sha256:145986fe66647eb489f18d9a997567a3fd358584c4b5a808769113abc07466af", size = 222752, upload-time = "2026-05-26T20:41:32.123Z" },
- { url = "https://files.pythonhosted.org/packages/8a/3c/1a983b9a745d7f83d53f057bcc5bf79ba6a2bbc08266b3f0c7d6fe630c9b/coverage-7.14.1-py3-none-any.whl", hash = "sha256:a252f21c27e38347e60111a3266b03827422a7d5525951aceee313aa68bab1d2", size = 211815, upload-time = "2026-05-26T20:41:34.078Z" },
+version = "7.14.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/b4/91/0a7c28934e50d8ac9a7b117712d176f2953c3170bccced5eaacfa3e96175/coverage-7.14.3.tar.gz", hash = "sha256:1a7563a443f3d53fdeb040ec8c9f7466aed7ca3dc5891aa09d3ca3625fa4387f", size = 924398, upload-time = "2026-06-22T23:10:25.584Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/bd/b0/8a911f6ffe6974dac4df95b468ab9a2899d0e59f0f99a489afeec39f00bc/coverage-7.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3d74ff26299c4879ce3a4d826f9d3d4d556fd285fde7bbce3c0ef5a8ab1cec24", size = 220672, upload-time = "2026-06-22T23:08:26.621Z" },
+ { url = "https://files.pythonhosted.org/packages/36/16/0fc0cb52538783dbbae0934b834f5a58fd5354380ee6cad4a07b15dc845d/coverage-7.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:96150a9cf3468ea20f0bc5d0e21b3df8972c31480ef90fa7614b773cc6429665", size = 221035, upload-time = "2026-06-22T23:08:28.372Z" },
+ { url = "https://files.pythonhosted.org/packages/77/e2/421ccfbb48335ac49e93301478cf5d623b0c2bf1c0cadd8e2b2fc6c0c710/coverage-7.14.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:27d07a46500ba23515b838dbcf52512026af04090755cf6cc64166d88c9b9a1a", size = 252540, upload-time = "2026-06-22T23:08:30.226Z" },
+ { url = "https://files.pythonhosted.org/packages/06/c2/05b8c890097c61a7f4406b35396b997a635200ded0339eda83dfbe526c5f/coverage-7.14.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:621e13c6108234d7960aaf5762ab5c3c00f33c30c15af06dcbff0c73bf112727", size = 255274, upload-time = "2026-06-22T23:08:31.876Z" },
+ { url = "https://files.pythonhosted.org/packages/dc/be/b6d9efe447f8ba3c3c854195f326bd64c54b907d936cd2fdebf8767ec72e/coverage-7.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b60ca6d8af70473491a15a343cbabab2e8f9ea66a4376e81c7aa24876a6f977", size = 256389, upload-time = "2026-06-22T23:08:33.843Z" },
+ { url = "https://files.pythonhosted.org/packages/d4/3c/f26e50acc429e608bc534ac06f0a3c169019c798178ec5e9de3dbc0df9c9/coverage-7.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c90a7cdd5e380e1ce02f19792e2ac2fbfbf177e35a27e69fd3e873b30d895c0c", size = 258648, upload-time = "2026-06-22T23:08:35.481Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/a2/01c1fabf816c8e1dae197e258edf878a3d3ddc86fbda34b76e5794277d8f/coverage-7.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5d788e5fd55347eef06ca0732c77d04a264de67e8ff24631270cdff3767a60cf", size = 252949, upload-time = "2026-06-22T23:08:37.562Z" },
+ { url = "https://files.pythonhosted.org/packages/89/c6/941166dd79c31fd44a13063780ae8d552eee0089a0a0930b9bdb7df554ed/coverage-7.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:62c7f79db2851c95ef020e5d28b97afde3daf9f7febcd35b53e05638f729063f", size = 254310, upload-time = "2026-06-22T23:08:39.174Z" },
+ { url = "https://files.pythonhosted.org/packages/10/31/80b1fd028201a961033ce95be3cd1e39e521b3762e6b4a1ac1616cb291e7/coverage-7.14.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:90f7608aeb5d9b60b523b9fb2a4ee1973867cc4865a3f26fe6c7577073b70205", size = 252453, upload-time = "2026-06-22T23:08:40.84Z" },
+ { url = "https://files.pythonhosted.org/packages/5f/85/c3d9addd94c4b524f3f4af0232075f5fe7170ce99a1386edff803e5934db/coverage-7.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1e3b91f9c4740aeb571ecf82e5e8d8e4ab62d34fcb5a5d4e5baa38c6f7d2857c", size = 256522, upload-time = "2026-06-22T23:08:42.494Z" },
+ { url = "https://files.pythonhosted.org/packages/91/14/e5a0575f73795af3a7a9ae13dadf812e17d32422896839987dc3f86947e1/coverage-7.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c946099774a7699de03cbd0ff0a64e21aed4525eed9d959adde4afe6d15758ef", size = 252023, upload-time = "2026-06-22T23:08:44.243Z" },
+ { url = "https://files.pythonhosted.org/packages/38/9b/9652ee531937ce3b8a63a8896885b2b4a2d56adc30e53c9540c666286d88/coverage-7.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16b206e521feb8b7133a45754643dead0538489cf8b783b90cf5f4e3299625fd", size = 253893, upload-time = "2026-06-22T23:08:46.113Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/05/42678841c8c38e4b08bdfc48269f5a16dfbf5806000fe6a89b4cece3c691/coverage-7.14.3-cp312-cp312-win32.whl", hash = "sha256:ea3169c7116eb6cdf7608c6c7da9ecfcb3da40688e3a510fac2d1d2bafd6dc35", size = 222734, upload-time = "2026-06-22T23:08:47.858Z" },
+ { url = "https://files.pythonhosted.org/packages/df/87/07a4fcee55177a25f1b52331a8e92cf4f2c53b1a9c75ce2981fd59c684ad/coverage-7.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:7ea52fc08f007bcc494d4bb3df3851e95843d881860ba38fe2c64dc100db5e7d", size = 223266, upload-time = "2026-06-22T23:08:49.494Z" },
+ { url = "https://files.pythonhosted.org/packages/aa/34/2b8b66a989282ea7b370beb49f50bab29470dc30bb0b03935b6b802782f7/coverage-7.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:8cec0ad652ec57790970d817490105bd917d783c2f7b38d6b58a0ca312e1a336", size = 222655, upload-time = "2026-06-22T23:08:51.766Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/83/7fefbf5df23ed2b7f489907564a7b34b9b07098128e12e0fdfa92626e456/coverage-7.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:47968988b367990ae4ab17523790c38cd125e02c6bfd379b6022be2d40bdc38c", size = 220699, upload-time = "2026-06-22T23:08:53.522Z" },
+ { url = "https://files.pythonhosted.org/packages/31/e6/38c3653ff6d56d704b29241362387ca824e38e15b76fdcb7096538195790/coverage-7.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0ee68f5c34812780f3a7063382c0a9fcbb99985b7ddcdcaa626e4f3fb2e0783a", size = 221068, upload-time = "2026-06-22T23:08:55.571Z" },
+ { url = "https://files.pythonhosted.org/packages/20/86/4f5c45d51c5cd10a128933f0fd235393c9146abbfd2ce2dfa68b3267ead3/coverage-7.14.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fa9e5c6857a7e80fa22ace5cf3550ae392bbfc322f1d8dd2d2d5a8be38cec027", size = 252060, upload-time = "2026-06-22T23:08:57.464Z" },
+ { url = "https://files.pythonhosted.org/packages/82/50/dfce42eff2cecabcd5a9bbad5489449c87db3415f408d23ffee417ce01f6/coverage-7.14.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:98a0859b0e98e43e1178a9402e19c8127766b14f7109a374d976e5a62c0e5c73", size = 254657, upload-time = "2026-06-22T23:08:59.453Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/d2/639ceb1bc8038fd0d66768278d5dc22df3391918b8278c2a21aa2602a531/coverage-7.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69918344541ed9c8368566c2adc03c0e33d4550d7faa87d1b35e49b6a3286ea9", size = 255892, upload-time = "2026-06-22T23:09:01.291Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/96/002094a10e113512500dc1e10430a449417e17b0f90f7d496bcb820208b7/coverage-7.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b7f300ac92cd4b570724c8ffbbd0c130fee298d2447f41d5a3abf58976fae1de", size = 258026, upload-time = "2026-06-22T23:09:03.017Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/ec/286a5d2fad9c4bee59bd724feeb7d5bf8303c6c9200b51d1dd945a9c72b0/coverage-7.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:11a7ec9f97ab950f4c5af62229befc7faf208fdbc0116d3902d7e306cf2c5abd", size = 252285, upload-time = "2026-06-22T23:09:04.773Z" },
+ { url = "https://files.pythonhosted.org/packages/d9/7d/a17753a0b12dd48d0d50f5fab079ad99d3be1eac790494d89f3a417ca0b9/coverage-7.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a571bd889cd36c5922ce8e42e059f9d37d02301531d11374afa4c87a578625d5", size = 254023, upload-time = "2026-06-22T23:09:06.513Z" },
+ { url = "https://files.pythonhosted.org/packages/86/ef/a76c6ceba6a2c313f905310abf2701d534cada22d372db11731831e9e209/coverage-7.14.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de76caefc8deabb0dd1678b6a980be97d14c8d87e213ac194dbf8b09e96d63fb", size = 251989, upload-time = "2026-06-22T23:09:08.382Z" },
+ { url = "https://files.pythonhosted.org/packages/d9/39/353013a75fec0fb49f7553519f9d52b4441e902e5178c93f38eb6c07cedb/coverage-7.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d20a15c622194234161535459affa8f7905830391c9ccfa060d495dbfe3a1c7f", size = 256144, upload-time = "2026-06-22T23:09:10.369Z" },
+ { url = "https://files.pythonhosted.org/packages/29/0e/613878555d734def11c5b20a2701a15cb3781b9e9ea749da27c5f436e928/coverage-7.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b488bd4b23397db62e7a9459129d01ff06a846582a732efd24834b24a6ada498", size = 251808, upload-time = "2026-06-22T23:09:12.057Z" },
+ { url = "https://files.pythonhosted.org/packages/af/76/359c058c9cfdcf1e8b107663881225b03b364a320017eda24a2a66e55102/coverage-7.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a3693b4153394d265f44fb855fdc80e72403024d4d6f91c4871b334d028e4e0", size = 253579, upload-time = "2026-06-22T23:09:13.858Z" },
+ { url = "https://files.pythonhosted.org/packages/1d/d9/4ba2f060933a30ebe363cef9f67a365b0a317e580c0d5d9169d56a73ef1c/coverage-7.14.3-cp313-cp313-win32.whl", hash = "sha256:338b19131ab1a6b767b462bfcbaa692e7ae22f24463e39d49b02a83410ff6b37", size = 222741, upload-time = "2026-06-22T23:09:15.636Z" },
+ { url = "https://files.pythonhosted.org/packages/76/e8/196ebc25d8f34c06d43a6e9c8513c9266ef8dbf3b5672beb1a00cf5e29fa/coverage-7.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:b3d77f7f196abdef7e01415de1bce09f216189e83e58159cfeef2b92d0464994", size = 223283, upload-time = "2026-06-22T23:09:17.478Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/af/51d2aac6417523a286f10fb25f09eb9518a84df9f1151e93ff6871f34849/coverage-7.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:e6230e688c7c3e65cedd41a774eb4ec221adc6bfee13768231015b702d5e4150", size = 222678, upload-time = "2026-06-22T23:09:19.7Z" },
+ { url = "https://files.pythonhosted.org/packages/61/56/14e3b97facbfa1304dd19e676e26599ad359f04714bed32f7f1c5a88efdc/coverage-7.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:605ab2b566a22bd94834529d66d295c364aba84afd3e5498285c7a524017b1fc", size = 220741, upload-time = "2026-06-22T23:09:21.616Z" },
+ { url = "https://files.pythonhosted.org/packages/12/1d/db378b5cca433b90b893f26dab728b280ddd89f272a1fdfed4aeaa05c686/coverage-7.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a3c2134809e80fac091bfed18a6991b5a5eb5df5ae32b17ac4f4f99864b73dd7", size = 221068, upload-time = "2026-06-22T23:09:23.452Z" },
+ { url = "https://files.pythonhosted.org/packages/47/f0/3f8421b20d9c4fcd39be9a8ca3c3fda8bc204b44efbd09fede153afd3e2f/coverage-7.14.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c02efd507227bde9969cab0db8f48890eb3b5dcad6afac57a4792df4133543ce", size = 252117, upload-time = "2026-06-22T23:09:25.458Z" },
+ { url = "https://files.pythonhosted.org/packages/27/ca/59ea35fb99743549ec8b37eff141ece4431fea590c89e536ed8032ef45cf/coverage-7.14.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1bb93c2aa61d2a5b38f1526546d95cf4132cb681e541a337bf8dfd092be816e5", size = 254622, upload-time = "2026-06-22T23:09:27.523Z" },
+ { url = "https://files.pythonhosted.org/packages/c8/25/ec6de51ae7493b92a1cf74d1b763121c29636759167e2a593ba4db5881e4/coverage-7.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f502e948e03e866538048bba081c075caaa62e5bda6ea5b7432e45f587eb462a", size = 255968, upload-time = "2026-06-22T23:09:29.43Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/05/c8bfc77823f42b4664fb25842f13b567022f6f84a4c83c8ecbb16734b7cb/coverage-7.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9973ef2463f8e6cfb61a6324126bb3e17d67a85f22f58d856e583ea2e3ca6501", size = 258284, upload-time = "2026-06-22T23:09:31.397Z" },
+ { url = "https://files.pythonhosted.org/packages/f6/15/1d1b242027124a32b26ef01f82018b8c4ef34ef174aa6aeba7b1eeef48e8/coverage-7.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9be4e7d4c5ca0427889f8f9d614bd630c2be741b1de7699bca3b2b6c0e41003e", size = 252143, upload-time = "2026-06-22T23:09:33.256Z" },
+ { url = "https://files.pythonhosted.org/packages/74/b6/d2a9842fd2a5d7d27f1ac851c043a734a494ad75402c5331db3da79ed691/coverage-7.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a574912f3bde4b0619f6e97d01aa590b70998859244793769eb3a6df78ee56d3", size = 253976, upload-time = "2026-06-22T23:09:35.351Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/30/e1600ddf7e226db5558bb5323d2186fff00f505c4b764643ec89ce5d8175/coverage-7.14.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e343fb086c9cd780b38622fea7c369acd64c1a0724312149b5d769c387a2b1f5", size = 251942, upload-time = "2026-06-22T23:09:37.313Z" },
+ { url = "https://files.pythonhosted.org/packages/d9/2c/9159de64f9dd648e324328d588a44cfab1e331eb5259ce1141afe2a92dfb/coverage-7.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:3c68df8e61f1e09633fefc7538297145623957a048534368c9d212782aa5e845", size = 256220, upload-time = "2026-06-22T23:09:39.165Z" },
+ { url = "https://files.pythonhosted.org/packages/91/67/b7f536cc2c124f48e91b22fbb741d2261f4e3d310faf6f76007f47566e5d/coverage-7.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3e5b550a128419373c2f6cec28a244207013ef15f5cbcff6a5ca09d1dfaaf027", size = 251756, upload-time = "2026-06-22T23:09:41.056Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/ec/f3718038e2d4860c715a55428377ca7f6c75872caf98cabd982e1d76967d/coverage-7.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2bfc4dd0a912329eccc7484a7d0b2a38032b38c40663b1e1ac595f10c457954b", size = 253413, upload-time = "2026-06-22T23:09:43.306Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/a5/91f11efeef89b3cc9b30461128db15b0511ef813ab889a7b7ab636b3a497/coverage-7.14.3-cp314-cp314-win32.whl", hash = "sha256:0423d64c013057a06e70f070f073cec4b0cbc7d2b27f3c7007292f2ff1d52965", size = 222946, upload-time = "2026-06-22T23:09:45.261Z" },
+ { url = "https://files.pythonhosted.org/packages/58/fd/98ac9f524d9ec378de831c034dbdeb544ca7ef7d2d9c9996daf232a037fd/coverage-7.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:92c22e19ce64ca3f2ad751f16f14df1468b4c231bd6af97185063a9c292a0cb3", size = 223436, upload-time = "2026-06-22T23:09:47.177Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/a0/7cd612d650a772a0ae80144443406bf61981c896c3d57c9e6e79fb2cdbd1/coverage-7.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:41de778bd41780586e2b04912079c73089ab5d839624e28db3bdb26de638da92", size = 222861, upload-time = "2026-06-22T23:09:49.384Z" },
+ { url = "https://files.pythonhosted.org/packages/55/57/017353fab573779c0d00448e47d102edd36c792f7b6f233a4d89a7a08384/coverage-7.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8427f370ca67db4c975d2a26acfc0e5783ca0b52444dbc50278ace0f35445949", size = 221474, upload-time = "2026-06-22T23:09:51.417Z" },
+ { url = "https://files.pythonhosted.org/packages/69/92/90cf1f1a5c468a9c1b7ba2716e0e205293ad9b02f5f573a6de4318b15ba1/coverage-7.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d8e88f335544a47e22ae2e45b344772925ec65166555c958720d5ed971880891", size = 221738, upload-time = "2026-06-22T23:09:53.487Z" },
+ { url = "https://files.pythonhosted.org/packages/a4/c0/4df964fa539f8399fd7679c09c472d73744de334686fd3f01e3a2465ce4e/coverage-7.14.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:beaab199b9e5ceaf5a225e16a9d4df136f2a1eae0a5c20de1e277c8a5225f388", size = 263101, upload-time = "2026-06-22T23:09:55.895Z" },
+ { url = "https://files.pythonhosted.org/packages/06/76/e5d33b2576ae3bf2be2058cd1cae57774b61e400f2c3c58f3783dc2ffb4a/coverage-7.14.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3ff255799f5a1676c71c1c32ec01fd043aa09d57b3d95764b24992757184784", size = 265225, upload-time = "2026-06-22T23:09:57.904Z" },
+ { url = "https://files.pythonhosted.org/packages/61/d2/e52419afe391a39ba27fdefaf0737d8e34bf03faef6ab3b3006545bbd0d0/coverage-7.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:878832eaac515b62decfa76965aed558775f86bf1fc8cca76993c0c84ae31aed", size = 267643, upload-time = "2026-06-22T23:09:59.938Z" },
+ { url = "https://files.pythonhosted.org/packages/58/7a/f2625d8d5006b6b20fba5afaef00b24a763fe96476ea798a3076cbc1f84e/coverage-7.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:611e62cb9386096d81b63e0a05330750268617231e7bd598e1fe77482a2c58a5", size = 268762, upload-time = "2026-06-22T23:10:01.943Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/bf/908024006bba57127354d74e938954b9c3cd765cc2e0412dc9c37b415cda/coverage-7.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:02c41de2a88011b893050fc9830267d927a50a215f7ad5ec17349db7090ccf26", size = 262208, upload-time = "2026-06-22T23:10:03.954Z" },
+ { url = "https://files.pythonhosted.org/packages/34/a0/d4f9296441b909817442fdb26bd77a698f08272ec683a7394b00eb2e47a0/coverage-7.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:526ce9721116af23b1065089f0b75046fe521e7772ab94b641cd66b7a0421889", size = 265096, upload-time = "2026-06-22T23:10:05.936Z" },
+ { url = "https://files.pythonhosted.org/packages/e8/da/4ae4f3f4e477b56a4ce1e5c48a35eff38a94b50130ce5bdc897024741cfc/coverage-7.14.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e4ed44705ca4bead6fc977a8b741f2145608289b33c8a9b42a95d0f15aedbf4d", size = 262699, upload-time = "2026-06-22T23:10:07.973Z" },
+ { url = "https://files.pythonhosted.org/packages/d8/7a/6927148073ff32856d78baa77b4ddc07a9be7e90020f9db0661c4ca523a1/coverage-7.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2415902f385a23dcc4ccd26e0ba803249a169af6a930c003a4c715eeb9a5444e", size = 266433, upload-time = "2026-06-22T23:10:10.145Z" },
+ { url = "https://files.pythonhosted.org/packages/f7/a7/774f658dbe9c4c3f5daa86a87e0459ac3832e4e3cc67affe078547f727b9/coverage-7.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:b75ee850fc2d7c831e883220c445b035f2224de2ba6103f1e56dbd237ab913f7", size = 261547, upload-time = "2026-06-22T23:10:12.191Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/14/a0c18c0376c43cbf973f43ef6ca20019c950597180e6396232f7b6a27102/coverage-7.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dc9b4e35e7c3920e925ba7f14886fd5fbe481232754624e832ddba66c7535635", size = 263859, upload-time = "2026-06-22T23:10:14.492Z" },
+ { url = "https://files.pythonhosted.org/packages/10/ac/43a3d0f460af524b131a6191805bc5d18b806ab4e828fbf82e8c8c3af446/coverage-7.14.3-cp314-cp314t-win32.whl", hash = "sha256:7b27c822a8161afbe48e99f1adfb098d270ae7e0f7d7b0555ce110529bdb69cc", size = 223250, upload-time = "2026-06-22T23:10:16.758Z" },
+ { url = "https://files.pythonhosted.org/packages/3f/5f/d5e5c56b0712e96ce8f69fe7dbf229ff938b437bc50862743c8a0d2cea84/coverage-7.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:39e1dbbb6ff2c338e0196a482558a792a1de3aa64261196f5cdb3da016ad9cda", size = 224082, upload-time = "2026-06-22T23:10:19.23Z" },
+ { url = "https://files.pythonhosted.org/packages/62/35/947cbd5be1d3bcbbdc43d6791de8a56c6501903311d42915ae06a82815f0/coverage-7.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:68520c90babfa2d560eca6d497921ed3a4f469623bd709733124491b2aa8ef3f", size = 223400, upload-time = "2026-06-22T23:10:21.24Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/e3/a0aa32bfa3a081951f60a23bc0e7b512891ef0eecda1153cf1d8ba36c6b1/coverage-7.14.3-py3-none-any.whl", hash = "sha256:fb7e18afb6e903c1a92401a2f0501ac277dca527bb9ca6fe1f691a8a0026a0e8", size = 212469, upload-time = "2026-06-22T23:10:23.405Z" },
]
[[package]]
@@ -853,36 +781,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/a4/80/5e05de89ba61df072aab6f8a6ee3ffeec57db68a0a456825b3b4ce608426/cupy_cuda12x-14.1.1-cp314-cp314t-manylinux2014_x86_64.whl", hash = "sha256:238080487174268d0f09770fe518de7c5b206527bef5c6792aef7ba0626a1c48", size = 132635338, upload-time = "2026-06-01T04:53:35.229Z" },
]
-[[package]]
-name = "debugpy"
-version = "1.8.20"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/e0/b7/cd8080344452e4874aae67c40d8940e2b4d47b01601a8fd9f44786c757c7/debugpy-1.8.20.tar.gz", hash = "sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33", size = 1645207, upload-time = "2026-01-29T23:03:28.199Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/14/57/7f34f4736bfb6e00f2e4c96351b07805d83c9a7b33d28580ae01374430f7/debugpy-1.8.20-cp312-cp312-macosx_15_0_universal2.whl", hash = "sha256:4ae3135e2089905a916909ef31922b2d733d756f66d87345b3e5e52b7a55f13d", size = 2550686, upload-time = "2026-01-29T23:03:42.023Z" },
- { url = "https://files.pythonhosted.org/packages/ab/78/b193a3975ca34458f6f0e24aaf5c3e3da72f5401f6054c0dfd004b41726f/debugpy-1.8.20-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:88f47850a4284b88bd2bfee1f26132147d5d504e4e86c22485dfa44b97e19b4b", size = 4310588, upload-time = "2026-01-29T23:03:43.314Z" },
- { url = "https://files.pythonhosted.org/packages/c1/55/f14deb95eaf4f30f07ef4b90a8590fc05d9e04df85ee379712f6fb6736d7/debugpy-1.8.20-cp312-cp312-win32.whl", hash = "sha256:4057ac68f892064e5f98209ab582abfee3b543fb55d2e87610ddc133a954d390", size = 5331372, upload-time = "2026-01-29T23:03:45.526Z" },
- { url = "https://files.pythonhosted.org/packages/a1/39/2bef246368bd42f9bd7cba99844542b74b84dacbdbea0833e610f384fee8/debugpy-1.8.20-cp312-cp312-win_amd64.whl", hash = "sha256:a1a8f851e7cf171330679ef6997e9c579ef6dd33c9098458bd9986a0f4ca52e3", size = 5372835, upload-time = "2026-01-29T23:03:47.245Z" },
- { url = "https://files.pythonhosted.org/packages/15/e2/fc500524cc6f104a9d049abc85a0a8b3f0d14c0a39b9c140511c61e5b40b/debugpy-1.8.20-cp313-cp313-macosx_15_0_universal2.whl", hash = "sha256:5dff4bb27027821fdfcc9e8f87309a28988231165147c31730128b1c983e282a", size = 2539560, upload-time = "2026-01-29T23:03:48.738Z" },
- { url = "https://files.pythonhosted.org/packages/90/83/fb33dcea789ed6018f8da20c5a9bc9d82adc65c0c990faed43f7c955da46/debugpy-1.8.20-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:84562982dd7cf5ebebfdea667ca20a064e096099997b175fe204e86817f64eaf", size = 4293272, upload-time = "2026-01-29T23:03:50.169Z" },
- { url = "https://files.pythonhosted.org/packages/a6/25/b1e4a01bfb824d79a6af24b99ef291e24189080c93576dfd9b1a2815cd0f/debugpy-1.8.20-cp313-cp313-win32.whl", hash = "sha256:da11dea6447b2cadbf8ce2bec59ecea87cc18d2c574980f643f2d2dfe4862393", size = 5331208, upload-time = "2026-01-29T23:03:51.547Z" },
- { url = "https://files.pythonhosted.org/packages/13/f7/a0b368ce54ffff9e9028c098bd2d28cfc5b54f9f6c186929083d4c60ba58/debugpy-1.8.20-cp313-cp313-win_amd64.whl", hash = "sha256:eb506e45943cab2efb7c6eafdd65b842f3ae779f020c82221f55aca9de135ed7", size = 5372930, upload-time = "2026-01-29T23:03:53.585Z" },
- { url = "https://files.pythonhosted.org/packages/33/2e/f6cb9a8a13f5058f0a20fe09711a7b726232cd5a78c6a7c05b2ec726cff9/debugpy-1.8.20-cp314-cp314-macosx_15_0_universal2.whl", hash = "sha256:9c74df62fc064cd5e5eaca1353a3ef5a5d50da5eb8058fcef63106f7bebe6173", size = 2538066, upload-time = "2026-01-29T23:03:54.999Z" },
- { url = "https://files.pythonhosted.org/packages/c5/56/6ddca50b53624e1ca3ce1d1e49ff22db46c47ea5fb4c0cc5c9b90a616364/debugpy-1.8.20-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:077a7447589ee9bc1ff0cdf443566d0ecf540ac8aa7333b775ebcb8ce9f4ecad", size = 4269425, upload-time = "2026-01-29T23:03:56.518Z" },
- { url = "https://files.pythonhosted.org/packages/c5/d9/d64199c14a0d4c476df46c82470a3ce45c8d183a6796cfb5e66533b3663c/debugpy-1.8.20-cp314-cp314-win32.whl", hash = "sha256:352036a99dd35053b37b7803f748efc456076f929c6a895556932eaf2d23b07f", size = 5331407, upload-time = "2026-01-29T23:03:58.481Z" },
- { url = "https://files.pythonhosted.org/packages/e0/d9/1f07395b54413432624d61524dfd98c1a7c7827d2abfdb8829ac92638205/debugpy-1.8.20-cp314-cp314-win_amd64.whl", hash = "sha256:a98eec61135465b062846112e5ecf2eebb855305acc1dfbae43b72903b8ab5be", size = 5372521, upload-time = "2026-01-29T23:03:59.864Z" },
- { url = "https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl", hash = "sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7", size = 5337658, upload-time = "2026-01-29T23:04:17.404Z" },
-]
-
-[[package]]
-name = "decorator"
-version = "5.2.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" },
-]
-
[[package]]
name = "defusedxml"
version = "0.7.1"
@@ -936,24 +834,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" },
]
-[[package]]
-name = "executing"
-version = "2.2.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" },
-]
-
-[[package]]
-name = "fastjsonschema"
-version = "2.21.2"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de", size = 374130, upload-time = "2025-08-14T18:49:36.666Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463", size = 24024, upload-time = "2025-08-14T18:49:34.776Z" },
-]
-
[[package]]
name = "flask"
version = "3.1.3"
@@ -1075,11 +955,11 @@ wheels = [
[[package]]
name = "fsspec"
-version = "2026.4.0"
+version = "2026.6.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d5/8d/1c51c094345df128ca4a990d633fe1a0ff28726c9e6b3c41ba65087bba1d/fsspec-2026.4.0.tar.gz", hash = "sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4", size = 312760, upload-time = "2026-04-29T20:42:38.635Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/10/a1/ae4e3e5003468d6391d2c77b6fa1cd73bd5d13511d81c642d7b28ac90ed4/fsspec-2026.6.0.tar.gz", hash = "sha256:f5bac145310fe30e16e1471bd6840b2d990d609e872251d7e674241822abf01a", size = 313646, upload-time = "2026-06-16T01:57:28.105Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl", hash = "sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2", size = 203402, upload-time = "2026-04-29T20:42:36.842Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/22/4222d7ddf3da30f363edaa98e329c2bce6c65497c9cb2810931c8b2c0fbc/fsspec-2026.6.0-py3-none-any.whl", hash = "sha256:02e0b71817df9b2169dc30a16832045764def1191b43dcff5bb85bdee212d2a1", size = 203949, upload-time = "2026-06-16T01:57:26.358Z" },
]
[[package]]
@@ -1149,14 +1029,14 @@ wheels = [
[[package]]
name = "hypothesis"
-version = "6.155.2"
+version = "6.155.7"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "sortedcontainers" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/f5/04/64032a1dccd2233615c8a3f701bbb563558575ed017496a24b6d81762c91/hypothesis-6.155.2.tar.gz", hash = "sha256:ae36880287c9c5defe9f199d3d2b67d9947a4da2a46e6c57373cbdf2345b20e1", size = 477765, upload-time = "2026-06-05T16:32:23.63Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/f2/55/983b6bc1b6b343a5ff6020388f9d0680ab477be59a731517e6c4a0387100/hypothesis-6.155.7.tar.gz", hash = "sha256:d8d6091753d0669db3c90c5e5b346cb37c72f3dd9378c8413acb1fd5da63f7ea", size = 478291, upload-time = "2026-06-21T05:54:31.573Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/ec/6e/e735f27ac1a530a4cd0a31cd970ec495a3a11830fdc5d281cc292593b330/hypothesis-6.155.2-py3-none-any.whl", hash = "sha256:c85ce6dcd630a90ce501f1d1dd1bc84b97f5649ca8a27e134c8cbf5aa480b1a5", size = 544213, upload-time = "2026-06-05T16:32:21.15Z" },
+ { url = "https://files.pythonhosted.org/packages/01/f8/c151e196d4f397ed9436a071e52666c70a2f021138dea828b0a461e245db/hypothesis-6.155.7-py3-none-any.whl", hash = "sha256:9f634bdb1f9e9b8ab6ba09431cf2deedb750c96978125a6fb3c5a0f6c6db4131", size = 544762, upload-time = "2026-06-21T05:54:29.506Z" },
]
[[package]]
@@ -1186,64 +1066,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
]
-[[package]]
-name = "ipykernel"
-version = "7.2.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "appnope", marker = "sys_platform == 'darwin'" },
- { name = "comm" },
- { name = "debugpy" },
- { name = "ipython" },
- { name = "jupyter-client" },
- { name = "jupyter-core" },
- { name = "matplotlib-inline" },
- { name = "nest-asyncio" },
- { name = "packaging" },
- { name = "psutil" },
- { name = "pyzmq" },
- { name = "tornado" },
- { name = "traitlets" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/ca/8d/b68b728e2d06b9e0051019640a40a9eb7a88fcd82c2e1b5ce70bef5ff044/ipykernel-7.2.0.tar.gz", hash = "sha256:18ed160b6dee2cbb16e5f3575858bc19d8f1fe6046a9a680c708494ce31d909e", size = 176046, upload-time = "2026-02-06T16:43:27.403Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/82/b9/e73d5d9f405cba7706c539aa8b311b49d4c2f3d698d9c12f815231169c71/ipykernel-7.2.0-py3-none-any.whl", hash = "sha256:3bbd4420d2b3cc105cbdf3756bfc04500b1e52f090a90716851f3916c62e1661", size = 118788, upload-time = "2026-02-06T16:43:25.149Z" },
-]
-
-[[package]]
-name = "ipython"
-version = "9.13.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "colorama", marker = "sys_platform == 'win32'" },
- { name = "decorator" },
- { name = "ipython-pygments-lexers" },
- { name = "jedi" },
- { name = "matplotlib-inline" },
- { name = "pexpect", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
- { name = "prompt-toolkit" },
- { name = "psutil" },
- { name = "pygments" },
- { name = "stack-data" },
- { name = "traitlets" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/cd/c4/87cda5842cf5c31837c06ddb588e11c3c35d8ece89b7a0108c06b8c9b00a/ipython-9.13.0.tar.gz", hash = "sha256:7e834b6afc99f020e3f05966ced34792f40267d64cb1ea9043886dab0dde5967", size = 4430549, upload-time = "2026-04-24T12:24:55.221Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/b9/86/3060e8029b7cc505cce9a0137431dda81d0a3fde93a8f0f50ee0bf37a795/ipython-9.13.0-py3-none-any.whl", hash = "sha256:57f9d4639e20818d328d287c7b549af3d05f12486ea8f2e7f73e52a36ec4d201", size = 627274, upload-time = "2026-04-24T12:24:53.038Z" },
-]
-
-[[package]]
-name = "ipython-pygments-lexers"
-version = "1.1.1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "pygments" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" },
-]
-
[[package]]
name = "itsdangerous"
version = "2.2.0"
@@ -1253,18 +1075,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" },
]
-[[package]]
-name = "jedi"
-version = "0.20.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "parso" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/46/b7/a3635f6a2d7cf5b5dd98064fc1d5fbbafcb25477bcea204a3a92145d158b/jedi-0.20.0.tar.gz", hash = "sha256:c3f4ccbd276696f4b19c54618d4fb18f9fc24b0aef02acf704b23f487daa1011", size = 3119416, upload-time = "2026-05-01T23:38:47.814Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/9a/93/242e2eab5fe682ffcb8b0084bde703a41d51e17ee0f3a31ff0d9d813620a/jedi-0.20.0-py2.py3-none-any.whl", hash = "sha256:7bdd9c2634f56713299976f4cbd59cb3fa92165cc5e05ea811fb253480728b67", size = 4884812, upload-time = "2026-05-01T23:38:43.919Z" },
-]
-
[[package]]
name = "jinja2"
version = "3.1.6"
@@ -1288,14 +1098,14 @@ wheels = [
[[package]]
name = "joserfc"
-version = "1.6.5"
+version = "1.6.8"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "cryptography" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/3b/dc/5f768c2e391e9afabe5d18e3221346deb5fb6338565f1ccc9e7c6d7befdd/joserfc-1.6.5.tar.gz", hash = "sha256:1482a7db78fb4602e44ed89e51b599d052e091288c7c532c5b694e20149dec48", size = 231881, upload-time = "2026-05-06T04:58:13.408Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/5d/ac/d4fd5b30f82900eac60d765f179f0ba005825ac462cc8ced6e13ec685ab3/joserfc-1.6.8.tar.gz", hash = "sha256:878620c553a6ebdd76ccdc356782fee3f735f21a356d079a546b42a4670ace5f", size = 232930, upload-time = "2026-05-27T03:22:37.819Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/54/3b/ad1cb22e75c963b1f07c8a2329bf47227ce7e4361df5eb2fb101b2ce33ef/joserfc-1.6.5-py3-none-any.whl", hash = "sha256:e9878a0f8243fe7b95e11fdda81374ca9f7a689e302751579d3dfdeec559675e", size = 70464, upload-time = "2026-05-06T04:58:11.668Z" },
+ { url = "https://files.pythonhosted.org/packages/98/8c/5cdce2cf3ce8155849baf9a5e2ce77e89dc87ec3bdb38259e5d85fbc45bd/joserfc-1.6.8-py3-none-any.whl", hash = "sha256:22fb31a69094a5e6f44632002a9df2c30c941fc6c8ce1b037e92c03de954cf9f", size = 70927, upload-time = "2026-05-27T03:22:35.796Z" },
]
[[package]]
@@ -1369,60 +1179,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" },
]
-[[package]]
-name = "jupyter-client"
-version = "8.8.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "jupyter-core" },
- { name = "python-dateutil" },
- { name = "pyzmq" },
- { name = "tornado" },
- { name = "traitlets" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/05/e4/ba649102a3bc3fbca54e7239fb924fd434c766f855693d86de0b1f2bec81/jupyter_client-8.8.0.tar.gz", hash = "sha256:d556811419a4f2d96c869af34e854e3f059b7cc2d6d01a9cd9c85c267691be3e", size = 348020, upload-time = "2026-01-08T13:55:47.938Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/2d/0b/ceb7694d864abc0a047649aec263878acb9f792e1fec3e676f22dc9015e3/jupyter_client-8.8.0-py3-none-any.whl", hash = "sha256:f93a5b99c5e23a507b773d3a1136bd6e16c67883ccdbd9a829b0bbdb98cd7d7a", size = 107371, upload-time = "2026-01-08T13:55:45.562Z" },
-]
-
-[[package]]
-name = "jupyter-core"
-version = "5.9.1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "platformdirs" },
- { name = "traitlets" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508", size = 89814, upload-time = "2025-10-16T19:19:18.444Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032, upload-time = "2025-10-16T19:19:16.783Z" },
-]
-
-[[package]]
-name = "jupyterlab-pygments"
-version = "0.3.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload-time = "2023-11-23T09:26:37.44Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload-time = "2023-11-23T09:26:34.325Z" },
-]
-
-[[package]]
-name = "jupytext"
-version = "1.19.2"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "markdown-it-py" },
- { name = "mdit-py-plugins" },
- { name = "nbformat" },
- { name = "packaging" },
- { name = "pyyaml" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/72/3a/4f13fcba0ed05965a48fca197d89fb8c78c4b61051dc0c9ee9ed92e77a8d/jupytext-1.19.2.tar.gz", hash = "sha256:da6198a42406a09142b6b26ebc46a3ec7077f525222a8f12b1811a0e289a2216", size = 4309931, upload-time = "2026-05-10T17:10:40.345Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/4c/65/b4b86e5fa07543bfbbcdc6c9f7f9f561e66a5f3539992e3009973f2b1314/jupytext-1.19.2-py3-none-any.whl", hash = "sha256:8a31e896c7e9215841783aade24336e945543057e1c2d7f00b22f9e870348688", size = 170653, upload-time = "2026-05-10T17:10:38.418Z" },
-]
-
[[package]]
name = "lazy-object-proxy"
version = "1.12.0"
@@ -1616,30 +1372,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" },
]
-[[package]]
-name = "matplotlib-inline"
-version = "0.2.2"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "traitlets" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/bd/c0/9f7c9a46090390368a4d7bcb76bb87a4a36c421e4c0792cdb53486ffac7a/matplotlib_inline-0.2.2.tar.gz", hash = "sha256:72f3fe8fce36b70d4a5b612f899090cd0401deddc4ea90e1572b9f4bfb058c79", size = 8150, upload-time = "2026-05-08T17:33:33.49Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/41/09/5b161152e2d90f7b87f781c2e1267494aef9c32498df793f73ad0a0a494a/matplotlib_inline-0.2.2-py3-none-any.whl", hash = "sha256:3c821cf1c209f59fb2d2d64abbf5b23b67bcb2210d663f9918dd851c6da1fcf6", size = 9534, upload-time = "2026-05-08T17:33:32.055Z" },
-]
-
-[[package]]
-name = "mdit-py-plugins"
-version = "0.6.1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "markdown-it-py" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/59/fc/f8d0863f8862f25602c0404d75568e89fb6b4109804645e5cdfb1be5cf56/mdit_py_plugins-0.6.1.tar.gz", hash = "sha256:a2bca0f039f39dbd35fb74ae1b5f998608c437463371f0ff7f49a19a17a114d0", size = 56114, upload-time = "2026-05-13T09:03:38.91Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a5/69/6da5581c6a7fede7dc261bf4e67d6adca4196f176b43288b55b3db395b6e/mdit_py_plugins-0.6.1-py3-none-any.whl", hash = "sha256:214c82fb2ac524472ab6a5bcab1de80f73b50443e187f401bfd77efbc7c6481d", size = 66663, upload-time = "2026-05-13T09:03:37.76Z" },
-]
-
[[package]]
name = "mdurl"
version = "0.1.2"
@@ -1675,15 +1407,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/76/8e/56ccb09c7232a55403a7637caa21922f3b65901a37f5e8bdb405d0de0946/mike-2.2.0-py3-none-any.whl", hash = "sha256:e1f4981c1152eec7c2490a3401142292cc47d686194188416db2648fdfe1d040", size = 34026, upload-time = "2026-04-14T04:59:02.602Z" },
]
-[[package]]
-name = "mistune"
-version = "3.2.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/ca/84/620cc3f7e3adf6f5067e10f4dbae71295d8f9e16d5d3f9ef97c40f2f592c/mistune-3.2.1.tar.gz", hash = "sha256:7c8e5501d38bac1582e067e46c8343f17d57ea1aaa735823f3aba1fd59c88a28", size = 98003, upload-time = "2026-05-03T14:33:22.312Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/2a/7f/a946aa4f8752b37102b41e64dca18a1976ac705c3a0d1dfe74d820a02552/mistune-3.2.1-py3-none-any.whl", hash = "sha256:78cdb0ba5e938053ccf63651b352508d2efa9411dc8810bfb05f2dc5140c0048", size = 53749, upload-time = "2026-05-03T14:33:20.551Z" },
-]
-
[[package]]
name = "mkdocs"
version = "1.6.1"
@@ -1736,23 +1459,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl", hash = "sha256:e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650", size = 9555, upload-time = "2026-03-10T02:46:32.256Z" },
]
-[[package]]
-name = "mkdocs-jupyter"
-version = "0.26.3"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "ipykernel" },
- { name = "jupytext" },
- { name = "mkdocs" },
- { name = "mkdocs-material" },
- { name = "nbconvert" },
- { name = "pygments" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/00/aa/f8d15409a9a3112486994a80d5a975694c7d145c4f8b5b484aeb383420ef/mkdocs_jupyter-0.26.3.tar.gz", hash = "sha256:e1e8bd48a1b96542e84e3028e3066112bac7b94d95ab69f8b91305c84003ca26", size = 1628353, upload-time = "2026-04-17T18:56:31.517Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/13/95/cf3f7fe4910cf0365fa8ea0c731f4b8a624d97cd76ea777913ac8d0868e2/mkdocs_jupyter-0.26.3-py3-none-any.whl", hash = "sha256:cd6644fb578131157194d750fd4d10fc2fd8f1e84e00036ee62df3b5b4b84c82", size = 1459740, upload-time = "2026-04-17T18:56:30.031Z" },
-]
-
[[package]]
name = "mkdocs-material"
version = "9.7.6"
@@ -1822,16 +1528,16 @@ wheels = [
[[package]]
name = "mkdocstrings-python"
-version = "2.0.4"
+version = "2.0.5"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "griffelib" },
{ name = "mkdocs-autorefs" },
{ name = "mkdocstrings" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/a4/b4/5fed370d8ebd96e4e399460a7146ae989263f16588b05a6facd6dbd51e60/mkdocstrings_python-2.0.4.tar.gz", hash = "sha256:58c73c5d358e64e9b1673447663f4a2f8a8941e392e225fc0a0c893758cc452f", size = 199219, upload-time = "2026-06-05T08:13:01.819Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/b1/b6/e858701499d57eee8b3fd8e78168083956c6683ddbe727b46758b19e1119/mkdocstrings_python-2.0.5.tar.gz", hash = "sha256:3a4d92556ad39637e88af94a5374213af9a8e3040c3824ceaed04b486c017594", size = 199578, upload-time = "2026-06-19T10:41:08.868Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/5e/e3/00ec594aef5f55522e6d373bc2ac53e53a8f5e9ae32f2d6854b0de4270f3/mkdocstrings_python-2.0.4-py3-none-any.whl", hash = "sha256:fd87c173e1e719a85997b6d4f852cdc55f36710e0ed08da3a7bd9abe79c9db00", size = 104790, upload-time = "2026-06-05T08:13:00.393Z" },
+ { url = "https://files.pythonhosted.org/packages/d1/fc/10ab7e80650a9c9e8f4f1105f8c8e73567f88ed0c06ada589ab81d38687c/mkdocstrings_python-2.0.5-py3-none-any.whl", hash = "sha256:30c837bbff016549f659fcba6539ac351303f0fd7e713c89a040611072236e9d", size = 104951, upload-time = "2026-06-19T10:41:07.378Z" },
]
[[package]]
@@ -2087,70 +1793,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" },
]
-[[package]]
-name = "nbclient"
-version = "0.10.4"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "jupyter-client" },
- { name = "jupyter-core" },
- { name = "nbformat" },
- { name = "traitlets" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/56/91/1c1d5a4b9a9ebba2b4e32b8c852c2975c872aec1fe42ab5e516b2cecd193/nbclient-0.10.4.tar.gz", hash = "sha256:1e54091b16e6da39e297b0ece3e10f6f29f4ac4e8ee515d29f8a7099bd6553c9", size = 62554, upload-time = "2025-12-23T07:45:46.369Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/83/a0/5b0c2f11142ed1dddec842457d3f65eaf71a0080894eb6f018755b319c3a/nbclient-0.10.4-py3-none-any.whl", hash = "sha256:9162df5a7373d70d606527300a95a975a47c137776cd942e52d9c7e29ff83440", size = 25465, upload-time = "2025-12-23T07:45:44.51Z" },
-]
-
-[[package]]
-name = "nbconvert"
-version = "7.17.1"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "beautifulsoup4" },
- { name = "bleach", extra = ["css"] },
- { name = "defusedxml" },
- { name = "jinja2" },
- { name = "jupyter-core" },
- { name = "jupyterlab-pygments" },
- { name = "markupsafe" },
- { name = "mistune" },
- { name = "nbclient" },
- { name = "nbformat" },
- { name = "packaging" },
- { name = "pandocfilters" },
- { name = "pygments" },
- { name = "traitlets" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/01/b1/708e53fe2e429c103c6e6e159106bcf0357ac41aa4c28772bd8402339051/nbconvert-7.17.1.tar.gz", hash = "sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2", size = 865311, upload-time = "2026-04-08T00:44:14.914Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/67/f8/bb0a9d5f46819c821dc1f004aa2cc29b1d91453297dbf5ff20470f00f193/nbconvert-7.17.1-py3-none-any.whl", hash = "sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8", size = 261927, upload-time = "2026-04-08T00:44:12.845Z" },
-]
-
-[[package]]
-name = "nbformat"
-version = "5.10.4"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "fastjsonschema" },
- { name = "jsonschema" },
- { name = "jupyter-core" },
- { name = "traitlets" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749, upload-time = "2024-04-04T11:20:37.371Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454, upload-time = "2024-04-04T11:20:34.895Z" },
-]
-
-[[package]]
-name = "nest-asyncio"
-version = "1.6.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" },
-]
-
[[package]]
name = "networkx"
version = "3.6.1"
@@ -2194,63 +1836,53 @@ msgpack = [
[[package]]
name = "numpy"
-version = "2.4.6"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/95/2a/3d7b5ac8aac24feaf9ad7ed58f45b0bbc06d37e4338ae84c9f2298b570f9/numpy-2.4.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:001fbb8e08d942dd57599e781f2472269ee7f2755fae407b4f67b2f0b17da3f1", size = 16689119, upload-time = "2026-05-18T23:33:54.065Z" },
- { url = "https://files.pythonhosted.org/packages/ea/12/92c4c131527599e8288d6918e888d88726f84d805d784b771f32408aeaef/numpy-2.4.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ebfb099f8dcf083deef3ac1ca4c1503f387cf76296fcb3816b66f5ecb5f54fdb", size = 14699246, upload-time = "2026-05-18T23:33:57.621Z" },
- { url = "https://files.pythonhosted.org/packages/ad/fe/c0a6b7b2ca128a8fb228575147073b660656734b8ebe4d76c8fd748dcc79/numpy-2.4.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3213d622a0283a39a93d188f3cf72b26862df52fbb4ca3697f51705016523d41", size = 5204410, upload-time = "2026-05-18T23:34:00.302Z" },
- { url = "https://files.pythonhosted.org/packages/f3/d4/9770d14ba719432bb90a421bfd443872ed0f70f7264b64bec12ea363d5fd/numpy-2.4.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:357cc07a6d7b0b182ff02249616a03742827ebb1277546b5c7cd7f7620a45698", size = 6551240, upload-time = "2026-05-18T23:34:02.852Z" },
- { url = "https://files.pythonhosted.org/packages/c9/c6/50a46a6205feba2343f1d6d17438107c5dc491ed1c736e6ea68689fd906b/numpy-2.4.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f", size = 15671012, upload-time = "2026-05-18T23:34:05.485Z" },
- { url = "https://files.pythonhosted.org/packages/99/60/14115e6364fa676c5397c2ad3004e527e9aa487abf5d0706ec81bbd08529/numpy-2.4.6-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853", size = 16645538, upload-time = "2026-05-18T23:34:09.265Z" },
- { url = "https://files.pythonhosted.org/packages/ae/c5/693cbe59e57db94d2231fa519ca3978dc9e19da5a8f088588f5c6e947ff2/numpy-2.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a", size = 17020706, upload-time = "2026-05-18T23:34:13.053Z" },
- { url = "https://files.pythonhosted.org/packages/ef/fc/85b7c4eff9b4966ade25c2273cf7e7012e92366c032058653934b37de044/numpy-2.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2", size = 18368541, upload-time = "2026-05-18T23:34:17.024Z" },
- { url = "https://files.pythonhosted.org/packages/f6/81/e1b27545deedce7f4a0b348618c6b62d74e36a4dc9ccd42f3eb2f85eee32/numpy-2.4.6-cp312-cp312-win32.whl", hash = "sha256:e3eeb0aabd6bd5ce64faae67e9935203a6991b4bc2a485a767fbafb2c5125f45", size = 5962825, upload-time = "2026-05-18T23:34:20.3Z" },
- { url = "https://files.pythonhosted.org/packages/ab/ca/feab00bd44aa5fe1ad2c18f08b4d3bb92e26484b0b1d1443897809ed528c/numpy-2.4.6-cp312-cp312-win_amd64.whl", hash = "sha256:d8e8286dd7cea7895157318d1b91cdacac64c479f3cbc8dce548331728484751", size = 12321687, upload-time = "2026-05-18T23:34:23.095Z" },
- { url = "https://files.pythonhosted.org/packages/63/cf/5a6d34850a39d1093558564f77ee8e8e0bee5061151b8f05a55711001ec7/numpy-2.4.6-cp312-cp312-win_arm64.whl", hash = "sha256:4081eb135ac24158bd51cdfbef16f1c64df7063b1143f24731387137c092bec8", size = 10221482, upload-time = "2026-05-18T23:34:25.876Z" },
- { url = "https://files.pythonhosted.org/packages/fb/82/bdab26d7438c6791ca31b7c024ca37c1eab8b726ba236129005cd4a06e45/numpy-2.4.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0", size = 16684648, upload-time = "2026-05-18T23:34:29.41Z" },
- { url = "https://files.pythonhosted.org/packages/1b/30/a80189bcc7f5e4258b3fbc3968d909d1756f54d023299ecc39ad6fdb9ef8/numpy-2.4.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb", size = 14693902, upload-time = "2026-05-18T23:34:33.013Z" },
- { url = "https://files.pythonhosted.org/packages/97/12/70b5d0d7c15e1ebb8a6a84a8caa1d19e181d84fb58bb6d70aca29099dec1/numpy-2.4.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f", size = 5198992, upload-time = "2026-05-18T23:34:36.132Z" },
- { url = "https://files.pythonhosted.org/packages/ba/8c/ebd2a8f8a83541f8d38cc5667e8c2b69cecfd30da6e45693e8158857d44b/numpy-2.4.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3", size = 6546944, upload-time = "2026-05-18T23:34:38.484Z" },
- { url = "https://files.pythonhosted.org/packages/bb/c5/7b863a97a91671a0338f4253bd3b5a3d3852f0692dae91711c9f4a10e787/numpy-2.4.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b", size = 15669392, upload-time = "2026-05-18T23:34:41.257Z" },
- { url = "https://files.pythonhosted.org/packages/a5/9d/3584b9984ca4c047aea75214ce1a4c4c73d849bd71b604264b7f5653f8a8/numpy-2.4.6-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089", size = 16633220, upload-time = "2026-05-18T23:34:45.075Z" },
- { url = "https://files.pythonhosted.org/packages/05/ae/7c67fba23bd98caec7c99261f3a16072ade14813486b0282cb29846de832/numpy-2.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a", size = 17020800, upload-time = "2026-05-18T23:34:49.065Z" },
- { url = "https://files.pythonhosted.org/packages/d9/5d/3b6725cb31d983c5e66916f5d36f6d7e5521129e4c4404d64f918292a5b6/numpy-2.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605", size = 18357600, upload-time = "2026-05-18T23:34:52.709Z" },
- { url = "https://files.pythonhosted.org/packages/f7/da/2ccc6c2fe8898dee01d90c75c5f5f914a23daf99e3e0f59516a08760c8b5/numpy-2.4.6-cp313-cp313-win32.whl", hash = "sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91", size = 5961134, upload-time = "2026-05-18T23:34:55.618Z" },
- { url = "https://files.pythonhosted.org/packages/b5/cd/9cc4dc876fb065d5c220aae4d5e14826b2715331bb7618ce1fb07a679d99/numpy-2.4.6-cp313-cp313-win_amd64.whl", hash = "sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359", size = 12318598, upload-time = "2026-05-18T23:34:58.928Z" },
- { url = "https://files.pythonhosted.org/packages/39/1e/c0bcba1f8694116485fe28fd1be698c278fcda4141c5b0e53a2aed8b12a8/numpy-2.4.6-cp313-cp313-win_arm64.whl", hash = "sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778", size = 10222272, upload-time = "2026-05-18T23:35:02.167Z" },
- { url = "https://files.pythonhosted.org/packages/63/6d/cc5619247c8f4204e507f5883528372e4ac4bb189e579fb859a12e480b1f/numpy-2.4.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1", size = 14821197, upload-time = "2026-05-18T23:35:05.468Z" },
- { url = "https://files.pythonhosted.org/packages/00/58/f1c39161c87d9e9bed660f1ed4bafc0e403d5ec9650b6dd77aead07d489b/numpy-2.4.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe", size = 5326287, upload-time = "2026-05-18T23:35:08.693Z" },
- { url = "https://files.pythonhosted.org/packages/af/57/3917ab0fd97f271a8694513581b8a36c655f111c446852c302f04ccdb6fc/numpy-2.4.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997", size = 6646763, upload-time = "2026-05-18T23:35:11.459Z" },
- { url = "https://files.pythonhosted.org/packages/eb/0f/037e64c494b67581ae18193d770adef354c41f3f2c8ebf865602d949bf8f/numpy-2.4.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20", size = 15728070, upload-time = "2026-05-18T23:35:14.79Z" },
- { url = "https://files.pythonhosted.org/packages/21/a6/5d2bae9c9542eb4df16dc9c46dc79c186e9bad53805dfa5399a6023c6db0/numpy-2.4.6-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d", size = 16681752, upload-time = "2026-05-18T23:35:18.836Z" },
- { url = "https://files.pythonhosted.org/packages/92/14/23d1dfb410ae362cd59ce53e936b1513d545eb40db3949ced632e19a459e/numpy-2.4.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67", size = 17086024, upload-time = "2026-05-18T23:35:22.52Z" },
- { url = "https://files.pythonhosted.org/packages/4b/6e/23595a2c642cdf3bc567877064bdd7f91c8b0038a4453cf2daf7248eafe9/numpy-2.4.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd", size = 18403398, upload-time = "2026-05-18T23:35:26.398Z" },
- { url = "https://files.pythonhosted.org/packages/8a/90/0ac3bc947217e66dec77e7cbc6a1979d1af70b6461b82f620d3bccd5e4c8/numpy-2.4.6-cp313-cp313t-win32.whl", hash = "sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab", size = 6084971, upload-time = "2026-05-18T23:35:29.387Z" },
- { url = "https://files.pythonhosted.org/packages/77/71/5673e351671a1d2bd6063b91b44f70c0affea7d1516fa7a6572941ba4aa1/numpy-2.4.6-cp313-cp313t-win_amd64.whl", hash = "sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75", size = 12458532, upload-time = "2026-05-18T23:35:32.175Z" },
- { url = "https://files.pythonhosted.org/packages/3f/88/19d3503c5046e688f049274b27a3ef3d771152fa80d3ba3d01a3dff61abe/numpy-2.4.6-cp313-cp313t-win_arm64.whl", hash = "sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd", size = 10291881, upload-time = "2026-05-18T23:35:35.465Z" },
- { url = "https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079", size = 16683458, upload-time = "2026-05-18T23:35:38.353Z" },
- { url = "https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7", size = 14704559, upload-time = "2026-05-18T23:35:42.14Z" },
- { url = "https://files.pythonhosted.org/packages/60/61/23f27c172f022e04025b7dc2367f4d63c1a398120607ec896228649a6f48/numpy-2.4.6-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5", size = 5209716, upload-time = "2026-05-18T23:35:45.377Z" },
- { url = "https://files.pythonhosted.org/packages/03/71/21cf70dc6ea3e3acb95fc53a265b2fc248b981f0194ceb5b475271b8809d/numpy-2.4.6-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096", size = 6543947, upload-time = "2026-05-18T23:35:47.926Z" },
- { url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197, upload-time = "2026-05-18T23:35:50.863Z" },
- { url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245, upload-time = "2026-05-18T23:35:54.752Z" },
- { url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587, upload-time = "2026-05-18T23:35:58.355Z" },
- { url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226, upload-time = "2026-05-18T23:36:02.845Z" },
- { url = "https://files.pythonhosted.org/packages/aa/b4/298628d98c72b57e57f7165ae6a481a1deaf6f3c28262a6e4c739c275930/numpy-2.4.6-cp314-cp314-win32.whl", hash = "sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", size = 6010196, upload-time = "2026-05-18T23:36:05.92Z" },
- { url = "https://files.pythonhosted.org/packages/df/ac/46de6dda46478f7942f839e094970be2d4a861e005c4b3bf07c92e291a09/numpy-2.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", size = 12450334, upload-time = "2026-05-18T23:36:09.107Z" },
- { url = "https://files.pythonhosted.org/packages/78/92/b8b798ac784102c0da830d2257d59358e3d3d90d1e2b3f2575dad976c5cf/numpy-2.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", size = 10495678, upload-time = "2026-05-18T23:36:12.766Z" },
- { url = "https://files.pythonhosted.org/packages/30/34/ec28d1aa8115971537c01469ab2011ee96827930f0a124de1000cc2a7ed7/numpy-2.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a", size = 14823672, upload-time = "2026-05-18T23:36:16.473Z" },
- { url = "https://files.pythonhosted.org/packages/16/bd/f6d1fede4e54e8042a7ff97bb495510f3c220f94bcd9e8b228e87c92cc0d/numpy-2.4.6-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e", size = 5328731, upload-time = "2026-05-18T23:36:19.767Z" },
- { url = "https://files.pythonhosted.org/packages/f4/f0/e105b9e2fd728a9910103884decd6951d9dd73896b914a98d9a231de02ee/numpy-2.4.6-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e", size = 6649805, upload-time = "2026-05-18T23:36:22.266Z" },
- { url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496, upload-time = "2026-05-18T23:36:25.713Z" },
- { url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616, upload-time = "2026-05-18T23:36:29.652Z" },
- { url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145, upload-time = "2026-05-18T23:36:33.449Z" },
- { url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813, upload-time = "2026-05-18T23:36:37.369Z" },
- { url = "https://files.pythonhosted.org/packages/9c/50/0753655aa844c99cd9e018aacf76f130f1bd81d881bb74bc0aef5d73a8ba/numpy-2.4.6-cp314-cp314t-win32.whl", hash = "sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", size = 6156982, upload-time = "2026-05-18T23:36:40.817Z" },
- { url = "https://files.pythonhosted.org/packages/b2/d4/7c67becf668f973cb490cec3e98dfd799d866f9c989a54d355672cfa0db6/numpy-2.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", size = 12638908, upload-time = "2026-05-18T23:36:43.996Z" },
- { url = "https://files.pythonhosted.org/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867, upload-time = "2026-05-18T23:36:47.114Z" },
+version = "2.5.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e7/05/3d27272d30698dc0ecb7fdfaa41ad70303b444f81722bb99bce1d818638a/numpy-2.5.0.tar.gz", hash = "sha256:5a129578019311b6e56bdd714250f19b518f7dceeeb8d1af5490f4942d3f891c", size = 20652461, upload-time = "2026-06-21T20:57:51.95Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fa/0a/11486d02add7b1384dff7374d124b1cfbb0ee864dcc9f6a2c0380638cf84/numpy-2.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:489780423903667933b4ed6197b6ec3b75ea5dd17d1d8f0f38d798feb6921561", size = 16789987, upload-time = "2026-06-21T20:56:16.657Z" },
+ { url = "https://files.pythonhosted.org/packages/55/b2/285f48640a181947b4587a3766d21ec1eaa7fea833d4b49957e09da467a2/numpy-2.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ece55976ced6bca95a03ae2839e2e5ccffe8eb6a3e7022415645eb154a81e4e6", size = 11760322, upload-time = "2026-06-21T20:56:19.813Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/67/b032db1eb03ca30d16eda3b0c22aaa615338b9263c2fd559d0f29451aca4/numpy-2.5.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:c83b664b0e6eee9594fa920cf0639d8af796606d3fad6cc70180c87e4b97c7be", size = 5319605, upload-time = "2026-06-21T20:56:22.173Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/83/03fc7300c7c6b6c84c487b1dc80d322817b95fbd1f4dd57a85e23b7198de/numpy-2.5.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bf80333980bf37f523341ddd72c783f39d6829ec7736b9eb99086388a2d52cc2", size = 6653628, upload-time = "2026-06-21T20:56:23.914Z" },
+ { url = "https://files.pythonhosted.org/packages/82/49/2ec21730bc63ccfda829323f7040a8ed4715b3852ce658689cf74ee96a8c/numpy-2.5.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1a4874217b36d5ac8fc876f52e39df56f8182c88463e9e2dceabf7ca8b7efb8", size = 15153691, upload-time = "2026-06-21T20:56:25.631Z" },
+ { url = "https://files.pythonhosted.org/packages/bb/6b/f4a3d0637692c49da8ef99d72d52526f92e0a8d6ac4f0ca9f31441b9d9ea/numpy-2.5.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aaa760137137e8d3c920d27927748215b56014f92667dc9b6c27dfc61249255a", size = 16660066, upload-time = "2026-06-21T20:56:28.009Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/2f/c354ec86d1f3f5c19649463b0d39652e160736e5b0a4cd18dff0576715c4/numpy-2.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7174ce8265fc7f7417d171c9ea8fe905220748893ea67a2a7abe726ec331c4b0", size = 16514638, upload-time = "2026-06-21T20:56:30.26Z" },
+ { url = "https://files.pythonhosted.org/packages/06/34/43efdcb319988648580f93c11f1ae82cf7e2faa74925e98e454ae3aa95f8/numpy-2.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b8c3daaf99de52415d20b42f8e8155c78642cb04207d02f9d317a0dcf1b3fb54", size = 18419647, upload-time = "2026-06-21T20:56:32.41Z" },
+ { url = "https://files.pythonhosted.org/packages/71/e2/f5d1676b1d7fb682eb5e9a1641e7ebd2414b3216c370661d1029778908b4/numpy-2.5.0-cp312-cp312-win32.whl", hash = "sha256:6206db0af545d73d068add6d992279145f158428d1da6cc49adc4b630c5d6ee5", size = 6056688, upload-time = "2026-06-21T20:56:34.657Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/7c/48f115d1c58a34032facebcd51fdf2d02df2c51d4a46a81dd1197bb2ea6b/numpy-2.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:6f2d6873e2940c860a309d21e25b1e69af6aaffdd80aa056b04c16380db1c4f2", size = 12419237, upload-time = "2026-06-21T20:56:36.24Z" },
+ { url = "https://files.pythonhosted.org/packages/86/26/2e0882f4044d1b1a1b63e875151fb2393389032022a8b7f5657a7996d3b2/numpy-2.5.0-cp312-cp312-win_arm64.whl", hash = "sha256:a55e1eb2bca2cfd17a16b213c99dfc8502d47b0d494224d2122277d0400935ca", size = 10339912, upload-time = "2026-06-21T20:56:38.733Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/33/07675aaad7f26ea013d5e884d9a0d784b79c6bd7566c333f5a52fa3c610b/numpy-2.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:520e6b8be0a4b65840ac8090d4f51cef4bed66e2b0894d5a520f099adc24a9b2", size = 16784890, upload-time = "2026-06-21T20:56:40.799Z" },
+ { url = "https://files.pythonhosted.org/packages/85/4b/953118a730ee3b35e28645e0eb4cf9beec5bdbb954e1ac2f5fcefba6bbc3/numpy-2.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:146b81cdd3967fdb6beca8ba25f00c58741d8f3cbd797f55af0fbe0bfec3469c", size = 11754584, upload-time = "2026-06-21T20:56:43.094Z" },
+ { url = "https://files.pythonhosted.org/packages/44/9b/56dd530c367c74ae17411027cea4135ca57e1e0583bf5594cee18bd83217/numpy-2.5.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:126b88d95e8ff9b00c9e717aa540469f21d6180162f84c0caec51b16215d49cd", size = 5313904, upload-time = "2026-06-21T20:56:45.503Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/b0/bcd672edad27ecca7da1f7bb0ce72cd1706a4f2d79ae94990afc97c13e1c/numpy-2.5.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d4313cef1594c5ce46c31b6e54e918338f63f16ee9322304e8c9114d6d81c8bd", size = 6648504, upload-time = "2026-06-21T20:56:47.567Z" },
+ { url = "https://files.pythonhosted.org/packages/80/9e/15cdfcbd30a1544a46c9e487a00df331c4672450216538705a9e51fa6710/numpy-2.5.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:750fb097caf26fa878746d9d119f6f9da12dedcbff1eea966c3e3447647c4a9e", size = 15150086, upload-time = "2026-06-21T20:56:49.352Z" },
+ { url = "https://files.pythonhosted.org/packages/32/4e/8d7656ccaab3e81e97258b8a9bc5f0c8502513a92fb4ceb0a2cbfebc17bf/numpy-2.5.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3893adc2dc7c0412ba76777db55a049215d99c9aa3113003be8f49f4f1290ab9", size = 16647250, upload-time = "2026-06-21T20:56:51.542Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/81/97060281b602ed07f21b12f4ec409eac1f75a2f91fbc829ed8b2becf3ad4/numpy-2.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:835e454dd99b238cdc5a3f63bce2371296f5ebc53ca1e0f8e6ddbb6d92a29aab", size = 16512864, upload-time = "2026-06-21T20:56:55.401Z" },
+ { url = "https://files.pythonhosted.org/packages/33/ab/4496208146911f8d8ddb54f68a972aafa6c8d44babcb2ea03b0e5cc87c9d/numpy-2.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6f9836778081a0a3c02a6a21493f3e9f5b311f8d2541934f31f05583dc999ea4", size = 18408407, upload-time = "2026-06-21T20:56:57.75Z" },
+ { url = "https://files.pythonhosted.org/packages/d4/9f/a4df67c181e4ee8b467aa3332dc2db10fd5c515136831302f3ca48bc0a01/numpy-2.5.0-cp313-cp313-win32.whl", hash = "sha256:0b525be4744b60bb0557ac872d53ef07d085b5f39622bc579c98d3809d05b988", size = 6054431, upload-time = "2026-06-21T20:57:00.016Z" },
+ { url = "https://files.pythonhosted.org/packages/30/53/491e1c47c55b62ccc6a63c1c5b8635c73fc2258dddeb9bda27cae4a0ae96/numpy-2.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:44353e2878930039db472b99dc353d749826e4010bd4d2a7f835e94a97a5c748", size = 12414420, upload-time = "2026-06-21T20:57:01.815Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/4a/25c2906f541e9d9f4c5769764db732e6627be91a13f4724fa10634d77db4/numpy-2.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:48f54b00711f83a5f796b70c518e8c2b3c5848dda03a54911f23eb68519b9b60", size = 10339533, upload-time = "2026-06-21T20:57:03.961Z" },
+ { url = "https://files.pythonhosted.org/packages/86/ad/abc44aaceaf7b17ee1edde2bbb4458da591bc79574cffff50c4bb35f00d1/numpy-2.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f27582c55ba4c750b7c58c8faf021d2cd9324a662b466229db8a417b41368af9", size = 16783807, upload-time = "2026-06-21T20:57:06.253Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/39/b72e168daf9c00fb20c9fc996d00437ccecdef3102387775d29d7a62576d/numpy-2.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:28e7137057d551e4a83c4ae414e3451f50568409db7569aacc7f9811ee06a446", size = 11765215, upload-time = "2026-06-21T20:57:08.547Z" },
+ { url = "https://files.pythonhosted.org/packages/f7/a0/8400a9c0e3625182347593f5e1f57da9a617a534794805c8df5518154ddc/numpy-2.5.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:e1da54b53e75cd9fcfc23efcc7edab2c6aecf97b6037566d8a0fe804af8ec57c", size = 5324493, upload-time = "2026-06-21T20:57:11.012Z" },
+ { url = "https://files.pythonhosted.org/packages/f6/8c/0d104deaa0401c93395a629ec902891618a2eff76d19229139cb5a887bfc/numpy-2.5.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:694d8f74e156f7fd01179f1aa8faa2f648ab6ae0f70b6c3fe57a03249aea2303", size = 6645211, upload-time = "2026-06-21T20:57:12.919Z" },
+ { url = "https://files.pythonhosted.org/packages/6a/d9/4a4a628c812750363786afc3d33492709a5cd64b215469c16b0f6c7bb811/numpy-2.5.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1a7569a7b53c77716f036bb28cb1c91f166a26ec7d9502cd1e4bdfe502fdec22", size = 15166004, upload-time = "2026-06-21T20:57:14.717Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/5e/2a902317d7fc4aa93236e80c932662dadfc459b323d758329e01775125e1/numpy-2.5.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:39a0433bd4086ebd462960cf375e19195bb07b53dc1d87dd5fcf47ad78576f03", size = 16650797, upload-time = "2026-06-21T20:57:16.906Z" },
+ { url = "https://files.pythonhosted.org/packages/e9/a0/a0090e6329f4ca5992c07847bb579c5259a19953dc57255bb08793142ffb/numpy-2.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:929f0c79ac38bcbd7154fe631dc907abfeddbcc5027a896bd1f7767323271e7a", size = 16524647, upload-time = "2026-06-21T20:57:19.165Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/7d/6caf27734c42b65837e7461ed0dbbd6b6fc835060c9714ec59d673bb383a/numpy-2.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cc4f247a47bbf070bfd70be53ccdcf47b800af563535e7bbe172322197c30e21", size = 18411841, upload-time = "2026-06-21T20:57:21.638Z" },
+ { url = "https://files.pythonhosted.org/packages/13/dc/26edadbd812536769a82c2e9e002234e33feb5da43061d47a044f6d309b7/numpy-2.5.0-cp314-cp314-win32.whl", hash = "sha256:5dc71423499fab3f46f7a7201155ade1669ea101f2f429d332df9e72f8161731", size = 6106361, upload-time = "2026-06-21T20:57:23.844Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/9e/4dd1459282229a72d92dece2ae9138e5cac94a72263a7ceb48f37434c925/numpy-2.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:ebb81d9d5443e0309d6c54894c3fbed74ad7da0714352a67b6d773cd189eae73", size = 12551749, upload-time = "2026-06-21T20:57:25.945Z" },
+ { url = "https://files.pythonhosted.org/packages/05/a7/6bc6384c080b86c7f6c85c5bc5b540b24f4f679cd144791d99574e90d462/numpy-2.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:3b94d0d0deceebfad3e67ae5c0e5eb87371e8f7a0581cd04a779928c2450cf1e", size = 10617072, upload-time = "2026-06-21T20:57:28.175Z" },
+ { url = "https://files.pythonhosted.org/packages/86/6b/4a2b71d66ada5608ae02b63f150dfad520f6940721cb7f029ad270befc0e/numpy-2.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:22f3d43e362d650bc39db1f17851302874a148ca95ba6981c1dfb5fa6862f35b", size = 11881067, upload-time = "2026-06-21T20:57:30.104Z" },
+ { url = "https://files.pythonhosted.org/packages/dc/b2/d365eb40a20efb49d67e9feb90494ed8511282ee1f5fa16006675c65397d/numpy-2.5.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:243563efb4cd7528a264567e9fd206c87826457322521d06206a00bfa316c927", size = 5440290, upload-time = "2026-06-21T20:57:32.193Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/5e/e9c03188de5f9b767e46a8fe988bcfd3efad066a4a3fda8b9cb11a93f895/numpy-2.5.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:84881d825ca75249b189bbee875fcfe3238aa5c479e6100893cda566e8e86826", size = 6748371, upload-time = "2026-06-21T20:57:33.933Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/1d/68c186a38a5027bae2c4ddd5ea681fdaf8b4d30fb7301def6d8ad270390f/numpy-2.5.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cda12aa4779d42b8771180aba759c96f527d43446d8f380ab59e2b35e8489efd", size = 15214643, upload-time = "2026-06-21T20:57:35.677Z" },
+ { url = "https://files.pythonhosted.org/packages/8c/67/73f67b7c7e20635baae9c4c3ead4ae7326a005900297a6110971abd62eb5/numpy-2.5.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c0121101093d2bd74981b10f8837d78e794a8ff57834eb27179f49e1ba11ac6", size = 16690128, upload-time = "2026-06-21T20:57:38.159Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/05/d4c1fb0c46d02a27d6b2b8b319a78c90937acec8631c1641874670b31e6f/numpy-2.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d371c92cfa09da00022f501ab67fafaea813d752eb30ac44336d45b1e5b0268a", size = 16577902, upload-time = "2026-06-21T20:57:40.447Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/1d/771c797d50fa26e4888989cccf1d50ee51f530d4e455ad2692dcb64fa711/numpy-2.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9990713e9c38154c6861e7547f1e3fc7a87e75ff09bab24ef1cc81d81c2835e9", size = 18452814, upload-time = "2026-06-21T20:57:42.875Z" },
+ { url = "https://files.pythonhosted.org/packages/e8/46/52fc0d2a68d7643f0f149eeea5a5d8ea2a3507056ac8afa83c9212606e8b/numpy-2.5.0-cp314-cp314t-win32.whl", hash = "sha256:edadfbd4794b1086c0d822f81863e8a68fc129d132fd0bb9e31e955d7fbbbdb7", size = 6253168, upload-time = "2026-06-21T20:57:45.101Z" },
+ { url = "https://files.pythonhosted.org/packages/2a/be/6c8d1118b5f13b2881dc095d5b345de19c6638b8959c17409b6eff84c8aa/numpy-2.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f7e5fa4382967ae6548bd2f174219afb908e294b0d5f625af01166edd5f7d9aa", size = 12736286, upload-time = "2026-06-21T20:57:46.935Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/6a/d3a169aaf8536cf228d56a09e04bcb713a2fe4410d4e2105b9419b5a9c89/numpy-2.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:016623417bb330d719d579daf2d6b9a01ddc52e41a9ed61a47f39fde46dcd865", size = 10686451, upload-time = "2026-06-21T20:57:49.313Z" },
]
[[package]]
@@ -2267,52 +1899,39 @@ wheels = [
[[package]]
name = "obstore"
-version = "0.10.1"
+version = "0.11.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/f1/b7/516498f128eeac220dd54df61fd8c4db88adb7675129ab5352f2706899a3/obstore-0.10.1.tar.gz", hash = "sha256:b193a53101bda703f887f1c0733cde7324ba6f9c80f0a81bdae5df8cb25c26f4", size = 126551, upload-time = "2026-06-09T20:29:33.848Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/42/23/532c9094def8ed33495d555749a21b6eac4c31c34a95e7154d4866e25666/obstore-0.10.1-cp311-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e5b009a5c257e9811b8d22bad2f090f8cdf24dca6afa1bafab88cb0ff5140317", size = 4092339, upload-time = "2026-06-09T19:51:43.938Z" },
- { url = "https://files.pythonhosted.org/packages/6d/3c/947a40ef9d64575a261fb3c0fd0c7e8ad4f160b4c6d4ee5c671705d92d5e/obstore-0.10.1-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:c949aa4d69c5a796f7daefa9bce2efcf5bc29a21399915e47efcbb6d18787f80", size = 3873610, upload-time = "2026-06-09T19:51:45.793Z" },
- { url = "https://files.pythonhosted.org/packages/53/15/1e8a507ae86c356e923f17ce0cfc3b7e2fdd3417b439c343f9ad09a3f452/obstore-0.10.1-cp311-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:beb2e6f5c2c633add1a80182c223c862bc523d9c7c55b793423851831ef8a9ac", size = 4028148, upload-time = "2026-06-09T19:51:47.265Z" },
- { url = "https://files.pythonhosted.org/packages/9e/7f/6d46085a65be661dbf10243de257d7d2705c5629af9279a3e7d404e8890d/obstore-0.10.1-cp311-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f195d3c1258406976848246cfb0490790ec0a22bd0560e548364afb846b4bce2", size = 4125215, upload-time = "2026-06-09T19:51:48.778Z" },
- { url = "https://files.pythonhosted.org/packages/b3/15/a681b578a104a28dc1098ac4f0b7c77b11f5f7a60a5d6a964b33889ade52/obstore-0.10.1-cp311-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cbad4afb93c26e39e6c51c390b9b6fec9602e9af50c4c0552f10f883524d197", size = 4412793, upload-time = "2026-06-09T19:51:50.258Z" },
- { url = "https://files.pythonhosted.org/packages/be/89/a610cf57ad94698952aad88dccbb0b6f6256f1e563d317b9e1393c30c338/obstore-0.10.1-cp311-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6bbd313dd82bd66b054cc1567927d69b17caed2bdf110da558e46e0ee4ba4e41", size = 4293828, upload-time = "2026-06-09T19:51:51.62Z" },
- { url = "https://files.pythonhosted.org/packages/2d/7a/82568065a1c21f45ae35069268247948d659b6a4d1c0a6186aa97538a102/obstore-0.10.1-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed4e795b9997f91041d2ad43b633099e0eb891337228d34e4c706ef8f0c5ae92", size = 4212724, upload-time = "2026-06-09T19:51:53.202Z" },
- { url = "https://files.pythonhosted.org/packages/03/7a/7581034bdf1c3e88df947eba1ba8512aaad71a96e95b4b355a40ff9febb6/obstore-0.10.1-cp311-abi3-manylinux_2_24_aarch64.whl", hash = "sha256:a3c35027a90ee1c97b82933907e5846c48d72bce714c7571f9fceac7a3c86551", size = 4103114, upload-time = "2026-06-09T19:51:54.776Z" },
- { url = "https://files.pythonhosted.org/packages/b4/ec/0448b41a9f111d2dfebfc4c7af8ad81f68c7ae3ccf0f61a181e652a73f1a/obstore-0.10.1-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b2902e2c9e1ca193bff39530bb907fd38204e68037ffb694a50042118eeb7a0b", size = 4291239, upload-time = "2026-06-09T19:51:56.253Z" },
- { url = "https://files.pythonhosted.org/packages/43/d3/63dfe45c22b43d579d6ef75a7dc81122d55b1af8ee020a7a7c241d982c66/obstore-0.10.1-cp311-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:c16e29b975430690c72ec71be9e6a4fe63854ff25985e6a3a1682419b55898ac", size = 4263387, upload-time = "2026-06-09T19:51:57.755Z" },
- { url = "https://files.pythonhosted.org/packages/e1/bd/66433876ca18172144cbcd6ff2e011cb512a4696d426a1946585d3855887/obstore-0.10.1-cp311-abi3-musllinux_1_2_i686.whl", hash = "sha256:c51488d41646bfd75fbb67507bbc55d6f5623d5b12ce0506a260a7a1f3e792da", size = 4253238, upload-time = "2026-06-09T19:51:59.428Z" },
- { url = "https://files.pythonhosted.org/packages/65/a1/46d61c7b871d0824973c3616277a68dc8a97269898d50a4b023de66c6507/obstore-0.10.1-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:84deb458af8601eb1dd948d58b9760bed2f0e7f36c6e9bcd5a61425cb2683b2a", size = 4434050, upload-time = "2026-06-09T19:52:00.889Z" },
- { url = "https://files.pythonhosted.org/packages/3f/b6/287d34041e73f1c5620462ba2ad0beecd9ef40ed7c3dd6e3924933bfa5fd/obstore-0.10.1-cp311-abi3-win_amd64.whl", hash = "sha256:f1b6e994b719e294a2b2aeb74f2ae8e5a294453a47d8a9d6f3104a28ef7d8aa5", size = 4174095, upload-time = "2026-06-09T19:52:02.335Z" },
- { url = "https://files.pythonhosted.org/packages/34/cd/86a2acdd1d37db34bef79d45d9aaeab740df58ff69e03c58b2ba5f328340/obstore-0.10.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:04e5f13af678993997f03fbc210e5da3dd36dfd9898235e977dacafe0e3bebfc", size = 4073194, upload-time = "2026-06-09T19:52:03.814Z" },
- { url = "https://files.pythonhosted.org/packages/8f/b3/ee84dab5325dcb579e6687438286acbd6ac25b257434e185b90f615a8849/obstore-0.10.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b9fc35c5642e3580497d9399e072ffb050b8e2fe8abf7d63b6dfdb62410071c8", size = 3864659, upload-time = "2026-06-09T19:52:05.523Z" },
- { url = "https://files.pythonhosted.org/packages/51/cb/db764c672e977c9f6fe9b16a16a93d24a22665bca28819a1b4795e0397ab/obstore-0.10.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5267922416b0e5c1092676ce386e5a0762011c3752eca92f58760ae5d01b5fba", size = 4023673, upload-time = "2026-06-09T19:52:06.995Z" },
- { url = "https://files.pythonhosted.org/packages/d6/68/249282efba38b21c070ebd4ac9ed5c958255c70c15d541935789b619f917/obstore-0.10.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31e0c82595ef3ff89c2ee9713d5cd0edbb7f86b0f2e73916683c535ed568293c", size = 4116817, upload-time = "2026-06-09T19:52:08.523Z" },
- { url = "https://files.pythonhosted.org/packages/bb/49/3f9b88caf396d8ba6eda797bc04906cb498a9f24c382d74e598c4a46a4ab/obstore-0.10.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d7c7bda05975df4ef37c516a617c041955d0bb700864015dbfcd6be89ab87c71", size = 4405345, upload-time = "2026-06-09T19:52:10.165Z" },
- { url = "https://files.pythonhosted.org/packages/43/fe/ec6e09dfa16b48c5a5e6a268abfbe63cdb339f213ade7f210ac638bb2548/obstore-0.10.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0409cbc5ff7e6bc33b78562cac5ca78b528c856bce50c03285aeb1abcd879805", size = 4297996, upload-time = "2026-06-09T19:52:12.081Z" },
- { url = "https://files.pythonhosted.org/packages/8b/24/2982f1efedd71f4cb417e0f532e0372ee5504dcbdae79b6d80fa5e63caef/obstore-0.10.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63bb830361b6d1c33aba41fb2466b9eb92c7ab84dcb061bfb96269c2b709e8c6", size = 4211926, upload-time = "2026-06-09T19:52:13.709Z" },
- { url = "https://files.pythonhosted.org/packages/e3/b5/169cf89cf67bb3750c9bea5d6d35424c964ae583ebc7f67614d7655acfb0/obstore-0.10.1-cp313-cp313t-manylinux_2_24_aarch64.whl", hash = "sha256:6dbbc0b3e672f4f822878361a07b9d3200871a460ef725e78bb68b063febb7a5", size = 4102832, upload-time = "2026-06-09T19:52:15.205Z" },
- { url = "https://files.pythonhosted.org/packages/ee/d1/d689516435a1e5e67ceea786325abfb43da10357f9ed114d8aa508f9066a/obstore-0.10.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3afca514671fa3f989242ef2b1694b53748881e7b29055e34007b530e116a5b8", size = 4290991, upload-time = "2026-06-09T19:52:16.867Z" },
- { url = "https://files.pythonhosted.org/packages/90/e9/83cf0dd637d2754557767cf438460ddcbbab5892987dadb5c42bdb2ec0d2/obstore-0.10.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:cf240b93e0f7856e396df9f4fa417df961db9a16d9e98619ed3c275676bffea7", size = 4258992, upload-time = "2026-06-09T19:52:18.714Z" },
- { url = "https://files.pythonhosted.org/packages/67/ed/06ebe9875c80b05111f597bc954074031e4f207784ba5951248ddd97723d/obstore-0.10.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2957cf29a1f6974e4d7d07e02ddc6b88994d010ae1f007237c945a3beb951728", size = 4244918, upload-time = "2026-06-09T19:52:20.321Z" },
- { url = "https://files.pythonhosted.org/packages/1d/c2/122c48a04f1a836f643378549fdc4d1bc3e905973d7d51d1aeb2f21c2017/obstore-0.10.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:730c7f0443aba5d0285245db65d6cf59bf87f3bf6fee8f99741a2e9254fb66a1", size = 4431686, upload-time = "2026-06-09T19:52:21.976Z" },
- { url = "https://files.pythonhosted.org/packages/72/09/25a8adf373b2b8824672b7a68211c6fdca8e950d815f3bc6df69a41abbb2/obstore-0.10.1-cp313-cp313t-win_amd64.whl", hash = "sha256:0440037e51f7e20224d84eb79bb49a47356916c5fc7e603dd5607d75997b73f8", size = 4165763, upload-time = "2026-06-09T19:52:23.531Z" },
- { url = "https://files.pythonhosted.org/packages/4c/d8/7c78f14d12472328c2fbf287405150bd98ff6111c465a0b9a0b7f24cb4be/obstore-0.10.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:34c7d76aa33bcac0e4d65d5760527f8c03be83b7584204dac142417a4c9703bf", size = 4073261, upload-time = "2026-06-09T19:52:25.203Z" },
- { url = "https://files.pythonhosted.org/packages/ef/15/84a1b3c4494ad7f7605a884e792a17fa4545f4e186e428ca84b58794d481/obstore-0.10.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8e9cfbcaf4afe00aaceef277bf9ea0604eda4cacd3511f459aaf48ac2e118392", size = 3864599, upload-time = "2026-06-09T19:52:26.643Z" },
- { url = "https://files.pythonhosted.org/packages/5e/a8/8332ab8076abaa086d8c8d17ff6f8e571af1725ee17a5b2b80888f297c68/obstore-0.10.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:282c9f85c56084dc3377818b77b7738301a1152bd6a49b0a36e06dc13d3cf7a9", size = 4023493, upload-time = "2026-06-09T19:52:28.327Z" },
- { url = "https://files.pythonhosted.org/packages/e4/fe/a87aa674f6cde2f7c0924d225ae9092bc0ccc8148810eaa0d2807204c367/obstore-0.10.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce13fd4693e5a5a52d5160a29863d8fa2aff26613e371c7041c78d3f1c1f14dc", size = 4116999, upload-time = "2026-06-09T20:28:47.361Z" },
- { url = "https://files.pythonhosted.org/packages/44/c5/2979d915c409d5dc24a01d27b0cfa81db06a7da2ea38bb54b19c0888b922/obstore-0.10.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4565c293dec7f234ed1bfee8c42d10fac9747f4de4d8d4401a94f442d3f2ff82", size = 4405326, upload-time = "2026-06-09T20:28:49.478Z" },
- { url = "https://files.pythonhosted.org/packages/a8/b5/b994342548f835bb63218369055621ac3d29eb8576dcf98ed123ea5ece92/obstore-0.10.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3bcf96ff1c52637602e705fbf616edbbb3109fe2c32ed08af718895d7800dc33", size = 4297910, upload-time = "2026-06-09T20:28:52.346Z" },
- { url = "https://files.pythonhosted.org/packages/6b/1c/34dacaf6bbda9df81ec57ae477da1b6273968f6a37c395068e531b4696e5/obstore-0.10.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:912d4b94f2949c722e4c6b9da7e99438aef91e30b01fd671abaf339e7b8b8c8d", size = 4212175, upload-time = "2026-06-09T20:28:54.777Z" },
- { url = "https://files.pythonhosted.org/packages/cb/b5/c25986eea6d043d199f972d5315a990984be50f8118c83fe64ceec443bb6/obstore-0.10.1-cp314-cp314t-manylinux_2_24_aarch64.whl", hash = "sha256:8df647f6821ae55c5aacd4c449a0e38ad08d0341bd693deca6294d30140885f7", size = 4103176, upload-time = "2026-06-09T20:28:56.794Z" },
- { url = "https://files.pythonhosted.org/packages/5c/4f/d94cdb5d66914ed7825a6185cbb5f288894a4c746e0b7a0e11c319a1e00f/obstore-0.10.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4f9bcf84db56d53e9cc720368f850f90989334047179eb8b44f39645290efca7", size = 4291332, upload-time = "2026-06-09T20:28:58.708Z" },
- { url = "https://files.pythonhosted.org/packages/11/42/94de2fc1ebdfef9b587961403e3b1bcde1fa7c6fe6f86bdd19519136c03b/obstore-0.10.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:59a3c5f98317c4a83cbed54772945314932d68f210f3f51a87f1955d73e31133", size = 4258949, upload-time = "2026-06-09T20:29:01.246Z" },
- { url = "https://files.pythonhosted.org/packages/b8/18/ce4fecee53b7ba8fd4c91180f3da2068e751b13620eabb03fea78a9a90e6/obstore-0.10.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f3c43d431593276c620a6c2870eb607401c679748c57ad57268b44e921c460fb", size = 4244717, upload-time = "2026-06-09T20:29:03.105Z" },
- { url = "https://files.pythonhosted.org/packages/73/d4/d432e10a7a080224c37455714717e5be6cb2cc85a673363f839b6403eac9/obstore-0.10.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:344239c68ffd21723cd306b4535ccaa5a9986b3aa003e3fe29b6822b2cefa671", size = 4432256, upload-time = "2026-06-09T20:29:04.993Z" },
- { url = "https://files.pythonhosted.org/packages/1f/d0/0ebae9b02583e6e37c50ce198fd0829b5850aa55247a6b7f21225ac186d1/obstore-0.10.1-cp314-cp314t-win_amd64.whl", hash = "sha256:04c4c751ed360ae1faf4dbb2dd2f0ea98595735d4b6b3b36b5e009ceb4ea0e68", size = 4165922, upload-time = "2026-06-09T20:29:06.878Z" },
+sdist = { url = "https://files.pythonhosted.org/packages/2e/2f/f83afaab7945509d72245b2b00af0b4834ce78fdd2d9ae9f0ad1a3036a91/obstore-0.11.0.tar.gz", hash = "sha256:a2f55163bcd348b4a60d12e6893eac50eddc742bad8032a1705d49140b992204", size = 130565, upload-time = "2026-06-25T18:29:49.405Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/fc/b2/00c213e7e5ca8065f97e37e55294adab836e3f6a88b23e4029069aaecf95/obstore-0.11.0-cp311-abi3-macosx_10_12_x86_64.whl", hash = "sha256:42f36546c7ac44dbab1173d2330a8a1b1a3f0e37950e553b8c904e3dd0744b25", size = 5491935, upload-time = "2026-06-25T18:28:32.029Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/37/6a6b9a5e15a8a37c24d14317a87648097c4888593b588510c03c030d2e90/obstore-0.11.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:687bb9d3962d568b7c439c5d0c6fea19b2749862a8e5c8eebd0c058c4eccde9e", size = 4672619, upload-time = "2026-06-25T18:28:33.852Z" },
+ { url = "https://files.pythonhosted.org/packages/28/f9/6745ce8c4f7bfac19dc14a4438b48a2e93a689b92b0cecfc695e41a4e8b1/obstore-0.11.0-cp311-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:010b51578c7514a41719d795cdb7a1e6529be509dac3772e477187a59422bb97", size = 5072806, upload-time = "2026-06-25T18:28:36.127Z" },
+ { url = "https://files.pythonhosted.org/packages/6c/18/991d3b3cdd851c0225e55f3dc45b47fd9e249827d188995011469f805132/obstore-0.11.0-cp311-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfaa8129a3f5d8518a3a75184d4b02348db0f6263177cd1f0951f6568243cc9e", size = 5303777, upload-time = "2026-06-25T18:28:37.89Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/e9/90e56015a45b5e56a84fc3188c4e5fb088b288d41992c73a629e10df6760/obstore-0.11.0-cp311-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c790a5cb9ff2970d1f464a6a708d734dce9939e9f668cb6708c5dba5d61589b2", size = 5493871, upload-time = "2026-06-25T18:28:39.981Z" },
+ { url = "https://files.pythonhosted.org/packages/66/02/f1744091d59ce71c5523174eb860fbb298275c901e89b9ea6fbf3e654a33/obstore-0.11.0-cp311-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:827113e12fe8088e0281a9d57b90b2b8dbc8a6ffe3b15dadb9baa5feb3d266c1", size = 5361913, upload-time = "2026-06-25T18:28:42.089Z" },
+ { url = "https://files.pythonhosted.org/packages/5d/59/3f47822683ee2b6db8685faa25829946d6343a561251ec2704548455d946/obstore-0.11.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2ff6d3ed553298828fb760b4aef6347fbcc7b5c5e3ce3f8381ce805c370021a", size = 5638724, upload-time = "2026-06-25T18:28:43.897Z" },
+ { url = "https://files.pythonhosted.org/packages/23/50/1df335fdf9b527b3933f1e94ab6fc720ad314260fab8591cb0b6668ff192/obstore-0.11.0-cp311-abi3-manylinux_2_24_aarch64.whl", hash = "sha256:39d04b324fcf984e7050734ebda77b81764025b0c011750201a0d8954087f7aa", size = 5413508, upload-time = "2026-06-25T18:28:45.624Z" },
+ { url = "https://files.pythonhosted.org/packages/de/dc/a259aba149b841ca7c91fea177df9972a60a636b54077beed1a35b254994/obstore-0.11.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:37c0d15d775b1370ef5204ee3919a5ddf7e2592d11815213105f8db031f2ab8d", size = 5619995, upload-time = "2026-06-25T18:28:47.599Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/b4/ec25fdb4d6b060bc6eea647fc0e88f75fcc20fe8d16d67fb0dbe999d323b/obstore-0.11.0-cp311-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:7f468caf9b6e0f12ff151e5fe618de5fc9192befa9bd02734b06de4efd2e49f6", size = 5299512, upload-time = "2026-06-25T18:28:49.629Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/e5/29be060d06ec13e2af3d1b6cfb77b7c37f8be6c56b77295c945fefad73e4/obstore-0.11.0-cp311-abi3-musllinux_1_2_i686.whl", hash = "sha256:42d8e8fad85be8ee488c1a9a9b7c6a42128abb84e67175da40d3d1165c1846df", size = 5427026, upload-time = "2026-06-25T18:28:51.317Z" },
+ { url = "https://files.pythonhosted.org/packages/57/b7/577a965f440e9ea64243518663f9d16be7df8eafc7123818e8e841fa21ce/obstore-0.11.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9c8fd2a544e2e0b926669c47fcfb8d2314e234abc240ea165dae04ee42e1d7ac", size = 5869187, upload-time = "2026-06-25T18:28:53.166Z" },
+ { url = "https://files.pythonhosted.org/packages/e2/18/8fdbaee22bfd5b9c44e1fdff8ca0508e2fe60c42bf9fc85f0c9c27b4ecf2/obstore-0.11.0-cp311-abi3-win_amd64.whl", hash = "sha256:6fb3d4678c0f4242d3109362e9b1df5d7b27765f43d5aacb2e81af53a75cb9ef", size = 5329384, upload-time = "2026-06-25T18:28:55.305Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/8b/7555e48ec768728fcfc71a051c6b28d6ddaf1bececf492ce5ef995aab5f0/obstore-0.11.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:f3132393eff9f3f2b543ecbb3bcc12319a7c433fef06493b4350d6854d505a14", size = 5515763, upload-time = "2026-06-25T18:28:57.527Z" },
+ { url = "https://files.pythonhosted.org/packages/23/8f/94d83f3336421cbb5e436ab0ae5695eae72f7c82990d6b1ac090712c8052/obstore-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a3a8da19b47af4c14ecc694209b3c18ac6d89f96be5656ee3a19b77947c14155", size = 4649491, upload-time = "2026-06-25T18:28:59.386Z" },
+ { url = "https://files.pythonhosted.org/packages/fe/86/11f4e1f51a8c6cf21a5915c018d2357201ad3c5799d418f0c6529fafaab2/obstore-0.11.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e91298b9b6c3a0408c28eece62bca6c5b6cda2f6350351d84e07b4dc8fb2631f", size = 5060659, upload-time = "2026-06-25T18:29:01.139Z" },
+ { url = "https://files.pythonhosted.org/packages/49/e7/fd3036b0923d10e878e2073020f1ef692a618ed1cc3980d3e4a468c93713/obstore-0.11.0-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3422c532486671dfb5e3e739bf15ec9ca2a8da544a3c23b74ae3857dcab1c6a8", size = 5277058, upload-time = "2026-06-25T18:29:02.96Z" },
+ { url = "https://files.pythonhosted.org/packages/2f/a7/b016c3ac6857ac856326dc0a292e3871b8500d03f25f3b90e168b05de357/obstore-0.11.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3de027ce46cf0592c2b41654e2c27dbc52a4a726f6fbc511380acc0da3a9f658", size = 5475852, upload-time = "2026-06-25T18:29:05.032Z" },
+ { url = "https://files.pythonhosted.org/packages/85/9e/644ffe8db7757de7f71f94a036ab24222bccb4de290d3ca69f76547e812d/obstore-0.11.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a80a95548678210bc336b866e37139c293565c3b163eb3fef2433d5d6640a33", size = 5363082, upload-time = "2026-06-25T18:29:06.878Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/0b/26af6b5fa6ba96af84086f44f78b4e5b0af1729c31402d7b28c68989d174/obstore-0.11.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acaa261dc15efb95bbeca06f8fe9b47ee23d7302a6aa1fa3a9654baab8b23d7c", size = 5629116, upload-time = "2026-06-25T18:29:08.771Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/ce/f30d502991c6719b2fbd7b8385ef3e39da07bfca099108bcc5eeed8b9c20/obstore-0.11.0-cp314-cp314t-manylinux_2_24_aarch64.whl", hash = "sha256:a3300cabbc3129670987b3723629c791d83c117ef1b6a0c670c2043648e000a1", size = 5404534, upload-time = "2026-06-25T18:29:11.294Z" },
+ { url = "https://files.pythonhosted.org/packages/52/20/d5bf5f816e868717ba647ed9a2109e800deb402d0265d410456b3fcb4376/obstore-0.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f4e6a9480843645cd4ee122c41d5c5a46a56f1e9cdda85638826f2e0e439fe5c", size = 5613159, upload-time = "2026-06-25T18:29:13.414Z" },
+ { url = "https://files.pythonhosted.org/packages/db/b4/6d4c1c211e3b06cc8554189e0d4406e8fa1f98ed55f9213b8e398a11599f/obstore-0.11.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:9fb2b1814c4314b8903f4e2ebbe8c3365fea6543669615ee9a0288b0d3a2edeb", size = 5286279, upload-time = "2026-06-25T18:29:15.424Z" },
+ { url = "https://files.pythonhosted.org/packages/02/5e/d7b5589424a56171b16ab94cf92eb493490c300aaa044913bbdd94cace68/obstore-0.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:63fb9b072815eafe4705f617f567d896b1c858adcb390795fa1e269367791031", size = 5401780, upload-time = "2026-06-25T18:29:17.514Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/18/841baea8936e51a18b0e5d4c51f09c0a7798cb73b027e9794be2362a0f0b/obstore-0.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:086fafba314ff98cfab1c4bf7814699e862513e8889720cf6f7462296cb32787", size = 5853618, upload-time = "2026-06-25T18:29:19.354Z" },
+ { url = "https://files.pythonhosted.org/packages/83/9a/d6127f5422b78e0222b0a9eadcfd7a5aa8d873a9498da7d4a77d4ac8ce2e/obstore-0.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:676d1154f6f08721110f9b7d14ee3a3c0293abaf9da135bb90f54e276dca1cac", size = 5314113, upload-time = "2026-06-25T18:29:21.209Z" },
]
[[package]]
@@ -2367,24 +1986,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" },
]
-[[package]]
-name = "pandocfilters"
-version = "1.5.1"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454, upload-time = "2024-01-18T20:08:13.726Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663, upload-time = "2024-01-18T20:08:11.28Z" },
-]
-
-[[package]]
-name = "parso"
-version = "0.8.7"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/30/4b/90c937815137d43ce71ba043cd3566221e9df6b9c805f24b5d138c9d40a7/parso-0.8.7.tar.gz", hash = "sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1", size = 401824, upload-time = "2026-05-01T23:13:02.138Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/99/5d/8268b644392ee874ee82a635cd0df1773de230bde356c38de28e298392cc/parso-0.8.7-py2.py3-none-any.whl", hash = "sha256:a8926eb2a1b915486941fdbd31e86a4baf88fe8c210f25f2f35ecec5b574ca1c", size = 107025, upload-time = "2026-05-01T23:12:58.867Z" },
-]
-
[[package]]
name = "pathable"
version = "0.5.0"
@@ -2412,18 +2013,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" },
]
-[[package]]
-name = "pexpect"
-version = "4.9.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "ptyprocess" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" },
-]
-
[[package]]
name = "pillow"
version = "12.2.0"
@@ -2511,18 +2100,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
]
-[[package]]
-name = "prompt-toolkit"
-version = "3.0.52"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "wcwidth" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" },
-]
-
[[package]]
name = "propcache"
version = "0.5.2"
@@ -2640,52 +2217,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/bd/4d/fc923f5c85318ee8cc903566dc4e0ebe41b2dfc1d2ecf5546db232397ed6/properdocs-1.6.7-py3-none-any.whl", hash = "sha256:6fa0cfa2e01bf338f684892c8a506cf70ea88ae7f3479c933b6fa20168101cbd", size = 225406, upload-time = "2026-03-20T20:07:46.875Z" },
]
-[[package]]
-name = "psutil"
-version = "7.2.2"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" },
- { url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" },
- { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" },
- { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" },
- { url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" },
- { url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" },
- { url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" },
- { url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" },
- { url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" },
- { url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" },
- { url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228, upload-time = "2026-01-28T18:15:18.385Z" },
- { url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284, upload-time = "2026-01-28T18:15:19.912Z" },
- { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" },
- { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" },
- { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" },
- { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" },
- { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" },
- { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" },
- { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" },
- { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" },
-]
-
-[[package]]
-name = "ptyprocess"
-version = "0.7.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" },
-]
-
-[[package]]
-name = "pure-eval"
-version = "0.2.3"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" },
-]
-
[[package]]
name = "py-cpuinfo"
version = "9.0.0"
@@ -2858,7 +2389,7 @@ wheels = [
[[package]]
name = "pytest"
-version = "9.0.3"
+version = "9.1.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
@@ -2867,22 +2398,22 @@ dependencies = [
{ name = "pluggy" },
{ name = "pygments" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" },
+ { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" },
]
[[package]]
name = "pytest-accept"
-version = "0.2.3"
+version = "0.3.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "astor" },
{ name = "pytest" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/36/15/37f660ba2b40875324b41d343976962f09c8bef5ba668544236afb424bd7/pytest_accept-0.2.3.tar.gz", hash = "sha256:c747d92ef0bcac0dc20e46f3dfb73b8e9aee970de11b98985868560ca508d06e", size = 25990, upload-time = "2026-03-01T05:00:45.561Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/6f/42/573e6dcd8d1a5fc779d525268d5036f710d018cdeefbae2bd5559687a6d5/pytest_accept-0.3.0.tar.gz", hash = "sha256:6f4e03e2492621e10b7678a331828274498cca04686b15b0f3e704e16e651068", size = 29744, upload-time = "2026-06-11T18:44:39.03Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/27/29/50a8582f90c7d31a9df2ecafb345f6cd3f6a9eaad1b4a94a50ce83eb6ee2/pytest_accept-0.2.3-py3-none-any.whl", hash = "sha256:dad6934349fcd78d31d2f4e0daa372d47f2c11525c7c0802f12c3efe422c8d89", size = 35642, upload-time = "2026-03-01T05:00:44.047Z" },
+ { url = "https://files.pythonhosted.org/packages/06/40/79f6f13e616f580b9c35110376818c76cacc54b70d2965bf1f82be336c66/pytest_accept-0.3.0-py3-none-any.whl", hash = "sha256:5e73f27020853b861a63dc630dfe63124af4bd60e0e0bb692e1376b99798f2b5", size = 39846, upload-time = "2026-06-11T18:44:37.965Z" },
]
[[package]]
@@ -3064,49 +2595,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" },
]
-[[package]]
-name = "pyzmq"
-version = "27.1.0"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "cffi", marker = "implementation_name == 'pypy'" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/92/e7/038aab64a946d535901103da16b953c8c9cc9c961dadcbf3609ed6428d23/pyzmq-27.1.0-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:452631b640340c928fa343801b0d07eb0c3789a5ffa843f6e1a9cee0ba4eb4fc", size = 1306279, upload-time = "2025-09-08T23:08:03.807Z" },
- { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" },
- { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" },
- { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" },
- { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" },
- { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" },
- { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" },
- { url = "https://files.pythonhosted.org/packages/e6/2f/104c0a3c778d7c2ab8190e9db4f62f0b6957b53c9d87db77c284b69f33ea/pyzmq-27.1.0-cp312-abi3-win32.whl", hash = "sha256:250e5436a4ba13885494412b3da5d518cd0d3a278a1ae640e113c073a5f88edd", size = 559184, upload-time = "2025-09-08T23:08:15.163Z" },
- { url = "https://files.pythonhosted.org/packages/fc/7f/a21b20d577e4100c6a41795842028235998a643b1ad406a6d4163ea8f53e/pyzmq-27.1.0-cp312-abi3-win_amd64.whl", hash = "sha256:9ce490cf1d2ca2ad84733aa1d69ce6855372cb5ce9223802450c9b2a7cba0ccf", size = 619480, upload-time = "2025-09-08T23:08:17.192Z" },
- { url = "https://files.pythonhosted.org/packages/78/c2/c012beae5f76b72f007a9e91ee9401cb88c51d0f83c6257a03e785c81cc2/pyzmq-27.1.0-cp312-abi3-win_arm64.whl", hash = "sha256:75a2f36223f0d535a0c919e23615fc85a1e23b71f40c7eb43d7b1dedb4d8f15f", size = 552993, upload-time = "2025-09-08T23:08:18.926Z" },
- { url = "https://files.pythonhosted.org/packages/60/cb/84a13459c51da6cec1b7b1dc1a47e6db6da50b77ad7fd9c145842750a011/pyzmq-27.1.0-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:93ad4b0855a664229559e45c8d23797ceac03183c7b6f5b4428152a6b06684a5", size = 1122436, upload-time = "2025-09-08T23:08:20.801Z" },
- { url = "https://files.pythonhosted.org/packages/dc/b6/94414759a69a26c3dd674570a81813c46a078767d931a6c70ad29fc585cb/pyzmq-27.1.0-cp313-cp313-android_24_x86_64.whl", hash = "sha256:fbb4f2400bfda24f12f009cba62ad5734148569ff4949b1b6ec3b519444342e6", size = 1156301, upload-time = "2025-09-08T23:08:22.47Z" },
- { url = "https://files.pythonhosted.org/packages/a5/ad/15906493fd40c316377fd8a8f6b1f93104f97a752667763c9b9c1b71d42d/pyzmq-27.1.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:e343d067f7b151cfe4eb3bb796a7752c9d369eed007b91231e817071d2c2fec7", size = 1341197, upload-time = "2025-09-08T23:08:24.286Z" },
- { url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05", size = 897275, upload-time = "2025-09-08T23:08:26.063Z" },
- { url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9", size = 660469, upload-time = "2025-09-08T23:08:27.623Z" },
- { url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128", size = 847961, upload-time = "2025-09-08T23:08:29.672Z" },
- { url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39", size = 1650282, upload-time = "2025-09-08T23:08:31.349Z" },
- { url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97", size = 2024468, upload-time = "2025-09-08T23:08:33.543Z" },
- { url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db", size = 1885394, upload-time = "2025-09-08T23:08:35.51Z" },
- { url = "https://files.pythonhosted.org/packages/4f/6f/55c10e2e49ad52d080dc24e37adb215e5b0d64990b57598abc2e3f01725b/pyzmq-27.1.0-cp313-cp313t-win32.whl", hash = "sha256:7ccc0700cfdf7bd487bea8d850ec38f204478681ea02a582a8da8171b7f90a1c", size = 574964, upload-time = "2025-09-08T23:08:37.178Z" },
- { url = "https://files.pythonhosted.org/packages/87/4d/2534970ba63dd7c522d8ca80fb92777f362c0f321900667c615e2067cb29/pyzmq-27.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:8085a9fba668216b9b4323be338ee5437a235fe275b9d1610e422ccc279733e2", size = 641029, upload-time = "2025-09-08T23:08:40.595Z" },
- { url = "https://files.pythonhosted.org/packages/f6/fa/f8aea7a28b0641f31d40dea42d7ef003fded31e184ef47db696bc74cd610/pyzmq-27.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6bb54ca21bcfe361e445256c15eedf083f153811c37be87e0514934d6913061e", size = 561541, upload-time = "2025-09-08T23:08:42.668Z" },
- { url = "https://files.pythonhosted.org/packages/87/45/19efbb3000956e82d0331bafca5d9ac19ea2857722fa2caacefb6042f39d/pyzmq-27.1.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:ce980af330231615756acd5154f29813d553ea555485ae712c491cd483df6b7a", size = 1341197, upload-time = "2025-09-08T23:08:44.973Z" },
- { url = "https://files.pythonhosted.org/packages/48/43/d72ccdbf0d73d1343936296665826350cb1e825f92f2db9db3e61c2162a2/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea", size = 897175, upload-time = "2025-09-08T23:08:46.601Z" },
- { url = "https://files.pythonhosted.org/packages/2f/2e/a483f73a10b65a9ef0161e817321d39a770b2acf8bcf3004a28d90d14a94/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96", size = 660427, upload-time = "2025-09-08T23:08:48.187Z" },
- { url = "https://files.pythonhosted.org/packages/f5/d2/5f36552c2d3e5685abe60dfa56f91169f7a2d99bbaf67c5271022ab40863/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d", size = 847929, upload-time = "2025-09-08T23:08:49.76Z" },
- { url = "https://files.pythonhosted.org/packages/c4/2a/404b331f2b7bf3198e9945f75c4c521f0c6a3a23b51f7a4a401b94a13833/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146", size = 1650193, upload-time = "2025-09-08T23:08:51.7Z" },
- { url = "https://files.pythonhosted.org/packages/1c/0b/f4107e33f62a5acf60e3ded67ed33d79b4ce18de432625ce2fc5093d6388/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd", size = 2024388, upload-time = "2025-09-08T23:08:53.393Z" },
- { url = "https://files.pythonhosted.org/packages/0d/01/add31fe76512642fd6e40e3a3bd21f4b47e242c8ba33efb6809e37076d9b/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a", size = 1885316, upload-time = "2025-09-08T23:08:55.702Z" },
- { url = "https://files.pythonhosted.org/packages/c4/59/a5f38970f9bf07cee96128de79590bb354917914a9be11272cfc7ff26af0/pyzmq-27.1.0-cp314-cp314t-win32.whl", hash = "sha256:1f0b2a577fd770aa6f053211a55d1c47901f4d537389a034c690291485e5fe92", size = 587472, upload-time = "2025-09-08T23:08:58.18Z" },
- { url = "https://files.pythonhosted.org/packages/70/d8/78b1bad170f93fcf5e3536e70e8fadac55030002275c9a29e8f5719185de/pyzmq-27.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:19c9468ae0437f8074af379e986c5d3d7d7bfe033506af442e8c879732bedbe0", size = 661401, upload-time = "2025-09-08T23:08:59.802Z" },
- { url = "https://files.pythonhosted.org/packages/81/d6/4bfbb40c9a0b42fc53c7cf442f6385db70b40f74a783130c5d0a5aa62228/pyzmq-27.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dc5dbf68a7857b59473f7df42650c621d7e8923fb03fa74a526890f4d33cc4d7", size = 575170, upload-time = "2025-09-08T23:09:01.418Z" },
-]
-
[[package]]
name = "referencing"
version = "0.37.0"
@@ -3355,41 +2843,41 @@ wheels = [
[[package]]
name = "ruff"
-version = "0.15.16"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/a6/bd/5f7ec371001337d8fa61701c186ff8b613ecac1651848c5950f4c4d5f2e9/ruff-0.15.16.tar.gz", hash = "sha256:d05e78d38c78caf020b03789e25106c93017db5a0cb6e2819885018c61343b78", size = 4714267, upload-time = "2026-06-04T16:33:09.974Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/0c/42/53ef1c3953f157956db9bf7861e3bc50b9b887ce93300aa48cdba8336fe6/ruff-0.15.16-py3-none-linux_armv6l.whl", hash = "sha256:6ac3c0b3969cc6cf6b158c4e2f8f682acb58e7d700d8a44b65ecdc72d66ab0b2", size = 10709025, upload-time = "2026-06-04T16:32:51.935Z" },
- { url = "https://files.pythonhosted.org/packages/93/9a/a79159346f19134a956607754e57d8d128f7a4c00f4ad2f7514d224c172c/ruff-0.15.16-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:197c207ed75ffba54a0dec23db4aa939a27a3053073e085e0042433cbdc58e4a", size = 11063550, upload-time = "2026-06-04T16:32:42.24Z" },
- { url = "https://files.pythonhosted.org/packages/bc/72/3ce2ac000a5299ec238e01f51397b3b653c93b077d9b1bfe8715bb895f20/ruff-0.15.16-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3a39fec45ab316cc23e7558f23fea4a70403ddb5648ea9a4a3854a16973d0071", size = 10421345, upload-time = "2026-06-04T16:32:37.251Z" },
- { url = "https://files.pythonhosted.org/packages/b0/c2/cc7fad3ec9169373f5b6a18f1917b91080feec40c3f9658334a1d28e2f03/ruff-0.15.16-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba93191d79003116b95128c9d306e045200fdbd0bccb782b110f3cd1d4abc5cf", size = 10757217, upload-time = "2026-06-04T16:32:54.722Z" },
- { url = "https://files.pythonhosted.org/packages/69/d2/3474009eaa0a65b31fa7152a2fad5e2f050c640ceb1e6b02ee6922e94c82/ruff-0.15.16-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c6ee4b90520630120ef032aa5cc10db483852dff950e78b1d717e2993a61ac8d", size = 10507035, upload-time = "2026-06-04T16:33:05.343Z" },
- { url = "https://files.pythonhosted.org/packages/ca/81/b7ae6ccbd11f0c8dc3d5d67fc4be9b57ff57ca86ba56152021378e1277f2/ruff-0.15.16-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e4215bc938bc3c8215c1472c1aa437e310fee20cd427335fec9d7e609563628", size = 11255291, upload-time = "2026-06-04T16:32:49.49Z" },
- { url = "https://files.pythonhosted.org/packages/d9/e1/46e526f1a7cc90857ce6ddf25fbb77eb6568651ac38d71b033af07076dd5/ruff-0.15.16-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7c8d26be963b090f10e29abc8b3e74a2a321f6fa34e02424e30b5af89350ecbb", size = 12124922, upload-time = "2026-06-04T16:33:07.821Z" },
- { url = "https://files.pythonhosted.org/packages/1a/da/5c791b088b596b24d0deb967fa28ae02ad751a140c0b9ea81c5ab915d6c0/ruff-0.15.16-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f198cf4123602a2280ed46c307bcbafe41758d6fee5b456b6b6058ca1514b3b4", size = 11332186, upload-time = "2026-06-04T16:33:02.971Z" },
- { url = "https://files.pythonhosted.org/packages/72/11/5da87abe20047c8962361473923ebb2f62b595250126aadfad8c20649c1e/ruff-0.15.16-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb27515fa6240fb586ae82b901a59e67d24acff86f2190b433dc542fe0435aeb", size = 11373541, upload-time = "2026-06-04T16:32:47.007Z" },
- { url = "https://files.pythonhosted.org/packages/fe/2a/8554754c23a854ae3fd6b507e36ad61ddb121e298c6d5d617dec94ed0f14/ruff-0.15.16-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:a267c46ba1593fc26b8eecbea050b39d40c0b6bb7781ee11c90a02cd10032951", size = 11353014, upload-time = "2026-06-04T16:32:34.795Z" },
- { url = "https://files.pythonhosted.org/packages/62/25/62ea41529ec89f742ea3fed9cb1059c72877ec7cf9b9e99ac9cf3294d1d9/ruff-0.15.16-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:528c68f39a91498a8d50e91ff5985df3d105782bab49cc378e73ac26bff083e8", size = 10737467, upload-time = "2026-06-04T16:32:26.348Z" },
- { url = "https://files.pythonhosted.org/packages/90/17/334d3ad9de4d40f9dd58fdd09e35ce64553bb501e2f19a839e2fb6be14fc/ruff-0.15.16-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7ed55c58950df60589a9a7a5d2f8fa5f54ebd287163be805adfe6ee95a9de123", size = 10521910, upload-time = "2026-06-04T16:32:32.54Z" },
- { url = "https://files.pythonhosted.org/packages/4d/bd/3ac7c6ae77a885c1004b3dda2446ea401768d24f851c14b4ad4b24f6639c/ruff-0.15.16-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d482feaf51512b50f9790ceb417a56a61dd1e9d9bf967662b9ed27c01b34f53a", size = 10979190, upload-time = "2026-06-04T16:32:57.492Z" },
- { url = "https://files.pythonhosted.org/packages/33/d7/609546e6a413c3f216fbf2a50c928f97c80939154f6a0503114094a86191/ruff-0.15.16-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1e15bc8c94513dae2a40cc9ef07c94fdd4ecc9e29dabebeebe170f952322c9e3", size = 11477014, upload-time = "2026-06-04T16:32:44.687Z" },
- { url = "https://files.pythonhosted.org/packages/74/0d/f2cd247ad32633a5c36e97141a2c21b11c6279f7957bc2ff360b1e08fddd/ruff-0.15.16-py3-none-win32.whl", hash = "sha256:580378f7bd4aa25f72e74aa54948a9622f142b1e509521dd10902e886681cc1e", size = 10735541, upload-time = "2026-06-04T16:32:30.145Z" },
- { url = "https://files.pythonhosted.org/packages/8b/9e/02e845ef151b1dee585e55c4739f8e1734ae1d9f1221dff65761c162208b/ruff-0.15.16-py3-none-win_amd64.whl", hash = "sha256:408256017284eddf98fff77b29aa4fb30f586042d535b2d9befc6512f400aaec", size = 11843403, upload-time = "2026-06-04T16:32:39.76Z" },
- { url = "https://files.pythonhosted.org/packages/15/19/016553f86f207450aebebc2b2b5088d086b901cc8186c02ac4284db3bd88/ruff-0.15.16-py3-none-win_arm64.whl", hash = "sha256:8cd61783afb39638a7133ef0d2dfb1e91277593962f81b5a8423eb0b888a6121", size = 11134555, upload-time = "2026-06-04T16:33:00.136Z" },
+version = "0.15.20"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/43/dc/35b341fc554ba02f217fc10da57d1a75168cfbcf75b0ef2202176d4c4f2d/ruff-0.15.20.tar.gz", hash = "sha256:1416eb04349192646b54de98f146c4f59afe37d0decfc02c3cbbf396f3a28566", size = 4755489, upload-time = "2026-06-25T17:20:37.578Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/94/d9/2d5014f0253ba541d2061d9fa7193f48e941c8b21bb88a7ff9bbe0bd0596/ruff-0.15.20-py3-none-linux_armv6l.whl", hash = "sha256:00e188c53e499c3c1637f73c91dcf2fb56d576cab76ce1be50a27c4e80e37078", size = 10839665, upload-time = "2026-06-25T17:19:44.702Z" },
+ { url = "https://files.pythonhosted.org/packages/c6/d3/ac1798ba64f670698867fcfc591d50e7e421bef137db564858f619a30fcf/ruff-0.15.20-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9ebd1fd9b9c95fc0bd7b2761aebec1f030013d2e193a2901b224af68fe47251b", size = 11208649, upload-time = "2026-06-25T17:19:48.787Z" },
+ { url = "https://files.pythonhosted.org/packages/47/47/d3ac899991202095dfcf3d5176be4272642be3cf981a2f1a30f72a2afb95/ruff-0.15.20-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c5b16cdd67ca108185cd36dce98c576350c03b1660a751de725fb049193a0632", size = 10622638, upload-time = "2026-06-25T17:19:51.354Z" },
+ { url = "https://files.pythonhosted.org/packages/33/13/4e043fe30aa94d4ff5213a9881fc296d12960f5971b234a5263fdc225312/ruff-0.15.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3413bb3c3d2ca6a8208f1f4809cd2dca3c6de6d0b491c0e70847672bde6e6efd", size = 10984227, upload-time = "2026-06-25T17:19:54.044Z" },
+ { url = "https://files.pythonhosted.org/packages/76/e6/92e7bf40388bc5800073b96564f56264f7e48bfd1a498f5ced6ae6d5a769/ruff-0.15.20-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd7ec42b3bb3da066488db093308a69c4ac5ee6d2af333a86ba6e2eb2e7dd44b", size = 10622882, upload-time = "2026-06-25T17:19:57.037Z" },
+ { url = "https://files.pythonhosted.org/packages/13/7a/43460be3f24495a3aa46d4b16873e2c4941b3b5f0b00cf88c03b7b94b339/ruff-0.15.20-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1a36ad0eb77fba9aabfb69ede54de6f376d04ac18ebea022847046d340a8267", size = 11474808, upload-time = "2026-06-25T17:20:00.357Z" },
+ { url = "https://files.pythonhosted.org/packages/27/a0/f37077884873221c6b33b4ab49eb18f9f88e54a16a25a5bca59bef46dd66/ruff-0.15.20-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b6df3b1e4610432f0386dba04d853b5f08cbbc903410c6fcc02f620f05aff53c", size = 12293094, upload-time = "2026-06-25T17:20:03.446Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/74/165545b60256a9704c21ac0ec4a0d07933b320812f9584836c9f4aca4292/ruff-0.15.20-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e89f198a1ea6ef0d727c1cf16088bc91a6cb0ab947dedc966715691647186eae", size = 11526176, upload-time = "2026-06-25T17:20:06.301Z" },
+ { url = "https://files.pythonhosted.org/packages/86/b1/a976a136d40ade83ce743578399865f57001003a409acadc0ecbb3051082/ruff-0.15.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309809086c2acb67624950a3c8133e80f32d0d3e27106c0cd60ff26657c9f24b", size = 11520767, upload-time = "2026-06-25T17:20:09.191Z" },
+ { url = "https://files.pythonhosted.org/packages/19/0f/f032696cb01c9b54c0263fa393474d7758f1cdc021a01b04e3cbc2500999/ruff-0.15.20-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2d2374caa2f2c2f9e2b7da0a50802cfb8b79f55a9b5e49379f564544fbf56487", size = 11500132, upload-time = "2026-06-25T17:20:13.602Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/f4/51b1a14bc69e8c224b15dab9cce8e99b425e0455d462caa2b3c9be2b6a8e/ruff-0.15.20-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a1ed17b65293e0c2f22fc387bc13198a5de94bf4429589b0ff6946b0feaf21a3", size = 10943828, upload-time = "2026-06-25T17:20:16.635Z" },
+ { url = "https://files.pythonhosted.org/packages/71/4b/fe267640783cd02bf6c5cc290b1df1051be2ec294c678b5c15fe19e52343/ruff-0.15.20-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:f701305e66b38ea6c91882490eb73459796808e4c6362a1b765255e0cdcd4053", size = 10645418, upload-time = "2026-06-25T17:20:19.4Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/c0/a65aa4ec2f5e87a1df32dc3ec1fede434fe3dfd5cbcf3b503cafc676ab54/ruff-0.15.20-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5b9c0c367ad8e5d0d5b5b8537864c469a0a0e55417aadfbeca41fa61333be9f4", size = 11211770, upload-time = "2026-06-25T17:20:22.033Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/a4/0caa331d954ae2723d729d351c989cb4ca8b6077d5c6c2cb6de75e98c041/ruff-0.15.20-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:01cc00dd58f0df339d0e902219dd53990ea99996a0344e5d9cc8d45d5307e460", size = 11618698, upload-time = "2026-06-25T17:20:25.259Z" },
+ { url = "https://files.pythonhosted.org/packages/10/9b/5f14927848d2fd4aa891fd88d883788c5a7baba561c7874732364045708c/ruff-0.15.20-py3-none-win32.whl", hash = "sha256:ed65ef510e43a137207e0f01cfcf998aeddb1aeeda5c9d35023e910284d7cf21", size = 10857322, upload-time = "2026-06-25T17:20:28.612Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/f0/fe47c501f9dea92a26d788ff98bb5d92ed4cb4c88792c5c88af6b697dc8e/ruff-0.15.20-py3-none-win_amd64.whl", hash = "sha256:a525c81c70fb0380344dd1d8745d8cc1c890b7fc94a58d5a07bd8eb9557b8415", size = 11993274, upload-time = "2026-06-25T17:20:31.871Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/2b/9555445e1201d92b3195f45cdb153a0b68f24e0a4273f6e3d5ab46e212bb/ruff-0.15.20-py3-none-win_arm64.whl", hash = "sha256:2f5b2a6d614e8700388806a14996c40fab2c47b819ef57d790a34878858ed9ca", size = 11343498, upload-time = "2026-06-25T17:20:35.03Z" },
]
[[package]]
name = "s3fs"
-version = "2026.4.0"
+version = "2026.6.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "aiobotocore" },
{ name = "aiohttp" },
{ name = "fsspec" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/cb/d8/76f3dc1558bdf4494b117a9f7a9cc0a5d9d34edadc9e5d7ceabc5a6a7c37/s3fs-2026.4.0.tar.gz", hash = "sha256:5bdce0abb00b0435ee150807a45fea727451dbc22de4cbc116464f8504ab9d37", size = 85986, upload-time = "2026-04-29T20:52:51.748Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/99/00/6677343dc919d6c072bb04d80210afdd22c16838a8d16b3315c122dc728f/s3fs-2026.6.0.tar.gz", hash = "sha256:b28de7082d0a4f72392884bdc497e34a4a1582f675d214c7da0acf6e950a0083", size = 87358, upload-time = "2026-06-16T02:05:48.719Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/5d/a4/9d1ea10ebc9e028a289a72fec84da170689549a8102c8aacfcad26bc5035/s3fs-2026.4.0-py3-none-any.whl", hash = "sha256:de0d2a1f33cdf03831fd2382d278c6e4e31fe57c3bf2f703c61f8aec6b703e2a", size = 32392, upload-time = "2026-04-29T20:52:50.295Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/0b/f68a968b49876eae0f2a515387093cebb2eb9451380a96741cc20efac0d0/s3fs-2026.6.0-py3-none-any.whl", hash = "sha256:60576e31bb31193c1f643f32b4c6439548720ea6918ac702e21cd757c80b5db8", size = 32573, upload-time = "2026-06-16T02:05:47.608Z" },
]
[[package]]
@@ -3449,15 +2937,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" },
]
-[[package]]
-name = "soupsieve"
-version = "2.8.3"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" },
-]
-
[[package]]
name = "sphinx"
version = "9.1.0"
@@ -3540,20 +3019,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072, upload-time = "2024-07-29T01:10:08.203Z" },
]
-[[package]]
-name = "stack-data"
-version = "0.6.3"
-source = { registry = "https://pypi.org/simple" }
-dependencies = [
- { name = "asttokens" },
- { name = "executing" },
- { name = "pure-eval" },
-]
-sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" },
-]
-
[[package]]
name = "sympy"
version = "1.14.0"
@@ -3587,23 +3052,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/6a/43/8bd850ee71a191bf072e31302c73a66be413fecdd98fdcd111ecbcce13ca/tomlkit-0.15.0-py3-none-any.whl", hash = "sha256:4dbc8f0fc024412b57ced8757ac7461305126a648ff8c2c807fcb8e133a78738", size = 41328, upload-time = "2026-05-10T07:38:23.517Z" },
]
-[[package]]
-name = "tornado"
-version = "6.5.7"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/64/24/95ec527ad67b76d59299e5465b3935d05e4294b7e0290a3924b7487df30b/tornado-6.5.7.tar.gz", hash = "sha256:66c513a76cda70d53907bc27cf1447557699c2e95aa48ba27a442ff61c3ddfc2", size = 519252, upload-time = "2026-06-08T17:34:51.232Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/02/dc/c7043cab6fed8ae159fc1923ce829ada35c4dbd797d408a43858ffaf9639/tornado-6.5.7-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:148b2eb15c2c765a50796172c1e499649b35f30d2e3c3d3e15913cfa56bfb163", size = 448543, upload-time = "2026-06-08T17:34:38.052Z" },
- { url = "https://files.pythonhosted.org/packages/92/4f/090b1431e5a43df696feceffc268c5383cc079ecb5f08ce58f917109aafe/tornado-6.5.7-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9da38de27f1da3b78a966f0dae12b5a1ea9afe72ca805d84ff06508272ddf100", size = 446707, upload-time = "2026-06-08T17:34:39.594Z" },
- { url = "https://files.pythonhosted.org/packages/37/d8/ef374952fd5da67d4463122c2b8e5a96536ec10b4b339254c6dcde81d01c/tornado-6.5.7-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8d759e71906ee783f8867b93bf26a265743da4c1e2f4a018464c1ba019862972", size = 449774, upload-time = "2026-06-08T17:34:41.204Z" },
- { url = "https://files.pythonhosted.org/packages/35/37/d434c73f4c6e014b745b9b37085f34f40c022f007efff3d7fe65991899f3/tornado-6.5.7-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a46347a18f23fb92b396beebe0fb78f61dda0cc302445202c16203d8a18848b", size = 450745, upload-time = "2026-06-08T17:34:42.531Z" },
- { url = "https://files.pythonhosted.org/packages/b6/2b/56b9aff361d7f1ab728a805ec7d7ea835f8807afa9f5cc690ea0e630efb9/tornado-6.5.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7778b30bef919231265e91c69963ce0f49a1e9c07ac900bbe75b19ce2575ba92", size = 450578, upload-time = "2026-06-08T17:34:43.787Z" },
- { url = "https://files.pythonhosted.org/packages/02/30/a7444fb23aa76860a14198fab96ac79f1866b0a6e19e26c4381b0938e50f/tornado-6.5.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e726f0c75da7726eec023aa62751ff8878bd2737e34fbdd33b1ae5897d2200f5", size = 449985, upload-time = "2026-06-08T17:34:45.326Z" },
- { url = "https://files.pythonhosted.org/packages/5c/42/5f0e56c01e8d9d36f4e23f367b85ae6cae0c1ecddd5e6977d8388ad27488/tornado-6.5.7-cp39-abi3-win32.whl", hash = "sha256:f8de3bf12d3efdd0cbe7c8887868198f8a91415e3f29fcf258d9b8eb7b1d9ae4", size = 451047, upload-time = "2026-06-08T17:34:46.784Z" },
- { url = "https://files.pythonhosted.org/packages/c9/a4/b393076ffb21b469eec5b328a0534cf03a3b90bfc6b1f09507cdd075d938/tornado-6.5.7-cp39-abi3-win_amd64.whl", hash = "sha256:de942f843533a039ef9fa3d9c88c7cd8a7c94553fb5ad0154270989b3d99a2c4", size = 451485, upload-time = "2026-06-08T17:34:48.248Z" },
- { url = "https://files.pythonhosted.org/packages/71/2e/7b1c769803121b809112cf9a00681c472eae1d80e32d7ec0e0bd61d0d0e1/tornado-6.5.7-cp39-abi3-win_arm64.whl", hash = "sha256:ff934fce95643af5f11efdae618eaa73d469dc588641e5c8d19295a0c65c4796", size = 450506, upload-time = "2026-06-08T17:34:49.702Z" },
-]
-
[[package]]
name = "towncrier"
version = "25.8.0"
@@ -3617,18 +3065,9 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/42/06/8ba22ec32c74ac1be3baa26116e3c28bc0e76a5387476921d20b6fdade11/towncrier-25.8.0-py3-none-any.whl", hash = "sha256:b953d133d98f9aeae9084b56a3563fd2519dfc6ec33f61c9cd2c61ff243fb513", size = 65101, upload-time = "2025-08-30T11:41:53.644Z" },
]
-[[package]]
-name = "traitlets"
-version = "5.15.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/1b/22/40f55b26baeab80c2d7b3f1db0682f8954e4617fee7d90ce634022ef05c6/traitlets-5.15.0.tar.gz", hash = "sha256:4fead733f81cf1c4c938e06f8ca4633896833c9d89eff878159457f4d4392971", size = 163197, upload-time = "2026-05-06T08:05:58.016Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/da/98/a9937a969d018a23badfea0b381f66783649d48e0ea6c41923265c3cbeb3/traitlets-5.15.0-py3-none-any.whl", hash = "sha256:fb36a18867a6803deab09f3c5e0fa81bb7b26a5c9e82501c9933f759166eff40", size = 85877, upload-time = "2026-05-06T08:05:55.853Z" },
-]
-
[[package]]
name = "typer"
-version = "0.26.7"
+version = "0.26.8"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "annotated-doc" },
@@ -3636,18 +3075,18 @@ dependencies = [
{ name = "rich" },
{ name = "shellingham" },
]
-sdist = { url = "https://files.pythonhosted.org/packages/5e/ed/ef06584ccdd5c410df0837951ecd7e15d9a6144ea1bd4c73cecab1a89891/typer-0.26.7.tar.gz", hash = "sha256:e314a34c617e419c091b2830dda3ea1f257134ff593061a8f5b9717ab8dddb3a", size = 201709, upload-time = "2026-06-03T07:18:06.843Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/7c/f7/68adc395201b20b872d68e975386832e8005ffeacedd43a1d837a32815be/typer-0.26.8.tar.gz", hash = "sha256:c244a6bd558886fe3f8780efb6bdd28bb9aff005a94eedebaa5cb32926fe2f7e", size = 202097, upload-time = "2026-06-26T09:22:45.705Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/24/25/2201973529af2c954de0bb725323c3aaed6d7f0ceee8f550dec9185df013/typer-0.26.7-py3-none-any.whl", hash = "sha256:5c87cfbc5d34491c5346ebf49c23e18d56ccb863268d3a8d592b26087c2f5e58", size = 122456, upload-time = "2026-06-03T07:18:05.732Z" },
+ { url = "https://files.pythonhosted.org/packages/80/87/b9fd69c92c6102a066e1b86a35243f53e70bd4c709f2a26d9f4fee4f4dc0/typer-0.26.8-py3-none-any.whl", hash = "sha256:3512ca79ac5c11113414b36e80281b872884477722440691c89d1112e321a49c", size = 122564, upload-time = "2026-06-26T09:22:44.72Z" },
]
[[package]]
name = "typing-extensions"
-version = "4.15.0"
+version = "4.16.0"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
+ { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" },
]
[[package]]
@@ -3686,28 +3125,28 @@ wheels = [
[[package]]
name = "uv"
-version = "0.11.20"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/80/09/c29c0b90bc9308cfa6f5d77ce9b38ce97852210fda17d79019c7bcf9c3a1/uv-0.11.20.tar.gz", hash = "sha256:a246f30931cbc93d0a39d0cfc75be045fddd45773a734ddf8afa869aabc46c63", size = 4237464, upload-time = "2026-06-10T17:20:05.905Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/6b/8a/25fc4d94ad3896e636466ee1fb03c4077f7a151c19cb25c1e6a731fa9cbf/uv-0.11.20-py3-none-linux_armv6l.whl", hash = "sha256:f867fd0807e39653fd101e16f2292ff488de14b5ffbb86a5678a87a27aa58ea0", size = 23713010, upload-time = "2026-06-10T17:19:32.058Z" },
- { url = "https://files.pythonhosted.org/packages/02/7d/bbaad5f0c616f7824149a4ac0271db14107b859b36bd75d16db1486c495f/uv-0.11.20-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f3bacc52778775cef671867ddab744b50c4183bc3cd6419a5fb4eb01a02f9526", size = 22918378, upload-time = "2026-06-10T17:19:20.828Z" },
- { url = "https://files.pythonhosted.org/packages/39/3e/e3d39361b95c262b43ccfe260f41184da71c536a08f39d4ad59ab962e459/uv-0.11.20-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c9f2062096e146b351fd5da3cd43e15a5c43bfa37166c509d884dab3dbb72f03", size = 21716975, upload-time = "2026-06-10T17:19:51.552Z" },
- { url = "https://files.pythonhosted.org/packages/24/30/9031204d7b592d1595322d7506944793728a74795a8c4a3c38bc4a8985f0/uv-0.11.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:8fe143572a1f02d536c4e9c6994f0c89d9fa58ff6e5d91de55f61660658c694b", size = 23571826, upload-time = "2026-06-10T17:19:46.206Z" },
- { url = "https://files.pythonhosted.org/packages/98/c3/7f9f00c7a152e67d59ae5f25635d19ac4252929dd6ac454cdb1dee3119fa/uv-0.11.20-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:3d00754be09a381030829526f7ff47c06d0e28ca90760c4439be48e71c1bf13a", size = 23249218, upload-time = "2026-06-10T17:19:26.603Z" },
- { url = "https://files.pythonhosted.org/packages/35/a9/1ce58670a89c25d4a8b84532207183b5a97b3623d9b9151afe641499fbc8/uv-0.11.20-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:edb59d33e602fc462b6ed8fde66d404445294de41ad4de31039f7a2c41153601", size = 23302149, upload-time = "2026-06-10T17:20:01.111Z" },
- { url = "https://files.pythonhosted.org/packages/61/cf/3a498a315364f906bd655a94fa6b5f74f5240dc90875d6ab67ef28c081ec/uv-0.11.20-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14026b64ccbe0174e4fcf107f585f5d23f0f5b9f5b3e8b28394fe63fff3e60ff", size = 24652804, upload-time = "2026-06-10T17:19:16.692Z" },
- { url = "https://files.pythonhosted.org/packages/ff/8c/68e4a805e3b49d834e95b3838e53a623d2e0ad956bb44e681ece54b3308b/uv-0.11.20-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73dcaf5543d1b24e4c6fa4c19af033ed015304171c132670ebe9ef01ddec3d17", size = 25660209, upload-time = "2026-06-10T17:20:08.156Z" },
- { url = "https://files.pythonhosted.org/packages/a6/de/e8e205a79b9a39454c5da5c2695e4911a42860a4404739e32802e599af0c/uv-0.11.20-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cac8ca5d187dc5040b1c22c83f6ed789195c3fc06b6a5a2b32c747c603f07820", size = 24866467, upload-time = "2026-06-10T17:19:37.981Z" },
- { url = "https://files.pythonhosted.org/packages/7e/38/f844d125db277d8ce0c921f0219078d292d0ee72d314d0c12f4cf510aa40/uv-0.11.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61588768f04a24b0b4d87b43f03b4521ba66d5eec3ab1aca37cb59b1d52337db", size = 24957448, upload-time = "2026-06-10T17:19:40.979Z" },
- { url = "https://files.pythonhosted.org/packages/ab/7d/b0e28abfa41c424d2a3df83be2b00b2fbe3ad5795baf7361262c6d800a62/uv-0.11.20-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:2d307d47b1a0cf8f76aa69bde850be407bca9482c13cff066142e586a5c57e77", size = 23671087, upload-time = "2026-06-10T17:19:54.595Z" },
- { url = "https://files.pythonhosted.org/packages/80/ff/92bce88101ce61d708e888db6ab7f5ebf4ccd61f54d3316e7e48a4be56a5/uv-0.11.20-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:bb5839cbb68d7469925fe1599dacd16cefdb7698a7adeaf9c8e4d8a7cd4122bf", size = 24324677, upload-time = "2026-06-10T17:19:43.534Z" },
- { url = "https://files.pythonhosted.org/packages/0f/90/d308bd88c7a53cae93f7fe13ce5c621895b8fb94e37911660a3de7283b67/uv-0.11.20-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:efefbd491ba443b326fdd344d7efc89c1de8a006cab5bc639a4d5ce9d1dd1ab9", size = 24429959, upload-time = "2026-06-10T17:19:29.352Z" },
- { url = "https://files.pythonhosted.org/packages/e5/e6/b87c941b93b61dceaa11f4f8d02760de7aa7d1c58ea24a2298e7c5aafb4f/uv-0.11.20-py3-none-musllinux_1_1_i686.whl", hash = "sha256:daa41b97386699212b2266a80c178140c5396e3c444ff5553f68f79812334e41", size = 23880515, upload-time = "2026-06-10T17:19:23.733Z" },
- { url = "https://files.pythonhosted.org/packages/53/ab/11b07641f8387177889f4341a36318561208c18703837bc47163244aa11b/uv-0.11.20-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:37ca61eddb940d1c698fce46d63789adfda3033344dabab0e18e2958e1a69771", size = 25171603, upload-time = "2026-06-10T17:19:34.848Z" },
- { url = "https://files.pythonhosted.org/packages/b4/7d/62af57509c7007600ce11cd5222b2cb84d5cd8f80f427a499d1b44ef3601/uv-0.11.20-py3-none-win32.whl", hash = "sha256:32893ee9f94657fbf89e22638ac88850db4529d454f102bfa7ceea5fc9fe8d77", size = 22570328, upload-time = "2026-06-10T17:19:48.808Z" },
- { url = "https://files.pythonhosted.org/packages/66/35/c9ee48cdce11f5cdac9e2be41a5446bae7382cde18d2ce1050bcd81dc05a/uv-0.11.20-py3-none-win_amd64.whl", hash = "sha256:4836044213bb23a3be1f5550db340d3a19babe1dfc3ca1313544e8b614085ce9", size = 25228859, upload-time = "2026-06-10T17:19:57.824Z" },
- { url = "https://files.pythonhosted.org/packages/8b/8d/00a382c2f8f44b328cf98f734a3fcd72957698c30bed2392bd241b573384/uv-0.11.20-py3-none-win_arm64.whl", hash = "sha256:442ae26f47bf6e58b072e99dbfd6d5296ab90308574b2c02adff1dace051008d", size = 23664943, upload-time = "2026-06-10T17:20:03.774Z" },
+version = "0.11.26"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d0/cb/5efc713948ddb10b00abfb51bfd429221c720175557f9c7965fea2448fe4/uv-0.11.26.tar.gz", hash = "sha256:2a433ece2ace088dd572d8abb0e6bd9a4ecb0e10bc9856447bbb37545f384f29", size = 4331220, upload-time = "2026-06-30T14:52:03.77Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c2/71/86dbffac9e26df28a16639c426cf4ba572aaf43d9231463e0dca337895b2/uv-0.11.26-py3-none-linux_armv6l.whl", hash = "sha256:fb97bf04512dfe16d86084e75d8129701fc8da9fb40de8746b73c3aa617c5897", size = 25197324, upload-time = "2026-06-30T14:50:51.75Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/80/525b73c8188e7052343e7109466a08fcd5195055aff4b0346ce3622e48cb/uv-0.11.26-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a58a06e5a4b0035538d3ab4160ad74c716076ea7148eb3317171c6276ac020b4", size = 24179172, upload-time = "2026-06-30T14:50:56.52Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/5e/cf7b94ed3b1932c2a62573dcd388ad6c1da5c52111cd71ab7f20faa4a0aa/uv-0.11.26-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7b6d078d2ce83897884c2330c0676f27be4bf3d223fb2a409460f579fb5f0a98", size = 22949576, upload-time = "2026-06-30T14:51:00.538Z" },
+ { url = "https://files.pythonhosted.org/packages/bf/fd/71fa021f6909c4139d8354bea623b5e0ef0ce4a08da250da1a1645528da2/uv-0.11.26-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:1cd9ba4951681ce17f1703106266fcbe27aaa7d37f07d53cce8b5686d68a8755", size = 24936673, upload-time = "2026-06-30T14:51:04.496Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/5e/273425e58a8812423e3d1f6c5da1015e636fbf13a83d104317ca37e16304/uv-0.11.26-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:e4f4c3268e69ac96f01972274a62f5f930c03cbc680adba6f21e63237ba3a639", size = 24719617, upload-time = "2026-06-30T14:51:08.419Z" },
+ { url = "https://files.pythonhosted.org/packages/81/f8/1601e2acc7c54963814b4831eab996d8599e690712722c5acec5114860be/uv-0.11.26-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:efcbe0e187846f5ddba23bcaed17e4f9cd2463da5c45bdb5869616f686d713ff", size = 24734176, upload-time = "2026-06-30T14:51:12.685Z" },
+ { url = "https://files.pythonhosted.org/packages/88/d2/a8a422e54c08cf4b8d51bedb9dbdd3cc233aa290ad8b3ee0438c0c02a3a5/uv-0.11.26-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:120ab2de93164d08cf5950f7fe18cbebe3ff670865ae41a292452bab2346477f", size = 26158780, upload-time = "2026-06-30T14:51:16.514Z" },
+ { url = "https://files.pythonhosted.org/packages/db/e6/647fe5fdc888a3d27f79977877ce4e88052fe9be5398371e51bb134fc262/uv-0.11.26-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9052bf27c7ee426901f35a48715fa9288ce631c1878b91c9a6c950288f4b8633", size = 27009550, upload-time = "2026-06-30T14:51:20.659Z" },
+ { url = "https://files.pythonhosted.org/packages/72/c2/85d8e762ad83b0f14fae2255b0578c4fd7dc915746f81b64ed786342627a/uv-0.11.26-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:efdddfcc9b1b790c5f7985c5c183c851682ced165b44ffa914f4947f5cad1fbf", size = 26183777, upload-time = "2026-06-30T14:51:24.715Z" },
+ { url = "https://files.pythonhosted.org/packages/d3/00/478c3a870dcac690b8c337ee950a60a952e817f574945e85155c3cc0ab34/uv-0.11.26-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dcf4e0b5b5cbdc242dcb002f1f8d99e7cf8c043609869228a9ce15e095c0b18", size = 26260589, upload-time = "2026-06-30T14:51:28.809Z" },
+ { url = "https://files.pythonhosted.org/packages/a7/51/e4e43e106fb8cdc026b97491ea4600f4194a9c4da0b4e4e30c2a7dceb268/uv-0.11.26-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:866ae8d28f7381c15de0906a284c1e97916424c635bf40f7960b3fc889cd725e", size = 25073850, upload-time = "2026-06-30T14:51:32.717Z" },
+ { url = "https://files.pythonhosted.org/packages/f2/c2/e772b7e6c8a835e8bf6739a391cdfc8e8e244c5c496d9b40625068b59ff4/uv-0.11.26-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:22f6d62e794b252ff3a1e2dfe5010cc76208f90b2c906e54971a0223ad6f16bc", size = 25682609, upload-time = "2026-06-30T14:51:36.888Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/69/ea77209a224a23a399cb7f6414f77ef032bd9e083e01199a0ebebf0d3ff2/uv-0.11.26-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:edd0c12b75141a6d830d138a91e366ad66e630f1c1dcaf83b8325b80cbacfcbb", size = 25800556, upload-time = "2026-06-30T14:51:40.937Z" },
+ { url = "https://files.pythonhosted.org/packages/77/60/b6c0c03d2538a016b6624fa251960012e564ea02f841e958c7d60e974685/uv-0.11.26-py3-none-musllinux_1_1_i686.whl", hash = "sha256:af6a45b11a569cc4d2437e89a25a53dcf753f2a02a8f2de96be09b9b942cb3ec", size = 25385658, upload-time = "2026-06-30T14:51:45.103Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/e7/46881ff9164aa2e7c649901837d58eee3c57beb3b0fcc0fea6a4e40cf8f3/uv-0.11.26-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:c28822517d03aebbe9549aaaecc88ad580e4b2b6a927abffe5774a74d6ba09f6", size = 26551013, upload-time = "2026-06-30T14:51:49.062Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/94/380dad6c2bbe12417025aacd12cfc08322ed4c9dd8f760bff7035b86f22d/uv-0.11.26-py3-none-win32.whl", hash = "sha256:79e5c1b3410047e1962290c3b7b8f512d2c1bb95200c60b016f7729287cf34c0", size = 23947180, upload-time = "2026-06-30T14:51:53.065Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/13/9c588226d5b478328d739e654944430719f3ffe8999d6a24d425ec9664ab/uv-0.11.26-py3-none-win_amd64.whl", hash = "sha256:d95567e9470dc48ff03265f420c3c6973f6437f18a79d5e00b6eb4b2d9379907", size = 26909320, upload-time = "2026-06-30T14:51:57.235Z" },
+ { url = "https://files.pythonhosted.org/packages/21/1d/ea66b12813878797126e2b3aca124b1c9c5ef53120702d1c00172f90a21d/uv-0.11.26-py3-none-win_arm64.whl", hash = "sha256:7e69d1569afbb936e7bf4e4ab2f72d606405f4a68f380f088a0b2233e84e056a", size = 25176820, upload-time = "2026-06-30T14:52:01.05Z" },
]
[[package]]
@@ -3743,15 +3182,6 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" },
]
-[[package]]
-name = "wcwidth"
-version = "0.7.0"
-source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/2c/ee/afaf0f85a9a18fe47a67f1e4422ed6cf1fe642f0ae0a2f81166231303c52/wcwidth-0.7.0.tar.gz", hash = "sha256:90e3a7ea092341c44b99562e75d09e4d5160fe7a3974c6fb842a101a95e7eed0", size = 182132, upload-time = "2026-05-02T16:04:12.653Z" }
-wheels = [
- { url = "https://files.pythonhosted.org/packages/41/52/e465037f5375f43533d1a80b6923955201596a99142ed524d77b571a1418/wcwidth-0.7.0-py3-none-any.whl", hash = "sha256:5d69154c429a82910e241c738cd0e2976fac8a2dd47a1a805f4afed1c0f136f2", size = 110825, upload-time = "2026-05-02T16:04:11.033Z" },
-]
-
[[package]]
name = "webencodings"
version = "0.5.1"
@@ -3991,7 +3421,6 @@ dev = [
{ name = "markdown-exec", extra = ["ansi"] },
{ name = "mike" },
{ name = "mkdocs" },
- { name = "mkdocs-jupyter" },
{ name = "mkdocs-material", extra = ["imaging"] },
{ name = "mkdocs-redirects" },
{ name = "mkdocstrings" },
@@ -4022,7 +3451,6 @@ docs = [
{ name = "markdown-exec", extra = ["ansi"] },
{ name = "mike" },
{ name = "mkdocs" },
- { name = "mkdocs-jupyter" },
{ name = "mkdocs-material", extra = ["imaging"] },
{ name = "mkdocs-redirects" },
{ name = "mkdocstrings" },
@@ -4092,37 +3520,36 @@ provides-extras = ["cast-value-rs", "cli", "gpu", "optional", "remote"]
dev = [
{ name = "astroid", specifier = "==4.1.2" },
{ name = "botocore" },
- { name = "coverage", specifier = "==7.14.1" },
+ { name = "coverage", specifier = "==7.14.3" },
{ name = "fsspec", specifier = ">=2023.10.0" },
{ name = "griffe-inherited-docstrings", specifier = "==1.1.3" },
- { name = "hypothesis", specifier = "==6.155.2" },
+ { name = "hypothesis", specifier = "==6.155.7" },
{ name = "markdown-exec", extras = ["ansi"], specifier = "==1.12.1" },
{ name = "mike", specifier = "==2.2.0" },
{ name = "mkdocs", specifier = "==1.6.1" },
- { name = "mkdocs-jupyter", specifier = "==0.26.3" },
{ name = "mkdocs-material", extras = ["imaging"], specifier = "==9.7.6" },
{ name = "mkdocs-redirects", specifier = "==1.2.3" },
{ name = "mkdocstrings", specifier = "==1.0.4" },
- { name = "mkdocstrings-python", specifier = "==2.0.4" },
+ { name = "mkdocstrings-python", specifier = "==2.0.5" },
{ name = "moto", extras = ["s3", "server"], specifier = "==5.2.2" },
{ name = "mypy", specifier = "==2.1.0" },
{ name = "numcodecs", extras = ["msgpack"] },
{ name = "numpydoc", specifier = "==1.10.0" },
{ name = "obstore", specifier = ">=0.5.1" },
- { name = "pytest", specifier = "==9.0.3" },
- { name = "pytest-accept", specifier = "==0.2.3" },
+ { name = "pytest", specifier = "==9.1.1" },
+ { name = "pytest-accept", specifier = "==0.3.0" },
{ name = "pytest-asyncio", specifier = "==1.4.0" },
{ name = "pytest-benchmark", specifier = "==5.2.3" },
{ name = "pytest-codspeed", specifier = "==5.0.3" },
{ name = "pytest-cov", specifier = "==7.1.0" },
{ name = "pytest-xdist", specifier = "==3.8.0" },
{ name = "requests", specifier = "==2.34.2" },
- { name = "ruff", specifier = "==0.15.16" },
+ { name = "ruff", specifier = "==0.15.20" },
{ name = "s3fs", specifier = ">=2023.10.0" },
{ name = "tomlkit", specifier = "==0.15.0" },
{ name = "towncrier", specifier = "==25.8.0" },
{ name = "universal-pathlib" },
- { name = "uv", specifier = "==0.11.20" },
+ { name = "uv", specifier = "==0.11.26" },
]
docs = [
{ name = "astroid", specifier = "==4.1.2" },
@@ -4130,28 +3557,27 @@ docs = [
{ name = "markdown-exec", extras = ["ansi"], specifier = "==1.12.1" },
{ name = "mike", specifier = "==2.2.0" },
{ name = "mkdocs", specifier = "==1.6.1" },
- { name = "mkdocs-jupyter", specifier = "==0.26.3" },
{ name = "mkdocs-material", extras = ["imaging"], specifier = "==9.7.6" },
{ name = "mkdocs-redirects", specifier = "==1.2.3" },
{ name = "mkdocstrings", specifier = "==1.0.4" },
- { name = "mkdocstrings-python", specifier = "==2.0.4" },
+ { name = "mkdocstrings-python", specifier = "==2.0.5" },
{ name = "numcodecs", extras = ["msgpack"] },
- { name = "pytest", specifier = "==9.0.3" },
- { name = "ruff", specifier = "==0.15.16" },
+ { name = "pytest", specifier = "==9.1.1" },
+ { name = "ruff", specifier = "==0.15.20" },
{ name = "s3fs", specifier = ">=2023.10.0" },
{ name = "towncrier", specifier = "==25.8.0" },
]
release = [{ name = "towncrier", specifier = "==25.8.0" }]
remote-tests = [
{ name = "botocore" },
- { name = "coverage", specifier = "==7.14.1" },
+ { name = "coverage", specifier = "==7.14.3" },
{ name = "fsspec", specifier = ">=2023.10.0" },
- { name = "hypothesis", specifier = "==6.155.2" },
+ { name = "hypothesis", specifier = "==6.155.7" },
{ name = "moto", extras = ["s3", "server"], specifier = "==5.2.2" },
{ name = "numpydoc", specifier = "==1.10.0" },
{ name = "obstore", specifier = ">=0.5.1" },
- { name = "pytest", specifier = "==9.0.3" },
- { name = "pytest-accept", specifier = "==0.2.3" },
+ { name = "pytest", specifier = "==9.1.1" },
+ { name = "pytest-accept", specifier = "==0.3.0" },
{ name = "pytest-asyncio", specifier = "==1.4.0" },
{ name = "pytest-benchmark", specifier = "==5.2.3" },
{ name = "pytest-codspeed", specifier = "==5.0.3" },
@@ -4160,19 +3586,19 @@ remote-tests = [
{ name = "requests", specifier = "==2.34.2" },
{ name = "s3fs", specifier = ">=2023.10.0" },
{ name = "tomlkit", specifier = "==0.15.0" },
- { name = "uv", specifier = "==0.11.20" },
+ { name = "uv", specifier = "==0.11.26" },
]
test = [
- { name = "coverage", specifier = "==7.14.1" },
- { name = "hypothesis", specifier = "==6.155.2" },
+ { name = "coverage", specifier = "==7.14.3" },
+ { name = "hypothesis", specifier = "==6.155.7" },
{ name = "numpydoc", specifier = "==1.10.0" },
- { name = "pytest", specifier = "==9.0.3" },
- { name = "pytest-accept", specifier = "==0.2.3" },
+ { name = "pytest", specifier = "==9.1.1" },
+ { name = "pytest-accept", specifier = "==0.3.0" },
{ name = "pytest-asyncio", specifier = "==1.4.0" },
{ name = "pytest-benchmark", specifier = "==5.2.3" },
{ name = "pytest-codspeed", specifier = "==5.0.3" },
{ name = "pytest-cov", specifier = "==7.1.0" },
{ name = "pytest-xdist", specifier = "==3.8.0" },
{ name = "tomlkit", specifier = "==0.15.0" },
- { name = "uv", specifier = "==0.11.20" },
+ { name = "uv", specifier = "==0.11.26" },
]