22
33from abc import abstractmethod
44from collections .abc import Mapping
5- from typing import TYPE_CHECKING , Generic , TypeGuard , TypeVar
5+ from typing import TYPE_CHECKING , TypeGuard
66
77from typing_extensions import ReadOnly , TypedDict
88
3434 "CodecPipeline" ,
3535]
3636
37- CodecInput = TypeVar ( " CodecInput" , bound = NDBuffer | Buffer )
38- CodecOutput = TypeVar ( " CodecOutput" , bound = NDBuffer | Buffer )
37+ type CodecInput = NDBuffer | Buffer
38+ type CodecOutput = NDBuffer | Buffer
3939
40- TName = TypeVar ("TName" , bound = str , covariant = True )
4140
42-
43- class CodecJSON_V2 (TypedDict , Generic [TName ]):
41+ class CodecJSON_V2 [TName : str ](TypedDict ):
4442 """The JSON representation of a codec for Zarr V2"""
4543
4644 id : ReadOnly [TName ]
@@ -59,7 +57,7 @@ def _check_codecjson_v2(data: object) -> TypeGuard[CodecJSON_V2[str]]:
5957"""The widest type of JSON-like input that could specify a codec."""
6058
6159
62- class BaseCodec ( Metadata , Generic [ CodecInput , CodecOutput ]):
60+ class BaseCodec [ CI : CodecInput , CO : CodecOutput ]( Metadata ):
6361 """Generic base class for codecs.
6462
6563 Codecs can be registered via zarr.codecs.registry.
@@ -137,13 +135,13 @@ def validate(
137135 The array chunk grid
138136 """
139137
140- async def _decode_single (self , chunk_data : CodecOutput , chunk_spec : ArraySpec ) -> CodecInput :
138+ async def _decode_single (self , chunk_data : CO , chunk_spec : ArraySpec ) -> CI :
141139 raise NotImplementedError # pragma: no cover
142140
143141 async def decode (
144142 self ,
145- chunks_and_specs : Iterable [tuple [CodecOutput | None , ArraySpec ]],
146- ) -> Iterable [CodecInput | None ]:
143+ chunks_and_specs : Iterable [tuple [CO | None , ArraySpec ]],
144+ ) -> Iterable [CI | None ]:
147145 """Decodes a batch of chunks.
148146 Chunks can be None in which case they are ignored by the codec.
149147
@@ -154,25 +152,23 @@ async def decode(
154152
155153 Returns
156154 -------
157- Iterable[CodecInput | None]
155+ Iterable[CI | None]
158156 """
159157 return await _batching_helper (self ._decode_single , chunks_and_specs )
160158
161- async def _encode_single (
162- self , chunk_data : CodecInput , chunk_spec : ArraySpec
163- ) -> CodecOutput | None :
159+ async def _encode_single (self , chunk_data : CI , chunk_spec : ArraySpec ) -> CO | None :
164160 raise NotImplementedError # pragma: no cover
165161
166162 async def encode (
167163 self ,
168- chunks_and_specs : Iterable [tuple [CodecInput | None , ArraySpec ]],
169- ) -> Iterable [CodecOutput | None ]:
164+ chunks_and_specs : Iterable [tuple [CI | None , ArraySpec ]],
165+ ) -> Iterable [CO | None ]:
170166 """Encodes a batch of chunks.
171167 Chunks can be None in which case they are ignored by the codec.
172168
173169 Parameters
174170 ----------
175- chunks_and_specs : Iterable[tuple[CodecInput | None, ArraySpec]]
171+ chunks_and_specs : Iterable[tuple[CI | None, ArraySpec]]
176172 Ordered set of to-be-encoded chunks with their accompanying chunk spec.
177173
178174 Returns
@@ -460,21 +456,21 @@ async def write(
460456 ...
461457
462458
463- async def _batching_helper (
464- func : Callable [[CodecInput , ArraySpec ], Awaitable [CodecOutput | None ]],
465- batch_info : Iterable [tuple [CodecInput | None , ArraySpec ]],
466- ) -> list [CodecOutput | None ]:
459+ async def _batching_helper [ CI : CodecInput , CO : CodecOutput ] (
460+ func : Callable [[CI , ArraySpec ], Awaitable [CO | None ]],
461+ batch_info : Iterable [tuple [CI | None , ArraySpec ]],
462+ ) -> list [CO | None ]:
467463 return await concurrent_map (
468464 list (batch_info ),
469465 _noop_for_none (func ),
470466 config .get ("async.concurrency" ),
471467 )
472468
473469
474- def _noop_for_none (
475- func : Callable [[CodecInput , ArraySpec ], Awaitable [CodecOutput | None ]],
476- ) -> Callable [[CodecInput | None , ArraySpec ], Awaitable [CodecOutput | None ]]:
477- async def wrap (chunk : CodecInput | None , chunk_spec : ArraySpec ) -> CodecOutput | None :
470+ def _noop_for_none [ CI : CodecInput , CO : CodecOutput ] (
471+ func : Callable [[CI , ArraySpec ], Awaitable [CO | None ]],
472+ ) -> Callable [[CI | None , ArraySpec ], Awaitable [CO | None ]]:
473+ async def wrap (chunk : CI | None , chunk_spec : ArraySpec ) -> CO | None :
478474 if chunk is None :
479475 return None
480476 return await func (chunk , chunk_spec )
0 commit comments