U
    Cvf                     @  s   U d dl mZ d dlZd dlZd dlZd dlmZmZ zd dlm	Z	 W n e
k
r`   ejZ	Y nX 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)AnyMutableMapping)SerializableLockz#MutableMapping[Any, threading.Lock]_FILE_LOCKSc                 C  s6   zt |  }W n$ tk
r0   t  }t | < Y nX |S N)r   KeyError	threadingLock)keylock r   9/tmp/pip-unpacked-wheel-h316xyqg/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   c                 C  sf   | dkrt S | dkrt S | dkr$tS | dkrZzddlm} W n tk
rT   d}Y nX |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threadedr   distributedr   )r
   )r   r   dask.distributedr
   ImportErrorr   )	schedulerZDistributedLockr   r   r   _get_lock_maker'   s    
r   z
str | None)returnc              	   C  s   z"ddl }ddlm} || |}W n tk
r8   Y dS X z"ddlm} t|j|rZW dS W n ttfk
rt   Y nX z||j	j
krW dS W n tk
r   Y nX 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   r   r   r   
isinstance__self__AttributeErrorr   get)r   Z
collectionr   r   Z
actual_getr   r   r   r   _get_schedulerF   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_lockl   s    r!   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acquire)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)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$   Nr"   .0r   r+   r   r   	<genexpr>   s     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   r1      s    
zCombinedLock.releasec                 C  s   | j D ]}|  qd S r   )r(   	__enter__r2   r   r   r   r3      s    
zCombinedLock.__enter__c                 G  s   | j D ]}|j|  qd S r   )r(   __exit__)r)   argsr   r   r   r   r4      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   r.      s     z&CombinedLock.locked.<locals>.<genexpr>)anyr(   r)   r   r   r   r6      s    zCombinedLock.lockedc                 C  s   dt | jdS )NzCombinedLock())listr(   r8   r   r   r   __repr__   s    zCombinedLock.__repr__N)T)__name__
__module____qualname____doc__r*   r#   r1   r3   r4   r6   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   r0   r   r   r   r#      s    zDummyLock.acquirec                 C  s   d S r   r   r8   r   r   r   r1      s    zDummyLock.releasec                 C  s   d S r   r   r8   r   r   r   r3      s    zDummyLock.__enter__c                 G  s   d S r   r   )r)   r5   r   r   r   r4      s    zDummyLock.__exit__c                 C  s   dS )NFr   r8   r   r   r   r6      s    zDummyLock.lockedN)T)	r<   r=   r>   r?   r#   r1   r3   r4   r6   r   r   r   r   r@      s   
r@   c                 C  sj   g }| D ].}t |tr$||j q|dk	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lenr@   )r(   Z	all_locksr   Z	num_locksr   r   r   combine_locks   s    
rE   c                 C  s   | dks| dkrt  S | S )z'Ensure that the given object is a lock.NF)r@   )r   r   r   r   ensure_lock   s    rF   )N)NN)T)
__future__r   r   r	   weakreftypingr   r   Z
dask.utilsr   r   r
   Z	HDF5_LOCKZNETCDFC_LOCKWeakValueDictionaryr   __annotations__r   r   r   r    r!   r#   r%   r@   rE   rF   r   r   r   r   <module>   s,    
&
 