`_.
-
-.. toctree::
- :caption: Getting Started
- :hidden:
-
- installation
-
-.. _NumCodecs: https://numcodecs.readthedocs.io/
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000000..eb3b6a5000
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,92 @@
+# Zarr-Python
+
+**Useful links**:
+[Source Repository](https://github.com/zarr-developers/zarr-python) |
+[Issue Tracker](https://github.com/zarr-developers/zarr-python/issues) |
+[Developer Chat](https://ossci.zulipchat.com/) |
+[Zarr specifications](https://zarr-specs.readthedocs.io)
+
+Zarr is a powerful library for storage of n-dimensional arrays, supporting chunking,
+compression, and various backends, making it a versatile choice for scientific and
+large-scale data.
+
+Zarr-Python is a Python library for reading and writing Zarr groups and arrays. Highlights include:
+
+* Specification support for both Zarr format 2 and 3.
+* Create and read from N-dimensional arrays using NumPy-like semantics.
+* Flexible storage enables reading and writing from local, cloud and in-memory stores.
+* High performance: Enables fast I/O with support for asynchronous I/O and multi-threading.
+* Extensible: Customizable with user-defined codecs and stores.
+
+## Installation
+
+Zarr requires Python 3.12 or higher. You can install it via `pip`:
+
+```bash
+pip install zarr
+```
+
+or `conda`:
+
+```bash
+conda install -c conda-forge zarr
+```
+
+## Navigating the documentation
+
+
+
+- [:material-clock-fast:{ .lg .middle } __Quick start__](quick-start.md)
+
+ ---
+
+ New to Zarr? Check out the quick start guide. It contains a brief
+ introduction to Zarr's main concepts and links to additional tutorials.
+
+- [: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/index.md)
+
+ ---
+
+ The reference guide contains a detailed description of the functions, modules,
+ and objects included in Zarr. The reference describes how the methods work and
+ which parameters can be used. It assumes that you have an understanding of the
+ key concepts.
+
+- [:material-package-variant:{ .lg .middle } __Related projects__](subprojects.md)
+
+ ---
+
+ Companion packages developed in the zarr-python repository and released
+ independently, such as `zarr-metadata` and `zarr-indexing`, plus pointers to
+ the wider Zarr ecosystem.
+
+- [:material-account-group:{ .lg .middle } __Contributor's Guide__](contributing.md)
+
+ ---
+
+ Want to contribute to Zarr? We welcome contributions in the form of bug reports,
+ bug fixes, documentation, enhancement proposals and more. The contributing guidelines
+ will guide you through the process of improving Zarr.
+
+
+
+## Project Status
+
+More information about the Zarr format can be found on the [main website](https://zarr.dev).
+
+If you are using Zarr-Python, we would [love to hear about it](https://github.com/zarr-developers/community/issues/19).
+
+### Funding and Support
+
+The project is fiscally sponsored by [NumFOCUS](https://numfocus.org/), a US
+501(c)(3) public charity, and development has been supported by the
+[MRC Centre for Genomics and Global Health](https://github.com/cggh/)
+and the [Chan Zuckerberg Initiative](https://chanzuckerberg.com/).
+
+[Donate to Zarr](https://numfocus.org/donate-to-zarr) to support the project!
diff --git a/docs/index.rst b/docs/index.rst
deleted file mode 100644
index 06f79b7e7c..0000000000
--- a/docs/index.rst
+++ /dev/null
@@ -1,105 +0,0 @@
-.. _zarr_docs_mainpage:
-
-***********
-Zarr-Python
-***********
-
-.. toctree::
- :maxdepth: 1
- :hidden:
-
- getting_started
- tutorial
- api
- spec
- release
- license
- acknowledgments
- contributing
-
-**Version**: |version|
-
-**Download documentation**: `PDF/Zipped HTML/EPUB `_
-
-**Useful links**:
-`Installation `_Β |
-`Source Repository `_Β |
-`Issue Tracker `_Β |
-`Gitter `_
-
-Zarr is a file storage format for chunked, compressed, N-dimensional arrays based on an open-source specification.
-
-.. grid:: 2
-
- .. grid-item-card::
- :img-top: _static/index_getting_started.svg
-
- Getting Started
- ^^^^^^^^^^^^^^^
-
- New to Zarr? Check out the getting started guide. It contains an
- introduction to Zarr's main concepts and links to additional tutorials.
-
- +++
-
- .. button-ref:: getting_started
- :expand:
- :color: dark
- :click-parent:
-
- To the getting started guide
-
- .. grid-item-card::
- :img-top: _static/index_user_guide.svg
-
- Tutorial
- ^^^^^^^^
-
- The tutorial provides working examples of Zarr classes and functions.
-
- +++
-
- .. button-ref:: tutorial
- :ref-type: ref
- :expand:
- :color: dark
- :click-parent:
-
- To the Tutorial
-
- .. grid-item-card::
- :img-top: _static/index_api.svg
-
- API Reference
- ^^^^^^^^^^^^^
-
- The reference guide contains a detailed description of the functions,
- modules, and objects included in Zarr. The reference describes how the
- methods work and which parameters can be used. It assumes that you have an
- understanding of the key concepts.
-
- +++
-
- .. button-ref:: api
- :expand:
- :color: dark
- :click-parent:
-
- To the api reference guide
-
- .. grid-item-card::
- :img-top: _static/index_contribute.svg
-
- Contributor's Guide
- ^^^^^^^^^^^^^^^^^^^
-
- Want to contribute to Zarr? We welcome contributions in the form of bug reports, bug fixes, documentation, enhancement proposals and more. The contributing guidelines will guide you through the process of improving Zarr.
-
- +++
-
- .. button-ref:: contributing
- :expand:
- :color: dark
- :click-parent:
-
- To the contributor's guide
diff --git a/docs/installation.rst b/docs/installation.rst
deleted file mode 100644
index 8553d451cb..0000000000
--- a/docs/installation.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-Installation
-============
-
-Zarr depends on NumPy. It is generally best to `install NumPy
-`_ first using whatever method is most
-appropriate for your operating system and Python distribution. Other dependencies should be
-installed automatically if using one of the installation methods below.
-
-Install Zarr from PyPI::
-
- $ pip install zarr
-
-Alternatively, install Zarr via conda::
-
- $ conda install -c conda-forge zarr
-
-To install the latest development version of Zarr, you can use pip with the
-latest GitHub main::
-
- $ pip install git+https://github.com/zarr-developers/zarr-python.git
-
-To work with Zarr source code in development, install from GitHub::
-
- $ git clone --recursive https://github.com/zarr-developers/zarr-python.git
- $ cd zarr-python
- $ python -m pip install -e .
-
-To verify that Zarr has been fully installed, run the test suite::
-
- $ pip install pytest
- $ python -m pytest -v --pyargs zarr
diff --git a/docs/license.rst b/docs/license.rst
deleted file mode 100644
index 8f93aa7d66..0000000000
--- a/docs/license.rst
+++ /dev/null
@@ -1,4 +0,0 @@
-License
-=======
-
-.. include:: ../LICENSE.txt
diff --git a/docs/overrides/main.html b/docs/overrides/main.html
new file mode 100644
index 0000000000..d61a1f54dc
--- /dev/null
+++ b/docs/overrides/main.html
@@ -0,0 +1,9 @@
+
+{% extends "base.html" %}
+
+{% block outdated %}
+ You're not viewing the latest version.
+
+ Click here to go to latest.
+
+{% endblock %}
diff --git a/docs/overrides/stylesheets/extra.css b/docs/overrides/stylesheets/extra.css
new file mode 100644
index 0000000000..6cb7c74e8d
--- /dev/null
+++ b/docs/overrides/stylesheets/extra.css
@@ -0,0 +1,209 @@
+:root {
+ --gradient-start: #e58077;
+ --gradient-mid-1: #e57a77;
+ --gradient-mid-2: #e46876;
+ --gradient-mid-3: #e34b75;
+ --gradient-mid-4: #e12374;
+ --gradient-mid-5: #e01073;
+ --gradient-end: #bb1085;
+
+ /* Primary theme colors
+ --md-primary-fg-color: #e34b75;
+ --md-primary-fg-color--light: #e57a77;
+ --md-primary-fg-color--dark: #bb1085;
+
+ /* Accent colors */
+ --md-accent-fg-color: #e01073;
+ --md-accent-fg-color--transparent: rgba(224, 16, 115, 0.1);
+
+ /* Text colors that work well with the palette */
+ --md-text-color: #333333;
+ --md-text-color--light: #666666;
+}
+
+/* Dark mode color adjustments */
+[data-md-color-scheme="slate"] {
+ --md-primary-fg-color: #e57a77;
+ --md-primary-fg-color--light: #e58077;
+ --md-primary-fg-color--dark: #bb1085;
+ --md-accent-fg-color: #e46876;
+ --md-accent-fg-color--transparent: rgba(228, 104, 118, 0.1);
+}
+
+/* Header styling with gradient background */
+.md-header {
+ background: linear-gradient(
+ 135deg,
+ var(--gradient-start) 0%,
+ var(--gradient-mid-1) 16.66%,
+ var(--gradient-mid-2) 33.33%,
+ var(--gradient-mid-3) 50%,
+ var(--gradient-mid-4) 66.66%,
+ var(--gradient-mid-5) 83.33%,
+ var(--gradient-end) 100%
+ );
+ box-shadow: 0 2px 8px rgba(187, 16, 133, 0.15);
+}
+
+/* Ensure header text is readable over gradient */
+.md-header__title,
+.md-header__button,
+.md-header .md-icon {
+ color: white;
+}
+
+/* Search box styling in the header */
+.md-header .md-search__input {
+ background-color: rgba(255, 255, 255, 0.15);
+ border: 1px solid rgba(255, 255, 255, 0.2);
+}
+
+/* Navigation tabs */
+.md-tabs {
+ background: linear-gradient(
+ 90deg,
+ var(--gradient-mid-3) 0%,
+ var(--gradient-mid-4) 50%,
+ var(--gradient-mid-5) 100%
+ );
+}
+
+.md-tabs__link {
+ color: rgba(255, 255, 255, 0.9);
+}
+
+.md-tabs__link--active,
+.md-tabs__link:hover {
+ color: white;
+ opacity: 1;
+}
+
+/* Sidebar navigation */
+.md-nav__link--active {
+ color: var(--md-primary-fg-color);
+ font-weight: 500;
+}
+
+.md-nav__link:hover {
+ color: var(--md-accent-fg-color);
+}
+
+/* Code blocks */
+.highlight {
+ border-left: 4px solid var(--md-accent-fg-color);
+ background-color: rgba(228, 104, 118, 0.05);
+}
+
+/* Admonitions */
+.md-typeset .admonition.note {
+ border-color: var(--md-primary-fg-color);
+}
+
+.md-typeset .admonition.note > .admonition-title {
+ background-color: rgba(227, 75, 117, 0.1);
+ border-color: var(--md-primary-fg-color);
+}
+
+.md-typeset .admonition.tip {
+ border-color: var(--gradient-mid-1);
+}
+
+.md-typeset .admonition.tip > .admonition-title {
+ background-color: rgba(229, 122, 119, 0.1);
+ border-color: var(--gradient-mid-1);
+}
+
+.md-typeset .admonition.warning {
+ border-color: var(--gradient-end);
+}
+
+.md-typeset .admonition.warning > .admonition-title {
+ background-color: rgba(187, 16, 133, 0.1);
+ border-color: var(--gradient-end);
+}
+
+/* Links */
+.md-content a {
+ color: var(--md-accent-fg-color);
+}
+
+.md-content a:hover {
+ color: var(--gradient-end);
+}
+
+/* Table of contents */
+.md-nav--secondary .md-nav__link--active {
+ color: var(--md-accent-fg-color);
+ border-left: 2px solid var(--md-accent-fg-color);
+ padding-left: calc(1rem - 2px);
+}
+
+/* Footer */
+.md-footer {
+ background-color: var(--gradient-end);
+}
+
+/* Buttons and interactive elements */
+.md-button {
+ background: linear-gradient(135deg, var(--md-primary-fg-color), var(--md-accent-fg-color));
+ border: none;
+ color: white;
+ transition: all 0.3s ease;
+}
+
+.md-button:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(187, 16, 133, 0.3);
+}
+
+/* Scrollbar styling */
+::-webkit-scrollbar {
+ width: 8px;
+}
+
+::-webkit-scrollbar-track {
+ background: rgba(187, 16, 133, 0.1);
+}
+
+::-webkit-scrollbar-thumb {
+ background: linear-gradient(
+ 180deg,
+ var(--md-primary-fg-color),
+ var(--md-accent-fg-color)
+ );
+ border-radius: 4px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: linear-gradient(
+ 180deg,
+ var(--md-accent-fg-color),
+ var(--gradient-end)
+ );
+}
+
+/* Search results highlighting */
+.md-search-result__title {
+ color: var(--md-primary-fg-color);
+}
+
+.md-search-result__teaser mark {
+ background-color: rgba(224, 16, 115, 0.2);
+ color: var(--gradient-end);
+}
+
+.md-header__button.md-logo img,
+.md-header__button.md-logo svg {
+ height: 42px !important; /* Increase from default ~24px */
+ width: auto !important;
+ max-height: none !important;
+ padding: 0 0 0 16px !important; /* Keep left padding, remove others */
+ margin: 0 !important; /* Remove any margin */
+}
+
+/* Also remove padding from the logo button container except left */
+.md-header__button.md-logo {
+ padding: 0 0 0 8px !important; /* Keep some left padding on container */
+ margin: 0 !important;
+ min-width: auto !important;
+}
diff --git a/docs/quick-start.md b/docs/quick-start.md
new file mode 100644
index 0000000000..123f05d5e9
--- /dev/null
+++ b/docs/quick-start.md
@@ -0,0 +1,191 @@
+# 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
+
+To get started, you can create a simple Zarr array:
+
+```python exec="true" session="quickstart"
+import shutil
+shutil.rmtree('data', ignore_errors=True)
+import numpy as np
+from pprint import pprint
+import io
+import warnings
+
+warnings.filterwarnings(
+ "ignore",
+ message="Numcodecs codecs are not in the Zarr version 3 specification*",
+ category=UserWarning
+)
+np.random.seed(0)
+```
+
+```python exec="true" session="quickstart" source="above" result="ansi"
+import zarr
+import numpy as np
+
+# Create a 2D Zarr array
+z = zarr.create_array(
+ store="data/example-1.zarr",
+ shape=(100, 100),
+ chunks=(10, 10),
+ dtype="f4"
+)
+
+# Assign data to the array
+z[:, :] = np.random.random((100, 100))
+print(z.info)
+```
+
+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
+
+Zarr supports data compression and filters. For example, to use Blosc compression:
+
+```python exec="true" session="quickstart" source="above" result="ansi"
+
+# Create a 2D Zarr array with Blosc compression
+z = zarr.create_array(
+ store="data/example-2.zarr",
+ shape=(100, 100),
+ chunks=(10, 10),
+ dtype="f4",
+ compressors=zarr.codecs.BloscCodec(
+ cname="zstd",
+ clevel=3,
+ shuffle="shuffle"
+ )
+)
+
+# Assign data to the array
+z[:, :] = np.random.random((100, 100))
+print(z.info)
+```
+
+This compresses the data using the Blosc codec with shuffle enabled for better compression.
+
+## Hierarchical Groups
+
+Zarr allows you to create hierarchical groups, similar to directories:
+
+```python exec="true" session="quickstart" source="above" result="ansi"
+
+# Create nested groups and add arrays
+root = zarr.group("data/example-3.zarr")
+foo = root.create_group(name="foo")
+bar = root.create_array(
+ name="bar", shape=(100, 10), chunks=(10, 10), dtype="f4"
+)
+spam = foo.create_array(name="spam", shape=(10,), dtype="i4")
+
+# Assign values
+bar[:, :] = np.random.random((100, 10))
+spam[:] = np.arange(10)
+
+# print the hierarchy
+print(root.tree())
+```
+
+This creates a group hierarchy with a group (`foo`) and two arrays (`bar` and `spam`).
+
+### 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="code"
+
+# Create nested groups and add arrays
+root = zarr.group("data/example-4.zarr", attributes={'name': 'root'})
+foo = root.create_group(name="foo")
+bar = root.create_array(
+ name="bar", shape=(100, 10), chunks=(10, 10), dtype="f4"
+)
+nodes = {'': root.metadata} | {k: v.metadata for k,v in root.members()}
+# Report nodes
+output = io.StringIO()
+pprint(nodes, stream=output, width=60, depth=3)
+result = output.getvalue()
+print(result)
+# Create new hierarchy from nodes
+new_nodes = dict(zarr.create_hierarchy(store=zarr.storage.MemoryStore(), nodes=nodes))
+new_root = new_nodes['']
+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
+
+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.
+
+A single-file store can also be created using the [`zarr.storage.ZipStore`][]:
+
+```python exec="true" session="quickstart" source="above"
+
+# Store the array in a ZIP file
+store = zarr.storage.ZipStore("data/example-5.zip", mode="w")
+
+z = zarr.create_array(
+ store=store,
+ shape=(100, 100),
+ chunks=(10, 10),
+ dtype="f4"
+)
+
+# write to the array
+z[:, :] = np.random.random((100, 100))
+
+# the ZipStore must be explicitly closed
+store.close()
+```
+
+To open an existing array from a ZIP file:
+
+```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)
+
+z = zarr.open_array(store, mode='r')
+
+# read the data as a NumPy Array
+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/en/latest/) or
+[gcsfs](https://gcsfs.readthedocs.io/en/latest/). 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
+import numpy as np
+
+z = zarr.create_array(
+ "s3://example-bucket/foo", shape=(100, 100), chunks=(10, 10), dtype="f4"
+)
+z[:, :] = np.random.random((100, 100))
+```
+
+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
new file mode 100644
index 0000000000..3b54ea993a
--- /dev/null
+++ b/docs/release-notes.md
@@ -0,0 +1,866 @@
+# Release notes
+
+
+
+
+
+## 3.3.0 (2026-07-30)
+
+### Features
+
+- Optimizes reading multiple chunks from a shard. Serial calls to `Store.get()`
+ in the sharding codec have been replaced with a single call to
+ `Store.get_ranges()`, which coalesces nearby byte ranges and fetches them
+ concurrently. ([#3004](https://github.com/zarr-developers/zarr-python/pull/3004))
+- Added a `subchunk_write_order` option to `ShardingCodec` to control the physical order of subchunks within a shard. Supported values are `morton`, `unordered`, `lexicographic`, and `colexicographic`. `unordered` makes no guarantee about subchunk layout. This setting affects only on-disk layout, not the data read back, and is not persisted in array metadata: it applies per codec instance and is not recovered when reopening a sharded array. ([#3826](https://github.com/zarr-developers/zarr-python/pull/3826))
+- Added `SyncByteGetter` and `SyncByteSetter` runtime-checkable protocols and a `get_ranges_sync` method on the `Store` ABC. These let custom byte getters/setters opt into the synchronous codec pipeline's fast path for in-memory IO, which the sharding codec uses for its inner chunks. ([#3885](https://github.com/zarr-developers/zarr-python/pull/3885))
+- Added `FusedCodecPipeline`, an opt-in codec pipeline that runs codec compute synchronously and in bulk (avoiding the per-chunk async scheduling overhead of the default `BatchedCodecPipeline`), giving large speedups for sharded arrays. The default `BatchedCodecPipeline` is unchanged for standard configurations, so existing code keeps working unless you opt in; enable the new pipeline with `zarr.config.set({"codec_pipeline.path": "zarr.core.codec_pipeline.FusedCodecPipeline"})`. ([#3885](https://github.com/zarr-developers/zarr-python/pull/3885))
+- Add `zarr.abc.store.Store.get_ranges` for concurrent, coalesced multi-range reads from a single key. The method is defined on the `Store` ABC with a default implementation built on `Store.get`, so every store inherits a working version; stores with native multi-range backends (e.g. `FsspecStore`) can override for efficiency. Coalescing knobs (`max_concurrency`, `max_gap_bytes`, `max_coalesced_bytes`) are passed as keyword arguments to `get_ranges`. Failures from underlying fetches surface as a `BaseExceptionGroup` (PEP 654); callers should use `except*` to filter for specific exception types such as `FileNotFoundError`. ([#3925](https://github.com/zarr-developers/zarr-python/pull/3925))
+- Two new fields on `ArrayConfig` control how the sharding codec coalesces partial-shard reads: `sharding_coalesce_max_gap_bytes` (default 1 MiB) and `sharding_coalesce_max_bytes` (default 16 MiB). When reading multiple chunks from the same shard, nearby byte ranges are merged into a single request to the store if separated by no more than `sharding_coalesce_max_gap_bytes` and the merged read stays within `sharding_coalesce_max_bytes`. Defaults are seeded from the matching `array.sharding_coalesce_max_gap_bytes` / `array.sharding_coalesce_max_bytes` keys in [`zarr.config`][] at array-creation time, and can be overridden per array by passing `config={...}` to [`zarr.create_array`][]. ([#3987](https://github.com/zarr-developers/zarr-python/pull/3987))
+
+- Added `Group.get_array`, `Group.get_group`, `AsyncGroup.get_array`, and `AsyncGroup.get_group`: type-safe accessors that return the child array or group at a given path, raising `ArrayNotFoundError` / `GroupNotFoundError` if no node exists there, and `ContainsGroupError` / `ContainsArrayError` if the node is not of the requested kind. Unlike `Group.__getitem__`, which returns `Array | Group`, these methods have precise return types. Nested paths like `"subgroup/subarray"` are supported. ([#4128](https://github.com/zarr-developers/zarr-python/pull/4128))
+- `ZipStore` now accepts an open binary file-like object in place of a path, enabling
+ zip archives on remote storage (e.g. a file opened with `fsspec` or an
+ `obstore.ReadableFile`). Operations that require a filesystem location
+ (`clear`, `move`) raise `NotImplementedError` for file-object-backed stores. ([#4187](https://github.com/zarr-developers/zarr-python/pull/4187))
+
+### Bugfixes
+
+- Stop emitting an `UnstableSpecificationWarning` when serializing the `struct` data type to Zarr V3 metadata. The `struct` data type now has a stable Zarr V3 specification. The legacy `structured` alias and the unspecified `null_terminated_bytes`, `raw_bytes`, and `variable_length_bytes` data types continue to warn. ([#4100](https://github.com/zarr-developers/zarr-python/pull/4100))
+- Fix equality comparison of `ArrayV2Metadata` and `ArrayV3Metadata` objects with a
+ `NaN` fill value. Such objects are now compared by their JSON-serialized form, so two
+ otherwise-identical metadata objects with a `NaN` (or infinite) fill value compare equal. ([#2929](https://github.com/zarr-developers/zarr-python/issues/2929))
+- Fixed `BytesCodec.from_dict` so that `BytesCodec` instances roundtrip to / from
+ their dict representation. `BytesCodec.from_dict` now interprets a missing
+ `endian` configuration as `endian=None` (matching what `BytesCodec.to_dict`
+ emits), instead of falling back to the system's native byte order. ([#3417](https://github.com/zarr-developers/zarr-python/pull/3417))
+- Fixed `save_array`, `Group.__setitem__`, and `load` for 0-dimensional arrays. ([#3469](https://github.com/zarr-developers/zarr-python/issues/3469))
+- Fixed inner-codec spec evolution for sharded arrays. The sharding codec now threads the array spec through its inner codec chain when evolving codecs, so a codec that changes the dtype upstream of `BytesCodec` no longer leaves the inner chain evolved against the wrong spec (which previously failed at decode time). This runs on the default `BatchedCodecPipeline` as well. Standard inner chains (`[BytesCodec]`, `[BytesCodec, ZstdCodec]`, transpose + bytes) are byte-identical to before. Restores the behavior of #2179. ([#3885](https://github.com/zarr-developers/zarr-python/pull/3885))
+- Make chunk normalization properly handle `-1` as a compact representation of the
+ length of an entire axis. Reject several previously-accepted but ill-defined
+ chunk specifications: `chunks=True` (previously silently produced size-1 chunks),
+ chunk tuples shorter than the array's number of dimensions (previously padded to
+ the array's shape), and `None` as a per-dimension chunk size. These all now
+ raise informative errors. Also fix chunk handling for 0-length array dimensions,
+ and add explicit rejection of 0-length chunks. ([#3899](https://github.com/zarr-developers/zarr-python/pull/3899))
+- Handle missing consolidated metadata in leaf Group nodes. ([#3954](https://github.com/zarr-developers/zarr-python/issues/3954))
+- Corrected the JSON type definitions for the `numpy.datetime64` and
+ `numpy.timedelta64` data types in Zarr V3 metadata: the `configuration` object
+ (holding `unit` and `scale_factor`) is now required, matching the published
+ specifications for these data types. Also updated the specification links in
+ the docstrings to point to the zarr-extensions repository. ([#3955](https://github.com/zarr-developers/zarr-python/pull/3955))
+- Fixed writing to 0-dimensional arrays that use the sharding codec. Previously
+ assigning to a 0-dimensional sharded array raised an error. ([#3966](https://github.com/zarr-developers/zarr-python/pull/3966))
+- Fix flaky stateful test bookkeeping when `delete_dir` matches string prefixes instead of true directory descendants. Previously a path such as `6/faNTβ¦` could be incorrectly removed when deleting `6/f`. (See [issue #3977](https://github.com/zarr-developers/zarr-python/issues/3977).) ([#3977](https://github.com/zarr-developers/zarr-python/issues/3977))
+- `FsspecStore.close()` no longer closes the underlying fsspec filesystem or its
+ network session. fsspec caches and shares filesystem instances across callers,
+ so the store cannot know whether it is the only user, and closing a shared
+ session would break other stores; the filesystem's lifecycle belongs to
+ whoever created it. ([#4165](https://github.com/zarr-developers/zarr-python/pull/4165))
+
+- Fixed an invalid `zarr.create_array` example in the quick-start documentation (it passed an unsupported `mode` argument) and made the cloud-storage example execute against a mock S3 backend in CI. Added a test ensuring every Python code block in the documentation is either executed or explicitly opted out with a documented reason, so an invalid example can no longer go untested. ([#4016](https://github.com/zarr-developers/zarr-python/issues/4016))
+- Fixed `ObjectStore.list_dir` for object-store listings that include a directory-marker object matching the requested non-root prefix. ([#4032](https://github.com/zarr-developers/zarr-python/issues/4032))
+- Prevents mutation of the attributes dict provided by the user by copying them instead of keeping the reference ([#4059](https://github.com/zarr-developers/zarr-python/issues/4059))
+- Fixed several storage and codec bugs:
+
+ - Reading a value with a `SuffixByteRequest` larger than the value now correctly returns the whole value (matching HTTP `bytes=-N` suffix-range semantics), instead of silently returning incorrect data for `MemoryStore`.
+ - `LoggingStore.get_partial_values` and `FsspecStore.get_partial_values` no longer return empty results when `key_ranges` is passed as a one-shot iterable (e.g. a generator).
+ - `Store.getsize_prefix` no longer over-counts sibling keys that merely share a string prefix (e.g. `getsize_prefix("foo")` no longer includes keys under `foobar/`).
+ - `ZipStore.close()` no longer raises `AttributeError` when the store was created but never opened (including when used as a context manager without any I/O).
+ - `codecs_from_list` now raises a descriptive `TypeError` when a `BytesBytesCodec` immediately follows an `ArrayArrayCodec`, instead of a misleading "Required ArrayBytesCodec was not found" `ValueError`.
+
+ ([#4074](https://github.com/zarr-developers/zarr-python/pull/4074))
+
+- 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. ([#4116](https://github.com/zarr-developers/zarr-python/pull/4116))
+- Fix silent byte-order corruption for structured dtypes with the `bytes` codec: multi-byte fields are now byte-swapped to the codec's configured `endian` on write and decoded honoring it on read, so non-native-endian structured data (e.g. big-endian fields, as produced by virtual references to external data) round-trips correctly. ([#4141](https://github.com/zarr-developers/zarr-python/issues/4141))
+
+- Fix `zarr.api.asynchronous.open_like` so it can create a new array by default when the
+ target path does not already exist. It now defaults to `mode="a"`; when using a read-only
+ store to open an existing array, pass `mode="r"` explicitly. ([#3352](https://github.com/zarr-developers/zarr-python/pull/3352))
+- `MemoryStore` now copies buffers as they are written, so it never retains the
+ caller's memory. Previously an uncompressed write handed the store a zero-copy
+ view of the user's array, and mutating that array afterwards would silently
+ rewrite chunks already committed to the store.
+
+ Only `MemoryStore` is affected: stores that serialize on write, such as
+ `LocalStore` and `ZipStore`, never aliased the caller's memory. Uncompressed
+ writes to a `MemoryStore` are correspondingly slower, since the copy that makes
+ the stored data independent is now actually performed; compressed writes are
+ unchanged. Buffers supplied through the `store_dict` argument remain the
+ caller's responsibility and are stored as-is. ([#4157](https://github.com/zarr-developers/zarr-python/pull/4157))
+
+- Fixed the opt-in `FusedCodecPipeline` for sharded arrays whose inner or index codec chain contains a codec implementing only the async codec interface (no `SupportsSyncCodec`). Such arrays previously raised `TypeError: All codecs must implement SupportsSyncCodec` on both read and write; the pipeline now declines its synchronous fast path for them and falls back to the async path, matching the behavior of the default `BatchedCodecPipeline`. Fully sync-capable codec chains keep the fast path unchanged. ([#4179](https://github.com/zarr-developers/zarr-python/pull/4179))
+- Fixed `TypeError: unhashable type: 'writeable void-scalar'` when writing to sharded arrays whose fill value is a `np.void` scalar, e.g. arrays with a structured dtype.
+
+ `ArraySpec` equality and hashing now compare the fill value by its byte representation rather than numeric equality. As a result, two specs with a `NaN` (or `NaT`) fill value now compare equal, while fill values of `-0.0` and `0.0` now compare unequal. This also restores the sharding codec's per-chunk spec cache, which had been disabled because of this bug. ([#4183](https://github.com/zarr-developers/zarr-python/pull/4183))
+
+- `FusedCodecPipeline` no longer runs chunk IO and codec compute on the thread
+ driving zarr's internal event loop. Previously each read/write executed its
+ synchronous fast path inline on that loop thread, and because every sync-API
+ call from every user thread is serviced by the same loop, concurrent
+ operations serialized behind each other's codec work β reported as the fused
+ pipeline being slower than `BatchedCodecPipeline` for zstd-compressed data
+ under multi-threaded (e.g. dask) access. The synchronous batch now runs on a
+ worker thread (one hop per batch, not per chunk), keeping the loop free.
+ Multi-threaded single-chunk reads of compressed data now scale with reader
+ threads; single-threaded performance is unchanged. ([#4194](https://github.com/zarr-developers/zarr-python/pull/4194))
+- The end-to-end benchmarks no longer invoke `sudo` to drop the OS page cache during a regular `pytest` run. Cache clearing is now opt-in via the `ZARR_BENCHMARK_CLEAR_CACHE` environment variable, which the benchmark CI jobs set. ([#4199](https://github.com/zarr-developers/zarr-python/pull/4199))
+- Fixed the opt-in `FusedCodecPipeline` for serializers that advertise the partial-decode/encode mixins with only the documented async partial methods: the partial dispatch previously asserted on the private `_decode_partial_sync`/`_encode_partial_sync` hooks (an `AssertionError`, or an `AttributeError` mid-IO under `python -O`); such codecs now take the full-chunk sync path. ([#4201](https://github.com/zarr-developers/zarr-python/pull/4201))
+- Fixed `FusedCodecPipeline` (the opt-in synchronous pipeline) silently skipping
+ array-array/bytes-bytes codecs placed outside a sharding serializer on its
+ partial-decode/partial-encode fast paths. With an outer compressor (e.g.
+ `compressors=[GzipCodec()]` around a `ShardingCodec` serializer), the fused
+ pipeline wrote non-conforming stored bytes that `BatchedCodecPipeline` (and any
+ other conforming reader) could not read, and could fail to read data that
+ `BatchedCodecPipeline` had written. With an outer array-array codec (e.g.
+ `TransposeCodec`), it silently returned wrong data in both directions with no
+ error. Only the opt-in `FusedCodecPipeline` was affected; the default
+ `BatchedCodecPipeline` was never impacted. ([#4202](https://github.com/zarr-developers/zarr-python/pull/4202))
+- Fixed silent data corruption in the experimental `FusedCodecPipeline`: reordering or duplicating fancy-index reads (e.g. `arr[perm, :]`, `arr.oindex[[0, 0, 1], :]`) on uncompressed, crc-free sharded arrays could return the shard in natural order because the vectorized whole-shard decode accepted any selection whose output shape matched the shard shape. The bulk decode now fires only for identity full-shard reads, declines structured dtypes (whose byte-order handling it lacks), and requires shard-index offsets to exactly tile the data section, so corrupt indexes with overlapping or out-of-range offsets can no longer be served as array data. ([#4203](https://github.com/zarr-developers/zarr-python/pull/4203))
+- `ManagedMemoryStore.get_sync`/`set_sync`/`delete_sync` now apply the store's
+ `path` prefix, matching the async `get`/`set`/`delete` methods. Previously the
+ sync methods were inherited unchanged from `MemoryStore` and used the raw key,
+ so code that takes the sync fast path (e.g. `FusedCodecPipeline`) would read
+ and write chunks outside the store's `path` prefix, silently returning fill
+ values when the data was re-read through a fresh handle. `GpuMemoryStore.set_sync`
+ now converts its value to a `gpu.Buffer`, matching `set`, so writes through the
+ sync API keep the store's all-values-are-GPU invariant. Also fixed
+ `ManagedMemoryStore.get_partial_values` applying its `path` prefix twice
+ whenever `path` is non-empty, which made it always return `None` for every
+ requested key.
+
+ The shared store test suite (`zarr.testing.store.StoreTests`) gained
+ sync/async parity checks β comparing sync and async observations of the same
+ key on the same store instance, including with a `byte_range` β so every
+ store subclass now exercises this invariant. The suite's former
+ `test_get_bytes`/`test_get_json` methods (and their `_sync` variants) were
+ folded into these parity tests and no longer exist as separate methods. ([#4204](https://github.com/zarr-developers/zarr-python/pull/4204))
+
+- Fixed several small correctness issues from the codec-pipeline performance work: construction-time
+ codec warnings (e.g. sharding's "disables partial reads" warning) no longer fire twice per array
+ open β including for `FusedCodecPipeline`, which previously re-warned via its own codec-chain
+ reconstruction and, on the async fallback path, on every decode/encode call; `concurrent_iter` now
+ schedules its tasks eagerly, matching its documented contract; an invalid
+ `codec_pipeline.max_workers` config/environment value now warns and falls back to the default
+ instead of raising mid-read; and `FusedCodecPipeline`'s async fallback helpers now cancel
+ already-spawned fetch/decode/write tasks instead of abandoning them in the background when one
+ fails. ([#4205](https://github.com/zarr-developers/zarr-python/pull/4205))
+- Fixed `FusedCodecPipeline`'s gating of its synchronous fast paths: stores exposing only part of the sync surface (e.g. `set_sync` without `get_sync`) now fall back cleanly to the async path instead of failing mid-write, and `WrapperStore` now forwards `get_sync`/`set_sync`/`delete_sync` to the wrapped store so wrapped sync-capable stores keep the fast path. The capability decision uses a private, interim convention (`zarr.abc.store._store_supports_sync_io`) rather than new public API, pending a formal sync/async store architecture. Also fixed `LatencyStore`: synchronous reads and writes now pay the configured latency, `get_ranges`/`get_partial_values` no longer bypass latency injection, and derived stores (e.g. from `with_read_only`) keep a stochastic `(loc, scale)` latency configuration instead of freezing a single sample. ([#4206](https://github.com/zarr-developers/zarr-python/pull/4206))
+- `DefaultChunkKeyEncoding.decode_chunk_key` now validates that a chunk key
+ starts with the configured `c` prefix and raises `ValueError` for
+ malformed keys, instead of silently decoding them incorrectly. ([#4219](https://github.com/zarr-developers/zarr-python/pull/4219))
+
+### Improved Documentation
+
+- Document the changes to `zarr.errors` in the 3.0 migration guide, including the removal of v2 exception classes and the introduction of `NodeNotFoundError`. ([#3009](https://github.com/zarr-developers/zarr-python/issues/3009))
+- 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. ([#3984](https://github.com/zarr-developers/zarr-python/pull/3984))
+- Updated the custom dtype example in `examples/custom_dtype/custom_dtype.py` to
+ use only the public API, eliminating all non-public imports, illustrating what
+ users should do.
+
+ To better support this, the following types and functions were made available
+ from public modules:
+
+ | Type/Function | Non-public module | Public module |
+ | ------------------------- | ------------------------ | ------------- |
+ | `DataTypeValidationError` | `zarr.core.dtype.common` | `zarr.errors` |
+ | `JSON` | `zarr.core.common` | `zarr.types` |
+ | `ZarrFormat` | `zarr.core.common` | `zarr.types` |
+ | `DTypeConfig_V2` | `zarr.core.dtype.common` | `zarr.types` |
+ | `DTypeJSON` | `zarr.core.dtype.common` | `zarr.types` |
+ | `DTypeSpec_V2` | `zarr.core.dtype.common` | `zarr.dtype` |
+ | `check_dtype_spec_v2` | `zarr.core.dtype.common` | `zarr.dtype` |
+
+ `DataTypeValidationError` was *moved* to `zarr.errors`. Importing it from
+ `zarr.core.dtype.common` (its original location), `zarr.core.dtype`, or
+ `zarr.dtype` still works but now raises a `ZarrDeprecationWarning`. The remaining
+ types and functions are simply re-exported from the listed public module. ([#4052](https://github.com/zarr-developers/zarr-python/pull/4052))
+
+- Document a self-merge policy in the contributor guide, describing when a core developer may merge their own pull request without a second reviewer and which changes warrant more caution. ([#4053](https://github.com/zarr-developers/zarr-python/pull/4053))
+- 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. ([#4132](https://github.com/zarr-developers/zarr-python/pull/4132))
+- 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. ([#4133](https://github.com/zarr-developers/zarr-python/pull/4133))
+
+- Added a blog section to the documentation, with a post covering two performance
+ highlights of the 3.3.0 release: the opt-in `FusedCodecPipeline` and byte-range
+ coalescing for partial reads of sharded arrays.
+
+ Added two runnable examples that accompany the post:
+ `examples/codec_pipeline_performance` compares the `BatchedCodecPipeline` and
+ `FusedCodecPipeline` on a sharded array across two stores and two codec
+ regimes, showing when the fused pipeline's thread pool helps and when it does
+ not, and `examples/sharding_coalescing` demonstrates how read coalescing
+ reduces the number of store requests when reading subregions of a sharded
+ array.
+
+ Also removed the hardware-specific speedup figures from the `FusedCodecPipeline`
+ release note, since they depend on the array layout, codec, and machine. ([#4191](https://github.com/zarr-developers/zarr-python/pull/4191))
+
+### Deprecations and Removals
+
+- The ``BloscShuffle`` and ``BloscCname`` enums (``zarr.codecs.BloscShuffle``,
+ ``zarr.codecs.BloscCname``) are now deprecated. Pass the equivalent literal
+ string (e.g. ``"zstd"``, ``"bitshuffle"``) when constructing a ``BloscCodec``.
+ The enum classes remain importable but emit ``DeprecationWarning`` on member
+ access, and will be removed in a future release. They are no longer ``Enum``
+ subclasses: constructor calls (e.g. ``BloscCname("zstd")``), iteration, and
+ ``.value`` access no longer work. ``BloscCodec.cname`` and
+ ``BloscCodec.shuffle`` are now plain strings rather than enum members.
+
+ Additional renames in ``zarr.codecs.blosc`` from the same change: the type
+ aliases ``Shuffle`` and ``CName`` are now ``BloscShuffleLiteral`` and
+ ``BloscCnameLiteral``, the constant ``SHUFFLE`` is now ``BLOSC_SHUFFLE``
+ (with a new ``BLOSC_CNAME`` alongside it), and ``BloscShuffle.from_int``
+ now returns a literal string rather than an enum member. ([#3963](https://github.com/zarr-developers/zarr-python/pull/3963))
+
+- The ``Endian`` (``zarr.codecs.bytes.Endian``) and ``ShardingCodecIndexLocation``
+ (``zarr.codecs.ShardingCodecIndexLocation``) enums are now deprecated. Pass the
+ equivalent literal string instead (e.g. ``"little"`` / ``"big"``, ``"start"`` /
+ ``"end"``). The enum classes remain importable but emit ``DeprecationWarning``
+ on member access, and will be removed in a future release. ``BytesCodec.endian``
+ and ``ShardingCodec.index_location`` are now plain strings rather than enum
+ members.
+
+ Two follow-on changes from this deprecation:
+
+ - ``NDBuffer.byteorder`` now returns a literal string (``"little"`` or
+ ``"big"``) rather than an ``Endian`` member. Subclasses overriding this
+ property should update their return type.
+ - The module-level binding ``zarr.codecs.bytes.default_system_endian`` was
+ removed. ``BytesCodec()`` continues to default to ``sys.byteorder``;
+ external callers that imported ``default_system_endian`` should use
+ ``sys.byteorder`` directly.
+
+ Additionally, the module-level function ``zarr.codecs.sharding.parse_index_location``
+ was made private as part of this change.
+
+ ([#3968](https://github.com/zarr-developers/zarr-python/pull/3968))
+
+- Removed the NumPy 1.x implementation of the `VariableLengthUTF8` data type because NumPy 1.x is no longer supported under [SPEC0](https://scientific-python.org/specs/spec-0000/). ([#3973](https://github.com/zarr-developers/zarr-python/pull/3973))
+
+### Misc
+
+- [#4139](https://github.com/zarr-developers/zarr-python/pull/4139), [#4140](https://github.com/zarr-developers/zarr-python/pull/4140), [#3908](https://github.com/zarr-developers/zarr-python/pull/3908), [#3972](https://github.com/zarr-developers/zarr-python/pull/3972), [#3975](https://github.com/zarr-developers/zarr-python/pull/3975), [#3979](https://github.com/zarr-developers/zarr-python/pull/3979), [#3990](https://github.com/zarr-developers/zarr-python/pull/3990), [#3998](https://github.com/zarr-developers/zarr-python/pull/3998), [#4000](https://github.com/zarr-developers/zarr-python/pull/4000), [#4001](https://github.com/zarr-developers/zarr-python/pull/4001), [#4012](https://github.com/zarr-developers/zarr-python/pull/4012), [#4046](https://github.com/zarr-developers/zarr-python/pull/4046), [#4054](https://github.com/zarr-developers/zarr-python/pull/4054), [#4073](https://github.com/zarr-developers/zarr-python/issues/4073), [#4086](https://github.com/zarr-developers/zarr-python/issues/4086), [#4138](https://github.com/zarr-developers/zarr-python/pull/4138)
+
+- [#4172](https://github.com/zarr-developers/zarr-python/pull/4172)
+
+## 3.2.1 (2026-05-05)
+
+### Bugfixes
+
+- Fixed a `CastValue` validation bug where the "can we use an out-of-range mode" check
+ inspected the source dtype instead of the target dtype. This meant arrays with a
+ float source dtype and an integer target dtype incorrectly raised a `ValueError`
+ when configured with a `wrap` out-of-range mode. ([#3938](https://github.com/zarr-developers/zarr-python/pull/3938))
+- Fixed a bug where the codec pipeline evolved each codec against the original
+ array spec instead of the spec produced by upstream array-to-array codecs. This
+ caused failures whenever an upstream codec changed the dtype between codec
+ boundaries β e.g. arrays using `CastValue` to convert a single-byte source dtype
+ (`int8`) to a multi-byte target dtype (`int16`) raised a `ValueError` from
+ `BytesCodec` about a missing `endian` configuration. ([#3941](https://github.com/zarr-developers/zarr-python/pull/3941))
+- Fixed breakage in existing fsspec-dependent workflows caused by associating the "memory" URL scheme with
+instances of `ManagedMemoryStore` instead of fsspec's memory-backed store. After this change, store URLs with a "memory" scheme are handled differently when `fsspec` is installed:
+with `fsspec`, a `FsspecStore` backed by a `MemoryFileSystem` is used. Without `fsspec`,
+a `ManagedMemoryStore` is used. ([#3944](https://github.com/zarr-developers/zarr-python/pull/3944))
+
+## 3.2.0 (2026-04-30)
+
+### Features
+
+- Adds a new in-memory storage backend called `ManagedMemoryStore`. Instances of `ManagedMemoryStore`
+ function similarly to `MemoryStore`, but instances of `ManagedMemoryStore` can be constructed from
+ a URL like `memory://store`. ([#3679](https://github.com/zarr-developers/zarr-python/pull/3679))
+- Added `array.read_missing_chunks` configuration option. When set to `False`, reading missing chunks raises a `ChunkNotFoundError` instead of filling them with the array's fill value. ([#3748](https://github.com/zarr-developers/zarr-python/pull/3748))
+- Added `Struct` class (subclass of `Structured`) implementing the zarr-extensions `struct` dtype spec. Uses object-style field format and dict fill values. Legacy `Structured` remains available for backward compatibility. ([#3781](https://github.com/zarr-developers/zarr-python/pull/3781))
+- Add support for rectilinear (variable-sized) chunk grids. This feature is experimental and
+ must be explicitly enabled via `zarr.config.set({'array.rectilinear_chunks': True})`.
+
+ Rectilinear chunks can be used through:
+
+ - **Creating arrays**: Pass nested sequences (e.g., `[[10, 20, 30], [50, 50]]`) to `chunks`
+ in `zarr.create_array`, `zarr.from_array`, `zarr.zeros`, `zarr.ones`, `zarr.full`,
+ `zarr.open`, and related functions, or to `chunk_shape` in `zarr.create`.
+ - **Opening existing arrays**: Arrays stored with the `rectilinear` chunk grid are read
+ transparently via `zarr.open` and `zarr.open_array`.
+ - **Rectilinear sharding**: Shard boundaries can be rectilinear while inner chunks remain regular.
+
+ **Breaking change**: The `validate` method on `BaseCodec` and `CodecPipeline` now receives
+ a `ChunkGridMetadata` instance instead of a `ChunkGrid` instance for the `chunk_grid`
+ parameter. Third-party codecs that override `validate` and inspect the chunk grid will need to
+ update their type annotations. No known downstream packages were using this parameter. ([#3802](https://github.com/zarr-developers/zarr-python/pull/3802))
+
+- Add `cast_value` and `scale_offset` codecs. ([#3874](https://github.com/zarr-developers/zarr-python/pull/3874))
+
+### Bugfixes
+
+- Fix `SyncError` raised when assigning a `zarr.Array` as the value in a `__setitem__` call (e.g. `dst[:] = src` where `src` is a zarr array). The source array is now converted to a NumPy array before entering the async codec pipeline. ([#3611](https://github.com/zarr-developers/zarr-python/issues/3611))
+- Fix an issue that prevents the correct parsing of special NumPy `uint32` dtypes resulting e.g.
+ from bit wise operations on `uint32` arrays on Windows. ([#3797](https://github.com/zarr-developers/zarr-python/pull/3797))
+- Fix `ZipStore.list()`, `list_dir()`, and `exists()` to auto-open the zip file when called before `open()`, consistent with the existing behavior of `get()` and `set()`. ([#3846](https://github.com/zarr-developers/zarr-python/issues/3846))
+- Fix handling of `NaT` default fill values for `datetime64` and `timedelta64` data types. Equality checks now use `numpy.isnat` so that the default fill value compares correctly against `NaT`. ([#3863](https://github.com/zarr-developers/zarr-python/pull/3863))
+- Use the unit associated with the `Datetime64` data type when creating the default `Nat` scalar value. ([#3920](https://github.com/zarr-developers/zarr-python/pull/3920))
+
+### Improved Documentation
+
+- Document removal of `zarr.storage.init_group` in v3 migration guide, with replacement using `zarr.open_group`/`zarr.create_group`. ([#2720](https://github.com/zarr-developers/zarr-python/issues/2720))
+- Document the `threading.max_workers` configuration option in the performance guide. ([#3492](https://github.com/zarr-developers/zarr-python/issues/3492))
+- Corrects the type annotation reported for the `batch_info` parameter in the `CodecPipeline.write`
+ method docstring. ([#3836](https://github.com/zarr-developers/zarr-python/pull/3836))
+- Remove result="ansi" from code blocks in the user guide that were causing empty output cells in the rendered documentation. ([#3845](https://github.com/zarr-developers/zarr-python/pull/3845))
+
+### Deprecations and Removals
+
+- Remove deprecated `zarr.convenience` and `zarr.creation` modules. ([#3900](https://github.com/zarr-developers/zarr-python/pull/3900))
+- Remove the deprecated `zarr_version` parameter from several functions and methods. That parameter is replaced with `zarr_format`. ([#3901](https://github.com/zarr-developers/zarr-python/pull/3901))
+- Remove deprecated `Group` methods `array`, `require_dataset`, and `create_dataset`. ([#3902](https://github.com/zarr-developers/zarr-python/pull/3902))
+- Remove deprecated `AsyncArray.create` and `Array.create` methods. ([#3903](https://github.com/zarr-developers/zarr-python/pull/3903))
+
+### Misc
+
+- [#3546](https://github.com/zarr-developers/zarr-python/issues/3546), [#3793](https://github.com/zarr-developers/zarr-python/pull/3793), [#3800](https://github.com/zarr-developers/zarr-python/pull/3800), [#3828](https://github.com/zarr-developers/zarr-python/pull/3828), [#3830](https://github.com/zarr-developers/zarr-python/pull/3830), [#3833](https://github.com/zarr-developers/zarr-python/pull/3833), [#3837](https://github.com/zarr-developers/zarr-python/pull/3837), [#3897](https://github.com/zarr-developers/zarr-python/pull/3897)
+
+
+## 3.1.6 (2026-03-19)
+
+### Features
+
+- Exposes the array runtime configuration as an attribute called `config` on the `Array` and
+ `AsyncArray` classes. The previous `AsyncArray._config` attribute is now a deprecated alias for `AsyncArray.config`. ([#3668](https://github.com/zarr-developers/zarr-python/pull/3668))
+- Adds a method for creating a new `Array` / `AsyncArray` instance with a new runtime configuration, and fixes inaccurate documentation about the `write_empty_chunks` configuration parameter. ([#3668](https://github.com/zarr-developers/zarr-python/pull/3668))
+- Adds synchronous methods to stores that do not benefit from an async event loop. The shape of these methods is defined by protocol classes to support structural subtyping. ([#3725](https://github.com/zarr-developers/zarr-python/pull/3725))
+- Fix near-miss penalty in `_morton_order` with hybrid ceiling+argsort strategy. ([#3718](https://github.com/zarr-developers/zarr-python/pull/3718))
+
+### Bugfixes
+
+- Correct the target bytes number for auto-chunking when auto-sharding. ([#3603](https://github.com/zarr-developers/zarr-python/pull/3603))
+- Fixed a bug in the sharding codec that prevented nested shard reads in certain cases. ([#3655](https://github.com/zarr-developers/zarr-python/pull/3655))
+- Fix obstore `_transform_list_dir` implementation to correctly relativize paths (removing `lstrip` usage). ([#3657](https://github.com/zarr-developers/zarr-python/pull/3657))
+- Raise error when trying to encode `numpy.dtypes.StringDType` with `na_object` set. ([#3695](https://github.com/zarr-developers/zarr-python/pull/3695))
+- `CacheStore`, `LoggingStore` and `LatencyStore` now support with_read_only. ([#3700](https://github.com/zarr-developers/zarr-python/pull/3700))
+- Skip chunk coordinate enumeration in resize when the array is only growing, avoiding unbounded memory usage for large arrays. ([#3702](https://github.com/zarr-developers/zarr-python/pull/3702))
+- Fix a performance bug in morton curve generation. ([#3705](https://github.com/zarr-developers/zarr-python/pull/3705))
+- Add a dedicated in-memory cache for byte-range requests to the experimental `CacheStore`. ([#3710](https://github.com/zarr-developers/zarr-python/pull/3710))
+- `BaseFloat._check_scalar` rejects invalid string values. ([#3586](https://github.com/zarr-developers/zarr-python/issues/3586))
+- Apply drop_axes squeeze in partial decode path for sharding. ([#3763](https://github.com/zarr-developers/zarr-python/pull/3763))
+- Set `copy=False` in reshape operation. ([#3649](https://github.com/zarr-developers/zarr-python/pull/3649))
+- Validate that dask-style chunks have regular shapes. ([#3779](https://github.com/zarr-developers/zarr-python/pull/3779))
+
+### Improved Documentation
+
+- Add documentation example for creating uncompressed arrays in the Compression section of the user guide. ([#3464](https://github.com/zarr-developers/zarr-python/issues/3464))
+- Add AI-assisted code policy to the contributing guide. ([#3769](https://github.com/zarr-developers/zarr-python/pull/3769))
+- Added a glossary. ([#3767](https://github.com/zarr-developers/zarr-python/pull/3767))
+
+### Misc
+
+- [#3562](https://github.com/zarr-developers/zarr-python/pull/3562), [#3605](https://github.com/zarr-developers/zarr-python/pull/3605), [#3619](https://github.com/zarr-developers/zarr-python/pull/3619), [#3623](https://github.com/zarr-developers/zarr-python/pull/3623), [#3636](https://github.com/zarr-developers/zarr-python/pull/3636), [#3648](https://github.com/zarr-developers/zarr-python/pull/3648), [#3656](https://github.com/zarr-developers/zarr-python/pull/3656), [#3658](https://github.com/zarr-developers/zarr-python/pull/3658), [#3673](https://github.com/zarr-developers/zarr-python/pull/3673), [#3704](https://github.com/zarr-developers/zarr-python/pull/3704), [#3706](https://github.com/zarr-developers/zarr-python/pull/3706), [#3708](https://github.com/zarr-developers/zarr-python/pull/3708), [#3712](https://github.com/zarr-developers/zarr-python/pull/3712), [#3713](https://github.com/zarr-developers/zarr-python/pull/3713), [#3717](https://github.com/zarr-developers/zarr-python/pull/3717), [#3721](https://github.com/zarr-developers/zarr-python/pull/3721), [#3728](https://github.com/zarr-developers/zarr-python/pull/3728), [#3778](https://github.com/zarr-developers/zarr-python/pull/3778)
+
+
+## 3.1.5 (2025-11-21)
+
+### Bugfixes
+
+- Fix formatting errors in the release notes section of the docs. ([#3594](https://github.com/zarr-developers/zarr-python/pull/3594))
+
+
+## 3.1.4 (2025-11-20)
+
+### Features
+
+- The `Array` class can now also be parametrized in the same manner as the `AsyncArray` class, allowing Zarr format v2 and v3 `Array`s to be distinguished.
+ New types have been added to `zarr.types` to help with this. ([#3304](https://github.com/zarr-developers/zarr-python/pull/3304))
+- Adds `zarr.experimental.cache_store.CacheStore`, a `Store` that implements caching by combining two other `Store` instances. See the [docs page](https://zarr.readthedocs.io/en/latest/user-guide/experimental#cachestore) for more information about this feature. ([#3366](https://github.com/zarr-developers/zarr-python/pull/3366))
+- Adds a `zarr.experimental` module for unstable user-facing features. ([#3490](https://github.com/zarr-developers/zarr-python/pull/3490))
+- Add a `array.target_shard_size_bytes` to [`zarr.config`][] to allow users to set a maximum number of bytes per-shard when `shards="auto"` in, for example, [`zarr.create_array`][]. ([#3547](https://github.com/zarr-developers/zarr-python/pull/3547))
+- Make `async_array` on the [`zarr.Array`][] class public (`_async_array` will remain untouched, but its stability is not guaranteed). ([#3556](https://github.com/zarr-developers/zarr-python/pull/3556))
+
+### Bugfixes
+
+- Fix a bug that prevented `PCodec` from being properly resolved when loading arrays using that compressor. ([#3483](https://github.com/zarr-developers/zarr-python/pull/3483))
+- Fixed a bug that prevented Zarr Python from opening Zarr V3 array metadata documents that contained
+ extra keys with permissible values (dicts with a `"must_understand"` key set to `"false"`). ([#3530](https://github.com/zarr-developers/zarr-python/pull/3530))
+- Fixed a bug where the `"consolidated_metadata"` key was written to metadata documents even when
+ consolidated metadata was not used, resulting in invalid metadata documents. ([#3535](https://github.com/zarr-developers/zarr-python/pull/3535))
+- Improve write performance to large shards by up to 10x. ([#3560](https://github.com/zarr-developers/zarr-python/issues/3560))
+
+### Improved Documentation
+
+- Use mkdocs-material for Zarr-Python documentation ([#3118](https://github.com/zarr-developers/zarr-python/pull/3118))
+- Document different values of StoreLike with examples in the user guide. ([#3303](https://github.com/zarr-developers/zarr-python/issues/3303))
+- Reorganize the top-level `examples` directory to give each example its own sub-directory. Adds content to the docs for each example. ([#3502](https://github.com/zarr-developers/zarr-python/pull/3502))
+- Updated 3.0 Migration Guide to include function signature change to zarr.Array.resize function. ([#3536](https://github.com/zarr-developers/zarr-python/issues/3536))
+
+### Misc
+
+- [#3515](https://github.com/zarr-developers/zarr-python/pull/3515), [#3532](https://github.com/zarr-developers/zarr-python/pull/3532), [#3533](https://github.com/zarr-developers/zarr-python/pull/3533), [#3553](https://github.com/zarr-developers/zarr-python/pull/3553)
+
+
+## 3.1.3 (2025-09-18)
+
+### Features
+
+- Add a command-line interface to migrate v2 Zarr metadata to v3. Corresponding functions are also provided under zarr.metadata. ([#1798](https://github.com/zarr-developers/zarr-python/issues/1798))
+- Add obstore implementation of delete_dir. ([#3310](https://github.com/zarr-developers/zarr-python/pull/3310))
+- Adds a registry for chunk key encodings for extensibility. This allows users to implement a custom `ChunkKeyEncoding`, which can be registered via `register_chunk_key_encoding` or as an entry point under `zarr.chunk_key_encoding`. ([#3436](https://github.com/zarr-developers/zarr-python/pull/3436))
+- Trying to open a group at a path where an array already exists now raises a helpful error. ([#3444](https://github.com/zarr-developers/zarr-python/pull/3444))
+
+### Bugfixes
+
+- Prevents creation of groups (.create_group) or arrays (.create_array) as children of an existing array. ([#2582](https://github.com/zarr-developers/zarr-python/issues/2582))
+- Fix a bug preventing `ones_like`, `full_like`, `empty_like`, `zeros_like` and `open_like` functions from accepting an explicit specification of array attributes like shape, dtype, chunks etc. The functions `full_like`, `empty_like`, and `open_like` now also more consistently infer a `fill_value` parameter from the provided array. ([#2992](https://github.com/zarr-developers/zarr-python/pull/2992))
+- LocalStore now uses atomic writes, which should prevent some cases of corrupted data. ([#3411](https://github.com/zarr-developers/zarr-python/issues/3411))
+- Fix a potential race condition when using `zarr.create_array` with the `data` parameter set to a NumPy array. Previously Zarr was iterating over the newly created array with a granularity that was too low. Now Zarr chooses a granularity that matches the size of the stored objects for that array. ([#3422](https://github.com/zarr-developers/zarr-python/pull/3422))
+- Fix ChunkGrid definition (broken in 3.1.2) ([#3425](https://github.com/zarr-developers/zarr-python/pull/3425))
+- Ensure syntax like `root['/subgroup']` works equivalently to `root['subgroup']` when using consolidated metadata. ([#3428](https://github.com/zarr-developers/zarr-python/pull/3428))
+- Creating a new group with `zarr.group` no longer errors. This fixes a regression introduced in version 3.1.2. ([#3431](https://github.com/zarr-developers/zarr-python/pull/3431))
+- Setting `fill_value` to a float like `0.0` when the data type of the array is an integer is a common mistake. This change lets Zarr Python read arrays with this erroneous metadata, although Zarr Python will not create such arrays. ([#3448](https://github.com/zarr-developers/zarr-python/pull/3448))
+
+### Deprecations and Removals
+
+- The `Store.set_partial_writes` method, which was not used by Zarr-Python, has been removed. `store.supports_partial_writes` is now always `False`. ([#2859](https://github.com/zarr-developers/zarr-python/issues/2859))
+
+### Misc
+
+- [#3376](https://github.com/zarr-developers/zarr-python/pull/3376), [#3390](https://github.com/zarr-developers/zarr-python/pull/3390), [#3403](https://github.com/zarr-developers/zarr-python/pull/3403), [#3449](https://github.com/zarr-developers/zarr-python/pull/3449)
+
+## 3.1.2 (2025-08-25)
+
+### Features
+
+- Added support for async vectorized and orthogonal indexing. ([#3083](https://github.com/zarr-developers/zarr-python/pull/3083))
+- Make config param optional in init_array ([#3391](https://github.com/zarr-developers/zarr-python/pull/3391))
+
+### Bugfixes
+
+- Ensure that -0.0 is not considered equal to 0.0 when checking if all the values in a chunk are equal to an array's fill value. ([#3144](https://github.com/zarr-developers/zarr-python/issues/3144))
+- Fix a bug in `create_array` caused by iterating over chunk-aligned regions instead of shard-aligned regions when writing data. Additionally, the behavior of `nchunks_initialized` has been adjusted. This function consistently reports the number of chunks present in stored objects, even when the array uses the sharding codec. ([#3299](https://github.com/zarr-developers/zarr-python/pull/3299))
+- Opening an array or group with `mode="r+"` will no longer create new arrays or groups. ([#3307](https://github.com/zarr-developers/zarr-python/pull/3307))
+- Added `zarr.errors.ArrayNotFoundError`, which is raised when attempting to open a zarr array that does not exist, and `zarr.errors.NodeNotFoundError`, which is raised when failing to open an array or a group in a context where either an array or a group was expected. ([#3367](https://github.com/zarr-developers/zarr-python/pull/3367))
+- Ensure passing `config` is handled properly when `open`ing an existing array. ([#3378](https://github.com/zarr-developers/zarr-python/pull/3378))
+- Raise a Zarr-specific error class when a codec can't be found by name when deserializing the given codecs. This avoids hiding this error behind a "not part of a zarr hierarchy" warning. ([#3395](https://github.com/zarr-developers/zarr-python/pull/3395))
+
+### Misc
+
+- [#3098](https://github.com/zarr-developers/zarr-python/pull/3098), [#3288](https://github.com/zarr-developers/zarr-python/pull/3288), [#3318](https://github.com/zarr-developers/zarr-python/pull/3318), [#3368](https://github.com/zarr-developers/zarr-python/issues/3368), [#3371](https://github.com/zarr-developers/zarr-python/pull/3371), [#3372](https://github.com/zarr-developers/zarr-python/pull/3372), [#3374](https://github.com/zarr-developers/zarr-python/pull/3374)
+
+## 3.1.1 (2025-07-28)
+
+### Features
+
+- Add lightweight implementations of `.getsize()` and `.getsize_prefix()` for ObjectStore. ([#3227](https://github.com/zarr-developers/zarr-python/pull/3227))
+
+### Bugfixes
+
+- Creating a Zarr format 2 array with the `order` keyword argument no longer raises a warning. ([#3112](https://github.com/zarr-developers/zarr-python/pull/3112))
+- Fixed the error message when passing both `config` and `write_empty_chunks` arguments to reflect the current behaviour (`write_empty_chunks` takes precedence). ([#3112](https://github.com/zarr-developers/zarr-python/pull/3112))
+- Creating a Zarr format 3 array with the `order` argument now consistently ignores this argument and raises a warning. ([#3112](https://github.com/zarr-developers/zarr-python/pull/3112))
+- When using [`from_array`][zarr.api.asynchronous.from_array] to copy a Zarr format 2 array to a Zarr format 3 array, if the memory order of the input array is `"F"` a warning is raised and the order ignored. This is because Zarr format 3 arrays are always stored in "C" order. ([#3112](https://github.com/zarr-developers/zarr-python/pull/3112))
+- The `config` argument to [`zarr.create`][zarr.create] (and functions that create arrays) is now used - previously it had no effect. ([#3112](https://github.com/zarr-developers/zarr-python/pull/3112))
+- Ensure that all abstract methods of [`ZDType`][zarr.core.dtype.ZDType] raise a `NotImplementedError` when invoked. ([#3251](https://github.com/zarr-developers/zarr-python/pull/3251))
+- Register 'gpu' marker with pytest for downstream StoreTests. ([#3258](https://github.com/zarr-developers/zarr-python/pull/3258))
+- Expand the range of types accepted by `parse_data_type` to include strings and Sequences.
+- Move the functionality of `zarr.core.dtype.parse_data_type` to a new function called `zarr.dtype.parse_dtype`. This change ensures that nomenclature is consistent across the codebase. `zarr.core.dtype.parse_data_type` remains, so this change is not breaking. ([#3264](https://github.com/zarr-developers/zarr-python/pull/3264))
+- Fix a regression introduced in 3.1.0 that prevented `inf`, `-inf`, and `nan` values from being stored in `attributes`. ([#3280](https://github.com/zarr-developers/zarr-python/pull/3280))
+- Fixes [`Group.nmembers()`][zarr.Group.nmembers] ignoring depth when using consolidated metadata. ([#3287](https://github.com/zarr-developers/zarr-python/pull/3287))
+
+### Improved Documentation
+
+- Expand the data type docs to include a demonstration of the `parse_data_type` function. Expand the docstring for the `parse_data_type` function. ([#3249](https://github.com/zarr-developers/zarr-python/pull/3249))
+- Add a section on codecs to the migration guide. ([#3273](https://github.com/zarr-developers/zarr-python/pull/3273))
+
+### Misc
+
+- Remove warnings about vlen-utf8 and vlen-bytes codecs ([#3268](https://github.com/zarr-developers/zarr-python/pull/3268))
+
+## 3.1.0 (2025-07-14)
+
+### Features
+
+- Ensure that invocations of `create_array` use consistent keyword arguments, with consistent defaults.
+
+ [`zarr.api.synchronous.create_array`][] now takes a `write_data` keyword argument
+ The `Group.create_array` method takes `data` and `write_data` keyword arguments.
+ The functions [`zarr.api.asynchronous.create`][], [`zarr.api.asynchronous.create_array`]
+ and the methods `Group.create_array`, `Group.array`, had the default
+ `fill_value` changed from `0` to the `DEFAULT_FILL_VALUE` value, which instructs Zarr to
+ use the default scalar value associated with the array's data type as the fill value. These are
+ all functions or methods for array creation that mirror, wrap or are wrapped by, another function
+ that already has a default `fill_value` set to `DEFAULT_FILL_VALUE`. This change is necessary
+ to make these functions consistent across the entire codebase, but as this changes default values,
+ new data might have a different fill value than expected after this change.
+
+ For data types where 0 is meaningful, like integers or floats, the default scalar is 0, so this
+ change should not be noticeable. For data types where 0 is ambiguous, like fixed-length unicode
+ strings, the default fill value might be different after this change. Users who were relying on how
+ Zarr interpreted `0` as a non-numeric scalar value should set their desired fill value explicitly
+ after this change.
+
+- Added public API for Buffer ABCs and implementations.
+
+ Use `zarr.buffer` to access buffer implementations, and
+ `zarr.abc.buffer` for the interface to implement new buffer types.
+
+ Users previously importing buffer from `zarr.core.buffer` should update their
+ imports to use `zarr.buffer`. As a reminder, all of `zarr.core` is
+ considered a private API that's not covered by zarr-python's versioning policy. ([#2871](https://github.com/zarr-developers/zarr-python/issues/2871))
+
+- Adds zarr-specific data type classes.
+
+ This change adds a `ZDType` base class for Zarr V2 and Zarr V3 data types. Child classes are
+ defined for each NumPy data type. Each child class defines routines for `JSON` serialization.
+ New data types can be created and registered dynamically.
+
+ Prior to this change, Zarr Python had two streams for handling data types. For Zarr V2 arrays,
+ we used NumPy data type identifiers. For Zarr V3 arrays, we used a fixed set of string enums. Both
+ of these systems proved hard to extend.
+
+ This change is largely internal, but it does change the type of the `dtype` and `data_type`
+ fields on the `ArrayV2Metadata` and `ArrayV3Metadata` classes. Previously, `ArrayV2Metadata.dtype`
+ was a NumPy `dtype` object, and `ArrayV3Metadata.data_type` was an internally-defined `enum`.
+ After this change, both `ArrayV2Metadata.dtype` and `ArrayV3Metadata.data_type` are instances of
+ `ZDType`. A NumPy data type can be generated from a `ZDType` via the `ZDType.to_native_dtype()`
+ method. The internally-defined Zarr V3 `enum` class is gone entirely, but the `ZDType.to_json(zarr_format=3)`
+ method can be used to generate either a string, or dictionary that has a string `name` field, that
+ represents the string value previously associated with that `enum`.
+
+ For more on this new feature, see the [documentation](user-guide/data_types.md) ([#2874](https://github.com/zarr-developers/zarr-python/pull/2874))
+
+- Added `NDBuffer.empty` method for faster ndbuffer initialization. ([#3191](https://github.com/zarr-developers/zarr-python/pull/3191))
+
+- The minimum version of NumPy has increased to 1.26. ([#3226](https://github.com/zarr-developers/zarr-python/pull/3226))
+
+- Add an alternate `from_array_metadata_and_store` constructor to `CodecPipeline`. ([#3233](https://github.com/zarr-developers/zarr-python/pull/3233))
+
+### Bugfixes
+
+- Fixes a variety of issues related to string data types.
+
+ - Brings the `VariableLengthUTF8` data type Zarr V3 identifier in alignment with Zarr Python 3.0.8
+ - Disallows creation of 0-length fixed-length data types
+ - Adds a regression test for the `VariableLengthUTF8` data type that checks against version 3.0.8
+ - Allows users to request the `VariableLengthUTF8` data type with `str`, `"str"`, or `"string"`. ([#3170](https://github.com/zarr-developers/zarr-python/pull/3170))
+
+- Add human readable size for No. bytes stored to `info_complete` ([#3190](https://github.com/zarr-developers/zarr-python/pull/3190))
+
+- Restores the ability to create a Zarr V2 array with a `null` fill value by introducing a new
+ class `DefaultFillValue`, and setting the default value of the `fill_value` parameter in array
+ creation routines to an instance of `DefaultFillValue`. For Zarr V3 arrays, `None` will act as an
+ alias for a `DefaultFillValue` instance, thus preserving compatibility with existing code. ([#3198](https://github.com/zarr-developers/zarr-python/pull/3198))
+
+- Fix the type of `ArrayV2Metadata.codec` to constrain it to `numcodecs.abc.Codec | None`.
+ Previously the type was more permissive, allowing objects that can be parsed into Codecs (e.g., the codec name).
+ The constructor of `ArrayV2Metadata` still allows the permissive input when creating new objects. ([#3232](https://github.com/zarr-developers/zarr-python/pull/3232))
+
+### Improved Documentation
+
+- Add a self-contained example of data type extension to the `examples` directory, and expanded
+ the documentation for data types. ([#3157](https://github.com/zarr-developers/zarr-python/pull/3157))
+
+- Add a description on how to create a RemoteStore of a specific filesystem to the `Remote Store` section in `docs/user-guide/storage.md`.
+ State in the docstring of `FsspecStore.from_url` that the filesystem type is inferred from the URL scheme.
+
+ It should help a user handling the case when the type of FsspecStore doesn't match the URL scheme. ([#3212](https://github.com/zarr-developers/zarr-python/pull/3212))
+
+### Deprecations and Removals
+
+- Removes default chunk encoding settings (filters, serializer, compressors) from the global
+ configuration object.
+
+ This removal is justified on the basis that storing chunk encoding settings in the config required
+ a brittle, confusing, and inaccurate categorization of array data types, which was particularly
+ unsuitable after the recent addition of new data types that didn't fit naturally into the
+ pre-existing categories.
+
+ The default chunk encoding is the same (Zstandard compression, and the required object codecs for
+ variable length data types), but the chunk encoding is now generated by functions that cannot be
+ reconfigured at runtime. Users who relied on setting the default chunk encoding via the global configuration object should
+ instead specify the desired chunk encoding explicitly when creating an array.
+
+ This change also adds an extra validation step to the creation of Zarr V2 arrays, which ensures that
+ arrays with a `VariableLengthUTF8` or `VariableLengthBytes` data type cannot be created without the
+ correct "object codec". ([#3228](https://github.com/zarr-developers/zarr-python/pull/3228))
+
+- Removes support for passing keyword-only arguments positionally to the following functions and methods:
+ `save_array`, `open`, `group`, `open_group`, `create`, `get_basic_selection`, `set_basic_selection`,
+ `get_orthogonal_selection`, `set_orthogonal_selection`, `get_mask_selection`, `set_mask_selection`,
+ `get_coordinate_selection`, `set_coordinate_selection`, `get_block_selection`, `set_block_selection`,
+ `Group.create_array`, `Group.empty`, `Group.zeroes`, `Group.ones`, `Group.empty_like`, `Group.full`,
+ `Group.zeros_like`, `Group.ones_like`, `Group.full_like`, `Group.array`. Prior to this change,
+ passing a keyword-only argument positionally to one of these functions or methods would raise a
+ deprecation warning. That warning is now gone. Passing keyword-only arguments to these functions
+ and methods positionally is now an error.
+
+## 3.0.10 (2025-07-03)
+
+### Bugfixes
+
+- Removed an unnecessary check from `_fsspec._make_async` that would raise an exception when
+ creating a read-only store backed by a local file system with `auto_mkdir` set to `False`. ([#3193](https://github.com/zarr-developers/zarr-python/pull/3193))
+
+- Add missing import for AsyncFileSystemWrapper for _make_async in _fsspec.py ([#3195](https://github.com/zarr-developers/zarr-python/pull/3195))
+
+## 3.0.9 (2025-06-30)
+
+### Features
+
+- Add `zarr.storage.FsspecStore.from_mapper()` so that `zarr.open()` supports stores of type `fsspec.mapping.FSMap`. ([#2774](https://github.com/zarr-developers/zarr-python/pull/2774))
+
+- Implemented `move` for `LocalStore` and `ZipStore`. This allows users to move the store to a different root path. ([#3021](https://github.com/zarr-developers/zarr-python/pull/3021))
+
+- Added `zarr.errors.GroupNotFoundError`, which is raised when attempting to open a group that does not exist. ([#3066](https://github.com/zarr-developers/zarr-python/pull/3066))
+
+- Adds `fill_value` to the list of attributes displayed in the output of the `AsyncArray.info()` method. ([#3081](https://github.com/zarr-developers/zarr-python/pull/3081))
+
+- Use `numpy.zeros` instead of `np.full` for a performance speedup when creating a `zarr.core.buffer.NDBuffer` with `fill_value=0`. ([#3082](https://github.com/zarr-developers/zarr-python/pull/3082))
+
+- Port more stateful testing actions from [Icechunk](https://icechunk.io/en/stable/). ([#3130](https://github.com/zarr-developers/zarr-python/pull/3130))
+
+- Adds a `with_read_only` convenience method to the `Store` abstract base class (raises `NotImplementedError`) and implementations to the `MemoryStore`, `ObjectStore`, `LocalStore`, and `FsspecStore` classes. ([#3138](https://github.com/zarr-developers/zarr-python/pull/3138))
+
+### Bugfixes
+
+- Ignore stale child metadata when reconsolidating metadata. ([#2921](https://github.com/zarr-developers/zarr-python/issues/2921))
+
+- For Zarr format 2, allow fixed-length string arrays to be created without automatically inserting a
+ `Vlen-UT8` codec in the array of filters. Fixed-length string arrays do not need this codec. This
+ change fixes a regression where fixed-length string arrays created with Zarr Python 3 could not be read with Zarr Python 2.18. ([#3100](https://github.com/zarr-developers/zarr-python/pull/3100))
+
+- When creating arrays without explicitly specifying a chunk size using `zarr.create` and other
+ array creation routines, the chunk size will now set automatically instead of defaulting to the data shape.
+ For large arrays this will result in smaller default chunk sizes.
+ To retain previous behaviour, explicitly set the chunk shape to the data shape.
+
+ This fix matches the existing chunking behaviour of
+ `zarr.save_array` and `zarr.api.asynchronous.AsyncArray.create`. ([#3103](https://github.com/zarr-developers/zarr-python/pull/3103))
+
+- When `zarr.save` has an argument `path=some/path/` and multiple arrays in `args`, the path resulted in `some/path/some/path` due to using the `path`
+ argument twice while building the array path. This is now fixed. ([#3127](https://github.com/zarr-developers/zarr-python/pull/3127))
+
+- Fix `zarr.open` default for argument `mode` when `store` is `read_only` ([#3128](https://github.com/zarr-developers/zarr-python/pull/3128))
+
+- Suppress `FileNotFoundError` when deleting non-existent keys in the `obstore` adapter.
+
+ When writing empty chunks (i.e. chunks where all values are equal to the array's fill value) to a zarr array, zarr
+ will delete those chunks from the underlying store. For zarr arrays backed by the `obstore` adapter, this will potentially
+ raise a `FileNotFoundError` if the chunk doesn't already exist.
+ Since whether or not a delete of a non-existing object raises an error depends on the behavior of the underlying store,
+ suppressing the error in all cases results in consistent behavior across stores, and is also what `zarr` seems to expect
+ from the store. ([#3140](https://github.com/zarr-developers/zarr-python/pull/3140))
+
+- Trying to open a StorePath/Array with `mode='r'` when the store is not read-only creates a read-only copy of the store. ([#3156](https://github.com/zarr-developers/zarr-python/pull/3156))
+
+## 3.0.8 (2025-05-19)
+
+!!! warning
+
+ In versions 3.0.0 to 3.0.7 opening arrays or groups with `mode='a'` (the default for many builtin functions) would cause any existing paths in the store to be deleted. This is fixed in 3.0.8, and we recommend all users upgrade to avoid this bug that could cause unintentional data loss.
+
+### Features
+
+- Added a `print_debug_info` function for bug reports. ([#2913](https://github.com/zarr-developers/zarr-python/pull/2913))
+
+### Bugfixes
+
+- Fix a bug that prevented the number of initialized chunks being counted properly. ([#2862](https://github.com/zarr-developers/zarr-python/pull/2862))
+- Fixed sharding with GPU buffers. ([#2978](https://github.com/zarr-developers/zarr-python/pull/2978))
+- Fix structured `dtype` fill value serialization for consolidated metadata ([#2998](https://github.com/zarr-developers/zarr-python/issues/2998))
+- It is now possible to specify no compressor when creating a zarr format 2 array.
+ This can be done by passing `compressor=None` to the various array creation routines.
+
+ The default behaviour of automatically choosing a suitable default compressor remains if the compressor argument is not given.
+ To reproduce the behaviour in previous zarr-python versions when `compressor=None` was passed, pass `compressor='auto'` instead. ([#3039](https://github.com/zarr-developers/zarr-python/pull/3039))
+
+- Fixed the typing of `dimension_names` arguments throughout so that it now accepts iterables that contain `None` alongside `str`. ([#3045](https://github.com/zarr-developers/zarr-python/pull/3045))
+- Using various functions to open data with `mode='a'` no longer deletes existing data in the store. ([#3062](https://github.com/zarr-developers/zarr-python/pull/3062))
+- Internally use `typesize` constructor parameter for `numcodecs.blosc.Blosc` to improve compression ratios back to the v2-package levels. ([#2962](https://github.com/zarr-developers/zarr-python/pull/2962))
+- Specifying the memory order of Zarr format 2 arrays using the `order` keyword argument has been fixed. ([#2950](https://github.com/zarr-developers/zarr-python/issues/2950))
+
+### Misc
+
+- [#2972](https://github.com/zarr-developers/zarr-python/pull/2972), [#3027](https://github.com/zarr-developers/zarr-python/pull/3027), [#3049](https://github.com/zarr-developers/zarr-python/pull/3049)
+
+## 3.0.7 (2025-04-22)
+
+### Features
+
+- Add experimental ObjectStore storage class based on obstore. ([#1661](https://github.com/zarr-developers/zarr-python/pull/1661))
+- Add `zarr.from_array` using concurrent streaming of source data ([#2622](https://github.com/zarr-developers/zarr-python/pull/2622))
+
+### Bugfixes
+
+- 0-dimensional arrays are now returning a scalar. Therefore, the return type of `__getitem__` changed
+ to NDArrayLikeOrScalar. This change is to make the behavior of 0-dimensional arrays consistent with
+ `numpy` scalars. ([#2718](https://github.com/zarr-developers/zarr-python/pull/2718))
+- Fix `fill_value` serialization for `NaN` in `ArrayV2Metadata` and add property-based testing of round-trip serialization ([#2802](https://github.com/zarr-developers/zarr-python/pull/2802))
+- Fixes `ConsolidatedMetadata` serialization of `nan`, `inf`, and `-inf` to be
+ consistent with the behavior of `ArrayMetadata`. ([#2996](https://github.com/zarr-developers/zarr-python/pull/2996))
+
+### Improved Documentation
+
+- Updated the 3.0 migration guide to include the removal of "." syntax for getting group members. ([#2991](https://github.com/zarr-developers/zarr-python/issues/2991), [#2997](https://github.com/zarr-developers/zarr-python/pull/2997))
+
+### Misc
+
+- Define a new versioning policy based on Effective Effort Versioning. This replaces the old Semantic
+ Versioning-based policy. ([#2924](https://github.com/zarr-developers/zarr-python/issues/2924), [#2910](https://github.com/zarr-developers/zarr-python/pull/2910))
+- Make warning filters in the tests more specific, so warnings emitted by tests added in the future
+ are more likely to be caught instead of ignored. ([#2714](https://github.com/zarr-developers/zarr-python/pull/2714))
+- Avoid an unnecessary memory copy when writing Zarr to a local file ([#2944](https://github.com/zarr-developers/zarr-python/pull/2944))
+
+## 3.0.6 (2025-03-20)
+
+### Bugfixes
+
+- Restore functionality of `del z.attrs['key']` to actually delete the key. ([#2908](https://github.com/zarr-developers/zarr-python/pull/2908))
+
+## 3.0.5 (2025-03-07)
+
+### Bugfixes
+
+- Fixed a bug where `StorePath` creation would not apply standard path normalization to the `path` parameter,
+ which led to the creation of arrays and groups with invalid keys. ([#2850](https://github.com/zarr-developers/zarr-python/pull/2850))
+- Prevent update_attributes calls from deleting old attributes ([#2870](https://github.com/zarr-developers/zarr-python/pull/2870))
+
+### Misc
+
+- [#2796](https://github.com/zarr-developers/zarr-python/pull/2796)
+
+## 3.0.4 (2025-02-23)
+
+### Features
+
+- Adds functions for concurrently creating multiple arrays and groups. ([#2665](https://github.com/zarr-developers/zarr-python/pull/2665))
+
+### Bugfixes
+
+- Fixed a bug where `ArrayV2Metadata` could save `filters` as an empty array. ([#2847](https://github.com/zarr-developers/zarr-python/pull/2847))
+- Fix a bug when setting values of a smaller last chunk. ([#2851](https://github.com/zarr-developers/zarr-python/pull/2851))
+
+### Misc
+
+- [#2828](https://github.com/zarr-developers/zarr-python/pull/2828)
+
+## 3.0.3 (2025-02-14)
+
+### Features
+
+- Improves performance of FsspecStore.delete_dir for remote filesystems supporting concurrent/batched deletes, e.g., s3fs. ([#2661](https://github.com/zarr-developers/zarr-python/pull/2661))
+- Added `zarr.config.enable_gpu` to update Zarr's configuration to use GPUs. ([#2751](https://github.com/zarr-developers/zarr-python/pull/2751))
+- Avoid reading chunks during writes where possible. [#757](https://github.com/zarr-developers/zarr-python/issues/757) ([#2784](https://github.com/zarr-developers/zarr-python/pull/2784))
+- `LocalStore` learned to `delete_dir`. This makes array and group deletes more efficient. ([#2804](https://github.com/zarr-developers/zarr-python/pull/2804))
+- Add `zarr.testing.strategies.array_metadata` to generate ArrayV2Metadata and ArrayV3Metadata instances. ([#2813](https://github.com/zarr-developers/zarr-python/pull/2813))
+- Add arbitrary `shards` to Hypothesis strategy for generating arrays. ([#2822](https://github.com/zarr-developers/zarr-python/pull/2822))
+
+### Bugfixes
+
+- Fixed bug with Zarr using device memory, instead of host memory, for storing metadata when using GPUs. ([#2751](https://github.com/zarr-developers/zarr-python/pull/2751))
+- The array returned by `zarr.empty` and an empty `zarr.core.buffer.cpu.NDBuffer` will now be filled with the
+ specified fill value, or with zeros if no fill value is provided.
+ This fixes a bug where Zarr format 2 data with no fill value was written with un-predictable chunk sizes. ([#2755](https://github.com/zarr-developers/zarr-python/pull/2755))
+- Fix zip-store path checking for stores with directories listed as files. ([#2758](https://github.com/zarr-developers/zarr-python/pull/2758))
+- Use removeprefix rather than replace when removing filename prefixes in `FsspecStore.list` ([#2778](https://github.com/zarr-developers/zarr-python/pull/2778))
+- Enable automatic removal of `needs release notes` with labeler action ([#2781](https://github.com/zarr-developers/zarr-python/pull/2781))
+- Use the proper label config ([#2785](https://github.com/zarr-developers/zarr-python/pull/2785))
+- Alters the behavior of `create_array` to ensure that any groups implied by the array's name are created if they do not already exist. Also simplifies the type signature for any function that takes an ArrayConfig-like object. ([#2795](https://github.com/zarr-developers/zarr-python/pull/2795))
+- Enitialise empty chunks to the default fill value during writing and add default fill values for datetime, timedelta, structured, and other (void* fixed size) data types ([#2799](https://github.com/zarr-developers/zarr-python/pull/2799))
+- Ensure utf8 compliant strings are used to construct numpy arrays in property-based tests ([#2801](https://github.com/zarr-developers/zarr-python/pull/2801))
+- Fix pickling for ZipStore ([#2807](https://github.com/zarr-developers/zarr-python/pull/2807))
+- Update numcodecs to not overwrite codec configuration ever. Closes [#2800](https://github.com/zarr-developers/zarr-python/issues/2800). ([#2811](https://github.com/zarr-developers/zarr-python/pull/2811))
+- Fix fancy indexing (e.g. arr[5, [0, 1]]) with the sharding codec ([#2817](https://github.com/zarr-developers/zarr-python/pull/2817))
+
+### Improved Documentation
+
+- Added new user guide on GPU. ([#2751](https://github.com/zarr-developers/zarr-python/pull/2751))
+
+## 3.0.2 (2025-01-31)
+
+### Features
+
+- Test `getsize()` and `getsize_prefix()` in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/pull/2693))
+- Test that a `ValueError` is raised for invalid byte range syntax in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/pull/2693))
+- Separate instantiating and opening a store in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/pull/2693))
+- Add a test for using Stores as context managers in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/pull/2693))
+- Implemented `LoggingStore.open()`. ([#2693](https://github.com/zarr-developers/zarr-python/pull/2693))
+- `LoggingStore` is now a generic class. ([#2693](https://github.com/zarr-developers/zarr-python/pull/2693))
+- Change StoreTest's `test_store_repr`, `test_store_supports_writes`,
+ `test_store_supports_partial_writes`, and `test_store_supports_listing`
+ to be implemented using `@abstractmethod`, rather than raising `NotImplementedError`. ([#2693](https://github.com/zarr-developers/zarr-python/pull/2693))
+- Test the error raised for invalid buffer arguments in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/pull/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/pull/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` 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/pull/2761))
+
+### Bugfixes
+
+- Wrap sync fsspec filesystems with `AsyncFileSystemWrapper`. ([#2533](https://github.com/zarr-developers/zarr-python/pull/2533))
+- Added backwards compatibility for Zarr format 2 structured arrays. ([#2681](https://github.com/zarr-developers/zarr-python/pull/2681))
+- Update equality for `LoggingStore` and `WrapperStore` such that 'other' must also be a `LoggingStore` or `WrapperStore` respectively, rather than only checking the types of the stores they wrap. ([#2693](https://github.com/zarr-developers/zarr-python/pull/2693))
+- Ensure that `ZipStore` is open before getting or setting any values. ([#2693](https://github.com/zarr-developers/zarr-python/pull/2693))
+- Use stdout rather than stderr as the default stream for `LoggingStore`. ([#2693](https://github.com/zarr-developers/zarr-python/pull/2693))
+- Match the errors raised by read only stores in `StoreTests`. ([#2693](https://github.com/zarr-developers/zarr-python/pull/2693))
+- Fixed `ZipStore` to make sure the correct attributes are saved when instances are pickled.
+ This fixes a previous bug that prevented using `ZipStore` with a `ProcessPoolExecutor`. ([#2762](https://github.com/zarr-developers/zarr-python/pull/2762))
+- Updated the optional test dependencies to include `botocore` and `fsspec`. ([#2768](https://github.com/zarr-developers/zarr-python/pull/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/pull/2768))
+- Optimize full chunk writes. ([#2782](https://github.com/zarr-developers/zarr-python/pull/2782))
+
+### Improved Documentation
+
+- Changed the machinery for creating changelog entries.
+ Now individual entries should be added as files to the `changes` directory in the `zarr-python` repository, instead of directly to the changelog file. ([#2736](https://github.com/zarr-developers/zarr-python/pull/2736))
+
+### Other
+
+- Created a type alias `ChunkKeyEncodingLike` to model the union of `ChunkKeyEncoding` instances and the dict form of the
+ 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/pull/2763))
+
+## 3.0.1 (2025-01-17)
+
+* Implement `zarr.from_array` using concurrent streaming ([#2622](https://github.com/zarr-developers/zarr-python/pull/2622)).
+
+### Bug fixes
+
+* Fixes `order` argument for Zarr format 2 arrays ([#2679](https://github.com/zarr-developers/zarr-python/pull/2679)).
+* Fixes a bug that prevented reading Zarr format 2 data with consolidated
+ metadata written using `zarr-python` version 2 ([#2694](https://github.com/zarr-developers/zarr-python/issues/2694)).
+* Ensure that compressor=None results in no compression when writing Zarr
+ format 2 data ([#2708](https://github.com/zarr-developers/zarr-python/issues/2708)).
+* Fix for empty consolidated metadata dataset: backwards compatibility with
+ Zarr-Python 2 ([#2695](https://github.com/zarr-developers/zarr-python/pull/2695)).
+
+### Documentation
+
+* Add v3.0.0 release announcement banner ([#2677](https://github.com/zarr-developers/zarr-python/pull/2677)).
+* Quickstart guide alignment with V3 API ([#2697](https://github.com/zarr-developers/zarr-python/pull/2697)).
+* Fix doctest failures related to numcodecs 0.15 ([#2727](https://github.com/zarr-developers/zarr-python/pull/2727)).
+
+### Other
+
+* Removed some unnecessary files from the source distribution
+ to reduce its size. ([#2686](https://github.com/zarr-developers/zarr-python/pull/2686)).
+* Enable codecov in GitHub actions ([#2682](https://github.com/zarr-developers/zarr-python/pull/2682)).
+* Speed up hypothesis tests ([#2650](https://github.com/zarr-developers/zarr-python/pull/2650)).
+* Remove multiple imports for an import name ([#2723](https://github.com/zarr-developers/zarr-python/pull/2723)).
+
+## 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.
+
+Normal release note service will resume with further releases in the 3.0.0
+series.
+
+Release notes for the zarr-python 2.x and 1.x releases can be found here:
+https://zarr.readthedocs.io/en/support-v2/release.html
diff --git a/docs/release.rst b/docs/release.rst
deleted file mode 100644
index ab74a3debd..0000000000
--- a/docs/release.rst
+++ /dev/null
@@ -1,1812 +0,0 @@
-Release notes
-=============
-
-..
- # Copy the warning statement _under_ the latest release version
- # and unindent for pre-releases.
-
- .. warning::
- Pre-release! Use :command:`pip install --pre zarr` to evaluate this release.
-
-..
- # Unindent the section between releases in order
- # to document your changes. On releases it will be
- # re-indented so that it does not show up in the notes.
-
-.. _unreleased:
-
-Unreleased
-----------
-
-Enhancements
-~~~~~~~~~~~~
-
-* Added type hints to ``zarr.creation.create()``.
- By :user:`David Stansby ` :issue:`1536`.
-
-Docs
-~~~~
-
-* Minor correction and changes in documentation.
- By :user:`Sanket Verma ` :issue:`1509`.
-
-* Fix typo in documentation.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1554`
-
-* The documentation build now fails if there are any warnings.
- By :user:`David Stansby ` :issue:`1548`.
-
-* Add links to ``numcodecs`` docs in the tutorial.
- By :user:`David Stansby ` :issue:`1535`.
-
-* Enable offline formats for documentation builds.
- By :user:`Sanket Verma ` :issue:`1551`.
-
-* Minor tweak to advanced indexing tutorial examples.
- By :user:`Ross Barnowski ` :issue:`1550`.
-
-* Added section about accessing zip files that are on s3.
- By :user:`Jeff Peck ` :issue:`1613`.
-
-Maintenance
-~~~~~~~~~~~
-
-* Drop Python 3.8 and NumPy 1.20
- By :user:`Josh Moore `; :issue:`1557`.
-
-* Cache result of ``FSStore._fsspec_installed()``.
- By :user:`Janick Martinez Esturo ` :issue:`1581`.
-
-* Extend copyright notice to 2023.
- By :user:`Jack Kelly ` :issue:`1528`.
-
-* Change occurrence of ``io.open()`` into ``open()``.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1421`.
-
-* Preserve ``dimension_separator`` when resizing arrays.
- By :user:`Ziwen Liu ` :issue:`1533`.
-
-* Initialise some sets in tests with set literals instead of list literals.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1534`.
-
-* Allow ``black`` code formatter to be run with any Python version.
- By :user:`David Stansby ` :issue:`1549`.
-
-* Remove ``sphinx-rtd-theme`` dependency from ``pyproject.toml``.
- By :user:`Sanket Verma ` :issue:`1563`.
-
-
-.. _release_2.16.1:
-
-2.16.1
-------
-
-Maintenance
-~~~~~~~~~~~
-
-* Require ``setuptools_scm`` version ``1.5.4``\+
- By :user:`John A. Kirkham ` :issue:`1477`.
-
-* Add ``docs`` requirements to ``pyproject.toml``
- By :user:`John A. Kirkham ` :issue:`1494`.
-
-* Fixed caching issue in ``LRUStoreCache``.
- By :user:`Mads R. B. Kristensen ` :issue:`1499`.
-
-.. _release_2.16.0:
-
-2.16.0
-------
-
-Enhancements
-~~~~~~~~~~~~
-
-* Allow for partial codec specification in V3 array metadata.
- By :user:`Joe Hamman ` :issue:`1443`.
-
-* Add ``__contains__`` method to ``KVStore``.
- By :user:`Christoph Gohlke ` :issue:`1454`.
-
-* **Block Indexing**: Implemented blockwise (chunk blocks) indexing to ``zarr.Array``.
- By :user:`Altay Sansal ` :issue:`1428`
-
-Maintenance
-~~~~~~~~~~~
-
-* Refactor the core array tests to reduce code duplication.
- By :user:`Davis Bennett ` :issue:`1462`.
-
-* Style the codebase with ``ruff`` and ``black``.
- By :user:`Davis Bennett` :issue:`1459`
-
-* Ensure that chunks is tuple of ints upon array creation.
- By :user:`Philipp Hanslovsky` :issue:`1461`
-
-.. _release_2.15.0:
-
-2.15.0
-------
-
-Enhancements
-~~~~~~~~~~~~
-
-* Implement more extensive fallback of getitem/setitem for orthogonal indexing.
- By :user:`Andreas Albert ` :issue:`1029`.
-
-* Getitems supports ``meta_array``.
- By :user:`Mads R. B. Kristensen ` :issue:`1131`.
-
-* ``open_array()`` now takes the ``meta_array`` argument.
- By :user:`Mads R. B. Kristensen ` :issue:`1396`.
-
-Maintenance
-~~~~~~~~~~~
-
-* Remove ``codecov`` from GitHub actions.
- By :user:`John A. Kirkham ` :issue:`1391`.
-
-* Replace ``np.product`` with ``np.prod`` due to deprecation.
- By :user:`James Bourbeau ` :issue:`1405`.
-
-* Activate Py 3.11 builds.
- By :user:`Joe Hamman ` :issue:`1415`.
-
-Documentation
-~~~~~~~~~~~~~
-
-* Add API reference for V3 Implementation in the docs.
- By :user:`Sanket Verma ` :issue:`1345`.
-
-Bug fixes
-~~~~~~~~~
-
-* Fix the conda-forge error. Read :issue:`1347` for detailed info.
- By :user:`Josh Moore ` :issue:`1364` and :issue:`1367`.
-
-* Fix ``ReadOnlyError`` when opening V3 store via fsspec reference file system.
- By :user:`Joe Hamman ` :issue:`1383`.
-
-* Fix ``normalize_fill_value`` for structured arrays.
- By :user:`Alan Du ` :issue:`1397`.
-
-.. _release_2.14.2:
-
-2.14.2
-------
-
-Bug fixes
-~~~~~~~~~
-
-* Ensure ``zarr.group`` uses writeable mode to fix issue with :issue:`1304`.
- By :user:`Brandur Thorgrimsson ` :issue:`1354`.
-
-.. _release_2.14.1:
-
-2.14.1
-------
-
-Documentation
-~~~~~~~~~~~~~
-
-* Fix API links.
- By :user:`Josh Moore ` :issue:`1346`.
-
-* Fix unit tests which prevented the conda-forge release.
- By :user:`Josh Moore ` :issue:`1348`.
-
-.. _release_2.14.0:
-
-2.14.0
-------
-
-Major changes
-~~~~~~~~~~~~~
-
-* Improve Zarr V3 support, adding partial store read/write and storage transformers.
- Add new features from the `v3 spec `_:
-
- * storage transformers
- * `get_partial_values` and `set_partial_values`
- * efficient `get_partial_values` implementation for `FSStoreV3`
- * sharding storage transformer
-
- By :user:`Jonathan Striebel `; :issue:`1096`, :issue:`1111`.
-
-* N5 nows supports Blosc.
- Remove warnings emitted when using N5Store or N5FSStore with a blosc-compressed array.
- By :user:`Davis Bennett `; :issue:`1331`.
-
-Bug fixes
-~~~~~~~~~
-
-* Allow reading utf-8 encoded json files
- By :user:`Nathan Zimmerberg ` :issue:`1308`.
-
-* Ensure contiguous data is give to ``FSStore``. Only copying if needed.
- By :user:`Mads R. B. Kristensen ` :issue:`1285`.
-
-* NestedDirectoryStore.listdir now returns chunk keys with the correct '/' dimension_separator.
- By :user:`Brett Graham ` :issue:`1334`.
-
-* N5Store/N5FSStore dtype returns zarr Stores readable dtype.
- By :user:`Marwan Zouinkhi ` :issue:`1339`.
-
-.. _release_2.13.6:
-
-2.13.6
-------
-
-Maintenance
-~~~~~~~~~~~
-
-* Bump gh-action-pypi-publish to 1.6.4.
- By :user:`Josh Moore ` :issue:`1320`.
-
-.. _release_2.13.5:
-
-2.13.5
-------
-
-Bug fixes
-~~~~~~~~~
-
-* Ensure ``zarr.create`` uses writeable mode to fix issue with :issue:`1304`.
- By :user:`James Bourbeau ` :issue:`1309`.
-
-.. _release_2.13.4:
-
-2.13.4
-------
-
-Appreciation
-~~~~~~~~~~~~~
-
-Special thanks to Outreachy participants for contributing to most of the
-maintenance PRs. Please read the blog post summarising the contribution phase
-and welcoming new Outreachy interns:
-https://zarr.dev/blog/welcoming-outreachy-2022-interns/
-
-
-Enhancements
-~~~~~~~~~~~~
-
-* Handle fsspec.FSMap using FSStore store.
- By :user:`Rafal Wojdyla ` :issue:`1304`.
-
-Bug fixes
-~~~~~~~~~
-
-* Fix bug that caused double counting of groups in ``groups()`` and ``group_keys()`` methods with V3 stores.
- By :user:`Ryan Abernathey ` :issue:`1228`.
-
-* Remove unnecessary calling of `contains_array` for key that ended in `.array.json`.
- By :user:`Joe Hamman ` :issue:`1149`.
-
-* Fix bug that caused double counting of groups in ``groups()`` and ``group_keys()``
- methods with V3 stores.
- By :user:`Ryan Abernathey ` :issue:`1228`.
-
-Documentation
-~~~~~~~~~~~~~
-
-* Fix minor indexing errors in tutorial and specification examples of documentation.
- By :user:`Kola Babalola ` :issue:`1277`.
-
-* Add `requirements_rtfd.txt` in `contributing.rst`.
- By :user:`AWA BRANDON AWA ` :issue:`1243`.
-
-* Add documentation for find/findall using visit.
- By :user:`Weddy Gikunda ` :issue:`1241`.
-
-* Refresh of the main landing page.
- By :user:`Josh Moore ` :issue:`1173`.
-
-Maintenance
-~~~~~~~~~~~
-
-* Migrate to ``pyproject.toml`` and remove redundant infrastructure.
- By :user:`Saransh Chopra ` :issue:`1158`.
-
-* Require ``setuptools`` 64.0.0+
- By :user:`Saransh Chopra ` :issue:`1193`.
-
-* Pin action versions (pypi-publish, setup-miniconda) for dependabot
- By :user:`Saransh Chopra ` :issue:`1205`.
-
-* Remove ``tox`` support
- By :user:`Saransh Chopra ` :issue:`1219`.
-
-* Add workflow to label PRs with "needs release notes".
- By :user:`Saransh Chopra ` :issue:`1239`.
-
-* Simplify if/else statement.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1227`.
-
-* Get coverage up to 100%.
- By :user:`John Kirkham ` :issue:`1264`.
-
-* Migrate coverage to ``pyproject.toml``.
- By :user:`John Kirkham ` :issue:`1250`.
-
-* Use ``conda-incubator/setup-miniconda@v2.2.0``.
- By :user:`John Kirkham ` :issue:`1263`.
-
-* Delete unused files.
- By :user:`John Kirkham ` :issue:`1251`.
-
-* Skip labeller for bot PRs.
- By :user:`Saransh Chopra ` :issue:`1271`.
-
-* Restore Flake8 configuration.
- By :user:`John Kirkham ` :issue:`1249`.
-
-* Add missing newline at EOF.
- By :user:`Dimitri Papadopoulos` :issue:`1253`.
-
-* Add `license_files` to `pyproject.toml`.
- By :user:`John Kirkham ` :issue:`1247`.
-
-* Adding `pyupgrade` suggestions.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1225`.
-
-* Fixed some linting errors.
- By :user:`Weddy Gikunda ` :issue:`1226`.
-
-* Added the link to main website in readthedocs sidebar.
- By :user:`Stephanie_nkwatoh ` :issue:`1216`.
-
-* Remove redundant wheel dependency in `pyproject.toml`.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1233`.
-
-* Turned on `isloated_build` in `tox.ini` file.
- By :user:`AWA BRANDON AWA ` :issue:`1210`.
-
-* Fixed `flake8` alert and avoid duplication of `Zarr Developers`.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1203`.
-
-* Bump to NumPy 1.20+ in `environment.yml`.
- By :user:`John Kirkham ` :issue:`1201`.
-
-* Bump to NumPy 1.20 in `pyproject.toml`.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1192`.
-
-* Remove LGTM (`.lgtm.yml`) configuration file.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1191`.
-
-* Codespell will skip `fixture` in pre-commit.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1197`.
-
-* Add msgpack in `requirements_rtfd.txt`.
- By :user:`Emmanuel Bolarinwa ` :issue:`1188`.
-
-* Added license to docs fixed a typo from `_spec_v2` to `_spec_v3`.
- By :user:`AWA BRANDON AWA ` :issue:`1182`.
-
-* Fixed installation link in `README.md`.
- By :user:`AWA BRANDON AWA ` :issue:`1177`.
-
-* Fixed typos in `installation.rst` and `release.rst`.
- By :user:`Chizoba Nweke ` :issue:`1178`.
-
-* Set `docs/conf.py` language to `en`.
- By :user:`AWA BRANDON AWA ` :issue:`1174`.
-
-* Added `installation.rst` to the docs.
- By :user:`AWA BRANDON AWA ` :issue:`1170`.
-
-* Adjustment of year to `2015-2018` to `2015-2022` in the docs.
- By :user:`Emmanuel Bolarinwa ` :issue:`1165`.
-
-* Updated `Forking the repository` section in `contributing.rst`.
- By :user:`AWA BRANDON AWA ` :issue:`1171`.
-
-* Updated GitHub actions.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1134`.
-
-* Update web links: `http:// β https://`.
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1313`.
-
-.. _release_2.13.3:
-
-2.13.3
-------
-
-* Improve performance of slice selections with steps by omitting chunks with no relevant
- data.
- By :user:`Richard Shaw ` :issue:`843`.
-
-.. _release_2.13.2:
-
-2.13.2
-------
-
-* Fix test failure on conda-forge builds (again).
- By :user:`Josh Moore `; see
- `zarr-feedstock#65 `_.
-
-.. _release_2.13.1:
-
-2.13.1
-------
-
-* Fix test failure on conda-forge builds.
- By :user:`Josh Moore `; see
- `zarr-feedstock#65 `_.
-
-.. _release_2.13.0:
-
-2.13.0
-------
-
-Major changes
-~~~~~~~~~~~~~
-
-* **Support of alternative array classes** by introducing a new argument,
- meta_array, that specifies the type/class of the underlying array. The
- meta_array argument can be any class instance that can be used as the like
- argument in NumPy (see `NEP 35
- `_).
- enabling support for CuPy through, for example, the creation of a CuPy CPU
- compressor.
- By :user:`Mads R. B. Kristensen ` :issue:`934`.
-
-* **Remove support for Python 3.7** in concert with NumPy dependency.
- By :user:`Davis Bennett ` :issue:`1067`.
-
-* **Zarr v3: add support for the default root path** rather than requiring
- that all API users pass an explicit path.
- By :user:`Gregory R. Lee ` :issue:`1085`, :issue:`1142`.
-
-
-Bug fixes
-~~~~~~~~~
-
-* Remove/relax erroneous "meta" path check (**regression**).
- By :user:`Gregory R. Lee ` :issue:`1123`.
-
-* Cast all attribute keys to strings (and issue deprecation warning).
- By :user:`Mattia Almansi ` :issue:`1066`.
-
-* Fix bug in N5 storage that prevented arrays located in the root of the hierarchy from
- bearing the `n5` keyword. Along with fixing this bug, new tests were added for N5 routines
- that had previously been excluded from testing, and type annotations were added to the N5 codebase.
- By :user:`Davis Bennett ` :issue:`1092`.
-
-* Fix bug in LRUEStoreCache in which the current size wasn't reset on invalidation.
- By :user:`BGCMHou ` and :user:`Josh Moore ` :issue:`1076`, :issue:`1077`.
-
-* Remove erroneous check that disallowed array keys starting with "meta".
- By :user:`Gregory R. Lee ` :issue:`1105`.
-
-Documentation
-~~~~~~~~~~~~~
-
-* Typo fixes to close quotes. By :user:`Pavithra Eswaramoorthy `
-
-* Added copy button to documentation.
- By :user:`Altay Sansal ` :issue:`1124`.
-
-Maintenance
-~~~~~~~~~~~
-
-* Simplify release docs.
- By :user:`Josh Moore ` :issue:`1119`.
-
-* Pin werkzeug to prevent test hangs.
- By :user:`Davis Bennett ` :issue:`1098`.
-
-* Fix a few DeepSource.io alerts
- By :user:`Dimitri Papadopoulos Orfanos ` :issue:`1080`.
-
-* Fix URLs.
- By :user:`Dimitri Papadopoulos Orfanos `, :issue:`1074`.
-
-* Fix spelling.
- By :user:`Dimitri Papadopoulos Orfanos `, :issue:`1073`.
-
-* Update GitHub issue templates with `YAML` format.
- By :user:`Saransh Chopra ` :issue:`1079`.
-
-* Remove option to return None from _ensure_store.
- By :user:`Greggory Lee ` :issue:`1068`.
-
-* Fix a typo of "integers".
- By :user:`Richard Scott ` :issue:`1056`.
-
-.. _release_2.12.0:
-
-2.12.0
-------
-
-Enhancements
-~~~~~~~~~~~~
-
-* **Add support for reading and writing Zarr V3.** The new `zarr._store.v3`
- package has the necessary classes and functions for evaluating Zarr V3.
- Since the format is not yet finalized, the classes and functions are not
- automatically imported into the regular `zarr` name space. Setting the
- `ZARR_V3_EXPERIMENTAL_API` environment variable will activate them.
- By :user:`Greggory Lee `; :issue:`898`, :issue:`1006`, and :issue:`1007`
- as well as by :user:`Josh Moore ` :issue:`1032`.
-
-* **Create FSStore from an existing fsspec filesystem**. If you have created
- an fsspec filesystem outside of Zarr, you can now pass it as a keyword
- argument to ``FSStore``.
- By :user:`Ryan Abernathey `; :issue:`911`.
-
-* Add numpy encoder class for json.dumps
- By :user:`Eric Prestat `; :issue:`933`.
-
-* Appending performance improvement to Zarr arrays, e.g., when writing to S3.
- By :user:`hailiangzhang `; :issue:`1014`.
-
-* Add number encoder for ``json.dumps`` to support numpy integers in
- ``chunks`` arguments. By :user:`Eric Prestat ` :issue:`697`.
-
-Bug fixes
-~~~~~~~~~
-
-* Fix bug that made it impossible to create an ``FSStore`` on unlistable filesystems
- (e.g. some HTTP servers).
- By :user:`Ryan Abernathey `; :issue:`993`.
-
-
-Documentation
-~~~~~~~~~~~~~
-
-* Update resize doc to clarify surprising behavior.
- By :user:`hailiangzhang `; :issue:`1022`.
-
-Maintenance
-~~~~~~~~~~~
-
-* Added Pre-commit configuration, incl. Yaml Check.
- By :user:`Shivank Chaudhary `; :issue:`1015`, :issue:`1016`.
-
-* Fix URL to renamed file in Blosc repo.
- By :user:`Andrew Thomas ` :issue:`1028`.
-
-* Activate Py 3.10 builds.
- By :user:`Josh Moore ` :issue:`1027`.
-
-* Make all unignored zarr warnings errors.
- By :user:`Josh Moore ` :issue:`1021`.
-
-
-.. _release_2.11.3:
-
-2.11.3
-------
-
-Bug fixes
-~~~~~~~~~
-
-* Fix missing case to fully revert change to default write_empty_chunks.
- By :user:`Tom White `; :issue:`1005`.
-
-
-.. _release_2.11.2:
-
-2.11.2
-------
-
-Bug fixes
-~~~~~~~~~
-
-* Changes the default value of ``write_empty_chunks`` to ``True`` to prevent
- unanticipated data losses when the data types do not have a proper default
- value when empty chunks are read back in.
- By :user:`Vyas Ramasubramani `; :issue:`965`, :issue:`1001`.
-
-.. _release_2.11.1:
-
-2.11.1
-------
-
-Bug fixes
-~~~~~~~~~
-
-* Fix bug where indexing with a scalar numpy value returned a single-value array.
- By :user:`Ben Jeffery ` :issue:`967`.
-
-* Removed `clobber` argument from `normalize_store_arg`. This enables to change
- data within an opened consolidated group using mode `"r+"` (i.e region write).
- By :user:`Tobias KΓΆlling ` :issue:`975`.
-
-.. _release_2.11.0:
-
-2.11.0
-------
-
-Enhancements
-~~~~~~~~~~~~
-
-* **Sparse changes with performance impact!** One of the advantages of the Zarr
- format is that it is sparse, which means that chunks with no data (more
- precisely, with data equal to the fill value, which is usually 0) don't need
- to be written to disk at all. They will simply be assumed to be empty at read
- time. However, until this release, the Zarr library would write these empty
- chunks to disk anyway. This changes in this version: a small performance
- penalty at write time leads to significant speedups at read time and in
- filesystem operations in the case of sparse arrays. To revert to the old
- behavior, pass the argument ``write_empty_chunks=True`` to the array creation
- function. By :user:`Juan Nunez-Iglesias `; :issue:`853` and
- :user:`Davis Bennett `; :issue:`738`.
-
-* **Fancy indexing**. Zarr arrays now support NumPy-style fancy indexing with
- arrays of integer coordinates. This is equivalent to using zarr.Array.vindex.
- Mixing slices and integer arrays is not supported.
- By :user:`Juan Nunez-Iglesias `; :issue:`725`.
-
-* **New base class**. This release of Zarr Python introduces a new
- ``BaseStore`` class that all provided store classes implemented in Zarr
- Python now inherit from. This is done as part of refactoring to enable future
- support of the Zarr version 3 spec. Existing third-party stores that are a
- MutableMapping (e.g. dict) can be converted to a new-style key/value store
- inheriting from ``BaseStore`` by passing them as the argument to the new
- ``zarr.storage.KVStore`` class. For backwards compatibility, various
- higher-level array creation and convenience functions still accept plain
- Python dicts or other mutable mappings for the ``store`` argument, but will
- internally convert these to a ``KVStore``.
- By :user:`Greggory Lee `; :issue:`839`, :issue:`789`, and :issue:`950`.
-
-* Allow to assign array ``fill_values`` and update metadata accordingly.
- By :user:`Ryan Abernathey `, :issue:`662`.
-
-* Allow to update array fill_values
- By :user:`Matthias Bussonnier ` :issue:`665`.
-
-Bug fixes
-~~~~~~~~~
-
-* Fix bug where the checksum of zipfiles is wrong
- By :user:`Oren Watson ` :issue:`930`.
-
-* Fix consolidate_metadata with FSStore.
- By :user:`Joe Hamman ` :issue:`916`.
-
-* Unguarded next inside generator.
- By :user:`Dimitri Papadopoulos Orfanos