Skip to content

Commit 8c61cbc

Browse files
authored
Merge pull request #69 from alimanfoo/issue_65
Group supports item deletion; resolves #65
2 parents 9a6de6e + a629da2 commit 8c61cbc

File tree

6 files changed

+65
-50
lines changed

6 files changed

+65
-50
lines changed

docs/release.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Release notes
22
=============
33

4+
* Group objects now support member deletion via ``del`` statement
5+
('#65 <https://github.com/alimanfoo/zarr/issues/65>'_)
46
* Added :class:`zarr.storage.TempStore` class for convenience to provide
57
storage via a temporary directory
68
(`#59 <https://github.com/alimanfoo/zarr/issues/59>`_)

zarr/creation.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -289,20 +289,15 @@ def array(data, **kwargs):
289289
data = np.asanyarray(data)
290290

291291
# setup dtype
292-
dtype = kwargs.pop('dtype', None)
293-
if dtype is None:
294-
dtype = data.dtype
292+
kwargs.setdefault('dtype', data.dtype)
295293

296-
# setup shape
297-
shape = data.shape
298-
299-
# setup chunks
300-
chunks = kwargs.pop('chunks', None)
301-
if chunks is None:
302-
_, chunks = _get_shape_chunks(data)
294+
# setup shape and chunks
295+
shape, chunks = _get_shape_chunks(data)
296+
kwargs['shape'] = data.shape
297+
kwargs.setdefault('chunks', chunks)
303298

304299
# instantiate array
305-
z = create(shape=shape, chunks=chunks, dtype=dtype, **kwargs)
300+
z = create(**kwargs)
306301

307302
# fill with data
308303
z[:] = data

zarr/hierarchy.py

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import absolute_import, print_function, division
3-
from collections import Mapping
3+
from collections import MutableMapping
44

55

66
import numpy as np
@@ -9,7 +9,7 @@
99
from zarr.attrs import Attributes
1010
from zarr.core import Array
1111
from zarr.storage import contains_array, contains_group, init_group, \
12-
DictStore, DirectoryStore, group_meta_key, attrs_key, listdir
12+
DictStore, DirectoryStore, group_meta_key, attrs_key, listdir, rmdir
1313
from zarr.creation import array, create, empty, zeros, ones, full, \
1414
empty_like, zeros_like, ones_like, full_like
1515
from zarr.util import normalize_storage_path, normalize_shape
@@ -18,7 +18,7 @@
1818
from zarr.meta import decode_group_metadata
1919

2020

21-
class Group(Mapping):
21+
class Group(MutableMapping):
2222
"""Instantiate a group from an initialized store.
2323
2424
Parameters
@@ -303,6 +303,20 @@ def __getitem__(self, item):
303303
else:
304304
raise KeyError(item)
305305

306+
def __setitem__(self, item, value):
307+
self.array(item, value, overwrite=True)
308+
309+
def __delitem__(self, item):
310+
return self._write_op(self._delitem_nosync, item)
311+
312+
def _delitem_nosync(self, item):
313+
path = self._item_path(item)
314+
if contains_array(self._store, path) or \
315+
contains_group(self._store, path):
316+
rmdir(self._store, path)
317+
else:
318+
raise KeyError(item)
319+
306320
def group_keys(self):
307321
"""Return an iterator over member names for groups only.
308322
@@ -494,10 +508,7 @@ def require_groups(self, *names):
494508
"""Convenience method to require multiple groups in a single call."""
495509
return tuple(self.require_group(name) for name in names)
496510

497-
def create_dataset(self, name, data=None, shape=None, chunks=None,
498-
dtype=None, compressor='default', fill_value=0,
499-
order='C', synchronizer=None, filters=None,
500-
overwrite=False, cache_metadata=True, **kwargs):
511+
def create_dataset(self, name, **kwargs):
501512
"""Create an array.
502513
503514
Parameters
@@ -550,43 +561,23 @@ def create_dataset(self, name, data=None, shape=None, chunks=None,
550561
551562
""" # flake8: noqa
552563

553-
return self._write_op(self._create_dataset_nosync, name, data=data,
554-
shape=shape, chunks=chunks, dtype=dtype,
555-
compressor=compressor, fill_value=fill_value,
556-
order=order, synchronizer=synchronizer,
557-
filters=filters, overwrite=overwrite,
558-
cache_metadata=cache_metadata, **kwargs)
564+
return self._write_op(self._create_dataset_nosync, name, **kwargs)
559565

560-
def _create_dataset_nosync(self, name, data=None, shape=None, chunks=None,
561-
dtype=None, compressor='default',
562-
fill_value=0, order='C', synchronizer=None,
563-
filters=None, overwrite=False,
564-
cache_metadata=True, **kwargs):
566+
def _create_dataset_nosync(self, name, data=None, **kwargs):
565567

566568
path = self._item_path(name)
567569

568570
# determine synchronizer
569-
if synchronizer is None:
570-
synchronizer = self._synchronizer
571+
kwargs.setdefault('synchronizer', self._synchronizer)
571572

572573
# create array
573-
if data is not None:
574-
a = array(data, chunks=chunks, dtype=dtype,
575-
compressor=compressor, fill_value=fill_value,
576-
order=order, synchronizer=synchronizer,
577-
store=self._store, path=path,
578-
chunk_store=self._chunk_store, filters=filters,
579-
overwrite=overwrite, cache_metadata=cache_metadata,
580-
**kwargs)
574+
if data is None:
575+
a = create(store=self._store, path=path,
576+
chunk_store=self._chunk_store, **kwargs)
581577

582578
else:
583-
a = create(shape=shape, chunks=chunks, dtype=dtype,
584-
compressor=compressor, fill_value=fill_value,
585-
order=order, synchronizer=synchronizer,
586-
store=self._store, path=path,
587-
chunk_store=self._chunk_store, filters=filters,
588-
overwrite=overwrite, cache_metadata=cache_metadata,
589-
**kwargs)
579+
a = array(data, store=self._store, path=path,
580+
chunk_store=self._chunk_store, **kwargs)
590581

591582
return a
592583

zarr/storage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -891,8 +891,8 @@ def getsize(self, path=None):
891891
return info.compress_size
892892
except KeyError:
893893
err_path_not_found(path)
894-
else:
895-
return 0
894+
else:
895+
return 0
896896

897897

898898
def migrate_1to2(store):

zarr/tests/test_creation.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ def test_array():
7272
eq(z.dtype, z2.dtype)
7373
assert_array_equal(z[:], z2[:])
7474

75+
# with chunky array-likes
76+
7577
b = np.arange(1000).reshape(100, 10)
7678
c = MockBcolzArray(b, 10)
7779
z3 = array(c)

zarr/tests/test_hierarchy.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,33 @@ def test_group_repr(self):
507507

508508
def test_setitem(self):
509509
g = self.create_group()
510-
with assert_raises(TypeError):
511-
g['foo'] = 'bar'
510+
try:
511+
data = np.arange(100)
512+
g['foo'] = data
513+
assert_array_equal(data, g['foo'])
514+
data = np.arange(200)
515+
g['foo'] = data
516+
assert_array_equal(data, g['foo'])
517+
except NotImplementedError:
518+
pass
519+
520+
def test_delitem(self):
521+
g = self.create_group()
522+
g.create_group('foo')
523+
g.create_dataset('bar/baz', shape=100, chunks=10)
524+
assert 'foo' in g
525+
assert 'bar' in g
526+
assert 'bar/baz' in g
527+
try:
528+
del g['bar']
529+
with assert_raises(KeyError):
530+
del g['xxx']
531+
except NotImplementedError:
532+
pass
533+
else:
534+
assert 'foo' in g
535+
assert 'bar' not in g
536+
assert 'bar/baz' not in g
512537

513538
def test_array_creation(self):
514539
grp = self.create_group()

0 commit comments

Comments
 (0)