U
    Cvf(                     @  s  d dl mZ 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mZmZ d dlmZmZ d dlmZmZmZ d dlmZ d dlmZ d d	lmZmZmZmZm Z  d d
l!m"Z" dd Z#dd Z$G dd de	Z%dd Z&G dd deZ'G dd de
Z(e(ed< dS )    )annotationsN)BACKEND_ENTRYPOINTSBackendArrayBackendEntrypointWritableCFDataStore_normalize_path)CachingFileManagerDummyFileManager)ensure_lockget_write_lock)encode_nc3_attr_valueencode_nc3_variableis_valid_nc3_name)StoreBackendEntrypoint)NumpyIndexingAdapter)Frozen
FrozenDictclose_on_errormodule_available'try_read_magic_number_from_file_or_path)Variablec                 C  s   t | tr| ddS | S )Nzutf-8replace)
isinstancebytesdecode)s r   :/tmp/pip-unpacked-wheel-h316xyqg/xarray/backends/scipy_.py_decode_string#   s    
r   c                 C  s   dd |   D S )Nc                 S  s&   i | ]\}}||d kr|nt |qS )
_FillValue)r   .0kvr   r   r   
<dictcomp>,   s      z!_decode_attrs.<locals>.<dictcomp>)items)dr   r   r   _decode_attrs)   s    r'   c                   @  s.   e Zd Zdd ZdddZdd Zdd	 Zd
S )ScipyArrayWrapperc                 C  s>   || _ || _|  j}|j| _t|jjt|jj	 | _d S N)
	datastorevariable_nameget_variabledatashapenpdtypekindstritemsize)selfr+   r*   arrayr   r   r   __init__0   s
    
zScipyArrayWrapper.__init__Tc                 C  s   | j j|}|j| j S r)   )r*   _manageracquire	variablesr+   )r4   
needs_lockdsr   r   r   r,   7   s    zScipyArrayWrapper.get_variablec                 C  s.   t |  j| }| jjj}tj|| j|dS )N)r0   copy)	r   r,   r-   r*   r;   Zuse_mmapr/   r5   r0   )r4   keyr-   r<   r   r   r   __getitem__;   s    
zScipyArrayWrapper.__getitem__c              	   C  s^   | j jL | jdd}z|||< W n, tk
rN   |tkrH||d d < n Y nX W 5 Q R X d S )NF)r:   )r*   lockr,   	TypeErrorEllipsis)r4   r=   valuer-   r   r   r   __setitem__C   s    
zScipyArrayWrapper.__setitem__N)T)__name__
__module____qualname__r6   r,   r>   rC   r   r   r   r   r(   /   s   
r(   c              
   C  s  dd l }t| trz| drzz|jjt| |||dW S  tk
rx } z"|j	d }d|krft
dn W 5 d }~X Y nX t| tr| drt| } z|jj| |||dW S  tk
 r } z.|j	d }d|krd}||7 }t|n W 5 d }~X Y nX d S )Nr   .gzmodemmapversionzis not a valid NetCDF 3 filez2gzipped file loading only supports NetCDF 3 files.   CDFz
            If this is a NetCDF4 file, you may need to install the
            netcdf4 library, e.g.,

            $ pip install netcdf4
            )Zscipy.ior   r2   endswithioZnetcdf_filegzipopenr@   args
ValueErrorr   
startswithBytesIO)filenamerI   rJ   rK   scipyeerrmsgmsgr   r   r   _open_scipy_netcdfP   s2       




rZ   c                   @  s   e Zd ZdZd!ddZedd Zdd	 Zd
d Zdd Z	dd Z
dd Zd"ddZdd Zdd Zdd Zd#ddZdd Zdd  ZdS )$ScipyDataStorezStore for reading and writing data via scipy.io.netcdf.

    This store has the advantage of being able to be initialized with a
    StringIO object, allow for serialization without writing to disk.

    It only supports the NetCDF3 file-format.
    rNc           
   	   C  s   |d k	rt d|d ks |dkr&d}n|dkr4d}nt d||d krd|dkrdt|trdt|}t|| _t|trtt|||t||dd	}nt||||d
}	t	|	}|| _
d S )Nz7cannot save to a group with the scipy.io.netcdf backendZNETCDF3_64BIT   ZNETCDF3_CLASSIC   z,invalid format for scipy.io.netcdf backend: r\   )rJ   rK   )rI   r?   kwargsrH   )rR   r   r2   r   r
   r?   r   rZ   dictr	   r7   )
r4   filename_or_objrI   formatgrouprJ   r?   rK   managerZscipy_datasetr   r   r   r6      s4    


   zScipyDataStore.__init__c                 C  s
   | j  S r)   )r7   r8   r4   r   r   r   r;      s    zScipyDataStore.dsc                 C  s   t |jt|| t|jS r)   )r   
dimensionsr(   r'   _attributes)r4   namevarr   r   r   open_store_variable   s
    z"ScipyDataStore.open_store_variablec                   s   t  fdd jj D S )Nc                 3  s"   | ]\}}|  ||fV  qd S r)   )rj   r    re   r   r   	<genexpr>   s    z/ScipyDataStore.get_variables.<locals>.<genexpr>)r   r;   r9   r%   re   r   re   r   get_variables   s    
zScipyDataStore.get_variablesc                 C  s   t t| jjS r)   )r   r'   r;   rg   re   r   r   r   	get_attrs   s    zScipyDataStore.get_attrsc                 C  s   t | jjS r)   )r   r;   rf   re   r   r   r   get_dimensions   s    zScipyDataStore.get_dimensionsc                 C  s   ddd | j j D iS )Nunlimited_dimsc                 S  s   h | ]\}}|d kr|qS r)   r   r    r   r   r   	<setcomp>   s      z.ScipyDataStore.get_encoding.<locals>.<setcomp>)r;   rf   r%   re   r   r   r   get_encoding   s     zScipyDataStore.get_encodingFc                 C  s>   || j jkr tt| j d|s(|nd }| j || d S )Nz& does not support modifying dimensions)r;   rf   rR   typerD   ZcreateDimension)r4   rh   lengthZis_unlimitedZ
dim_lengthr   r   r   set_dimension   s    zScipyDataStore.set_dimensionc                 C  s   t |stdd S )NzNot a valid attribute name)r   rR   )r4   r=   r   r   r   _validate_attr_key   s    z!ScipyDataStore._validate_attr_keyc                 C  s$   |  | t|}t| j|| d S r)   )ru   r   setattrr;   )r4   r=   rB   r   r   r   set_attribute   s    
zScipyDataStore.set_attributec                 C  s   t |}|S r)   )r   )r4   variabler   r   r   encode_variable   s    zScipyDataStore.encode_variablec           
      C  s   |r,|j r,|j dd ikr,tdt|j  |j}|| jjkrR| j||j|j | jj| }|j	
 D ]\}}| | t||| qht|| }	|	|fS )Nr   z'unexpected encoding for scipy backend: )encodingrR   listr-   r;   r9   ZcreateVariabler0   Zdimsattrsr%   ru   rv   r(   )
r4   rh   rx   Zcheck_encodingro   r-   Z	scipy_varr"   r#   targetr   r   r   prepare_variable   s$    

zScipyDataStore.prepare_variablec                 C  s   | j   d S r)   )r;   syncre   r   r   r   r      s    zScipyDataStore.syncc                 C  s   | j   d S r)   )r7   closere   r   r   r   r      s    zScipyDataStore.close)r\   NNNN)F)FN)rD   rE   rF   __doc__r6   propertyr;   rj   rl   rm   rn   rq   rt   ru   rw   ry   r~   r   r   r   r   r   r   r[   v   s.   	         
"

   
r[   c                   @  s2   e Zd ZdZedZdZdZdd Zdd
dZ	dS )ScipyBackendEntrypointa  
    Backend for netCDF files based on the scipy package.

    It can open ".nc", ".nc4", ".cdf" and ".gz" files but will only be
    selected as the default if the "netcdf4" and "h5netcdf" engines are
    not available. It has the advantage that is is a lightweight engine
    that has no system requirements (unlike netcdf4 and h5netcdf).

    Additionally it can open gizp compressed (".gz") files.

    For more information about the underlying library, visit:
    https://docs.scipy.org/doc/scipy/reference/generated/scipy.io.netcdf_file.html

    See Also
    --------
    backends.ScipyDataStore
    backends.NetCDF4BackendEntrypoint
    backends.H5netcdfBackendEntrypoint
    rV   zAOpen netCDF files (.nc, .nc4, .cdf and .gz) using scipy in XarrayzWhttps://docs.xarray.dev/en/stable/generated/xarray.backends.ScipyBackendEntrypoint.htmlc              	   C  s~   t |}|d k	r8|dr8t|}t |}W 5 Q R X |d k	rJ|dS ztj|\}}W n tk
rt   Y dS X |dkS )Ns   rL   F>   .nc4.ncrG   .cdf)r   rS   rO   rP   ospathsplitextr@   )r4   ra   Zmagic_numberf_extr   r   r   guess_can_open  s    
z%ScipyBackendEntrypoint.guess_can_openTNr\   c                 C  sT   t |}t||	|
|||d}t }t|  |j||||||||d}W 5 Q R X |S )N)rI   rb   rc   rJ   r?   )mask_and_scaledecode_timesconcat_charactersdecode_coordsdrop_variables
use_cftimedecode_timedelta)r   r[   r   r   open_dataset)r4   ra   r   r   r   r   r   r   r   rI   rb   rc   rJ   r?   storeZstore_entrypointr;   r   r   r   r     s,         

z#ScipyBackendEntrypoint.open_dataset)TTTTNNNr\   NNNN)
rD   rE   rF   r   r   	availabledescriptionurlr   r   r   r   r   r   r      s$               r   rV   ))
__future__r   rO   rN   r   Znumpyr/   Zxarray.backends.commonr   r   r   r   r   Zxarray.backends.file_managerr   r	   Zxarray.backends.locksr
   r   Zxarray.backends.netcdf3r   r   r   Zxarray.backends.storer   Zxarray.core.indexingr   Zxarray.core.utilsr   r   r   r   r   Zxarray.core.variabler   r   r'   r(   rZ   r[   r   r   r   r   r   <module>   s&   !&}M