a
    İaC                     @   s$  U d dl Z d dlZd dlZd dlmZmZmZ zd dlmZ W n e	yV   ej
ZY n0 zd dlm
Z W n e	y~   dZY n0 e Ze Ze Zeeej
f ed< dd Zdd	 Zeeeed
ZdddZdee 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 )     N)AnyMutableMappingOptional)SerializableLock)Lock_FILE_LOCKSc                 C   s4   zt |  }W n" ty.   t  }t | < Y n0 |S N)r   KeyError	threadingr   )keylock r   4lib/python3.9/site-packages/xarray/backends/locks.py_get_threaded_lock   s
    r   c                 C   s
   ~ t  S r   )multiprocessingr   )r   r   r   r   _get_multiprocessing_lock#   s    r   )Nthreadedr   distributedc                 C   s   t |  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
    )_LOCK_MAKERS)	schedulerr   r   r   _get_lock_maker2   s    r   )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)Clientr   r   r   )daskZ	dask.baser   ImportErrordask.distributedr   
isinstance__self__AttributeErrorr   get)r    Z
collectionr   r   Z
actual_getr   r   r   r   _get_schedulerA   s$    	

r!   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.
    )r!   r   )r   r   Z
lock_makerr   r   r   get_write_lockg   s    r"   Tc                 C   s8   |r|   S tdur*t| tr*| j dd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.
    Nr   )timeout)acquireDistributedLockr   )r   blockingr   r   r   r$   x   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)selfr*   r   r   r   __init__   s    zCombinedLock.__init__Tc                    s   t  fdd| jD S )Nc                 3   s   | ]}t | d V  qdS )r&   N)r$   .0r   r-   r   r   	<genexpr>       z'CombinedLock.acquire.<locals>.<genexpr>)allr*   r+   r&   r   r-   r   r$      s    zCombinedLock.acquirec                 C   s   | j D ]}|  qd S r   )r*   releaser+   r   r   r   r   r4      s    
zCombinedLock.releasec                 C   s   | j D ]}|  qd S r   )r*   	__enter__r5   r   r   r   r6      s    
zCombinedLock.__enter__c                 G   s   | j D ]}|j|  qd S r   )r*   __exit__)r+   argsr   r   r   r   r7      s    
zCombinedLock.__exit__c                 C   s   t dd | jD S )Nc                 s   s   | ]}|j V  qd S r   )lockedr.   r   r   r   r0      r1   z&CombinedLock.locked.<locals>.<genexpr>)anyr*   r+   r   r   r   r9      s    zCombinedLock.lockedc                 C   s   dt | jdS )NzCombinedLock())listr*   r;   r   r   r   __repr__   s    zCombinedLock.__repr__N)T)__name__
__module____qualname____doc__r,   r$   r4   r6   r7   r9   r>   r   r   r   r   r'      s   
r'   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   r3   r   r   r   r$      s    zDummyLock.acquirec                 C   s   d S r   r   r;   r   r   r   r4      s    zDummyLock.releasec                 C   s   d S r   r   r;   r   r   r   r6      s    zDummyLock.__enter__c                 G   s   d S r   r   )r+   r8   r   r   r   r7      s    zDummyLock.__exit__c                 C   s   dS )NFr   r;   r   r   r   r9      s    zDummyLock.lockedN)T)	r?   r@   rA   rB   r$   r4   r6   r7   r9   r   r   r   r   rC      s   
rC   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   r'   extendr*   appendlenrC   )r*   Z	all_locksr   Z	num_locksr   r   r   combine_locks   s    
rH   c                 C   s   | du s| du rt  S | S )z'Ensure that the given object is a lock.NF)rC   )r   r   r   r   ensure_lock   s    rI   )N)NN)T)r   r
   weakreftypingr   r   r   Z
dask.utilsr   r   r   r   r%   Z	HDF5_LOCKZNETCDFC_LOCKWeakValueDictionaryr   __annotations__r   r   r   r   strr!   r"   r$   r'   rC   rH   rI   r   r   r   r   <module>   s:   


&
 