a
    İa:0                     @   s6  U d dl Z d dlZd dlZd dlZd dlmZmZmZmZm	Z	 d dl
ZddlmZ ddlmZ ddlmZ ddlmZmZmZ e eZdZd	d
 Zdd Zdd Zdd ZeddfddZG dd deej Z!G dd dZ"G dd dZ#G dd de"Z$G dd de$Z%G dd  d Z&i Z'ee(ee& f e)d!< dS )"    N)AnyDictTupleTypeUnion   )
cf_encoder)indexing)is_duck_dask_array)
FrozenDictNdimSizeLenMixinis_remote_uriZ
__values__c                 C   s@   t | tjrt| } t | tr<t| s<tjtj| } | S N)	
isinstanceosPathLikefspathstrr   pathabspath
expanduser)r    r   5lib/python3.9/site-packages/xarray/backends/common.py_normalize_path   s
    
r   c                 C   s   | d u rt } | S r   NONE_VAR_NAMEnamer   r   r   _encode_variable_name   s    r   c                 C   s   | t krd } | S r   r   r   r   r   r   _decode_variable_name%   s    r   c                 C   sB   d}| j dur,| jdd f| }| j } qdd| }| |fS )z;Find the root and group name of a netCDF4/h5netcdf dataset.r   N/)parentr   splitjoin)ZdsZ	hierarchygroupr   r   r   find_root_and_group+   s    
r&      i  c           	      C   s   |dksJ t |d D ]}z| | W   S  |y   ||krB |d|  }|tj| }d| d||  dt  }t| t	d|  Y q0 qdS )	z
    Robustly index an array, using retry logic with exponential backoff if any
    of the errors ``catch`` are raised. The initial_delay is measured in ms.

    With the default settings, the maximum delay will be in the range of 32-64
    seconds.
    r      r   zgetitem failed, waiting z ms before trying again (z# tries remaining). Full traceback: gMbP?N)
rangenpZrandomZrandint	traceback
format_excloggerdebugtimesleep)	arraykeyZcatchZmax_retriesZinitial_delaynZ
base_delayZ
next_delaymsgr   r   r   robust_getitem5   s"    
r5   c                   @   s   e Zd ZdZdddZdS )BackendArrayr   Nc                 C   s(   t td f| j }tj| | |dS )N)dtype)r	   ZBasicIndexerslicendimr*   Zasarray)selfr7   r2   r   r   r   	__array__Q   s    zBackendArray.__array__)N)__name__
__module____qualname__	__slots__r;   r   r   r   r   r6   N   s   r6   c                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )AbstractDataStorer   c                 C   s
   t  d S r   NotImplementedErrorr:   r   r   r   get_dimensionsY   s    z AbstractDataStore.get_dimensionsc                 C   s
   t  d S r   rA   rC   r   r   r   	get_attrs\   s    zAbstractDataStore.get_attrsc                 C   s
   t  d S r   rA   rC   r   r   r   get_variables_   s    zAbstractDataStore.get_variablesc                 C   s   i S r   r   rC   r   r   r   get_encodingb   s    zAbstractDataStore.get_encodingc                 C   s.   t dd |   D }t |  }||fS )a,  
        This loads the variables and attributes simultaneously.
        A centralized loading function makes it easier to create
        data stores that do automatic encoding/decoding.

        For example::

            class SuffixAppendingDataStore(AbstractDataStore):

                def load(self):
                    variables, attributes = AbstractDataStore.load(self)
                    variables = {'%s_suffix' % k: v
                                 for k, v in variables.items()}
                    attributes = {'%s_suffix' % k: v
                                  for k, v in attributes.items()}
                    return variables, attributes

        This function will be called anytime variables or attributes
        are requested, so care should be taken to make sure its fast.
        c                 s   s   | ]\}}t ||fV  qd S r   )r   .0kvr   r   r   	<genexpr>z   s   z)AbstractDataStore.load.<locals>.<genexpr>)r   rF   itemsrE   r:   	variables
attributesr   r   r   loade   s
    
zAbstractDataStore.loadc                 C   s   d S r   r   rC   r   r   r   close   s    zAbstractDataStore.closec                 C   s   | S r   r   rC   r   r   r   	__enter__   s    zAbstractDataStore.__enter__c                 C   s   |    d S r   )rR   )r:   Zexception_typeZexception_valuer+   r   r   r   __exit__   s    zAbstractDataStore.__exit__N)r<   r=   r>   r?   rD   rE   rF   rG   rQ   rR   rS   rT   r   r   r   r   r@   V   s   r@   c                   @   s.   e Zd ZdZd
ddZdddZddd	ZdS )ArrayWritersourcestargetsregionslockNc                 C   s   g | _ g | _g | _|| _d S r   rV   )r:   rZ   r   r   r   __init__   s    zArrayWriter.__init__c                 C   sH   t |r.| j| | j| | j| n|r<|||< n||d< d S )N.)r
   rW   appendrX   rY   )r:   sourcetargetZregionr   r   r   add   s    
zArrayWriter.addTc                 C   sJ   | j rFdd lm} |j| j | j| j|d| jd}g | _ g | _g | _|S d S )Nr   T)rZ   computeflushrY   )rW   Z
dask.arrayr1   storerX   rZ   rY   )r:   r`   daZdelayed_storer   r   r   sync   s    zArrayWriter.sync)N)N)T)r<   r=   r>   r?   r[   r_   rd   r   r   r   r   rU      s   

rU   c                   @   sv   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
e ddfddZdd ZdddZdddZdS )AbstractWritableDataStorer   c                    s4    fdd|  D } fdd|  D }||fS )a  
        Encode the variables and attributes in this store

        Parameters
        ----------
        variables : dict-like
            Dictionary of key/value (variable name / xr.Variable) pairs
        attributes : dict-like
            Dictionary of key/value (attribute name / attribute) pairs

        Returns
        -------
        variables : dict-like
        attributes : dict-like

        c                    s   i | ]\}}|  |qS r   encode_variablerH   rC   r   r   
<dictcomp>       z4AbstractWritableDataStore.encode.<locals>.<dictcomp>c                    s   i | ]\}}|  |qS r   encode_attributerH   rC   r   r   rh      ri   )rM   rN   r   rC   r   encode   s    z AbstractWritableDataStore.encodec                 C   s   |S )zencode one variabler   )r:   rK   r   r   r   rg      s    z)AbstractWritableDataStore.encode_variablec                 C   s   |S )zencode one attributer   )r:   ar   r   r   rk      s    z*AbstractWritableDataStore.encode_attributec                 C   s
   t  d S r   rA   )r:   dimlengthr   r   r   set_dimension   s    z'AbstractWritableDataStore.set_dimensionc                 C   s
   t  d S r   rA   r:   rJ   rK   r   r   r   set_attribute   s    z'AbstractWritableDataStore.set_attributec                 C   s
   t  d S r   rA   rq   r   r   r   set_variable   s    z&AbstractWritableDataStore.set_variablec                 C   s   |  ||j dS )z
        in stores, variables are all variables AND coordinates
        in xarray.Dataset variables are variables NOT coordinates,
        so here we pass the whole dataset in instead of doing
        dataset.variables
        N)rb   attrs)r:   Zdatasetr   r   r   store_dataset   s    z'AbstractWritableDataStore.store_datasetNc                 C   sL   |du rt  }| ||\}}| | | j||d | j||||d dS )a  
        Top level method for putting data on this store, this method:
          - encodes variables/attributes
          - sets dimensions
          - sets variables

        Parameters
        ----------
        variables : dict-like
            Dictionary of key/value (variable name / xr.Variable) pairs
        attributes : dict-like
            Dictionary of key/value (attribute name / attribute) pairs
        check_encoding_set : list-like
            List of variables that should be checked for invalid encoding
            values
        writer : ArrayWriter
        unlimited_dims : list-like
            List of dimension names that should be treated as unlimited
            dimensions.
        Nunlimited_dims)rU   rl   set_attributesset_dimensionsset_variables)r:   rO   rP   check_encoding_setwriterrw   r   r   r   rb      s    
zAbstractWritableDataStore.storec                 C   s"   |  D ]\}}| || qdS )z
        This provides a centralized method to set the dataset attributes on the
        data store.

        Parameters
        ----------
        attributes : dict-like
            Dictionary of key/value (attribute name / attribute) pairs
        N)rM   rr   )r:   rP   rJ   rK   r   r   r   rx     s    
z(AbstractWritableDataStore.set_attributesc                 C   sH   |  D ]:\}}t|}||v }| j||||d\}	}
||
|	 qdS )a  
        This provides a centralized method to set the variables on the data
        store.

        Parameters
        ----------
        variables : dict-like
            Dictionary of key/value (variable name / xr.Variable) pairs
        check_encoding_set : list-like
            List of variables that should be checked for invalid encoding
            values
        writer : ArrayWriter
        unlimited_dims : list-like
            List of dimension names that should be treated as unlimited
            dimensions.
        rv   N)rM   r   Zprepare_variabler_   )r:   rO   r{   r|   rw   ZvnrK   r   checkr^   r]   r   r   r   rz     s    
z'AbstractWritableDataStore.set_variablesc           	   	   C   s   |du rt  }|  }i }|D ]}d||< q| D ]}|tt|j|j q4| D ]\\}}||v r||| krt	d|d| d||  dqZ||vrZ||v }| 
||| qZdS )au  
        This provides a centralized method to set the dimensions on the data
        store.

        Parameters
        ----------
        variables : dict-like
            Dictionary of key/value (variable name / xr.Variable) pairs
        unlimited_dims : list-like
            List of dimension names that should be treated as unlimited
            dimensions.
        Nz,Unable to update size for existing dimensionz (z != ))setrD   valuesupdatedictzipdimsshaperM   
ValueErrorrp   )	r:   rO   rw   Zexisting_dimsr   rK   rn   ro   Zis_unlimitedr   r   r   ry   5  s,    
z(AbstractWritableDataStore.set_dimensions)N)N)r<   r=   r>   r?   rl   rg   rk   rp   rr   rs   ru   	frozensetrb   rx   rz   ry   r   r   r   r   re      s   
'
re   c                   @   s   e Zd ZdZdd ZdS )WritableCFDataStorer   c                    sB   t ||\}} fdd| D } fdd| D }||fS )Nc                    s   i | ]\}}|  |qS r   rf   rH   rC   r   r   rh   _  ri   z.WritableCFDataStore.encode.<locals>.<dictcomp>c                    s   i | ]\}}|  |qS r   rj   rH   rC   r   r   rh   `  ri   )r   rM   rN   r   rC   r   rl   [  s    zWritableCFDataStore.encodeN)r<   r=   r>   r?   rl   r   r   r   r   r   X  s   r   c                   @   sF   e Zd ZU dZdZeedf ed< d	eee e	dddZ
dd ZdS )
BackendEntrypointa  
    ``BackendEntrypoint`` is a class container and it is the main interface
    for the backend plugins, see :ref:`RST backend_entrypoint`.
    It shall implement:

    - ``open_dataset`` method: it shall implement reading from file, variables
      decoding and it returns an instance of :py:class:`~xarray.Dataset`.
      It shall take in input at least ``filename_or_obj`` argument and
      ``drop_variables`` keyword argument.
      For more details see :ref:`RST open_dataset`.
    - ``guess_can_open`` method: it shall return ``True`` if the backend is able to open
      ``filename_or_obj``, ``False`` otherwise. The implementation of this
      method is not mandatory.
    Nopen_dataset_parameters)filename_or_objdrop_variableskwargsc                 K   s   t dS )`
        Backend open_dataset method used by Xarray in :py:func:`~xarray.open_dataset`.
        NrA   )r:   r   r   r   r   r   r   open_datasetw  s    
zBackendEntrypoint.open_datasetc                 C   s   dS )r   Fr   )r:   r   r   r   r   guess_can_open  s    z BackendEntrypoint.guess_can_open)N)r<   r=   r>   __doc__r   r   r   __annotations__r   r   r   r   r   r   r   r   r   d  s   
 r   BACKEND_ENTRYPOINTS)*loggingr   r/   r+   typingr   r   r   r   r   Znumpyr*   Zconventionsr   corer	   Zcore.pycompatr
   Z
core.utilsr   r   r   Z	getLoggerr<   r-   r   r   r   r   r&   	Exceptionr5   ZExplicitlyIndexedr6   r@   rU   re   r   r   r   r   r   r   r   r   r   <module>   s0   



4* %'