a
    iDf'                     @  s   U 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 d dl	m
Z
mZ d dlmZ G dd dZe Ze Ze Zded	< d
d Zdd Zd!ddZd"ddddZdd Zd#ddZG dd dZG dd dZdd Zdd  ZdS )$    )annotationsN)HashableMutableMapping)AnyClassVar)WeakValueDictionaryc                   @  s   e Zd ZU dZe Zded< ded< ded< dd	d
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d ZeZdS )SerializableLocka  A Serializable per-process Lock

    This wraps a normal ``threading.Lock`` object and satisfies the same
    interface.  However, this lock can also be serialized and sent to different
    processes.  It will not block concurrent operations between processes (for
    this you should look at ``dask.multiprocessing.Lock`` or ``locket.lock_file``
    but will consistently deserialize into the same lock.

    So if we make a lock in one process::

        lock = SerializableLock()

    And then send it over to another process multiple times::

        bytes = pickle.dumps(lock)
        a = pickle.loads(bytes)
        b = pickle.loads(bytes)

    Then the deserialized objects will operate as though they were the same
    lock, and collide as appropriate.

    This is useful for consistently protecting resources on a per-process
    level.

    The creation of locks is itself not threadsafe.
    z7ClassVar[WeakValueDictionary[Hashable, threading.Lock]]_locksr   tokenzthreading.LocklockNzHashable | Noner
   c                 C  sJ   |pt t | _| jtjv r.tj| j | _nt | _| jtj| j< d S N)	struuiduuid4r
   r   r	   r   	threadingLockselfr
    r   b/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/site-packages/xarray/backends/locks.py__init__1   s
    
zSerializableLock.__init__c                 O  s   | j j|i |S r   )r   acquirer   argskwargsr   r   r   r   9   s    zSerializableLock.acquirec                 O  s   | j j|i |S r   )r   releaser   r   r   r   r   <   s    zSerializableLock.releasec                 C  s   | j   d S r   )r   	__enter__r   r   r   r   r   ?   s    zSerializableLock.__enter__c                 G  s   | j j|  d S r   )r   __exit__r   r   r   r   r   r   B   s    zSerializableLock.__exit__c                 C  s
   | j  S r   )r   lockedr   r   r   r   r!   E   s    zSerializableLock.lockedc                 C  s   | j S r   r   r   r   r   r   __getstate__H   s    zSerializableLock.__getstate__c                 C  s   |  | d S r   )r   r   r   r   r   __setstate__K   s    zSerializableLock.__setstate__c                 C  s   d| j j d| j dS )N<z: >)	__class____name__r
   r   r   r   r   __str__N   s    zSerializableLock.__str__)N)r'   
__module____qualname____doc__r   r	   __annotations__r   r   r   r   r   r!   r"   r#   r(   __repr__r   r   r   r   r      s   

r   z#MutableMapping[Any, threading.Lock]_FILE_LOCKSc                 C  s4   zt |  }W n" ty.   t  }t | < Y n0 |S r   )r.   KeyErrorr   r   )keyr   r   r   r   _get_threaded_lock]   s
    r1   c                 C  s
   ~ t  S r   )multiprocessingr   )r0   r   r   r   _get_multiprocessing_locke   s    r3   c                 C  sd   | du rt S | dkrt S | dkr$tS | dkrXzddlm} W n tyR   d}Y n0 |S t| dS )zReturns an appropriate function for creating resource locks.

    Parameters
    ----------
    scheduler : str or None
        Dask scheduler being used.

    See Also
    --------
    dask.utils.get_scheduler_lock
    Nthreadedr2   distributedr   )r   )r1   r3   dask.distributedr   ImportErrorr/   )	schedulerZDistributedLockr   r   r   _get_lock_makerl   s    
r9   z
str | None)returnc              	   C  s   z"ddl }ddlm} || |}W n ty6   Y dS 0 z"ddlm} t|j|rXW dS W n ttfyp   Y n0 z||j	j
u rW dS W n ty   Y n0 dS )zDetermine the dask scheduler that is being used.

    None is returned if no dask scheduler is active.

    See Also
    --------
    dask.base.get_scheduler
    r   N)get_scheduler)Clientr5   r2   r4   )daskZ	dask.baser;   r7   r6   r<   
isinstance__self__AttributeErrorr2   get)rA   Z
collectionr=   r;   Z
actual_getr<   r   r   r   _get_scheduler   s$    	

rB   c                 C  s   t  }t|}|| S )a  Get a scheduler appropriate lock for writing to the given resource.

    Parameters
    ----------
    key : str
        Name of the resource for which to acquire a lock. Typically a filename.

    Returns
    -------
    Lock object that can be used like a threading.Lock object.
    )rB   r9   )r0   r8   Z
lock_makerr   r   r   get_write_lock   s    rC   Tc                 C  s   |r|   S |  |S dS )zAcquire a lock, possibly in a non-blocking fashion.

    Includes backwards compatibility hacks for old versions of Python, dask
    and dask-distributed.
    Nr   )r   blockingr   r   r   r      s    r   c                   @  sJ   e Zd ZdZdd ZdddZdd Zd	d
 Zdd Zdd Z	dd Z
dS )CombinedLockzA combination of multiple locks.

    Like a locked door, a CombinedLock is locked if any of its constituent
    locks are locked.
    c                 C  s   t t|| _d S r   )tuplesetlocks)r   rI   r   r   r   r      s    zCombinedLock.__init__Tc                   s   t  fdd| jD S )Nc                 3  s   | ]}t | d V  qdS )rE   NrD   .0r   rJ   r   r   	<genexpr>       z'CombinedLock.acquire.<locals>.<genexpr>)allrI   r   rE   r   rJ   r   r      s    zCombinedLock.acquirec                 C  s   | j D ]}|  qd S r   )rI   r   r   r   r   r   r   r      s    
zCombinedLock.releasec                 C  s   | j D ]}|  qd S r   )rI   r   rQ   r   r   r   r      s    
zCombinedLock.__enter__c                 G  s   | j D ]}|j|  qd S r   )rI   r   )r   r   r   r   r   r   r      s    
zCombinedLock.__exit__c                 C  s   t dd | jD S )Nc                 s  s   | ]}|j V  qd S r   )r!   rK   r   r   r   rM      rN   z&CombinedLock.locked.<locals>.<genexpr>)anyrI   r   r   r   r   r!      s    zCombinedLock.lockedc                 C  s   dt | jdS )NzCombinedLock())listrI   r   r   r   r   r-      s    zCombinedLock.__repr__N)T)r'   r)   r*   r+   r   r   r   r   r   r!   r-   r   r   r   r   rF      s   
rF   c                   @  s:   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdS )	DummyLockz;DummyLock provides the lock API without any actual locking.Tc                 C  s   d S r   r   rP   r   r   r   r      s    zDummyLock.acquirec                 C  s   d S r   r   r   r   r   r   r      s    zDummyLock.releasec                 C  s   d S r   r   r   r   r   r   r      s    zDummyLock.__enter__c                 G  s   d S r   r   r    r   r   r   r      s    zDummyLock.__exit__c                 C  s   dS )NFr   r   r   r   r   r!     s    zDummyLock.lockedN)T)	r'   r)   r*   r+   r   r   r   r   r!   r   r   r   r   rU      s   
rU   c                 C  sj   g }| D ].}t |tr$||j q|dur|| qt|}|dkrPt|S |dkr`|d S t S dS )z/Combine a sequence of locks into a single lock.N   r   )r>   rF   extendrI   appendlenrU   )rI   Z	all_locksr   Z	num_locksr   r   r   combine_locks  s    
rZ   c                 C  s   | du s| du rt  S | S )z'Ensure that the given object is a lock.NF)rU   )r   r   r   r   ensure_lock  s    r[   )N)NN)T)
__future__r   r2   r   r   weakrefcollections.abcr   r   typingr   r   r   r   Z	HDF5_LOCKZNETCDFC_LOCKr.   r,   r1   r3   r9   rB   rC   r   rF   rU   rZ   r[   r   r   r   r   <module>   s*   G
&
 