U
    n/e~                     @   s   d dl Z d dlZd dlmZmZ d dlmZ edZedd Z	G dd dZ
G d	d
 d
eZdd ZG dd deZG dd deZdd ZdS )    N)contextmanagerAsyncExitStack)ClientErrorZs3fsc                  g   s$   z
d V  W n | k
r   Y nX d S N )
exceptionsr   r   ./tmp/pip-unpacked-wheel-zv_a3qq1/s3fs/utils.pyignoring
   s    
r	   c                   @   s>   e Zd Zdd ZdddZdd Zdd	 Zd
d Zdd ZdS )S3BucketRegionCachec                 K   s*   || _ t | _d | _|| _i | _i | _d S r   )_sessionr   _stack_client_client_kwargs_buckets_regions)selfsessionZclient_kwargsr   r   r   __init__   s    zS3BucketRegionCache.__init__Nc              
      s  || j kr| j | S |  I d H }|d kr.|S z|j|dI d H }W nV tk
r } z8|jd di d}|std| | W Y S W 5 d }~X Y nX |d d d }|| jkrtd|| | j	
| jjd	d|i| jI d H | j|< | j|  }| j |< |S )
N)ZBucketZResponseMetadataZHTTPHeaderszx-amz-bucket-regionzDRC: HEAD_BUCKET call for %r has failed, returning the general clientz:RC: Creating a new regional client for %r on the region %rs3Zregion_name)r   )r   
get_clientZhead_bucketr   responsegetloggerdebugr   r   enter_async_contextr   create_clientr   )r   Zbucket_nameZgeneral_clientr   eZregionclientr   r   r   get_bucket_client   sN    


 
 z%S3BucketRegionCache.get_bucket_clientc                    s,   | j s&| j| jjd| jI d H | _ | j S )Nr   )r   )r   r   r   r   r   r   r   r   r   r   r   F   s
    zS3BucketRegionCache.get_clientc                    s8   t d | j  | j  d | _| j I d H  d S )NzRC: discarding all clients)r   r   r   clearr   r   r   acloser   r   r   r   r    M   s
    


zS3BucketRegionCache.clearc                    s   | S r   r   r   r   r   r   
__aenter__T   s    zS3BucketRegionCache.__aenter__c                    s   |   I d H  d S r   )r    )r   Zexc_argsr   r   r   	__aexit__W   s    zS3BucketRegionCache.__aexit__)N)	__name__
__module____qualname__r   r   r   r    r"   r#   r   r   r   r   r
      s   
(r
   c                       s(   e Zd ZdZeed fddZ  ZS )FileExpireda  
    Is raised, when the file content has been changed from a different process after
    opening the file. Reading the file would lead to invalid or inconsistent output.
    This can also be triggered by outdated file-information inside the directory cache.
    In this case ``S3FileSystem.invalidate_cache`` can be used to force an update of
    the file-information when opening the file.
    )filenamee_tagc                    s   t  tjd||f  d S )NzJThe remote file corresponding to filename %s and Etag %s no longer exists.)superr   errnoZEBUSY)r   r(   r)   	__class__r   r   r   d   s    zFileExpired.__init__)r$   r%   r&   __doc__strr   __classcell__r   r   r,   r   r'   [   s   r'   c                 C   s   d dd | dD S )zl
    TitleCases a given string.

    Parameters
    ----------
    string : underscore separated string
     c                 s   s   | ]}|  V  qd S r   )
capitalize).0xr   r   r   	<genexpr>t   s     ztitle_case.<locals>.<genexpr>_)joinsplit)stringr   r   r   
title_casel   s    r:   c                   @   s,   e Zd ZdZi Zdd Zdd Zdd ZdS )	ParamKwargsHelperz
    Utility class to help extract the subset of keys that an s3 method is
    actually using

    Parameters
    ----------
    s3 : boto S3FileSystem
    c                 C   s
   || _ d S r   )r   )r   r   r   r   r   r      s    zParamKwargsHelper.__init__c                 C   sN   || j krD| jjj|}|jd k	r4t|jj nt }|| j |< | j | S r   )	_kwarg_cacher   metaZservice_modelZoperation_modelZinput_shapesetmemberskeys)r   
model_namemodel
valid_keysr   r   r   _get_valid_keys   s    

z!ParamKwargsHelper._get_valid_keysc                    s:   t |}| | t|tr$| } fdd| D S )Nc                    s   i | ]\}}| kr||qS r   r   r3   kvrC   r   r   
<dictcomp>   s       z1ParamKwargsHelper.filter_dict.<locals>.<dictcomp>)r:   rD   
isinstance	SSEParams	to_kwargsitems)r   method_namedrA   r   rH   r   filter_dict   s
    

zParamKwargsHelper.filter_dictN)r$   r%   r&   r.   r<   r   rD   rP   r   r   r   r   r;   w   s
   	r;   c                   @   s   e Zd ZdddZdd ZdS )rK   Nc                 C   s   || _ || _|| _|| _d S r   )ZServerSideEncryptionZSSECustomerAlgorithmZSSECustomerKeyZSSEKMSKeyId)r   Zserver_side_encryptionZsse_customer_algorithmZsse_customer_keyZsse_kms_key_idr   r   r   r      s    zSSEParams.__init__c                 C   s   dd | j  D S )Nc                 S   s   i | ]\}}|d k	r||qS r   r   rE   r   r   r   rI      s       z'SSEParams.to_kwargs.<locals>.<dictcomp>)__dict__rM   r   r   r   r   rL      s    zSSEParams.to_kwargs)NNNN)r$   r%   r&   r   rL   r   r   r   r   rK      s       
rK   c                 c   s2   t d| |D ] }|t|| d | d fV  qdS )z
    Chunk up a file into zero-based byte ranges

    Parameters
    ----------
    size : file size
    block : block size
    r      N)rangemin)sizeblockoffsetr   r   r   _get_brange   s    	rX   )r+   logging
contextlibr   r   Zbotocore.exceptionsr   	getLoggerr   r	   r
   IOErrorr'   r:   objectr;   rK   rX   r   r   r   r   <module>   s   

I"