numcodecs-combinators 0.2.9__tar.gz → 0.2.10__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/PKG-INFO +1 -1
  2. numcodecs_combinators-0.2.10/_typos.toml +2 -0
  3. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/mkdocs.yml +1 -0
  4. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/pyproject.toml +1 -1
  5. numcodecs_combinators-0.2.10/src/numcodecs_combinators/_chunked.py +12 -0
  6. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/src/numcodecs_combinators/best.py +3 -1
  7. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/src/numcodecs_combinators/framed.py +10 -2
  8. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/src/numcodecs_combinators/stack.py +20 -25
  9. numcodecs_combinators-0.2.9/_typos.toml +0 -2
  10. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/.github/workflows/ci.yml +0 -0
  11. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/.github/workflows/publish.yml +0 -0
  12. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/.gitignore +0 -0
  13. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/.python-version +0 -0
  14. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/.readthedocs.yaml +0 -0
  15. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/LICENSE +0 -0
  16. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/README.md +0 -0
  17. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/docs/index.md +0 -0
  18. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/docs/requirements.txt +0 -0
  19. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/src/numcodecs_combinators/__init__.py +0 -0
  20. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/src/numcodecs_combinators/abc.py +0 -0
  21. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/src/numcodecs_combinators/py.typed +0 -0
  22. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/tests/test_best.py +0 -0
  23. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/tests/test_framed.py +0 -0
  24. {numcodecs_combinators-0.2.9 → numcodecs_combinators-0.2.10}/tests/test_stack.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: numcodecs-combinators
3
- Version: 0.2.9
3
+ Version: 0.2.10
4
4
  Summary: Combinator codecs for the `numcodecs` buffer compression API
5
5
  License: Copyright (c) 2024, Juniper Tyree
6
6
 
@@ -0,0 +1,2 @@
1
+ [default.extend-identifiers]
2
+ ChunkedNdArray = "ChunkedNdArray"
@@ -24,6 +24,7 @@ plugins:
24
24
  source_dirs:
25
25
  - nav_heading: [Documentation]
26
26
  base: src
27
+ ignore: ["_chunked.py"]
27
28
  - exclude:
28
29
  glob:
29
30
  - requirements.txt
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "numcodecs-combinators"
7
- version = "0.2.9"
7
+ version = "0.2.10"
8
8
  description = "Combinator codecs for the `numcodecs` buffer compression API"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -0,0 +1,12 @@
1
+ import numpy as np
2
+
3
+
4
+ class ChunkedNdArray(np.ndarray):
5
+ __slots__ = ()
6
+
7
+ def __new__(cls, array):
8
+ return np.asarray(array).view(cls)
9
+
10
+ @property
11
+ def chunked(self) -> bool:
12
+ return True
@@ -70,7 +70,9 @@ class PickBestCodec(Codec, CodecCombinatorMixin, tuple[Codec]):
70
70
  if len(self) == 0:
71
71
  return buf
72
72
 
73
- data = numcodecs.compat.ensure_ndarray(buf)
73
+ data = (
74
+ buf if isinstance(buf, np.ndarray) else numcodecs.compat.ensure_ndarray(buf)
75
+ )
74
76
 
75
77
  best_size = np.inf
76
78
  best_index = None
@@ -16,6 +16,7 @@ import varint
16
16
  from numcodecs.abc import Codec
17
17
  from typing_extensions import Buffer, Self # MSPV 3.12
18
18
 
19
+ from ._chunked import ChunkedNdArray
19
20
  from .abc import CodecCombinatorMixin
20
21
 
21
22
 
@@ -74,6 +75,8 @@ class FramedCodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
74
75
  Encoded and framed data as a bytestring.
75
76
  """
76
77
 
78
+ chunked = getattr(buf, "chunked", False)
79
+
77
80
  encoded = buf
78
81
  encoded_ndarray = np.asarray(
79
82
  numcodecs.compat.ensure_contiguous_ndarray_like(encoded, flatten=False)
@@ -82,7 +85,9 @@ class FramedCodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
82
85
  frames = [(encoded_ndarray.dtype, encoded_ndarray.shape)]
83
86
 
84
87
  for codec in self:
85
- encoded = codec.encode(encoded_ndarray)
88
+ encoded = codec.encode(
89
+ ChunkedNdArray(encoded_ndarray) if chunked else encoded_ndarray
90
+ )
86
91
  encoded_ndarray = np.asarray(
87
92
  numcodecs.compat.ensure_contiguous_ndarray_like(encoded, flatten=False)
88
93
  )
@@ -132,6 +137,8 @@ class FramedCodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
132
137
  buffer protocol.
133
138
  """
134
139
 
140
+ chunked = getattr(out, "chunked", False)
141
+
135
142
  b = numcodecs.compat.ensure_bytes(buf)
136
143
 
137
144
  b_io = BytesIO(b)
@@ -165,10 +172,11 @@ class FramedCodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
165
172
  decoded = decoded.byteswap()
166
173
 
167
174
  for codec, (dtype, shape) in zip(reversed(self), frames[:-1][::-1]):
175
+ empty = np.empty(shape, dtype)
168
176
  decoded = (
169
177
  codec.decode(
170
178
  decoded,
171
- out=np.empty(shape, dtype),
179
+ out=ChunkedNdArray(empty) if chunked else empty,
172
180
  )
173
181
  .view(dtype)
174
182
  .reshape(shape)
@@ -19,6 +19,7 @@ except ImportError:
19
19
 
20
20
  from numcodecs.abc import Codec
21
21
 
22
+ from ._chunked import ChunkedNdArray
22
23
  from .abc import CodecCombinatorMixin
23
24
 
24
25
 
@@ -89,11 +90,22 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
89
90
  protocol.
90
91
  """
91
92
 
93
+ if len(self) == 0:
94
+ return buf
95
+
96
+ chunked = getattr(buf, "chunked", False)
97
+
92
98
  encoded = buf
93
99
  for codec in self:
94
- encoded = codec.encode(
100
+ encoded_ndarray = np.asarray(
95
101
  numcodecs.compat.ensure_contiguous_ndarray_like(encoded, flatten=False)
96
102
  )
103
+ encoded = codec.encode(
104
+ ChunkedNdArray(encoded_ndarray) if chunked else encoded_ndarray
105
+ )
106
+
107
+ if getattr(encoded, "chunked", False):
108
+ return np.array(encoded).view(np.ndarray) # type: ignore
97
109
  return encoded
98
110
 
99
111
  def decode(self, buf: Buffer, out: Optional[Buffer] = None) -> Buffer:
@@ -151,7 +163,7 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
151
163
  silhouettes.append((encoded.shape, encoded.dtype))
152
164
  encoded = np.asarray(
153
165
  numcodecs.compat.ensure_contiguous_ndarray_like(
154
- codec.encode(_MaybeChunkedNdArray(encoded) if chunked else encoded),
166
+ codec.encode(ChunkedNdArray(encoded) if chunked else encoded),
155
167
  flatten=False,
156
168
  )
157
169
  )
@@ -162,12 +174,13 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
162
174
  shape, dtype = silhouettes.pop()
163
175
  out = np.empty(shape=shape, dtype=dtype)
164
176
  decoded = (
165
- codec.decode(decoded, _MaybeChunkedNdArray(out) if chunked else out)
177
+ codec.decode(decoded, ChunkedNdArray(out) if chunked else out)
166
178
  .view(dtype)
167
179
  .reshape(shape)
168
180
  )
169
181
 
170
- decoded = decoded.view(np.ndarray)
182
+ if getattr(decoded, "chunked", False):
183
+ decoded = decoded.view(np.ndarray)
171
184
 
172
185
  if isinstance(decoded, type(buf)):
173
186
  return decoded
@@ -205,7 +218,8 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
205
218
 
206
219
  import xarray as xr
207
220
 
208
- chunked = da.chunks is not None
221
+ if da.chunks is None:
222
+ return da.copy(data=self.encode_decode(da.values)) # type: ignore
209
223
 
210
224
  def encode_decode_data_array_single_chunk(
211
225
  da: xr.DataArray,
@@ -217,7 +231,7 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
217
231
  return da.copy(deep=False).chunk(single_chunk)
218
232
 
219
233
  # eagerly compute the input chunk and encode and decode it
220
- decoded = self.encode_decode(_MaybeChunkedNdArray(da.values, chunked)) # type: ignore
234
+ decoded = self.encode_decode(ChunkedNdArray(da.values)) # type: ignore
221
235
 
222
236
  return da.copy(deep=False, data=np.array(decoded).view(np.ndarray)).chunk(
223
237
  single_chunk
@@ -307,22 +321,3 @@ class CodecStack(Codec, CodecCombinatorMixin, tuple[Codec]):
307
321
 
308
322
 
309
323
  numcodecs.registry.register_codec(CodecStack)
310
-
311
-
312
- class _MaybeChunkedNdArray(np.ndarray):
313
- __slots__ = ("_chunked",)
314
- _chunked: bool
315
-
316
- def __new__(cls, array, chunked: bool = True):
317
- obj = np.asarray(array).view(cls)
318
- obj._chunked = chunked
319
- return obj
320
-
321
- def __array_finalize__(self, obj):
322
- if obj is None:
323
- return
324
- self._chunked = getattr(obj, "chunked", True)
325
-
326
- @property
327
- def chunked(self) -> bool:
328
- return self._chunked
@@ -1,2 +0,0 @@
1
- [default.extend-identifiers]
2
- _MaybeChunkedNdArray = "_MaybeChunkedNdArray"