U
    @f2                     @   s$  d dl m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lm	Z	 d dl
mZ d d	lmZ d dlZd
dddddddgZejZd)ddZdd Zdd Zdd Zdd Zdd Zdd ZeZdd Zdd dd e	jfd!d"e	jffD \ZZd#d$ ZG d%d dejZd&d' Zd(d Z dS )*    )dequeN)GreenletExit)event)hubs)support)timeout)timer)	greenlets
getcurrentsleepspawnspawn_nkillspawn_afterspawn_after_localGreenThreadc                 C   sJ   t  }t }|j|kr td|| |j}z|  W 5 |  X dS )a	  Yield control to another eligible coroutine until at least *seconds* have
    elapsed.

    *seconds* may be specified as an integer, or a float if fractional seconds
    are desired. Calling :func:`~greenthread.sleep` with *seconds* of 0 is the
    canonical way of expressing a cooperative yield. For example, if one is
    looping over a large list performing an expensive calculation without
    calling any socket methods, it's a good idea to call ``sleep(0)``
    occasionally; otherwise nothing else will run.
    z0do not call blocking functions from the mainloopN)r   get_hubr
   greenletRuntimeErrorschedule_call_globalswitchcancel)secondshubcurrentr    r   N/var/www/html/chatgpt/venv/lib/python3.8/site-packages/eventlet/greenthread.pyr      s    
c                 O   s*   t  }t|j}|d|j| || |S )a  Create a greenthread to run ``func(*args, **kwargs)``.  Returns a
    :class:`GreenThread` object which you can use to get the results of the
    call.

    Execution control returns immediately to the caller; the created greenthread
    is merely scheduled to be run at the next available opportunity.
    Use :func:`spawn_after` to  arrange for greenthreads to be spawned
    after a finite delay.
    r   r   r   r   r   r   r   )funcargskwargsr   gr   r   r   r   +   s    

c                 O   s   t d| ||d S )a  Same as :func:`spawn`, but returns a ``greenlet`` object from
    which it is not possible to retrieve either a return value or
    whether it raised any exceptions.  This is faster than
    :func:`spawn`; it is fastest if there are no keyword arguments.

    If an exception is raised in the function, spawn_n prints a stack
    trace; the print can be disabled by calling
    :func:`eventlet.debug.hub_exceptions` with False.
    r      )_spawn_n)r   r   r    r   r   r   r   ;   s    
c                 O   s*   t  }t|j}|| |j||| |S )ah  Spawns *func* after *seconds* have elapsed.  It runs as scheduled even if
    the current greenthread has completed.

    *seconds* may be specified as an integer, or a float if fractional seconds
    are desired. The *func* will be called with the given *args* and
    keyword arguments *kwargs*, and will be executed within its own greenthread.

    The return value of :func:`spawn_after` is a :class:`GreenThread` object,
    which can be used to retrieve the results of the call.

    To cancel the spawn and prevent *func* from being called,
    call :meth:`GreenThread.cancel` on the return value of :func:`spawn_after`.
    This will not abort the function if it's already started running, which is
    generally the desired behavior.  If terminating *func* regardless of whether
    it's started or not is the desired behavior, call :meth:`GreenThread.kill`.
    r   r   r   r   r    r   r!   r   r   r   r   H   s    
c                 O   s*   t  }t|j}|| |j||| |S )a+  Spawns *func* after *seconds* have elapsed.  The function will NOT be
    called if the current greenthread has exited.

    *seconds* may be specified as an integer, or a float if fractional seconds
    are desired. The *func* will be called with the given *args* and
    keyword arguments *kwargs*, and will be executed within its own greenthread.

    The return value of :func:`spawn_after` is a :class:`GreenThread` object,
    which can be used to retrieve the results of the call.

    To cancel the spawn and prevent *func* from being called,
    call :meth:`GreenThread.cancel` on the return value. This will not abort the
    function if it's already started running.  If terminating *func* regardless
    of whether it's started or not is the desired behavior, call
    :meth:`GreenThread.kill`.
    )r   r   r   r   schedule_call_localr   r$   r   r   r   r   _   s    
c                 O   s"   t jdtdd t| |||d S )Nzcall_after_global is renamed to spawn_after, whichhas the same signature and semantics (plus a bit extra).  Please do a quick search-and-replace on your codebase, thanks!   
stacklevelr   )warningswarnDeprecationWarningr#   )r   r   r   r    r   r   r   call_after_globalv   s     r,   c                 O   sB   t jdtdd t }tj||jd}|j| |jf||}|S )Nzocall_after_local is renamed to spawn_after_local, whichhas the same signature and semantics (plus a bit extra).r&   r'   parent)r)   r*   r+   r   r   r   r%   r   )r   functionr   r    r   r!   tr   r   r   call_after_local   s     r1   c                 G   sF   t jdtdd | d kr(t| dd S t }|j| t j	f| S )NzJInstead of exc_after, which is deprecated, use Timeout(seconds, exception)r&   r'   c                   S   s   d S Nr   r   r   r   r   <lambda>       zexc_after.<locals>.<lambda>)
r)   r*   r+   r   Timerr   r   r%   r
   throw)r   
throw_argsr   r   r   r   	exc_after   s     r8   c                 c   s$   | ]\}}}t |||V  qd S r2   )r   Zwrap_deprecated).0oldnewZfunr   r   r   	<genexpr>   s    r<   zgreenthread.TimeoutErrorTimeoutzgreenthread.with_timeoutwith_timeoutc                 C   s6   t  }tj||jd}|j| |jf||}||fS )Nr-   )r   r   r   r   r   )r   r   r   r    r   r!   r0   r   r   r   r#      s    r#   c                   @   sX   e Zd Z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dd ZdS )r   zThe GreenThread class is a type of Greenlet which has the additional
    property of being able to retrieve the return value of the main function.
    Do not construct GreenThread objects directly; call :func:`spawn` to get one.
    c                 C   s,   t j | | j| t | _d| _d | _d S )NF)r   __init__mainr   Event_exit_event_resolving_links_exit_funcs)selfr.   r   r   r   r?      s    
zGreenThread.__init__c                    sd   ddl m} t }t||s&td|j  fdd} |  fdd}	|  
 S )zS
        Enable ``GreenThread``s to be ``await``ed in ``async`` functions.
        r   )HubzmThis API only works with eventlet's asyncio hub. To use it, set an EVENTLET_HUB=asyncio environment variable.c                    s   |   r js   d S r2   )	cancelleddeadr   futurerE   r   r   got_future_result   s    z0GreenThread.__await__.<locals>.got_future_resultc              
      sn      rd S z|  } | W nF tk
r>      Y n, tk
rh } z | W 5 d }~X Y nX d S r2   )donewait
set_resultr   r   BaseExceptionset_exception)ZgthreadresulterI   r   r   got_gthread_result   s    z1GreenThread.__await__.<locals>.got_gthread_result)Zeventlet.hubs.asynciorF   r   r   
isinstancer   loopcreate_futureadd_done_callbacklink	__await__)rE   rF   r   rL   rT   r   )rJ   rE   r   rZ      s    



zGreenThread.__await__c                 C   s
   | j  S )aH   Returns the result of the main function of this GreenThread.  If the
        result is a normal return value, :meth:`wait` returns it.  If it raised
        an exception, :meth:`wait` will raise the same exception (though the
        stack trace will unavoidably contain some frames from within the
        greenthread module).)rB   rN   rK   r   r   r   rN      s    zGreenThread.waitc                 O   s:   | j dkrt | _ | j |||f | j r6|   dS )a   Set up a function to be called with the results of the GreenThread.

        The function must have the following signature::

            def func(gt, [curried args/kwargs]):

        When the GreenThread finishes its run, it calls *func* with itself
        and with the `curried arguments <http://en.wikipedia.org/wiki/Currying>`_ supplied
        at link-time.  If the function wants to retrieve the result of the GreenThread,
        it should call wait() on its first argument.

        Note that *func* is called within execution context of
        the GreenThread, so it is possible to interfere with other linked
        functions by doing things like switching explicitly to another
        greenthread.
        N)rD   r   appendrB   ready_resolve_linksrE   r   Zcurried_argsZcurried_kwargsr   r   r   rY      s
    

zGreenThread.linkc                 O   s>   | j s
dS z| j |||f W dS  tk
r8   Y dS X dS )zn remove linked function set by :meth:`link`

        Remove successfully return True, otherwise False
        FTN)rD   remove
ValueErrorr^   r   r   r   unlink   s    zGreenThread.unlinkc                 C   sN   z|||}W n&   | j jt   |    Y nX | j | |   d S r2   )rB   Zsend_exceptionsysexc_infor]   send)rE   r/   r   r    rR   r   r   r   r@     s    zGreenThread.mainc                 C   sT   | j r
d S | jsd S d| _ z,| jrD| j \}}}|| f|| qW 5 d| _ X d S )NTF)rC   rD   popleft)rE   fcaZckwr   r   r   r]     s    zGreenThread._resolve_linksc                 G   s   t | f| S )zKills the greenthread using :func:`kill`.  After being killed
        all calls to :meth:`wait` will raise *throw_args* (which default
        to :class:`greenlet.GreenletExit`).r   rE   r7   r   r   r   r      s    zGreenThread.killc                 G   s   t | f| S )zKills the greenthread using :func:`kill`, but only if it hasn't
        already started running.  After being canceled,
        all calls to :meth:`wait` will raise *throw_args* (which default
        to :class:`greenlet.GreenletExit`).)r   ri   r   r   r   r   &  s    zGreenThread.cancelN)__name__
__module____qualname____doc__r?   rZ   rN   rY   ra   r@   r]   r   r   r   r   r   r   r      s   )c                 G   s   | st | f|  dS )zLike :func:`kill`, but only terminates the greenthread if it hasn't
    already started execution.  If the grenthread has already started
    execution, :func:`cancel` has no effect.Nrh   )r!   r7   r   r   r   r   .  s    r   c                    s   | j r
dS t }| sR fdd}|| _t| trRz| |di  W n   Y nX t }||jk	rx|	  |
d|j | j   dS )a  Terminates the target greenthread by raising an exception into it.
    Whatever that greenthread might be doing; be it waiting for I/O or another
    primitive, it sees an exception right away.

    By default, this exception is GreenletExit, but a specific exception
    may be specified.  *throw_args* should be the same as the arguments to
    raise; either an exception instance or an exc_info tuple.

    Calling :func:`kill` causes the calling greenthread to cooperatively yield.
    Nc                     s$    r d   d nt d S )Nr"   r&   )with_tracebackr   r   )akwr7   r   r   
just_raiseH  s    zkill.<locals>.just_raiser   r   )rH   r   r   runrU   r   r@   r
   r   Zensure_greenletr   r   r6   )r!   r7   r   rr   r   r   rq   r   r   6  s     

)r   )!collectionsr   rb   r   r   Zeventletr   r   r   r   Zeventlet.hubsr   Zeventlet.supportr	   r)   __all__r
   r   r   r   r   r   r,   r1   Z
call_afterr8   r=   r>   TimeoutErrorr#   r   r   r   r   r   r   r   <module>   sF     
	


 	