33from  abc  import  ABCMeta , abstractmethod 
44from  collections .abc  import  Iterable 
55from  warnings  import  warn 
6- from  typing  import  Tuple 
6+ from  typing  import  Tuple ,  Callable 
77from  itertools  import  product , chain 
88
99import  h5py 
@@ -190,9 +190,10 @@ def __init__(self, **kwargs):
190190        HDF5 recommends chunk size in the range of 2 to 16 MB for optimal cloud performance. 
191191        https://youtu.be/rcS5vt-mKok?t=621 
192192        """ 
193-         buffer_gb , buffer_shape , chunk_mb , chunk_shape , self .display_progress , self . progress_bar_options  =  getargs (
193+         buffer_gb , buffer_shape , chunk_mb , chunk_shape , self .display_progress , progress_bar_options  =  getargs (
194194            "buffer_gb" , "buffer_shape" , "chunk_mb" , "chunk_shape" , "display_progress" , "progress_bar_options" , kwargs 
195195        )
196+         self .progress_bar_options  =  progress_bar_options  or  dict ()
196197
197198        if  buffer_gb  is  None  and  buffer_shape  is  None :
198199            buffer_gb  =  1.0 
@@ -264,15 +265,13 @@ def __init__(self, **kwargs):
264265        )
265266
266267        if  self .display_progress :
267-             if  self .progress_bar_options  is  None :
268-                 self .progress_bar_options  =  dict ()
269- 
270268            try :
271269                from  tqdm  import  tqdm 
272270
273271                if  "total"  in  self .progress_bar_options :
274272                    warn ("Option 'total' in 'progress_bar_options' is not allowed to be over-written! Ignoring." )
275273                    self .progress_bar_options .pop ("total" )
274+ 
276275                self .progress_bar  =  tqdm (total = self .num_buffers , ** self .progress_bar_options )
277276            except  ImportError :
278277                warn (
@@ -345,12 +344,6 @@ def _get_default_buffer_shape(self, **kwargs) -> Tuple[int, ...]:
345344            ]
346345        )
347346
348-     def  recommended_chunk_shape (self ) ->  Tuple [int , ...]:
349-         return  self .chunk_shape 
350- 
351-     def  recommended_data_shape (self ) ->  Tuple [int , ...]:
352-         return  self .maxshape 
353- 
354347    def  __iter__ (self ):
355348        return  self 
356349
@@ -371,6 +364,11 @@ def __next__(self):
371364                self .progress_bar .write ("\n " )  # Allows text to be written to new lines after completion 
372365            raise  StopIteration 
373366
367+     def  __reduce__ (self ) ->  Tuple [Callable , Iterable ]:
368+         instance_constructor  =  self ._from_dict 
369+         initialization_args  =  (self ._to_dict (),)
370+         return  (instance_constructor , initialization_args )
371+ 
374372    @abstractmethod  
375373    def  _get_data (self , selection : Tuple [slice ]) ->  np .ndarray :
376374        """ 
@@ -391,24 +389,42 @@ def _get_data(self, selection: Tuple[slice]) -> np.ndarray:
391389        """ 
392390        raise  NotImplementedError ("The data fetching method has not been built for this DataChunkIterator!" )
393391
394-     @property  
395-     def  maxshape (self ) ->  Tuple [int , ...]:
396-         return  self ._maxshape 
397- 
398392    @abstractmethod  
399393    def  _get_maxshape (self ) ->  Tuple [int , ...]:
400394        """Retrieve the maximum bounds of the data shape using minimal I/O.""" 
401395        raise  NotImplementedError ("The setter for the maxshape property has not been built for this DataChunkIterator!" )
402396
403-     @property  
404-     def  dtype (self ) ->  np .dtype :
405-         return  self ._dtype 
406- 
407397    @abstractmethod  
408398    def  _get_dtype (self ) ->  np .dtype :
409399        """Retrieve the dtype of the data using minimal I/O.""" 
410400        raise  NotImplementedError ("The setter for the internal dtype has not been built for this DataChunkIterator!" )
411401
402+     def  _to_dict (self ) ->  dict :
403+         """Optional method to add in child classes to enable pickling (required for multiprocessing).""" 
404+         raise  NotImplementedError (
405+             "The `._to_dict()` method for pickling has not been defined for this DataChunkIterator!" 
406+         )
407+ 
408+     @staticmethod  
409+     def  _from_dict (self ) ->  Callable :
410+         """Optional method to add in child classes to enable pickling (required for multiprocessing).""" 
411+         raise  NotImplementedError (
412+             "The `._from_dict()` method for pickling has not been defined for this DataChunkIterator!" 
413+         )
414+ 
415+     def  recommended_chunk_shape (self ) ->  Tuple [int , ...]:
416+         return  self .chunk_shape 
417+ 
418+     def  recommended_data_shape (self ) ->  Tuple [int , ...]:
419+         return  self .maxshape 
420+ 
421+     @property  
422+     def  maxshape (self ) ->  Tuple [int , ...]:
423+         return  self ._maxshape 
424+     @property  
425+     def  dtype (self ) ->  np .dtype :
426+         return  self ._dtype 
427+ 
412428
413429class  DataChunkIterator (AbstractDataChunkIterator ):
414430    """ 
0 commit comments