Skip to content

Commit 18f0dc1

Browse files
committed
document attributes
1 parent bbc6da6 commit 18f0dc1

File tree

4 files changed

+65
-2
lines changed

4 files changed

+65
-2
lines changed

docs/api.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ API reference
88
api/core
99
api/hierarchy
1010
api/storage
11+
api/convenience
1112
api/codecs
13+
api/attrs
1214
api/sync
13-
api/convenience

docs/api/attrs.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
The Attributes class (``zarr.attrs``)
2+
=====================================
3+
.. module:: zarr.attrs
4+
5+
.. autoclass:: Attributes
6+
7+
.. automethod:: __getitem__
8+
.. automethod:: __setitem__
9+
.. automethod:: __delitem__
10+
.. automethod:: __iter__
11+
.. automethod:: __len__
12+
.. automethod:: keys
13+
.. automethod:: asdict
14+
.. automethod:: put
15+
.. automethod:: update

zarr/attrs.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,22 @@
1111
class Attributes(MutableMapping):
1212
"""Class providing access to user attributes on an array or group. Should not be
1313
instantiated directly, will be available via the `.attrs` property of an array or
14-
group."""
14+
group.
15+
16+
Parameters
17+
----------
18+
store : MutableMapping
19+
The store in which to store the attributes.
20+
key : str, optional
21+
The key under which the attributes will be stored.
22+
read_only : bool, optional
23+
If True, attributes cannot be modified.
24+
cache : bool, optional
25+
If True (default), attributes will be cached locally.
26+
synchronizer : Synchronizer
27+
Only necessary if attributes may be modified from multiple threads or processes.
28+
29+
"""
1530

1631
def __init__(self, store, key='.zattrs', read_only=False, cache=True,
1732
synchronizer=None):

zarr/tests/test_attrs.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,66 +115,98 @@ def test_key_completions(self):
115115

116116
def test_caching_on(self):
117117
# caching is turned on by default
118+
119+
# setup store
118120
store = CountingDict()
119121
eq(0, store.counter['__getitem__', 'attrs'])
120122
eq(0, store.counter['__setitem__', 'attrs'])
121123
store['attrs'] = json.dumps(dict(foo='xxx', bar=42)).encode('ascii')
122124
eq(0, store.counter['__getitem__', 'attrs'])
123125
eq(1, store.counter['__setitem__', 'attrs'])
126+
127+
# setup attributes
124128
a = self.init_attributes(store)
129+
130+
# test __getitem__ causes all attributes to be cached
125131
eq(a['foo'], 'xxx')
126132
eq(1, store.counter['__getitem__', 'attrs'])
127133
eq(a['bar'], 42)
128134
eq(1, store.counter['__getitem__', 'attrs'])
129135
eq(a['foo'], 'xxx')
130136
eq(1, store.counter['__getitem__', 'attrs'])
137+
138+
# test __setitem__ updates the cache
131139
a['foo'] = 'yyy'
132140
eq(2, store.counter['__getitem__', 'attrs'])
133141
eq(2, store.counter['__setitem__', 'attrs'])
134142
eq(a['foo'], 'yyy')
135143
eq(2, store.counter['__getitem__', 'attrs'])
136144
eq(2, store.counter['__setitem__', 'attrs'])
145+
146+
# test update() updates the cache
137147
a.update(foo='zzz', bar=84)
138148
eq(3, store.counter['__getitem__', 'attrs'])
139149
eq(3, store.counter['__setitem__', 'attrs'])
140150
eq(a['foo'], 'zzz')
141151
eq(a['bar'], 84)
142152
eq(3, store.counter['__getitem__', 'attrs'])
143153
eq(3, store.counter['__setitem__', 'attrs'])
154+
155+
# test __contains__ uses the cache
144156
assert 'foo' in a
145157
eq(3, store.counter['__getitem__', 'attrs'])
146158
eq(3, store.counter['__setitem__', 'attrs'])
147159
assert 'spam' not in a
148160
eq(3, store.counter['__getitem__', 'attrs'])
149161
eq(3, store.counter['__setitem__', 'attrs'])
150162

163+
# test __delitem__ updates the cache
164+
del a['bar']
165+
eq(4, store.counter['__getitem__', 'attrs'])
166+
eq(4, store.counter['__setitem__', 'attrs'])
167+
assert 'bar' not in a
168+
eq(4, store.counter['__getitem__', 'attrs'])
169+
eq(4, store.counter['__setitem__', 'attrs'])
170+
151171
def test_caching_off(self):
172+
173+
# setup store
152174
store = CountingDict()
153175
eq(0, store.counter['__getitem__', 'attrs'])
154176
eq(0, store.counter['__setitem__', 'attrs'])
155177
store['attrs'] = json.dumps(dict(foo='xxx', bar=42)).encode('ascii')
156178
eq(0, store.counter['__getitem__', 'attrs'])
157179
eq(1, store.counter['__setitem__', 'attrs'])
180+
181+
# setup attributes
158182
a = self.init_attributes(store, cache=False)
183+
184+
# test __getitem__
159185
eq(a['foo'], 'xxx')
160186
eq(1, store.counter['__getitem__', 'attrs'])
161187
eq(a['bar'], 42)
162188
eq(2, store.counter['__getitem__', 'attrs'])
163189
eq(a['foo'], 'xxx')
164190
eq(3, store.counter['__getitem__', 'attrs'])
191+
192+
# test __setitem__
165193
a['foo'] = 'yyy'
166194
eq(4, store.counter['__getitem__', 'attrs'])
167195
eq(2, store.counter['__setitem__', 'attrs'])
168196
eq(a['foo'], 'yyy')
169197
eq(5, store.counter['__getitem__', 'attrs'])
170198
eq(2, store.counter['__setitem__', 'attrs'])
199+
200+
# test update()
171201
a.update(foo='zzz', bar=84)
172202
eq(6, store.counter['__getitem__', 'attrs'])
173203
eq(3, store.counter['__setitem__', 'attrs'])
174204
eq(a['foo'], 'zzz')
175205
eq(a['bar'], 84)
176206
eq(8, store.counter['__getitem__', 'attrs'])
177207
eq(3, store.counter['__setitem__', 'attrs'])
208+
209+
# test __contains__
178210
assert 'foo' in a
179211
eq(9, store.counter['__getitem__', 'attrs'])
180212
eq(3, store.counter['__setitem__', 'attrs'])

0 commit comments

Comments
 (0)