o
    0׾g                     @   s  d Z ddlmZmZ ddlmZ ddl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 g d	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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&m'Z' ddl(m)Z) ddl*m+Z+ e+j,Z-e+j.Z/ddl0m1Z1 ddl0m2Z2 ddl3m4Z4 e5ej6Z7e7 Z8dd Z9d/d!d"Z:d0d#d$Z;efd%d&Z<G d'd( d(e=Z>d1d)d*Z?G d+d, d,e)Z@e%e@ G d-d. d.e=ZAdS )2z
Event-loop hub.
    )absolute_importprint_function)partialN)greenlet)
getcurrent)GreenletExit)error)
r   r   	spawn_rawsleepkillsignalreinitget_hubHubWaiter)config)thread_mod_name)reraise)readproperty)Lazy)gmctimeIdentRegistry)r   )get_loop)set_hub)set_loop)get_hub_if_exists)get_hub_noargs)set_default_hub_class)TrackedRawGreenlet)WaitOperationsGreenlet)_hub_primitives)LoopExit)HubDestroyed)r   c                 O   s   t | stdt }|j}tjrtnt}|r.t| g|R i |} || |}|	|j
 n|| |}|j	|j
g|R   |j|_|S )a  
    Create a new :class:`greenlet.greenlet` object and schedule it to
    run ``function(*args, **kwargs)``.

    This returns a raw :class:`~greenlet.greenlet` which does not have all the useful
    methods that :class:`gevent.Greenlet` has. Typically, applications
    should prefer :func:`~gevent.spawn`, but this method may
    occasionally be useful as an optimization if there are many
    greenlets involved.

    .. versionchanged:: 1.1a3
        Verify that ``function`` is callable, raising a TypeError if not. Previously,
        the spawned greenlet would have failed the first time it was switched to.

    .. versionchanged:: 1.1b1
       If *function* is not callable, immediately raise a :exc:`TypeError`
       instead of spawning a greenlet that will raise an uncaught TypeError.

    .. versionchanged:: 1.1rc2
        Accept keyword arguments for ``function`` as previously (incorrectly)
        documented. Note that this may incur an additional expense.

    .. versionchanged:: 1.3a2
       Populate the ``spawning_greenlet`` and ``spawn_tree_locals``
       attributes of the returned greenlet.

    .. versionchanged:: 1.3b1
       *Only* populate ``spawning_greenlet`` and ``spawn_tree_locals``
       if ``GEVENT_TRACK_GREENLET_TREE`` is enabled (the default). If not enabled,
       those attributes will not be set.

    .. versionchanged:: 1.5a3
       The returned greenlet always has a *loop* attribute matching the
       current hub's loop. This helps it work better with more gevent APIs.
    zfunction must be callable)callable	TypeError_get_hub_noargsloopGEVENT_CONFIGtrack_greenlet_treer   RawGreenlet_functools_partialrun_callbackswitch)functionargskwargshubr'   factoryg r4   T/var/www/html/backend_erp/backend_erp_env/lib/python3.10/site-packages/gevent/hub.pyr	   F   s   $

r	   Tc                 C   s|   t  }|j}| dkrt|}||jd |  dS |j| |d}|  || W d   dS 1 s7w   Y  dS )a  
    Put the current greenlet to sleep for at least *seconds*.

    *seconds* may be specified as an integer, or a float if fractional
    seconds are desired.

    .. tip:: In the current implementation, a value of 0 (the default)
       means to yield execution to any other runnable greenlets, but
       this greenlet may be scheduled again before the event loop
       cycles (in an extreme case, a greenlet that repeatedly sleeps
       with 0 can prevent greenlets that are ready to do I/O from
       being scheduled for some (small) period of time); a value greater than
       0, on the other hand, will delay running this greenlet until
       the next iteration of the loop.

    If *ref* is False, the greenlet running ``sleep()`` will not prevent :func:`gevent.wait`
    from exiting.

    .. versionchanged:: 1.3a1
       Sleeping with a value of 0 will now be bounded to approximately block the
       loop for no longer than :func:`gevent.getswitchinterval`.

    .. seealso:: :func:`idle`
    r   Nref)	r&   r'   r   r,   r-   gettimer
update_nowwait)secondsr7   r1   r'   waitertr4   r4   r5   r
      s   "r
   c                 C   sJ   t  }|j }| r| |_|| W d   dS 1 sw   Y  dS )aO  
    Cause the calling greenlet to wait until the event loop is idle.

    Idle is defined as having no other events of the same or higher
    *priority* pending. That is, as long as sockets, timeouts or even
    signals of the same or higher priority are being processed, the loop
    is not idle.

    .. seealso:: :func:`sleep`
    N)r&   r'   idlepriorityr;   )r@   r1   watcherr4   r4   r5   r?      s   "r?   c                 C   s<   | j st| dr| j|dd dS t j| j| dS dS )a%  
    Kill greenlet asynchronously. The current greenlet is not unscheduled.

    .. note::

        The method :meth:`Greenlet.kill` method does the same and
        more (and the same caveats listed there apply here). However, the MAIN
        greenlet - the one that exists initially - does not have a
        ``kill()`` method, and neither do any created with :func:`spawn_raw`,
        so you have to use this function.

    .. caution:: Use care when killing greenlets. If they are not prepared for
       exceptions, this could result in corrupted state.

    .. versionchanged:: 1.1a2
        If the ``greenlet`` has a :meth:`kill <Greenlet.kill>` method, calls it. This prevents a
        greenlet from being switched to for the first time after it's been
        killed but not yet executed.
    r   F)	exceptionblockN)deadhasattrr   r&   r'   r,   throw)r   rB   r4   r4   r5   r      s
   
r   c                   @   sF   e Zd ZdZdZdd Zedd dd Zdd	 Zd
d Z	dd Z
dS )r   a  
    signal_handler(signalnum, handler, *args, **kwargs) -> object

    Call the *handler* with the *args* and *kwargs* when the process
    receives the signal *signalnum*.

    The *handler* will be run in a new greenlet when the signal is
    delivered.

    This returns an object with the useful method ``cancel``, which,
    when called, will prevent future deliveries of *signalnum* from
    calling *handler*. It's best to keep the returned object alive
    until you call ``cancel``.

    .. note::

        This may not operate correctly with ``SIGCHLD`` if libev child
        watchers are used (as they are by default with
        `gevent.os.fork`). See :mod:`gevent.signal` for a more
        general purpose solution.

    .. versionchanged:: 1.2a1

        The ``handler`` argument is required to
        be callable at construction time.

    .. versionchanged:: 20.5.1
       The ``cancel`` method now properly cleans up all native resources,
       and drops references to all the arguments of this function.
    Nc                 O   sv   t |stdt | _| jjj|dd| _|| _|| _|| _	| j
d u r2ddlm} |t| _
|| _
| j| j d S )Nz signal handler must be callable.Fr6   r   )Greenlet)r$   r%   r&   r1   r'   r   rA   handlerr/   r0   greenlet_classgeventrG   typestart_start)self	signalnumrH   r/   r0   rG   r4   r4   r5   __init__   s   

zsignal.__init__c                 C   s   | j jS N)rA   r7   rN   r4   r4   r5   <lambda>  s    zsignal.<lambda>c                 C   s   t | jd|S )Nr7   )setattrrA   )rN   nvr4   r4   r5   rS     s    c                 C   sF   | j d ur| j   | j   d | _ d | _d | _d | _d | _d | _d S rQ   )rA   stopcloserH   r/   r0   r1   rI   rR   r4   r4   r5   cancel  s   



zsignal.cancelc                 C   s@   z|  | j}|  W d S    | jjd gt R   Y d S rQ   )rI   handler-   r1   handle_errorsys	_exc_info)rN   r   r4   r4   r5   rM   "  s
   zsignal._startc                 C   s@   z| j | ji | j W d S    | jjd gt R   Y d S rQ   )rH   r/   r0   r1   rZ   r[   exc_inforR   r4   r4   r5   rY   *  s   zsignal.handle)__name__
__module____qualname____doc__rI   rP   propertyr7   rX   rM   rY   r4   r4   r4   r5   r      s    !r   c                 C   sT   | du rt  n| } | du rdS | j  | j| j| jfD ]}t|ddd   qdS )a  
    reinit() -> None

    Prepare the gevent hub to run in a new (forked) process.

    This should be called *immediately* after :func:`os.fork` in the
    child process. This is done automatically by
    :func:`gevent.os.fork` or if the :mod:`os` module has been
    monkey-patched. If this function is not called in a forked
    process, symptoms may include hanging of functions like
    :func:`socket.getaddrinfo`, and the hub's threadpool is unlikely
    to work.

    .. note:: Registered fork watchers may or may not run before
       this function (and thus ``gevent.os.fork``) return. If they have
       not run, they will run "soon", after an iteration of the event loop.
       You can force this by inserting a few small (but non-zero) calls to :func:`sleep`
       after fork returns. (As of gevent 1.1 and before, fork watchers will
       not have run, but this may change in the future.)

    .. note:: This function may be removed in a future major release
       if the fork process can be more smoothly managed.

    .. warning:: See remarks in :func:`gevent.os.fork` about greenlets
       and event loop watchers in the child process.
    N_on_forkc                   S   s   d S rQ   r4   r4   r4   r4   r5   rS   i  s    zreinit.<locals>.<lambda>)_get_hubr'   r   _threadpool	_resolverperiodic_monitoring_threadgetattr)r1   objr4   r4   r5   r   1  s   
r   c                   @   s.  e Zd ZdZeeefZeefZ	dZ
dZdZdZdZd6ddZedd	 Zed
d Zedd Zedd Zdd Zdd Zdd Zd7ddZedd Zdd Zdd Zdd Zd7d d!Zd7d"d#Z ed$d% Z!d&d' Z"d(d) Z#d*d+ Z$ee"e#e$d,Z%ed-d. Z&d/d0 Z'd1d2 Z(d3d4 Z)ee'e(e)d5Z*dS )8r   a  
    A greenlet that runs the event loop.

    It is created automatically by :func:`get_hub`.

    .. rubric:: Switching

    Every time this greenlet (i.e., the event loop) is switched *to*,
    if the current greenlet has a ``switch_out`` method, it will be
    called. This allows a greenlet to take some cleanup actions before
    yielding control. This method should not call any gevent blocking
    functions.
    
   N r   c                 C   s   t | d d  t | _t|dr|d urtd|| _n$t d ur&t | _n|d u r1| jtkr1d}|d u r8| j	}| j
||d| _d | _d | _tj| _t jd7  _tj| _d S )NrunzUnexpected argument: defaultF)flagsdefault   )r    rP   get_thread_identthread_identrE   r%   r'   r   MAIN_THREAD_IDENTbackend
loop_classrf   re   r(   format_contextr   _hub_counterminimal_ident)rN   r'   rn   r4   r4   r5   rP     s$   


zHub.__init__c                 C   s   t  S rQ   r   rR   r4   r4   r5   ident_registry     zHub.ident_registryc                 C      t jS rQ   )r(   r'   rR   r4   r4   r5   rt     ry   zHub.loop_classc                 C   rz   rQ   )r(   libev_backendrR   r4   r4   r5   rs     ry   zHub.backendc                 C   s
   | j tkS )zW
        Is this the hub for the main thread?

        .. versionadded:: 1.3b1
        )rq   rr   rR   r4   r4   r5   main_hub  s   
zHub.main_hubc              
   C   s   | j d u rd}n$z| j  }W n ty+ } zt|p t|p d}W Y d }~nd }~ww d| jj| jt| |f }| j	d urE|d| j	 7 }| j
d urQ|d| j
 7 }|dt| jf 7 }|d S )N	destroyedr   z<%s %r at 0x%x %sz resolver=%rz threadpool=%rz thread_ident=%s>)r'   _format	Exceptionstrrepr	__class__r^   nameidrf   re   hexrq   )rN   infoexresultr4   r4   r5   __repr__  s(   
 

zHub.__repr__c                 C   s8   |||fdkrt  \}}}t|tr||}|||fS )N)NNN)r[   r]   
isinstancer   )rN   r>   vtbr4   r4   r5   _normalize_exception  s
   

zHub._normalize_exceptionc                 C   sn   |  |||\}}}|tu rt||| t|| js"| |||| |du s,t|| jr5| ||| dS dS )a$  
        Called by the event loop when an error occurs. The default
        action is to print the exception to the :attr:`exception
        stream <exception_stream>`.

        The arguments ``type``, ``value``, and ``tb`` are the standard
        tuple as returned by :func:`sys.exc_info`. (Note that when
        this is called, it may not be safe to call
        :func:`sys.exc_info`.)

        Errors that are :attr:`not errors <NOT_ERROR>` are not
        printed.

        Errors that are :attr:`system errors <SYSTEM_ERROR>` are
        passed to :meth:`handle_system_error` after being printed.

        Applications can set a property on the hub instance with this
        same signature to override the error handling provided by this
        class. This is an advanced usage and requires great care. This
        function *must not* raise any exceptions.

        :param context: If this is ``None``, indicates a system error
            that should generally result in exiting the loop and being
            thrown to the parent greenlet.
        N)r   r#   r   
issubclass	NOT_ERRORprint_exceptionSYSTEM_ERRORhandle_system_error)rN   contextrK   valuer   r4   r4   r5   rZ     s   zHub.handle_errorc                 C   s   t  }|| u s|| ju s| jdu r| j||| dS d}z	| j|j}W n   tj| jd Y z| j||| W |durF|	  dS dS |durQ|	  w w )a  
        Called from `handle_error` when the exception type is determined
        to be a :attr:`system error <SYSTEM_ERROR>`.

        System errors cause the exception to be raised in the main
        greenlet (the parent of this hub).

        .. versionchanged:: 20.5.1
           Allow passing the traceback to associate with the
           exception if it is rethrown into the main greenlet.
        Nfile)
r   parentr'   rF   r,   r-   	traceback	print_excexception_streamrV   )rN   rK   r   r   currentcbr4   r4   r5   r   !  s   
zHub.handle_system_errorc                 C   s&   t rt jnd}t|jdkr|j}|S )z
        The stream to which exceptions will be written.
        Defaults to ``sys.stderr`` unless assigned. Assigning a
        false (None) value disables printing exceptions.

        .. versionadded:: 1.2a1
        NFileObjectThread)r[   stderrrK   r^   io)rN   r   r4   r4   r5   r   >  s   zHub.exception_streamc                 C   s   | j }|sd S | |||\}}}|d u r|d|j  n	tj||||d ~z|t  ||d ur7dnd W n   Y |d urot|ts`z| 	|}W n   tj
| j d t|}Y |d|t|ddf  d S d S )Nz%s
r    
z%s failed with %s

r^   rB   )r   r   writer^   r   r   r   r   r   ru   r   r   rh   )rN   r   r>   r   r   	errstreamr4   r4   r5   r   Q  s,   

zHub.print_exceptionc                 C   sx   | t  u s	J d|   	 | j}| |_z	|  W d|_nd|_w g }t|dr-| }d}| jt	d| | d}q)a  
        Entry-point to running the loop. This method is called automatically
        when the hub greenlet is scheduled; do not call it directly.

        :raises gevent.exceptions.LoopExit: If the loop finishes running. This means
           that there are no other scheduled greenlets, and no active
           watchers or servers. In some situations, this indicates a
           programming error.
        zDo not call Hub.run() directlyro   Ndebugz"This operation would block forever)
r    start_periodic_monitoring_threadr'   error_handlerrl   rE   r   r   rF   r"   )rN   r'   r   r4   r4   r5   rl   w  s$   



zHub.runc                 C   sb   | j d u r.tjr.ddlm} ddlm} ddlm} || | _ | jr'| j 	  ||| j  | j S )Nr   )PeriodicMonitoringThread)!PeriodicMonitorThreadStartedEvent)notify_and_call_entry_points)
rg   r(   monitor_threadgevent._monitorr   gevent.eventsr   r   r|   install_monitor_memory_usage)rN   r   r   r   r4   r4   r5   r     s   

z$Hub.start_periodic_monitoring_threadc                 C   s   t  | ju s
J d| jrdS t| }|dur&| jj|dd}||jd z3z|  W n t	yG   Y W ~~ |durD|
  |  ~dS w W ~~ |durW|
  |  ~dS ~~ |durh|
  |  ~w )a8  
        Wait for the event loop to finish. Exits only when there
        are no more spawned greenlets, started servers, active
        timeouts or watchers.

        .. caution:: This doesn't clean up all resources associated
           with the hub. For that, see :meth:`destroy`.

        :param float timeout: If *timeout* is provided, wait no longer
            than the specified number of seconds.

        :return: `True` if this method returns because the loop
                 finished execution. Or `False` if the timeout
                 expired.
        z$only possible from the MAIN greenletTNFr6   )r   r   rD   r   r'   r9   rL   r-   r8   r"   rV   rW   )rN   timeoutr=   r4   r4   r5   join  sB   zHub.joinc                 C   s   |du r	| j j }| jdur| j  d| _| jdur"| j  | `| jdur.| j  | `z	| t| W n t	y@   Y n	 t
yH   Y nw |r[t | j u rUtd | j   nt| j  d| _ t | u rntd dS dS )a  
        Destroy this hub and clean up its resources.

        If you manually create hubs, or you use a hub or the gevent
        blocking API from multiple native threads, you *should* call this
        method before disposing of the hub object reference. Ideally,
        this should be called from the same thread running the hub, but
        it can be called from other threads after that thread has exited.

        Once this is done, it is impossible to continue running the
        hub. Attempts to use the blocking gevent API with pre-existing
        objects from this native thread and bound to this hub will fail.

        .. versionchanged:: 20.5.1
            Attempt to ensure that Python stack frames and greenlets referenced by this
            hub are cleaned up. This guarantees that switching to the hub again
            is not safe after this. (It was never safe, but it's even less safe.)

            Note that this only works if the hub is destroyed in the same thread it
            is running in. If the hub is destroyed by a different thread
            after a ``fork()``, for example, expect some garbage to leak.
        N)r'   rn   rg   r   rf   rW   re   rF   r#   r"   GreenletErrorr   r   destroyrd   r   )rN   destroy_loopr4   r4   r5   r     s6   








zHub.destroyc                 C   rz   rQ   )r(   resolverrR   r4   r4   r5   resolver_classC  ry   zHub.resolver_classc                 C   s   | j d u r| j| d| _ | j S )N)r1   )rf   r   rR   r4   r4   r5   _get_resolverG  s   
zHub._get_resolverc                 C   
   || _ d S rQ   rf   rN   r   r4   r4   r5   _set_resolverL     
zHub._set_resolverc                 C   
   d | _ d S rQ   r   rR   r4   r4   r5   _del_resolverO  r   zHub._del_resolverz
                        The DNS resolver that the socket functions will use.

                        .. seealso:: :doc:`/dns`
                        c                 C   rz   rQ   )r(   
threadpoolrR   r4   r4   r5   threadpool_classZ  ry   zHub.threadpool_classc                 C   s&   | j d u r| j| j| tjd| _ | j S )N)r1   idle_task_timeout)re   r   threadpool_sizer(   threadpool_idle_task_timeoutrR   r4   r4   r5   _get_threadpool^  s   
zHub._get_threadpoolc                 C   r   rQ   re   r   r4   r4   r5   _set_threadpoolh  r   zHub._set_threadpoolc                 C   r   rQ   r   rR   r4   r4   r5   _del_threadpoolk  r   zHub._del_threadpoola  
                          The threadpool associated with this hub.

                          Usually this is a
                          :class:`gevent.threadpool.ThreadPool`, but
                          you :attr:`can customize that
                          <gevent._config.Config.threadpool>`.

                          Use this object to schedule blocking
                          (non-cooperative) operations in a different
                          thread to prevent them from halting the event loop.
                          )NNrQ   )+r^   r_   r`   ra   KeyboardInterrupt
SystemExitSystemErrorr   r   r   r   rg   rq   r   rv   rP   r   rx   rb   rt   rs   r|   r   r   rZ   r   r   r   r   rl   r   r   r   r   r   r   r   r   r   r   r   r   r   r4   r4   r4   r5   r   u  sZ    






&
&:

4J


r   c                   @   s$   e Zd ZddgZdd Zdd ZdS )	linkproxycallbackri   c                 C   s   || _ || _d S rQ   r   ri   )rN   r   ri   r4   r4   r5   rP     s   
zlinkproxy.__init__c                 G   s$   | j }| j}d | _ d | _|| d S rQ   r   )rN   r/   r   ri   r4   r4   r5   __call__  s
   zlinkproxy.__call__N)r^   r_   r`   	__slots__rP   r   r4   r4   r4   r5   r     s    r   )r   T)r   rQ   )Bra   
__future__r   r   	functoolsr   r+   r[   r   r   r*   r   r   r   r   __all__gevent._configr   r(   gevent._compatr   r   gevent._utilr   r   r   gevent._identr   gevent._hub_localr   r   r   r   r   rd   r   r&   r   gevent._greenlet_primitivesr   gevent._hub_primitivesr    rJ   r!   wait_on_objectsr;   iwait_on_objectsiwaitgevent.exceptionsr"   r#   gevent._waiterr   
__import__	get_identrp   rr   r	   r
   r?   r   objectr   r   r   r   r4   r4   r4   r5   <module>   s^   

;
(
XD    