
    i:4                     <   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g d
Zej        ZddZd Zd Zd Zd Zd Zd ZeZd Zd dde	j        fdde	j        ffD             \  ZZd Z G d dej                  Zd Zd Z dS )    )dequeN)GreenletExit)event)hubs)support)timeout)timer)	greenlets)
getcurrentsleepspawnspawn_nkillspawn_afterspawn_after_localGreenThreadc                 .   t          j                    }t                      }|j        |u r| dk    rdS t	          d          |                    | |j                  }	 |                                  |j                     dS #  |j                     w xY w)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.
    r   Nz0do not call blocking functions from the mainloop)r   get_hubr   greenletRuntimeErrorschedule_call_globalswitchcancel)secondshubcurrentr	   s       ?/usr/local/lib/python3.11/dist-packages/eventlet/greenthread.pyr   r      s     ,..CllG
|wa<< FMNNN$$Wgn==E

s   B Bc                     t          j                    }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   gs        r   r   r   2   sA     ,..CCL!!AQ$f===H    c                 2    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"   s      r   r   r   B   s     AtT6**1--r$   c                     t          j                    }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#   s         r   r   r   O   sA    " ,..CCL!!AWahdFCCCHr$   c                     t          j                    }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)   s         r   r   r   f   sA    " ,..CCL!!AGQXtT6BBBHr$   c                 j    t          j        dt          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"   s       r   call_after_globalr3   }   sB    M	> 	q	* * * *
 GT40033r$   c                     t          j        dt          d           t          j                    }t          j        ||j                  } |j        | |j        g|R i |}|S )Nzocall_after_local is renamed to spawn_after_local, whichhas the same signature and semantics (plus a bit extra).r-   r.   parent)r0   r1   r2   r   r   r   r+   r   )r   functionr!   r"   r   r#   ts          r   call_after_localr9      su    M	Cq* * * * ,..C(3<888ACDCCCFCCAHr$   c                     t          j        dt          d           | t          j        | d           S t          j                    } |j        | t                      j	        g|R  S )NzJInstead of exc_after, which is deprecated, use Timeout(seconds, exception)r-   r.   c                      d S N r=   r$   r   <lambda>zexc_after.<locals>.<lambda>   s    D r$   )
r0   r1   r2   r	   Timerr   r   r+   r   throw)r   
throw_argsr   s      r   	exc_afterrB      so    M 0$4 4 4 4 {7LL111
,..C"3"7JLL,>LLLLLr$   c              #   Z   K   | ]&\  }}} t          j        ||          |          V  'd S r<   )r   wrap_deprecated).0oldnewfuns       r   	<genexpr>rI      sQ        /<sC%GC%%c**     r$   zgreenthread.TimeoutErrorTimeoutzgreenthread.with_timeoutwith_timeoutc                     t          j                    }t          j        ||j                  } |j        | |j        g|R i |}||fS )Nr5   )r   r   r   r   r   )r   r    r!   r"   r   r#   r8   s          r   r'   r'      sS    
,..C$s|444A  !(DTDDDVDDAa4Kr$   c                   H    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Z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                     t           j                             | | j        |           t          j                    | _        d| _        d | _        d S )NF)r   __init__mainr   Event_exit_event_resolving_links_exit_funcs)selfr6   s     r   rO   zGreenThread.__init__   sC    ""4F;;; ;== %r$   c                 8    ddl m} t          j                    }t	          ||          st          d          |j                                         fd}                    |           f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                 n    |                                  rj        s                                 d S d S d S r<   )	cancelleddeadr   )futurerU   s    r   got_future_resultz0GreenThread.__await__.<locals>.got_future_result   sE    !! $) 		   r$   c                 "                                    rd S 	 |                                 }                    |           d S # t          $ r                                  Y d S t
          $ r }                    |           Y d }~d S d }~ww xY wr<   )donewait
set_resultr   r   BaseExceptionset_exception)gthreadresulter[   s      r   got_gthread_resultz1GreenThread.__await__.<locals>.got_gthread_result   s    {{}} ( !!&)))))        ( ( ($$Q'''''''''(s   )A B%	B.B		B)eventlet.hubs.asynciorW   r   r   
isinstancer   loopcreate_futureadd_done_callbacklink	__await__)rU   rW   r   r\   rf   r[   s   `    @r   rm   zGreenThread.__await__   s     	.-----lnn#s## 	Q  
 ''))	 	 	 	 	
 	  !2333	( 	( 	( 	( 	( 			$%%%!!!r$   c                 4    | 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).)rR   r_   )rU   s    r   r_   zGreenThread.wait   s     $$&&&r$   c                     | j         t                      | _         | j                             |||f           | j                                        r|                                  dS 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)rT   r   appendrR   ready_resolve_linksrU   r    curried_argscurried_kwargss       r   rl   zGreenThread.link   sp    " #$wwD|^ DEEE!!## 	"!!!!!	" 	"r$   c                 v    | j         sdS 	 | j                             |||f           dS # t          $ r Y dS w xY w)zn remove linked function set by :meth:`link`

        Remove successfully return True, otherwise False
        FT)rT   remove
ValueErrorrs   s       r   unlinkzGreenThread.unlink  s^    
  	5	##T<$HIII4 	 	 	55	s   * 
88c                     	  ||i |}| j                             |           |                                  d S #   | j         j        t	          j                      |                                   xY wr<   )rR   sendrr   send_exceptionsysexc_info)rU   r7   r!   r"   rd   s        r   rP   zGreenThread.main  s    	"Xt.v..F !!&)))!!!!!	+D+S\^^<<!!!s	   : 7A1c                     | j         rd S | j        sd S d| _         	 | j        r0| j                                        \  }}} || g|R i | | j        0d| _         d S # d| _         w xY w)NTF)rS   rT   popleft)rU   fcackws       r   rr   zGreenThread._resolve_links  s      	F 	F $	*" $!-5577
2s$####s### " $ %*D!!!ED!))))s   7A 	A$c                     t          | g|R  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   rU   rA   s     r   r   zGreenThread.kill'  s     D&:&&&&r$   c                     t          | g|R  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   r   s     r   r   zGreenThread.cancel-  s    
 d(Z((((r$   N)__name__
__module____qualname____doc__rO   rm   r_   rl   ry   rP   rr   r   r   r=   r$   r   r   r      s         
     '" '" '"R' ' '" " ".  	" 	" 	"* * *' ' ') ) ) ) )r$   r   c                 (    | st          | g|R   dS 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.Nr   )r#   rA   s     r   r   r   5  s2      Q r$   c                 f   | j         rdS t          j                    }| sAfd}|| _        t	          | t
                    r 	 |                     |di            n#  Y nxY wt                      }||j        ur/|	                                 |
                    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                  p    r!d                              d                   t          j                    )Nr&   r-   )with_tracebackr   r   )akwrA   s     r   
just_raisezkill.<locals>.just_raiseO  s6     . m22:a=AAA+---r$   r=   r   )rZ   r   r   runrh   r   rP   r   r   ensure_greenletr   r   r@   )r#   rA   r   r   r   s    `   r   r   r   =  s     	v 
,..C 	. 	. 	. 	. 	.
 a%% 	z2r****llGcl""  GN333AGZs   A A)r   )!collectionsr   r}   r   r   eventletr   r   r   r   eventlet.hubsr	   eventlet.supportr
   r0   __all__r   r   r   r   r   r   r3   r9   
call_afterrB   rJ   rK   TimeoutErrorr'   r   r   r   r=   r$   r   <module>r      s         



 ! ! ! ! ! !                               2 2 2 2 2 2 > > >  
   :   
. 
. 
.  .  .4 4 4   
M M M 	#Y@	#^W5IJA   l  E) E) E) E) E)(# E) E) E)P  $ $ $ $ $r$   