o
    0׾g                     @   s   d Z ddlmZ ddlmZ ddlmZ ddlZddlmZ ddl	m
Z
 dgZe Zed	je d
< dd e d< G dd deZG dd deZdd Ze  ddlmZ ee d dS )z 
Low-level waiting primitives.

    )absolute_import)division)print_functionN)get_hub_noargs)ConcurrentObjectUseErrorWaitergreenlet
getcurrentc                   C   s   d S N r   r   r   X/var/www/html/backend_erp/backend_erp_env/lib/python3.10/site-packages/gevent/_waiter.py<lambda>   s    r   greenlet_initc                   @   sv   e Zd ZdZg dZdddZdd Zdd	 Zd
d Zdd Z	e
dd Zdd Zdd Zdd Zdd Zdd ZdS )r   a:  
    A low level communication utility for greenlets.

    Waiter is a wrapper around greenlet's ``switch()`` and ``throw()`` calls that makes them somewhat safer:

    * switching will occur only if the waiting greenlet is executing :meth:`get` method currently;
    * any error raised in the greenlet is handled inside :meth:`switch` and :meth:`throw`
    * if :meth:`switch`/:meth:`throw` is called before the receiver calls :meth:`get`, then :class:`Waiter`
      will store the value/exception. The following :meth:`get` will return the value/raise the exception.

    The :meth:`switch` and :meth:`throw` methods must only be called from the :class:`Hub` greenlet.
    The :meth:`get` method must be called from a greenlet other than :class:`Hub`.

        >>> from gevent.hub import Waiter
        >>> from gevent import get_hub
        >>> result = Waiter()
        >>> timer = get_hub().loop.timer(0.1)
        >>> timer.start(result.switch, 'hello from Waiter')
        >>> result.get() # blocks for 0.1 seconds
        'hello from Waiter'
        >>> timer.close()

    If switch is called before the greenlet gets a chance to call :meth:`get` then
    :class:`Waiter` stores the value.

        >>> from gevent.time import sleep
        >>> result = Waiter()
        >>> timer = get_hub().loop.timer(0.1)
        >>> timer.start(result.switch, 'hi from Waiter')
        >>> sleep(0.2)
        >>> result.get() # returns immediately without blocking
        'hi from Waiter'
        >>> timer.close()

    .. warning::

        This is a limited and dangerous way to communicate between
        greenlets. It can easily leave a greenlet unscheduled forever
        if used incorrectly. Consider using safer classes such as
        :class:`gevent.event.Event`, :class:`gevent.event.AsyncResult`,
        or :class:`gevent.queue.Queue`.
    )hubr   value
_exceptionNc                 C   s*   |d u rt  n|| _d | _d | _t| _d S r
   )get_hubr   r   r   _NONEr   selfr   r   r   r   __init__I   s   
zWaiter.__init__c                 C   s   d | _ d | _t| _d S r
   )r   r   r   r   r   r   r   r   clearO   s   
zWaiter.clearc                 C   sX   | j tu rdt| j| jf S | j d u r dt| j| j| jf S dt| j| j| jf S )Nz<%s greenlet=%s>z<%s greenlet=%s value=%r>z<%s greenlet=%s exc_info=%r>)r   r   type__name__r   r   exc_infor   r   r   r   __str__T   s
   

zWaiter.__str__c                 C   s
   | j tuS )z;Return true if and only if it holds a value or an exceptionr   r   r   r   r   r   ready[      
zWaiter.readyc                 C   s
   | j du S )z8Return true if and only if it is ready and holds a valueN)r   r   r   r   r   
successful_   r   zWaiter.successfulc                 C   s   | j tur| j S dS )zaHolds the exception info passed to :meth:`throw` if :meth:`throw` was called. Otherwise ``None``.Nr   r   r   r   r   r   c   s   
zWaiter.exc_infoc                 C   sl   | j }|du r|| _d| _dS t | jurtd|j}z|| W dS    | jj|gt	 R   Y dS )z
        Switch to the greenlet if one's available. Otherwise store the
        *value*.

        .. versionchanged:: 1.3b1
           The *value* is no longer optional.
        N7Can only use Waiter.switch method from the Hub greenlet)
r   r   r   r	   r   AssertionErrorswitchhandle_errorsysr   )r   r   r   r#   r   r   r   r#   i   s   
zWaiter.switchc                 G   s
   |  |S r
   )r#   )r   argsr   r   r   switch_args~      
zWaiter.switch_argsc                 G   sf   | j }|du r|| _dS t | jurtd|j}z||  W dS    | jj|gt R   Y dS )zWSwitch to the greenlet with the exception. If there's no greenlet, store the exception.Nr!   )	r   r   r	   r   r"   throwr$   r%   r   )r   
throw_argsr   r)   r   r   r   r)      s   
zWaiter.throwc                 C   sj   | j tur| j du r| jS t j| j   dS | jdur#td| jf t | _z	| j W d| _S d| _w )zbIf a value/an exception is stored, return/raise it. Otherwise until switch() or throw() is called.Nz!This Waiter is already used by %r)	r   r   r   r	   r)   r   r   r   r#   r   r   r   r   get   s   



z
Waiter.getc                 C   s*   |j d u r| |j d S | |j  d S r
   )	exceptionr#   r   r)   )r   sourcer   r   r   __call__   s   
zWaiter.__call__r
   )r   
__module____qualname____doc__	__slots__r   r   r   r   r    propertyr   r#   r'   r)   r+   r.   r   r   r   r   r      s    +

c                   @   s0   e Zd ZdZdgZd
ddZdd Zdd	 ZdS )MultipleWaitera:  
    An internal extension of Waiter that can be used if multiple objects
    must be waited on, and there is a chance that in between waits greenlets
    might be switched out. All greenlets that switch to this waiter
    will have their value returned.

    This does not handle exceptions or throw methods.
    _valuesNc                 C   s   t | | g | _d S r
   )r   r   r5   r   r   r   r   r      s   
zMultipleWaiter.__init__c                 C   s   | j | t| d d S )NT)r5   appendr   r#   )r   r   r   r   r   r#      s   zMultipleWaiter.switchc                 C   s&   | j st|  t|  | j dS )Nr   )r5   r   r+   r   popr   r   r   r   r+      s   

zMultipleWaiter.getr
   )r   r/   r0   r1   r2   r   r#   r+   r   r   r   r   r4      s    
	r4   c                   C   s
   t   d S r
   )r   r   r   r   r   _init   r(   r8   )import_c_accelzgevent.__waiter)r1   
__future__r   r   r   r%   gevent._hub_localr   r   gevent.exceptionsr   __all__objectr   
__import__r	   localsr   r4   r8   gevent._utilr9   globalsr   r   r   r   <module>   s&    