Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/zarr-codec-extraction.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: zarr-codec extraction

on:
pull_request:
paths:
- 'packages/zarr-codec/**'
- 'src/zarr/abc/codec.py'
- '.github/workflows/zarr-codec-extraction.yml'
push:
branches: [main]
paths:
- 'packages/zarr-codec/**'
- 'src/zarr/abc/codec.py'
- '.github/workflows/zarr-codec-extraction.yml'
workflow_dispatch:

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ['3.12', '3.14']
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
- name: Install Python and Hatch
run: |
uv python install ${{ matrix.python-version }}
uv tool install hatch==1.18.0
- name: Test extracted interfaces against this checkout
env:
PYTHONPATH: packages/zarr-codec/src
run: >-
hatch run test.py${{ matrix.python-version }}-minimal:pytest
packages/zarr-codec/tests --import-mode=importlib
- name: Build codec distributions
working-directory: packages/zarr-codec
run: hatch build
- name: Test built wheels
env:
PYTHONPATH: packages/zarr-codec/dist/zarr_codec-0.1.0-py3-none-any.whl
run: >-
hatch run test.py${{ matrix.python-version }}-minimal:pytest
packages/zarr-codec/tests --import-mode=importlib
5 changes: 5 additions & 0 deletions packages/zarr-codec/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# zarr-codec changelog

## Unreleased

- Extract the existing interface into `zarr_codec.legacy` without changing Zarr runtime imports.
21 changes: 21 additions & 0 deletions packages/zarr-codec/LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2015-2025 Zarr Developers <https://github.com/zarr-developers>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
54 changes: 54 additions & 0 deletions packages/zarr-codec/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# zarr-codec

An initial extraction of the existing Zarr-Python codec interfaces:
codec base classes, partial-IO mixins, sync capability protocols, and CodecPipeline.

```python
from zarr_codec.legacy import BytesBytesCodec
```

## Status and scope

This is an experimental extraction draft, not a replacement Zarr backend.
The `legacy` namespace reproduces `src/zarr/abc/codec.py` from Zarr-Python commit
`1b16efee6`. Signatures, docstrings, inherited implementations, and async
behavior are preserved. New APIs can be developed under a different namespace;
none are introduced here. Built-in concrete stores/codecs remain in `zarr`.

**There is still a runtime dependency on `zarr`.** The legacy interfaces use
its shared foundations. This package must not become a dependency of `zarr`
until that dependency is removed. The tested compatibility baseline is the
source checkout at the commit above; the dependency range is not a claim that
every release in that range has been tested.

These are independent class definitions, not aliases to Zarr's classes.
Existing Zarr entry points do not yet recognize them as their own nominal
base classes. Do not switch an existing extension to this namespace and expect
it to plug into Zarr before runtime integration lands. At that point, the old
Zarr import paths should re-export one canonical definition, preserving class
identity. There are no deprecations or changes to Zarr's runtime in this draft.

## Remaining extraction dependencies

- Metadata and its recursive serialization behavior.
- Buffer and NDBuffer, including runtime generic type bounds.
- NamedConfig, configuration, and concurrent_map for batching.
- Annotation dependencies: ArraySpec, dtype classes, metadata, indexing, and store interfaces.

The global config remains shared with Zarr, preserving concurrency behavior.
Replacing these dependencies with smaller protocols would be an API design
change and is deliberately deferred.

## Development

From the repository root, expose this draft package and use a Hatch test environment:

```sh
PYTHONPATH=packages/zarr-codec/src hatch run test.py3.12-minimal:pytest packages/zarr-codec/tests --import-mode=importlib
```

The contract tests compare the draft against the source checkout. Behavioral
tests exercise third-party-style subclasses, not only copied signatures.

Build this distribution from its directory with `hatch build`. API documentation
is in `docs/api/index.md`; inherited docstrings remain in the extracted module.
3 changes: 3 additions & 0 deletions packages/zarr-codec/docs/api/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Legacy codec API

::: zarr_codec.legacy
38 changes: 38 additions & 0 deletions packages/zarr-codec/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[build-system]
requires = ["hatchling>=1.29.0"]
build-backend = "hatchling.build"

[project]
name = "zarr-codec"
version = "0.1.0"
description = "Legacy Zarr codec interfaces, extracted for API evolution."
readme = "README.md"
requires-python = ">=3.12"
license = "MIT"
license-files = ["LICENSE.txt"]
authors = [{ name = "Davis Bennett", email = "davis.v.bennett@gmail.com" }]
# Temporary: legacy interfaces still consume Zarr's shared foundations.
# Remove this dependency before making zarr depend on this distribution.
dependencies = ["zarr>=3.3,<3.4", "typing_extensions>=4.14"]

[project.urls]
Source = "https://github.com/zarr-developers/zarr-python/tree/main/packages/zarr-codec"
Issues = "https://github.com/zarr-developers/zarr-python/issues"

[tool.hatch.build.targets.wheel]
packages = ["src/zarr_codec"]

[tool.hatch.build.targets.sdist]
include = ["/src", "/tests", "/docs", "/CHANGELOG.md"]

[tool.pytest.ini_options]
addopts = ["--import-mode=importlib"]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"

[tool.ruff]
extend = "../../pyproject.toml"

# Match the parent project's validation of the verbatim legacy docstrings.
[tool.numpydoc_validation]
checks = ["GL10", "SS04", "PR02", "PR03", "PR05", "PR06"]
5 changes: 5 additions & 0 deletions packages/zarr-codec/src/zarr_codec/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Extracted Zarr codec interfaces; see :mod:`zarr_codec.legacy`."""

from zarr_codec import legacy

__all__ = ["legacy"]
Loading
Loading