
    jj$                       d Z ddlmZ ddlZddlZddlZddlZddlmZ ddl	m
Z
mZ ddlmZmZ ej                  r6ddlmZ dd	lmZmZ dd
lmZmZ ddlmZ  ed      Z ej6                  d      ZdZ G d de      Z G d de      Zy)zTTwisted Reactor based urwid EventLoop implementation.

Twisted library is required.
    )annotationsN)FileDescriptor)AlreadyCalledAlreadyCancelled   )	EventLoopExitMainLoop)Callable)ExecutorFuture)DelayedCallReactorBase)	ParamSpec_Spec_T)TwistedEventLoopc                  B     e Zd Zd fdZddZd Zd Zd Zd	dZ xZ	S )
_TwistedInputDescriptorc                @    || _         || _        t        |   |       y N)_filenocbsuper__init__)selfreactorfdr   	__class__s       f/home/ubuntu/.cache/pipx/cdb5059130eadca/lib/python3.12/site-packages/urwid/event_loop/twisted_loop.pyr   z _TwistedInputDescriptor.__init__5   s    !    c                    | j                   S r   )r   r   s    r   filenoz_TwistedInputDescriptor.fileno:   s    ||r    c                "    | j                         S r   )r   r"   s    r   doReadz_TwistedInputDescriptor.doRead=   s    wwyr    c                    t        d      NzNo network operation expectedNotImplementedErrorr"   s    r   getHostz_TwistedInputDescriptor.getHost@       !"ABBr    c                    t        d      r'   r(   r"   s    r   getPeerz_TwistedInputDescriptor.getPeerC   r+   r    c                    t        d      )Nz Reduced functionality: read-onlyr(   )r   datas     r   writeSomeDataz%_TwistedInputDescriptor.writeSomeDataF   s    !"DEEr    )r   r   r   intr   Callable[[], typing.Any]returnNone)r3   r1   )r/   bytesr3   r4   )
__name__
__module____qualname__r   r#   r%   r*   r-   r0   __classcell__r   s   @r   r   r   4   s$    "
CCFr    r   c                       e Zd ZdZdZdd f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dZdddZ xZS )r   z&
    Event loop based on Twisted_
    g      p?c                ^   t         |           t        j                  t              j                  | j                  j                        | _        |ddl}|j                  j                  }|| _
        i | _        d| _        d| _        i | _        d| _        || _        | j#                          y)a#  
        :param reactor: reactor to use
        :type reactor: :class:`twisted.internet.reactor`.
        :param: manage_reactor: `True` if you want this event loop to run
                                and stop the reactor.
        :type manage_reactor: boolean

        .. WARNING::
           Twisted's reactor doesn't like to be stopped and run again.  If you
           need to stop and run your :class:`MainLoop`, consider setting
           ``manage_reactor=False`` and take care of running/stopping the reactor
           at the beginning/ending of your program yourself.

           You can also forego using :class:`MainLoop`'s run() entirely, and
           instead call start() and stop() before and after starting the
           reactor.

        .. _Twisted: https://twisted.org/
        Nr   F)r   r   logging	getLoggerr6   getChildr   loggertwisted.internet.reactorinternetr   _watch_files_idle_handle_twisted_idle_enabled_idle_callbacks_excmanage_reactor_enable_twisted_idle)r   r   rH   twistedr   s       r   r   zTwistedEventLoop.__init__Q   s    ( 	''1::4>>;R;RS?+&&..G$+@B!"%*"DF*.	,!!#r    c                    t        d      )Na  Twisted implement it's own ThreadPool executor. Please use native API for call:
'threads.deferToThread(Callable[..., Any], *args, **kwargs)'
And use 'addCallback' api for callbacks:
'threads.deferToThread(Callable[..., T], *args, **kwargs).addCallback(Callable[[T], None])'r(   )r   executorfuncargskwargss        r   run_in_executorz TwistedEventLoop.run_in_executort   s     "j
 	
r    c                \    | j                   j                  || j                  |            }|S )a#  
        Call callback() a given time from now.  No parameters are
        passed to callback.

        Returns a handle that may be passed to remove_alarm()

        seconds -- floating point time to wait before calling callback
        callback -- function to call from event loop
        )r   	callLaterhandle_exit)r   secondscallbackhandles       r   alarmzTwistedEventLoop.alarm   s*     ''1A1A(1KLr    c                P    	 |j                          y# t        t        f$ r Y yw xY w)z]
        Remove an alarm.

        Returns True if the alarm exists, False otherwise
        FT)cancelr   r   r   rV   s     r   remove_alarmzTwistedEventLoop.remove_alarm   s.    	MMO
  !-0 		s    %%c                    t        | j                  || j                  |            }|| j                  |<   | j                  j	                  |       |S )a"  
        Call callback() when fd has some data to read.  No parameters
        are passed to callback.

        Returns a handle that may be passed to remove_watch_file()

        fd -- file descriptor to watch for input
        callback -- function to call when input is available
        )r   r   rS   rC   	addReader)r   r   rU   inds       r   
watch_filezTwistedEventLoop.watch_file   sH     &dllB8H8H8RS #"s#	r    c                    || j                   v r6| j                  j                  | j                   |          | j                   |= yy)zg
        Remove an input file.

        Returns True if the input file exists, False otherwise
        TF)rC   r   removeReaderrZ   s     r   remove_watch_filez"TwistedEventLoop.remove_watch_file   sC     T&&&LL%%d&7&7&?@!!&)r    c                v    | xj                   dz  c_         || j                  | j                   <   | j                   S )zw
        Add a callback for entering idle.

        Returns a handle that may be passed to remove_enter_idle()
        r   )rD   rF   r   rU   s     r   
enter_idlezTwistedEventLoop.enter_idle   s7     	Q2:T../   r    c                    | j                   ry| j                  j                  | j                  | j	                  | j
                  d             d| _         y)aU  
        Twisted's reactors don't have an idle or enter-idle callback
        so the best we can do for now is to set a timer event in a very
        short time to approximate an enter-idle callback.

        .. WARNING::
           This will perform worse than the other event loops until we can find a
           fix or workaround
        NF)enable_idleT)rE   r   rR   _idle_emulation_delayrS   _twisted_idle_callbackr"   s    r   rI   z%TwistedEventLoop._enable_twisted_idle   sN     %%&&T88eL	
 &*"r    c                ^    | j                   j                         D ]	  } |         d| _        y )NF)rF   valuesrE   rd   s     r   ri   z'TwistedEventLoop._twisted_idle_callback   s-    ,,335 	HJ	%*"r    c                >    	 | j                   |= y# t        $ r Y yw xY w)z[
        Remove an idle callback.

        Returns True if the handle was removed.
        FT)rF   KeyErrorrZ   s     r   remove_enter_idlez"TwistedEventLoop.remove_enter_idle   s.    	$$V,   		s    	c                    | j                   sy| j                  j                          | j                  r.| j                  }d| _        |j	                  |j
                        y)z
        Start the event loop.  Exit the loop when any callback raises
        an exception.  If ExitMainLoop is raised, exit cleanly.
        N)rH   r   runrG   with_traceback__traceback__)r   excs     r   rp   zTwistedEventLoop.run   sS    
 ""99))CDI$$S%6%677	 r    c                L     t        j                        d fd       }|S )a1  
        Decorator that cleanly exits the :class:`TwistedEventLoop` if
        :class:`ExitMainLoop` is thrown inside of the wrapped function. Store the
        exception info if some other exception occurs, it will be reraised after
        the loop quits.

        *f* -- function to be wrapped
        c                 b   d }	  | i |}rj                          |S # t         $ r) j                  rj                  j                          Y Et        $ rT}t        t        j                                |_        j                  rj                  j                          Y d }~d }~ww xY wr   )r	   rH   r   stopBaseExceptionprintsysexc_inforG   crashrI   )rN   rO   rvalrs   rg   fr   s       r   wrapperz-TwistedEventLoop.handle_exit.<locals>.wrapper   s    D	)$)&) ))+K   (&&LL%%'  )clln%	&&LL&&(	)s   ! /B.B.A
B))B.)rN   z
_Spec.argsrO   z_Spec.kwargsr3   z	_T | None)	functoolswraps)r   r}   rg   r~   s   ``` r   rS   zTwistedEventLoop.handle_exit   s'     
		 
	  r    )NT)r   zReactorBase | NonerH   boolr3   r4   )
rL   r   rM   zCallable[..., _T]rN   objectrO   r   r3   z
Future[_T])rT   floatrU   r2   r3   r   )rV   r   r3   r   )r   r1   rU   r2   r3   r1   )rV   r1   r3   r   )rU   r2   r3   r1   )r3   r4   )T)r}   zCallable[_Spec, _T]rg   r   r3   zCallable[_Spec, _T | None])r6   r7   r8   __doc__rh   r   rP   rW   r[   r_   rb   re   rI   ri   rn   rp   rS   r9   r:   s   @r   r   r   J   s     &!$F

  
 	

 
 


!*$+

8 r    r   ) r   
__future__r   r   r=   ry   typingtwisted.internet.abstractr   twisted.internet.errorr   r   abstract_loopr   r	   TYPE_CHECKINGcollections.abcr
   concurrent.futuresr   r   twisted.internet.baser   r   typing_extensionsr   r   TypeVarr   __all__r   r    r    r   <module>r      st   ,
 #   
  4 B 2	(3>+gE		B
Fn F,Dy Dr    