Skip to content

Commit 80552bb

Browse files
committed
remove NoCompressor
1 parent 7bd218b commit 80552bb

File tree

9 files changed

+89
-124
lines changed

9 files changed

+89
-124
lines changed

docs/api/compressors.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,3 @@ code of this module for details.
1818
.. autoclass:: BZ2Compressor
1919

2020
.. autoclass:: LZMACompressor
21-
22-
.. autoclass:: NoCompressor
23-

docs/tutorial.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ the delta filter::
235235
nbytes: 381.5M; nbytes_stored: 248.1K; ratio: 1574.5; initialized: 100/100
236236
store: builtins.dict
237237

238+
To disable compression, set ``compression=None`` when creating an array.
239+
238240
.. _tutorial_sync:
239241

240242
Filters

zarr/compressors.py

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -501,82 +501,6 @@ def from_filter_config(cls, config):
501501
registry[LZMACompressor.canonical_name] = LZMACompressor
502502

503503

504-
class NoCompressor(object):
505-
"""No compression, i.e., pass bytes through. Registered under the
506-
name 'none'.
507-
508-
Examples
509-
--------
510-
>>> import zarr
511-
>>> z = zarr.zeros((10000, 10000), chunks=(1000, 1000), dtype='i4',
512-
... compression='none')
513-
514-
"""
515-
516-
canonical_name = 'none'
517-
518-
def __init__(self, compression_opts):
519-
pass
520-
521-
@classmethod
522-
def normalize_opts(cls, compression_opts):
523-
if compression_opts is not None:
524-
raise ValueError('no compression options supported')
525-
return None
526-
527-
# noinspection PyMethodMayBeStatic
528-
def decompress(self, cdata, dest=None):
529-
"""Decompression.
530-
531-
Parameters
532-
----------
533-
cdata : bytes-like
534-
Compressed data. Can be any object supporting buffer protocol.
535-
dest : ndarray, optional
536-
Destination for decompressed data.
537-
538-
Returns
539-
-------
540-
dest : bytes
541-
Decompressed data.
542-
543-
Notes
544-
-----
545-
This is a no-op. If `dest` is None, returns `cdata`. Otherwise,
546-
copies `cdata` to `dest`.`
547-
548-
"""
549-
if dest is None:
550-
dest = cdata
551-
else:
552-
arr = np.frombuffer(cdata, dtype=dest.dtype).reshape(dest.shape)
553-
np.copyto(dest, arr)
554-
return dest
555-
556-
# noinspection PyMethodMayBeStatic
557-
def compress(self, data):
558-
return data
559-
560-
# enable usage as a filter
561-
562-
filter_name = canonical_name
563-
encode = compress
564-
decode = decompress
565-
566-
def get_filter_config(self):
567-
config = dict()
568-
config['name'] = self.filter_name
569-
return config
570-
571-
@classmethod
572-
def from_filter_config(cls, config):
573-
return cls(config)
574-
575-
576-
registry[NoCompressor.canonical_name] = NoCompressor
577-
registry[None] = NoCompressor # alias
578-
579-
580504
def get_compressor_cls(compression):
581505
if compression == 'default':
582506
compression = default_compression

zarr/core.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,27 @@ def __init__(self, store, path=None, read_only=False, chunk_store=None,
9696
except KeyError:
9797
raise ValueError('store has no metadata')
9898
else:
99+
100+
# decode and store metadata
99101
meta = decode_array_metadata(meta_bytes)
100102
self._meta = meta
101103
self._shape = meta['shape']
102104
self._chunks = meta['chunks']
103105
self._dtype = meta['dtype']
104-
self._compression = meta['compression']
105-
self._compression_opts = meta['compression_opts']
106106
self._fill_value = meta['fill_value']
107107
self._order = meta['order']
108-
compressor_cls = get_compressor_cls(self._compression)
109-
self._compressor = compressor_cls(self._compression_opts)
110108
self._filters = get_filters(meta['filters'])
111109
self._is_view = False
110+
self._compression = meta['compression']
111+
112+
# setup compressor
113+
if self._compression is None:
114+
self._compressor = None
115+
self._compression_opts = None
116+
else:
117+
self._compression_opts = meta['compression_opts']
118+
compressor_cls = get_compressor_cls(self._compression)
119+
self._compressor = compressor_cls(self._compression_opts)
112120

113121
# initialize attributes
114122
akey = self._key_prefix + attrs_key
@@ -569,7 +577,12 @@ def _chunk_getitem(self, cidx, item, dest):
569577
# optimization: we want the whole chunk, and the destination is
570578
# contiguous, so we can decompress directly from the chunk
571579
# into the destination array
572-
self._compressor.decompress(cdata, dest)
580+
if self._compressor:
581+
self._compressor.decompress(cdata, dest)
582+
else:
583+
arr = np.frombuffer(cdata, dtype=self._dtype)
584+
arr = arr.reshape(self._chunks, order=self._order)
585+
np.copyto(dest, arr)
573586

574587
else:
575588

@@ -671,7 +684,10 @@ def _chunk_key(self, cidx):
671684
def _decode_chunk(self, cdata):
672685

673686
# decompress
674-
chunk = self._compressor.decompress(cdata)
687+
if self._compressor:
688+
chunk = self._compressor.decompress(cdata)
689+
else:
690+
chunk = cdata
675691

676692
# apply filters
677693
if self._filters:
@@ -697,7 +713,10 @@ def _encode_chunk(self, chunk):
697713
chunk = f.encode(chunk)
698714

699715
# compress
700-
cdata = self._compressor.compress(chunk)
716+
if self._compressor:
717+
cdata = self._compressor.compress(chunk)
718+
else:
719+
cdata = chunk
701720

702721
return cdata
703722

@@ -711,12 +730,14 @@ def __repr__(self):
711730
r += 'order=%s' % self.order
712731
r += ')'
713732
r += '\n compression: %s' % self.compression
714-
r += '; compression_opts: %s' % str(self.compression_opts)
733+
if self.compression:
734+
r += '; compression_opts: %s' % str(self.compression_opts)
715735
r += '\n nbytes: %s' % human_readable_size(self.nbytes)
716-
if self.nbytes_stored > 0:
717-
r += '; nbytes_stored: %s' % human_readable_size(
718-
self.nbytes_stored)
719-
r += '; ratio: %.1f' % (self.nbytes / self.nbytes_stored)
736+
if self.compression:
737+
if self.nbytes_stored > 0:
738+
r += '; nbytes_stored: %s' % human_readable_size(
739+
self.nbytes_stored)
740+
r += '; ratio: %.1f' % (self.nbytes / self.nbytes_stored)
720741
n_chunks = reduce(operator.mul, self.cdata_shape)
721742
r += '; initialized: %s/%s' % (self.initialized, n_chunks)
722743
if self._filters:

zarr/storage.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,23 @@ def init_array(store, shape, chunks, dtype=None, compression='default',
244244
shape = normalize_shape(shape)
245245
dtype = np.dtype(dtype)
246246
chunks = normalize_chunks(chunks, shape, dtype.itemsize)
247-
compressor_cls = get_compressor_cls(compression)
248-
compression = compressor_cls.canonical_name
249-
compression_opts = compressor_cls.normalize_opts(
250-
compression_opts
251-
)
252247
order = normalize_order(order)
253248

249+
# normalize compression
250+
if compression and compression.lower() == 'none':
251+
# backwards compatibility
252+
compression = None
253+
254+
# normalize compression_opts
255+
if compression is None:
256+
compression_opts = None
257+
else:
258+
compressor_cls = get_compressor_cls(compression)
259+
compression = compressor_cls.canonical_name
260+
compression_opts = compressor_cls.normalize_opts(
261+
compression_opts
262+
)
263+
254264
# initialize metadata
255265
meta = dict(shape=shape, chunks=chunks, dtype=dtype,
256266
compression=compression, compression_opts=compression_opts,

zarr/tests/test_compression.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -187,22 +187,6 @@ def test_compress_decompress_raw(self):
187187
self._test_compress_decompress(opts)
188188

189189

190-
class TestNoCompressor(unittest.TestCase, CompressorTests):
191-
192-
compression = 'none'
193-
194-
def test_normalize_opts(self):
195-
cls = get_compressor_cls(self.compression)
196-
197-
# test defaults
198-
opts = cls.normalize_opts(None)
199-
eq(None, opts)
200-
201-
# test invalid args
202-
with assert_raises(ValueError):
203-
cls.normalize_opts(9)
204-
205-
206190
def test_get_compressor_cls():
207191
# expect ValueError, more friendly
208192
with assert_raises(ValueError):

zarr/tests/test_core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424

2525
compression_configs = [
26-
('none', None),
26+
(None, None),
2727
('zlib', None),
2828
('bz2', None),
2929
('blosc', None)

zarr/tests/test_filters.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,9 @@ def test_errors(self):
140140
# bad labels
141141
CategoryFilter(dtype='S2', labels=[1, 2])
142142

143+
143144
compression_configs = [
144-
('none', None),
145+
(None, None),
145146
('zlib', None),
146147
('bz2', None),
147148
('blosc', None)
@@ -170,8 +171,11 @@ def test_array_with_delta_filter():
170171
# check chunks
171172
for i in range(10):
172173
cdata = a.store[str(i)]
173-
actual = np.frombuffer(a.compressor.decompress(cdata),
174-
dtype=astype)
174+
if a.compressor:
175+
chunk = a.compressor.decompress(cdata)
176+
else:
177+
chunk = cdata
178+
actual = np.frombuffer(chunk, dtype=astype)
175179
expect = np.array([i * 10] + ([1] * 9), dtype=astype)
176180
assert_array_equal(expect, actual)
177181

@@ -198,8 +202,11 @@ def test_array_with_scaleoffset_filter():
198202
# check chunks
199203
for i in range(6):
200204
cdata = a.store[str(i)]
201-
actual = np.frombuffer(a.compressor.decompress(cdata),
202-
dtype=astype)
205+
if a.compressor:
206+
chunk = a.compressor.decompress(cdata)
207+
else:
208+
chunk = cdata
209+
actual = np.frombuffer(chunk, dtype=astype)
203210
expect = flt.encode(data[i*5:(i*5)+5])
204211
assert_array_equal(expect, actual)
205212

@@ -225,8 +232,11 @@ def test_array_with_quantize_filter():
225232
# check chunks
226233
for i in range(6):
227234
cdata = a.store[str(i)]
228-
actual = np.frombuffer(a.compressor.decompress(cdata),
229-
dtype=dtype)
235+
if a.compressor:
236+
chunk = a.compressor.decompress(cdata)
237+
else:
238+
chunk = cdata
239+
actual = np.frombuffer(chunk, dtype=dtype)
230240
expect = flt.encode(data[i*5:(i*5)+5])
231241
assert_array_equal(expect, actual)
232242

@@ -250,8 +260,11 @@ def test_array_with_packbits_filter():
250260
# check chunks
251261
for i in range(20):
252262
cdata = a.store[str(i)]
253-
actual = np.frombuffer(a.compressor.decompress(cdata),
254-
dtype='u1')
263+
if a.compressor:
264+
chunk = a.compressor.decompress(cdata)
265+
else:
266+
chunk = cdata
267+
actual = np.frombuffer(chunk, dtype='u1')
255268
expect = flt.encode(data[i*5:(i*5)+5])
256269
assert_array_equal(expect, actual)
257270

@@ -275,14 +288,20 @@ def test_array_with_category_filter():
275288
# check chunks
276289
for i in range(20):
277290
cdata = a.store[str(i)]
278-
actual = np.frombuffer(a.compressor.decompress(cdata),
279-
dtype='u1')
291+
if a.compressor:
292+
chunk = a.compressor.decompress(cdata)
293+
else:
294+
chunk = cdata
295+
actual = np.frombuffer(chunk, dtype='u1')
280296
expect = flt.encode(data[i*5:(i*5)+5])
281297
assert_array_equal(expect, actual)
282298

283299

284300
def test_compressor_as_filter():
285301
for compression, compression_opts in compression_configs:
302+
if compression is None:
303+
# skip
304+
continue
286305

287306
# setup compressor
288307
compressor_cls = get_compressor_cls(compression)

zarr/tests/test_storage.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,14 @@ def test_init_array_overwrite_chunk_store(self):
395395
assert '0' not in chunk_store
396396
assert '1' not in chunk_store
397397

398+
def test_init_array_compat(self):
399+
store = self.create_store()
400+
init_array(store, shape=1000, chunks=100, compression='none',
401+
compression_opts='foo')
402+
meta = decode_array_metadata(store[array_meta_key])
403+
assert_is_none(meta['compression'])
404+
assert_is_none(meta['compression_opts'])
405+
398406
def test_init_group(self):
399407
store = self.create_store()
400408
init_group(store)

0 commit comments

Comments
 (0)