o
    Œõ±j‘&  ã                
   @   sº   d Z ddlZddlmZ ddlmZ ddlmZ ddl	m
Z
 dd	giZg d
¢ZG dd„ dƒZed!dd„ƒZdd„ Zdd„ Zddddedddddœ	dd„Zdd„ Zdd„ Zddœdd „ZdS )"z,
Thin wrappers around `concurrent.futures`.
é    N)Úcontextmanager©Úlength_hinté   )Útqdm)ÚTqdmWarningzgithub.com/Ú	casperdcl)Ú
thread_mapÚprocess_mapÚinterpreter_mapc                   @   sR   e Zd ZdZddlmZ ddlmZ dd„ Z	dd	d
„Z
dd„ Zdd„ Zdd„ ZdS )Ú_InterpreterLockz3Reentrant lock backed by a cross-interpreter queue.r   )Ú	get_ident)Ú	monotonicc                 C   s*   ddl m} || _|ƒ | _d | _d| _d S )Nr   )ÚRLock)Ú	threadingr   Ú_queueÚ_lockÚ_ownerÚ_depth)ÚselfÚqueuer   © r   úŠ/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/tqdm/contrib/concurrent.pyÚ__init__   s
   
z_InterpreterLock.__init__Téÿÿÿÿc                 C   sØ   ddl m} |  ¡ }|dkr| j |¡}n| j ||¡}|s dS | jr,|  jd7  _dS z&|s5| j ¡  n|dkr?| j ¡  nt	d||  ¡ |  ƒ}| jj|d� W n |ya   | j 
¡  Y dS w |  ¡ | _d| _dS )Nr   )ÚEmptyr   Fé   T)Útimeout)r   r   Ú_timer   Úacquirer   r   Ú
get_nowaitÚgetÚmaxÚreleaser   r   )r   Úblockingr   r   ÚstartÚacquiredÚ	remainingr   r   r   r      s2   €
þ
z_InterpreterLock.acquirec                 C   sJ   | j |  ¡ krtdƒ‚|  jd8  _| jsd | _ | j d ¡ | j ¡  d S )Nzcannot release un-acquired lockr   )r   r   ÚRuntimeErrorr   r   Úputr   r#   ©r   r   r   r   r#   6   s   z_InterpreterLock.releasec                 C   s   |   ¡  | S ©N)r   r*   r   r   r   Ú	__enter__?   s   z_InterpreterLock.__enter__c                 G   s   |   ¡  d S r+   )r#   )r   Úexcr   r   r   Ú__exit__C   s   z_InterpreterLock.__exit__N)Tr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   Útimer   r   r   r   r#   r,   r.   r   r   r   r   r      s    
	r   Ú c                 c   s\   � t | ddƒ}|du r|p|  ¡ }t |||ƒ}|  |¡ |V  |du r'| `dS |  |¡ dS )z>get (create if necessary) and then restore `tqdm_class`'s lockr   N)ÚgetattrÚget_lockÚset_lockr   )Ú
tqdm_classÚ	lock_nameÚlockÚold_lockr   r   r   Úensure_lockG   s   €
r<   c              	   C   s4   dt j›d| j›d| j d¡›d|›d�	}t|ffS )zGReturn an initializer which bootstraps the parent import path and lock.zimport sys
sys.path[:] = z™
from concurrent import interpreters
from importlib import import_module
from tqdm.contrib.concurrent import _InterpreterLock
tqdm_class = import_module(z)
for name in Ú.z…:
    tqdm_class = getattr(tqdm_class, name)
tqdm_class.monitor_interval = 0
tqdm_class.set_lock(_InterpreterLock(interpreters.Queue(z))))ÚsysÚpathr0   r1   ÚsplitÚexec)r8   Úlock_queue_idÚcoder   r   r   Ú_get_interpreter_initV   s   ÿû
ú	÷ÿ
rD   c                    s   t ‡ fdd„| D ƒdd�S )z+min(map(length_hint, iterables), default=0)c                 3   s&   � | ]}t |d ƒ ‰ dkrˆ V  qdS )r   r   Nr   )Ú.0Úit©Únr   r   Ú	<genexpr>h   s   €$ z_min_map_len.<locals>.<genexpr>r   )Údefault)Úmin)Ú	iterablesr   rG   r   Ú_min_map_lenf   s   rM   r   g        )	Úmax_workersr   Ú	chunksizer9   r8   Ú	smoothingr   Ú_initializerÚ	_initargsc       	      
      sô  |  ¡ }d|vrt|ƒ|d< i }d|v r| d¡|d< i }dD ]}||v r,| |¡||< qd}|d rgd|vrgzddlm} W n tyN   ddlm} Y nw |pZtd	|ƒ pWd
d ƒ}|d |krg||d< d}t|||d��‚}|	du ry|j	}	|f}
| d||	|
dœ|¤Ž�T}|dd|i|¤Ž�;‰|dur–dˆ_
|j‰ ‡ ‡fdd„}||_t|j|g|¢R ||dœ|¤ŽƒW  d  ƒ W  d  ƒ W  d  ƒ S 1 sÌw   Y  W d  ƒ n1 sÛw   Y  W d  ƒ dS W d  ƒ dS 1 sów   Y  dS )a  
    Implementation of `thread_map`, `process_map` and `interpreter_map`.

    Parameters
    ----------
    max_workers  : int
    timeout  : int
    buffersize  : int
        Requires Python>=3.14.
    thread_name_prefix  : str
    max_tasks_per_child  : int
    mp_context  : str
    ÚtotalÚ
buffersize)Úthread_name_prefixÚmax_tasks_per_childÚ
mp_contextNÚminitersr   )Úprocess_cpu_count)Ú	cpu_counté    r   é   T)r9   r:   )rN   ÚinitializerÚinitargsrP   c                     s$   ˆ | i |¤Ž}|  ‡fdd„¡ |S )Nc                    s   ˆ   ¡ S r+   )Úupdate)Ú_)Úpbarr   r   Ú<lambda>    s    z4_executor_map.<locals>.patchsubmit.<locals>.<lambda>)Úadd_done_callback)ÚargsÚkwargsÚfut©Ú	orisubmitra   r   r   Úpatchsubmitž   s   z"_executor_map.<locals>.patchsubmit)r   rO   r   )ÚcopyrM   ÚpopÚosrY   ÚImportErrorrZ   rK   r<   r7   Údynamic_minitersÚsubmitÚlistÚmap)ÚPoolExecutorÚfnrN   r   rO   r9   r8   rP   r   rQ   rR   rL   Útqdm_kwargsre   Ú
map_kwargsÚpool_kwargsÚkrn   rZ   Ú	rough_maxÚlkÚexri   r   rg   r   Ú_executor_mapk   sj   €ÿÿÿÿÿÿöþûþû"ûr{   c                 O   s$   ddl m} t|| g|¢R i |¤ŽS )a°  
    Equivalent of `list(map(fn, *iterables))`
    driven by `concurrent.futures.ThreadPoolExecutor`.

    Parameters
    ----------
    max_workers  : int, optional
        Maximum number of workers to spawn; passed to `concurrent.futures.ThreadPoolExecutor`.
    thread_name_prefix  : str, optional
        Passed to `concurrent.futures.ThreadPoolExecutor` [default: ''].
    timeout  : int or float, optional
        Seconds to wait before raising `TimeoutError` if `__next__` is called and the
        result isn't available. [default: None].
    buffersize  : int, optional
        Requires Python>=3.14 [default: None].
    tqdm_class  : optional
        `tqdm` class to use for bars [default: tqdm.auto.tqdm].
    smoothing  : float, optional
        Passed to `tqdm_class`; the [default: 0] is average (due to erratic update frequency).
    lock_name  : str, optional
        Member of `tqdm_class.get_lock()` to use [default: ''].
    r   )ÚThreadPoolExecutor)Úconcurrent.futuresr|   r{   )rs   rL   rt   r|   r   r   r   r	   §   s   r	   c           	      O   sj   ddl m} ddlm} | ¡ }| d¡ | dt¡}t||j	ƒ\}}t
|| g|¢R t|ƒ||dœ|¤ŽS )aj  
    Equivalent of `list(map(fn, *iterables))`
    driven by `concurrent.futures.InterpreterPoolExecutor` (Python 3.14+).

    Parameters
    ----------
    Same as `thread_map`.

    Notes
    -----
    `fn`, its arguments, and its return values must be pickleable.
    Worker progress bars using the same `tqdm_class` share a cross-interpreter write lock.
    r   )Úinterpreters)ÚInterpreterPoolExecutorNr8   )r   rQ   rR   )Ú
concurrentr~   r}   r   Úcreate_queuer)   r!   Ú	tqdm_autorD   Úidr{   r   )	rs   rL   rt   r~   r   Ú
lock_queuer8   r]   r^   r   r   r   r   Â   s    
ÿÿþþr   Úmp_lock)r9   c                O   sb   ddl m} |r#d|vr#t|ƒ}|dkr#ddlm} |d| tdd� t|| g|¢R d	|i|¤ŽS )
aI  
    Equivalent of `list(map(fn, *iterables))`
    driven by `concurrent.futures.ProcessPoolExecutor`.

    Parameters
    ----------
    max_workers  : int, optional
        Maximum number of workers to spawn; passed to `concurrent.futures.ProcessPoolExecutor`.
    timeout  : int or float, optional
        Seconds to wait before raising `TimeoutError` if `__next__` is called and the
        result isn't available. [default: None].
    chunksize  : int, optional
        Approximate size of chunks sent to worker processes; passed to
        `concurrent.futures.ProcessPoolExecutor.map`. [default: 1].
    buffersize  : int, optional
        Requires Python>=3.14 [default: None].
    max_tasks_per_child  : int, optional
        Maximum number of tasks a worker process can complete before being replaced
        with a new process; passed to `concurrent.futures.ProcessPoolExecutor`.
    mp_context  : multiprocessing.BaseContext, optional
        Multiprocessing context to use, e.g. `multiprocessing.get_context('fork')`.
    lock_name  : str, optional
        Member of `tqdm_class.get_lock()` to use [default: mp_lock].
    tqdm_class  : optional
        `tqdm` class to use for bars [default: tqdm.auto.tqdm].
    smoothing  : float, optional
        Passed to `tqdm_class`; the [default: 0] is average (due to erratic update frequency).
    r   )ÚProcessPoolExecutorrO   iè  )Úwarnz…Iterable length %d > 1000 but `chunksize` is not set. This may seriously degrade multiprocess performance. Set `chunksize=1` or more.r   )Ú
stacklevelr9   )r}   r†   rM   Úwarningsr‡   r   r{   )rs   r9   rL   rt   r†   Úshortest_iterable_lenr‡   r   r   r   r
   Û   s   þýr
   )r4   N)r2   r>   Ú
contextlibr   Úoperatorr   Úautor   r‚   Ústdr   Ú
__author__Ú__all__r   r<   rD   rM   r{   r	   r   r
   r   r   r   r   Ú<module>   s&    
8
þ<