@@ -35,6 +35,10 @@ class Group(MutableMapping):
3535 chunk_store : MutableMapping, optional
3636 Separate storage for chunks. If not provided, `store` will be used
3737 for storage of both chunks and metadata.
38+ cache_attrs : bool, optional
39+ If True (default), user attributes will be cached for attribute read
40+ operations. If False, user attributes are reloaded from the store prior
41+ to all attribute read operations.
3842 synchronizer : object, optional
3943 Array synchronizer.
4044
@@ -86,7 +90,7 @@ class Group(MutableMapping):
8690 """
8791
8892 def __init__ (self , store , path = None , read_only = False , chunk_store = None ,
89- synchronizer = None ):
93+ cache_attrs = True , synchronizer = None ):
9094
9195 self ._store = store
9296 self ._chunk_store = chunk_store
@@ -115,7 +119,7 @@ def __init__(self, store, path=None, read_only=False, chunk_store=None,
115119 # setup attributes
116120 akey = self ._key_prefix + attrs_key
117121 self ._attrs = Attributes (store , key = akey , read_only = read_only ,
118- synchronizer = synchronizer )
122+ cache = cache_attrs , synchronizer = synchronizer )
119123
120124 # setup info
121125 self ._info = InfoReporter (self )
@@ -320,10 +324,12 @@ def __getitem__(self, item):
320324 path = self ._item_path (item )
321325 if contains_array (self ._store , path ):
322326 return Array (self ._store , read_only = self ._read_only , path = path ,
323- chunk_store = self ._chunk_store , synchronizer = self ._synchronizer )
327+ chunk_store = self ._chunk_store ,
328+ synchronizer = self ._synchronizer , cache_attrs = self .attrs .cache )
324329 elif contains_group (self ._store , path ):
325330 return Group (self ._store , read_only = self ._read_only , path = path ,
326- chunk_store = self ._chunk_store , synchronizer = self ._synchronizer )
331+ chunk_store = self ._chunk_store , cache_attrs = self .attrs .cache ,
332+ synchronizer = self ._synchronizer )
327333 else :
328334 raise KeyError (item )
329335
@@ -403,6 +409,7 @@ def groups(self):
403409 if contains_group (self ._store , path ):
404410 yield key , Group (self ._store , path = path , read_only = self ._read_only ,
405411 chunk_store = self ._chunk_store ,
412+ cache_attrs = self .attrs .cache ,
406413 synchronizer = self ._synchronizer )
407414
408415 def array_keys (self ):
@@ -447,6 +454,7 @@ def arrays(self):
447454 if contains_array (self ._store , path ):
448455 yield key , Array (self ._store , path = path , read_only = self ._read_only ,
449456 chunk_store = self ._chunk_store ,
457+ cache_attrs = self .attrs .cache ,
450458 synchronizer = self ._synchronizer )
451459
452460 def visitvalues (self , func ):
@@ -649,7 +657,8 @@ def _create_group_nosync(self, name, overwrite=False):
649657 overwrite = overwrite )
650658
651659 return Group (self ._store , path = path , read_only = self ._read_only ,
652- chunk_store = self ._chunk_store , synchronizer = self ._synchronizer )
660+ chunk_store = self ._chunk_store , cache_attrs = self .attrs .cache ,
661+ synchronizer = self ._synchronizer )
653662
654663 def create_groups (self , * names , ** kwargs ):
655664 """Convenience method to create multiple groups in a single call."""
@@ -692,7 +701,8 @@ def _require_group_nosync(self, name, overwrite=False):
692701 overwrite = overwrite )
693702
694703 return Group (self ._store , path = path , read_only = self ._read_only ,
695- chunk_store = self ._chunk_store , synchronizer = self ._synchronizer )
704+ chunk_store = self ._chunk_store , cache_attrs = self .attrs .cache ,
705+ synchronizer = self ._synchronizer )
696706
697707 def require_groups (self , * names ):
698708 """Convenience method to require multiple groups in a single call."""
@@ -760,6 +770,7 @@ def _create_dataset_nosync(self, name, data=None, **kwargs):
760770
761771 # determine synchronizer
762772 kwargs .setdefault ('synchronizer' , self ._synchronizer )
773+ kwargs .setdefault ('cache_attrs' , self .attrs .cache )
763774
764775 # create array
765776 if data is None :
@@ -804,9 +815,10 @@ def _require_dataset_nosync(self, name, shape, dtype=None, exact=False,
804815
805816 synchronizer = kwargs .get ('synchronizer' , self ._synchronizer )
806817 cache_metadata = kwargs .get ('cache_metadata' , True )
818+ cache_attrs = kwargs .get ('cache_attrs' , self .attrs .cache )
807819 a = Array (self ._store , path = path , read_only = self ._read_only ,
808820 chunk_store = self ._chunk_store , synchronizer = synchronizer ,
809- cache_metadata = cache_metadata )
821+ cache_metadata = cache_metadata , cache_attrs = cache_attrs )
810822 shape = normalize_shape (shape )
811823 if shape != a .shape :
812824 raise TypeError ('shape do not match existing array; expected {}, got {}'
@@ -834,6 +846,7 @@ def create(self, name, **kwargs):
834846 def _create_nosync (self , name , ** kwargs ):
835847 path = self ._item_path (name )
836848 kwargs .setdefault ('synchronizer' , self ._synchronizer )
849+ kwargs .setdefault ('cache_attrs' , self .attrs .cache )
837850 return create (store = self ._store , path = path , chunk_store = self ._chunk_store ,
838851 ** kwargs )
839852
@@ -845,6 +858,7 @@ def empty(self, name, **kwargs):
845858 def _empty_nosync (self , name , ** kwargs ):
846859 path = self ._item_path (name )
847860 kwargs .setdefault ('synchronizer' , self ._synchronizer )
861+ kwargs .setdefault ('cache_attrs' , self .attrs .cache )
848862 return empty (store = self ._store , path = path , chunk_store = self ._chunk_store ,
849863 ** kwargs )
850864
@@ -856,6 +870,7 @@ def zeros(self, name, **kwargs):
856870 def _zeros_nosync (self , name , ** kwargs ):
857871 path = self ._item_path (name )
858872 kwargs .setdefault ('synchronizer' , self ._synchronizer )
873+ kwargs .setdefault ('cache_attrs' , self .attrs .cache )
859874 return zeros (store = self ._store , path = path , chunk_store = self ._chunk_store ,
860875 ** kwargs )
861876
@@ -867,6 +882,7 @@ def ones(self, name, **kwargs):
867882 def _ones_nosync (self , name , ** kwargs ):
868883 path = self ._item_path (name )
869884 kwargs .setdefault ('synchronizer' , self ._synchronizer )
885+ kwargs .setdefault ('cache_attrs' , self .attrs .cache )
870886 return ones (store = self ._store , path = path , chunk_store = self ._chunk_store , ** kwargs )
871887
872888 def full (self , name , fill_value , ** kwargs ):
@@ -877,6 +893,7 @@ def full(self, name, fill_value, **kwargs):
877893 def _full_nosync (self , name , fill_value , ** kwargs ):
878894 path = self ._item_path (name )
879895 kwargs .setdefault ('synchronizer' , self ._synchronizer )
896+ kwargs .setdefault ('cache_attrs' , self .attrs .cache )
880897 return full (store = self ._store , path = path , chunk_store = self ._chunk_store ,
881898 fill_value = fill_value , ** kwargs )
882899
@@ -888,6 +905,7 @@ def array(self, name, data, **kwargs):
888905 def _array_nosync (self , name , data , ** kwargs ):
889906 path = self ._item_path (name )
890907 kwargs .setdefault ('synchronizer' , self ._synchronizer )
908+ kwargs .setdefault ('cache_attrs' , self .attrs .cache )
891909 return array (data , store = self ._store , path = path , chunk_store = self ._chunk_store ,
892910 ** kwargs )
893911
@@ -899,6 +917,7 @@ def empty_like(self, name, data, **kwargs):
899917 def _empty_like_nosync (self , name , data , ** kwargs ):
900918 path = self ._item_path (name )
901919 kwargs .setdefault ('synchronizer' , self ._synchronizer )
920+ kwargs .setdefault ('cache_attrs' , self .attrs .cache )
902921 return empty_like (data , store = self ._store , path = path ,
903922 chunk_store = self ._chunk_store , ** kwargs )
904923
@@ -910,6 +929,7 @@ def zeros_like(self, name, data, **kwargs):
910929 def _zeros_like_nosync (self , name , data , ** kwargs ):
911930 path = self ._item_path (name )
912931 kwargs .setdefault ('synchronizer' , self ._synchronizer )
932+ kwargs .setdefault ('cache_attrs' , self .attrs .cache )
913933 return zeros_like (data , store = self ._store , path = path ,
914934 chunk_store = self ._chunk_store , ** kwargs )
915935
@@ -921,6 +941,7 @@ def ones_like(self, name, data, **kwargs):
921941 def _ones_like_nosync (self , name , data , ** kwargs ):
922942 path = self ._item_path (name )
923943 kwargs .setdefault ('synchronizer' , self ._synchronizer )
944+ kwargs .setdefault ('cache_attrs' , self .attrs .cache )
924945 return ones_like (data , store = self ._store , path = path ,
925946 chunk_store = self ._chunk_store , ** kwargs )
926947
@@ -932,6 +953,7 @@ def full_like(self, name, data, **kwargs):
932953 def _full_like_nosync (self , name , data , ** kwargs ):
933954 path = self ._item_path (name )
934955 kwargs .setdefault ('synchronizer' , self ._synchronizer )
956+ kwargs .setdefault ('cache_attrs' , self .attrs .cache )
935957 return full_like (data , store = self ._store , path = path ,
936958 chunk_store = self ._chunk_store , ** kwargs )
937959
@@ -971,7 +993,8 @@ def _normalize_store_arg(store, clobber=False):
971993 return normalize_store_arg (store , clobber = clobber , default = DictStore )
972994
973995
974- def group (store = None , overwrite = False , chunk_store = None , synchronizer = None , path = None ):
996+ def group (store = None , overwrite = False , chunk_store = None ,
997+ cache_attrs = True , synchronizer = None , path = None ):
975998 """Create a group.
976999
9771000 Parameters
@@ -984,6 +1007,10 @@ def group(store=None, overwrite=False, chunk_store=None, synchronizer=None, path
9841007 chunk_store : MutableMapping, optional
9851008 Separate storage for chunks. If not provided, `store` will be used
9861009 for storage of both chunks and metadata.
1010+ cache_attrs : bool, optional
1011+ If True (default), user attributes will be cached for attribute read
1012+ operations. If False, user attributes are reloaded from the store prior
1013+ to all attribute read operations.
9871014 synchronizer : object, optional
9881015 Array synchronizer.
9891016 path : string, optional
@@ -1021,10 +1048,10 @@ def group(store=None, overwrite=False, chunk_store=None, synchronizer=None, path
10211048 path = path )
10221049
10231050 return Group (store , read_only = False , chunk_store = chunk_store ,
1024- synchronizer = synchronizer , path = path )
1051+ cache_attrs = cache_attrs , synchronizer = synchronizer , path = path )
10251052
10261053
1027- def open_group (store , mode = 'a' , synchronizer = None , path = None ):
1054+ def open_group (store , mode = 'a' , cache_attrs = True , synchronizer = None , path = None ):
10281055 """Open a group using file-mode-like semantics.
10291056
10301057 Parameters
@@ -1036,6 +1063,10 @@ def open_group(store, mode='a', synchronizer=None, path=None):
10361063 read/write (must exist); 'a' means read/write (create if doesn't
10371064 exist); 'w' means create (overwrite if exists); 'w-' means create
10381065 (fail if exists).
1066+ cache_attrs : bool, optional
1067+ If True (default), user attributes will be cached for attribute read
1068+ operations. If False, user attributes are reloaded from the store prior
1069+ to all attribute read operations.
10391070 synchronizer : object, optional
10401071 Array synchronizer.
10411072 path : string, optional
@@ -1093,4 +1124,5 @@ def open_group(store, mode='a', synchronizer=None, path=None):
10931124 # determine read only status
10941125 read_only = mode == 'r'
10951126
1096- return Group (store , read_only = read_only , synchronizer = synchronizer , path = path )
1127+ return Group (store , read_only = read_only , cache_attrs = cache_attrs ,
1128+ synchronizer = synchronizer , path = path )
0 commit comments