
    AHj|                       U d Z ddlmZ ddlZddlZddlmZmZmZmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZmZmZmZmZmZmZmZmZ dd	lmZ dd
lmZmZmZmZ ddl m!Z! ddl"m#Z# ddl$m%Z%m&Z&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l0m1Z1 ddl2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl8m9Z9m:Z: ddl;m<Z< ddl=m>Z>m?Z? erddl@mAZA ddlBmCZC ddlDmEZE dZFdeGd<    G d  d!eH      ZI G d" d#eH      ZJ ed$d%&      ZK G d' d%eL      ZM G d( d)eM*      ZNy)+z

A `MessagePump` is a base class for any object which processes messages, which includes Widget, Screen, and App.

!!! tip

    Most of the method here are useful in general app development.

    )annotationsN)CancelledError
QueueEmptyTaskcreate_task)contextmanager)partial)perf_counter)	TYPE_CHECKINGAny	AwaitableCallable	GeneratorIterableTypeTypeVarcast)WeakSet)Loggereventslogmessages)invoke)cached_property)NoActiveAppError
active_appactive_message_pump)message_hook)prevent_message_types_stack)
OnNoWidgetQueue)time)SLOW_THRESHOLD)match)Event)Message)ReactiveTooManyComputesError)Signal)TimerTimerCallback)	TypeAliasApp)SelectorSetz2Callable[..., Any] | Callable[..., Awaitable[Any]]r-   Callbackc                      e Zd Zy)CallbackErrorN__name__
__module____qualname__     L/root/tools/cai/cai_env/lib/python3.12/site-packages/textual/message_pump.pyr3   r3   ;       r9   r3   c                      e Zd Zy)MessagePumpClosedNr4   r8   r9   r:   r=   r=   ?   r;   r9   r=   _MessagePumpMetaSub_MessagePumpMeta)boundc                  <     e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 d fdZ xZS )r?   z}Metaclass for message pump. This exists to populate a Message inner class of a Widget with the
    parent classes' name.
    c                   |j                  di       }||d<   |j                         D ]T  }t        |      st        |d      st	        |d      }|D ](  \  }}	|j                  |g       j                  ||	f       * V d}
t        |
      }|j                         D ]W  \  }}|j                  |
      st        |      s$||d  }||v s.t        ||   t              sBd| |v sJt        d|d       t        | 8  | |||fi |}|S )N_decorated_handlers_textual_oncompute__z	reactive z can't have two computes.)getvaluescallablehasattrgetattr
setdefaultappendlenitems
startswith
isinstancer(   r)   super__new__)clsnamebases
class_dictkwargshandlersvalue
textual_onmessage_type	selectorsprefix
prefix_len	attr_namereactive_name	class_obj	__class__s                  r:   rS   z_MessagePumpMeta.__new__K   sG    NN0"5 	 -5
()&&( 	UE75-#@ E=1  0: U+L)''b9@@%ASTU	U [
 * 0 0 2 
	Iu##F+ )*+ 6!Z/":m#<hGI;:5.#M#44MN 
	 GOCujKFK	r9   )rT   zType[_MessagePumpMetaSub]rU   strrV   ztuple[type, ...]rW   zdict[str, Any]rX   r   returnr>   )r5   r6   r7   __doc__rS   __classcell__)rc   s   @r:   r?   r?   F   sJ    %&%%  % #	%
 % 
% %r9   c                     e Zd ZdZd;d<dZed=d       Zed>d       Zed?d       Z	d Z
d@dZdAd	ZedBd
       ZedCd       ZedDd       ZedEd       Zed        ZerddlmZ ej-                  e      Zn	edFd       ZedDd       ZedDd       ZedDd       ZedGd       ZdHdZdIdZdJdZdKdZdKdZ dLdZ!dMdZ"	 d;ddd	 	 	 	 	 	 	 	 	 dNdZ#	 d;dddd 	 	 	 	 	 	 	 	 	 	 	 dOd!Z$dPd"Z%dDd#Z&dPd$Z'dQd%Z(dRd&Z)dSdTd'Z*dId(Z+dId)Z,dId*Z-dDd+Z.d, Z/dId-Z0edUd.       Z1dVd/Z2dId0Z3dId1Z4dWd2Z5	 	 	 	 	 	 dXd3Z6dYd4Z7dWd5Z8dId6Z9dJd7Z:dJd8Z;dZd9Z<d[d:Z=y)\MessagePumpz)Base class which supplies a message pump.Nc                Z   || _         d| _        d| _        d| _        t	               | _        d | _        d | _        t               | _	        t               | _        d | _        d| _        	 g | _        t        j                          | _        | j$                  d   | _        t)        | d      | _        y )NFr   )_parent_running_closing_closedset_disabled_messages_pending_message_taskr   _timersr#   
_last_idle	_max_idle_is_mounted_next_callbacks	threading	get_ident
_thread_id_prevent_message_types_stack_prevented_messages_on_mountr*   message_signalselfparents     r:   __init__zMessagePump.__init__v   s    ##"69e04"&
'.y!%'+ 	 79(224,0,M,Mb,Q)/5dJ/G	r9   c                    t               S Nr!   r   s    r:   _message_queuezMessagePump._message_queue   s	    wr9   c                *    t        j                         S r   )asyncior&   r   s    r:   _mounted_eventzMessagePump._mounted_event   s    }}r9   c                    	 t        j                         }|S # t        $ r$ t               g}t        j                  |       Y |S w xY w)z*The stack that manages prevented messages.)r   rG   LookupErrorrp   )r   stacks     r:   r|   z(MessagePump._prevent_message_types_stack   sI    	3/335E   	3UGE'++E2	3s    )AAc                4    | j                    | j                   y)zInitialize threading primitives for the current thread.

        Require for Python3.8 https://github.com/Textualize/textual/issues/5845

        N)r   r   r   s    r:   _thread_initzMessagePump._thread_init   s     	r9   c                     | j                   d   S )z)A set of all the prevented message types.rk   r|   r   s    r:   _get_prevented_messagesz#MessagePump._get_prevented_messages   s    0044r9   c                $    || j                   d   v S )a?  Check if a message type has been prevented via the
        [prevent][textual.message_pump.MessagePump.prevent] context manager.

        Args:
            message_type: A message type.

        Returns:
            `True` if the message has been prevented from sending, or `False` if it will be sent as normal.
        rk   r   )r   r\   s     r:   _is_preventedzMessagePump._is_prevented   s     t@@DDDr9   c              '     K   |rE| j                   }|j                  |d   j                  |             	 d |j                          yd y# |j                          w xY ww)a  A context manager to *temporarily* prevent the given message types from being posted.

        Example:
            ```python
            input = self.query_one(Input)
            with self.prevent(Input.Changed):
                input.value = "foo"
            ```
        rk   N)r|   rM   unionpop)r   message_typesprevent_stacks      r:   preventzMessagePump.prevent   sZ       ==M  r!2!8!8!GH$!!# !!#s   2A$A A$A!!A$c                6    | j                   J | j                   S r   )rs   r   s    r:   taskzMessagePump.task   s    zz%%%zzr9   c                    | j                   duS )zDoes this object have a parent?Nrl   r   s    r:   
has_parentzMessagePump.has_parent   s     ||4''r9   c                6    | j                   j                         S )z&The current size of the message queue.)r   qsizer   s    r:   message_queue_sizezMessagePump.message_queue_size   s     ""((**r9   c                     y)z#Is this a root node (i.e. the App)?Fr8   r   s    r:   is_dom_rootzMessagePump.is_dom_root   s     r9   r   )gettersc                    	 t        j                         S # t        $ r> ddlm} | }t        ||      s%|
t               |j                  }t        ||      s%|cY S w xY w)z
            Get the current app.

            Returns:
                The current app.

            Raises:
                NoActiveAppError: if no active app could be found for the current asyncio context
            r   r.   )r   rG   r   textual.appr/   rQ   r   rl   )r   r/   nodes      r:   appzMessagePump.app   s_    !~~'' 	++/$T3/|.00<<D %T3/
 	s    AAAAc                    	 | j                   j                  ry	 | }|j                  x}|j                  ry|j                  x}y# t        $ r Y yw xY w)z/Is this node linked to the app through the DOM?FT)r   _exitr   rl   r   )r   r   s     r:   is_attachedzMessagePump.is_attached  sf    	xx~~  $(||#t0 ||#t0    		s   A 	AAc                p    | j                   }t        |duxr |j                   xr |j                         S )zIs the parent active?N)rl   boolro   rn   r   s     r:   is_parent_activezMessagePump.is_parent_active  s5     F$&Uv~~+=UfooBUVVr9   c                    | j                   S )z>Is the message pump running (potentially processing messages)?)rm   r   s    r:   
is_runningzMessagePump.is_running  s     }}r9   c                .    | j                   j                  S )zNGet a logger for this object.

        Returns:
            A logger.
        )r   _loggerr   s    r:   r   zMessagePump.log  s     xxr9   c                    || _         y)ztSet the parent, and therefore attach this node to the tree.

        Args:
            parent: Parent node.
        Nr   r   s     r:   _attachzMessagePump._attach&  s     r9   c                    d| _         y)z8Set the parent to None to remove the node from the tree.Nr   r   s    r:   _detachzMessagePump._detach.  s	    r9   c                0    t        |      | j                  vS )zCheck if a given message is enabled (allowed to be sent).

        Args:
            message: A message object.

        Returns:
            `True` if the message will be sent, or `False` if it is disabled.
        )typerq   r   messages     r:   check_message_enabledz!MessagePump.check_message_enabled2  s     G}D$;$;;;r9   c                :    | j                   j                  |       y)z+Disable message types from being processed.N)rq   updater   r   s     r:   disable_messageszMessagePump.disable_messages>  s    &&x0r9   c                :    | j                   j                  |       y)z$Enable processing of messages types.N)rq   difference_updater   s     r:   enable_messageszMessagePump.enable_messagesB  s    11(;r9   c                  K   | j                   rt        d      | j                  	 | j                  d| _        S | j                  j	                          d{   }|d| _         t        d      |S # d| _        w xY w7 &w)zyGet the next event on the queue, or None if queue is closed.

        Returns:
            Event object or None.
        zThe message pump is closedNTThe message pump is now closed)ro   r=   rr   r   rG   r   s     r:   _get_messagezMessagePump._get_messageF  s      <<#$@AA  ,-,,(,%++//11?DL#$DEE )-%1s'   $B A2 %B A>B 2	A;;B c                    | j                   6	 | j                  j                         }|d| _        t	        d      || _         | j                   | j                   S y# t
        $ r Y $w xY w)zPeek the message at the head of the queue (does not remove it from the queue),
        or return None if the queue is empty.

        Returns:
            The message or None.
        NTr   )rr   r   
get_nowaitro   r=   r   r   s     r:   _peek_messagezMessagePump._peek_message[  sz       (0--88: ?#'DL+,LMM(/%  ,(((  s   A 	A('A(F)rU   pausec          	         t        | ||xs dt         j                   |dnt        | j                  |      d|      }|j	                          | j
                  j                  |       |S )a&  Call a function after a delay.

        Example:
            ```python
            def ready():
                self.notify("Your soft boiled egg is ready!")
            # Call ready() after 3 minutes
            self.set_timer(3 * 60, ready)
            ```

        Args:
            delay: Time (in seconds) to wait before invoking callback.
            callback: Callback to call after time has expired.
            name: Name of the timer (for debug).
            pause: Start timer paused.

        Returns:
            A timer object.
        z
set_timer#Nr   rU   callbackrepeatr   )r+   _timer_countr	   	call_next_startrt   add)r   delayr   rU   r   timers         r:   	set_timerzMessagePump.set_timerq  sg    8 ::e&8&8%9:%-T74>>83T
 	r9   )rU   r   r   c                   t        | ||xs dt         j                   ||xs d|      }|j                          | j                  j	                  |       |S )an  Call a function at periodic intervals.

        Args:
            interval: Time (in seconds) between calls.
            callback: Function to call.
            name: Name of the timer object.
            repeat: Number of times to repeat the call or 0 for continuous.
            pause: Start the timer paused.

        Returns:
            A timer object.
        zset_interval#Nr   )r+   r   r   rt   r   )r   intervalr   rU   r   r   r   s          r:   set_intervalzMessagePump.set_interval  sY    * ==););(<=>T
 	r9   c                h    t        j                  t        |g|i |      }| j                  |      S )a  Schedule a callback to run after all messages are processed and the screen
        has been refreshed. Positional and keyword arguments are passed to the callable.

        Args:
            callback: A callable.

        Returns:
            `True` if the callback was scheduled, or `False` if the callback could not be
                scheduled (may occur if the message pump was closed or closing).

        )r   InvokeLaterr	   post_messager   r   argsrX   r   s        r:   call_after_refreshzMessagePump.call_after_refresh  s4     &&wx'I$'I&'IJ  ))r9   c                  K   | j                   J d       t        j                         | j                   u ryt        j                         }| j	                  |j
                         |j                          d{    y7 w)a  Wait for the next refresh.

        This method should only be called from a task other than the one running this widget.
        If called from the same task, it will return immediately to avoid blocking the event loop.

        Returns:
            `True` if waiting for refresh was successful, or `False` if the call was a null-op
                due to calling it within the node's own task.

        Nz4Node must be running before calling wait_for_refreshFT)rs   r   current_taskr&   r   rp   wait)r   refreshed_events     r:   wait_for_refreshzMessagePump.wait_for_refresh  su      JJ"	BA	B"!TZZ/!--/ 3 34""$$$ 	%s   A7B9A?:Bc                j    t        j                  t        |g|i |      }| j                  |      S )a  Schedule a callback to run after all messages are processed in this object.
        Positional and keywords arguments are passed to the callable.

        Args:
            callback: Callable to call next.
            *args: Positional arguments to pass to the callable.
            **kwargs: Keyword arguments to pass to the callable.

        Returns:
            `True` if the callback was scheduled, or `False` if the callback could not be
                scheduled (may occur if the message pump was closed or closing).

        r   )r   r1   r	   r   r   s        r:   
call_laterzMessagePump.call_later  s2     //78+Md+Mf+MN  ))r9   c                   |J d       t        j                  t        |g|i |      }|j                  j	                  | j                                | j                  j                  |       | j                          y)a!  Schedule a callback to run immediately after processing the current message.

        Args:
            callback: Callable to run after current event.
            *args: Positional arguments to pass to the callable.
            **kwargs: Keyword arguments to pass to the callable.
        NzCallback must not be Noner   )	r   r1   r	   _preventr   r   rx   rM   
check_idle)r   r   r   rX   callback_messages        r:   r   zMessagePump.call_next  sp     #@%@@#!??GH4Vt4Vv4VW!!(()E)E)GH##$45r9   c                    | j                   j                  rQ| j                   j                  j                  |j                  |j
                  xs t        j                                y y r   )r   rm   screen_invoke_laterr   _senderr   rG   r   s     r:   _on_invoke_laterzMessagePump._on_invoke_later   sH    88HHOO))  '//"N5H5L5L5N r9   c                T  K   | j                   s| j                  ryd| _        | j                  rAt        j                  | j                         d{    | j                  j                          t        j                  |        | j                  j                  d       |ra| j                  Tt        j                         | j                  k7  r2	 t        j                         }||| ur	 | j                   d{    yyyyy7 # t        $ r d}Y /w xY w7 # t         $ r Y yw xY ww)zHClose message queue, and optionally wait for queue to finish processing.NT)ro   rn   rt   r+   	_stop_allclearr(   _reset_objectr   
put_nowaitrs   r   r   r   rG   r   r   )r   r   running_widgets      r:   _close_messageszMessagePump._close_messages  s    <<4==<<//$,,///LL t$&&t,DJJ*w/C/C/E/S&!4!8!8!: %t)C**$$ *D 0T*4	 0  &!%&
 %% sm   AD(DA=D(D $D(+D :D;D ?D(DD(DD(D 	D%"D($D%%D(c                    | j                          | j                  j                  r$t        | j	                         d|        | _        yd| _        d| _        y)zStart messages task.zmessage pump )rU   TN)r   r   rm   r   _process_messagesrs   rn   ro   r   s    r:   _start_messageszMessagePump._start_messages  sL    88$&&(tf/EDJ !DMDLr9   c                  K   d| _         | j                         5  | j                          d {   sd| _         	 d d d        y 	 | j                          d {    d| _         	 | j
                  rAt        j                  | j
                         d {    | j
                  j                          t        j                  |        | j                          d {    	 d d d        d | _        y 7 7 # t        $ r Y w xY w7 o7 *# | j                          d {  7   w xY w# d| _         	 | j
                  rBt        j                  | j
                         d {  7   | j
                  j                          t        j                  |        | j                          d {  7   w # | j                          d {  7   w xY wxY w# 1 sw Y   d | _        y xY ww)NTF)rm   _context_pre_process_process_messages_loopr   rt   r+   r   r   r(   _clear_watchers_message_loop_exitrs   r   s    r:   r   zMessagePump._process_messages)  sx    ]]_ 	4**,,, %	4 	4
411333 !&4||#oodll;;;**,,,T211333#	4$ 
# -
 4!  < 4$11333 !&4||#oodll;;;**,,,T211333$11333#	4$ 
s   GGC0G	GC4C2C4G%.DD3DGDG G0G2C44	D =D%?D  D%DGD"D
D""G%G	..F+E
4F+G	$F'
%G	+G	?G G	G		GGGc                   K   yw)z+Called when the message loop has completed.Nr8   r   s    r:   r   zMessagePump._message_loop_exit@  s     s   c                  K   	 | j                  t        j                                d{    | j                  rN | j                  | j                   5  | j                  t        j
                                d{    ddd       n+| j                  t        j
                                d{    | j                          	 | j                  j                          d| _        y7 7 m# 1 sw Y   @xY w7 G# t        $ rF}| j                  j                  |       Y d}~| j                  j                          d| _        yd}~ww xY w# | j                  j                          d| _        w xY ww)zProcedure to run before processing messages.

        Returns:
            `True` if successful, or `False` if any exception occurred.

        NTF)_dispatch_messager   Composer}   r   Mount_post_mount	Exceptionr   _handle_exceptionr   rp   rw   )r   errors     r:   r   zMessagePump._pre_processC  s2    	$(()9:::00!T\\4#D#DE A00@@@A A ,,V\\^<<< ##%#D ; AA A = 	HH&&u- ##%#D	
 ##%#Ds   E1&C9 C')C9 'C+;C)<C+ /C9 /C70C9 "E1'C9 )C++C40C9 9	EEE !"E1EE #E..E1c                     y)z)Called after the object has been mounted.Nr8   r   s    r:   r  zMessagePump._post_mount^  s    r9   c                ^    | j                   j                  t        j                                y)z.Request the message queue to immediately exit.N)r   r   r   CloseMessagesr   s    r:   _close_messages_no_waitz#MessagePump._close_messages_no_waita  s    &&x'='='?@r9   c              #     K   t        j                  |       }	 d t        j                  |       y# t        j                  |       w xY ww)z#Context manager to set ContextVars.N)r   rp   reset)r   reset_tokens     r:   r   zMessagePump._contexte  s=      *--d3	3%%k2%%k2s   A3 AA

Ac                @   K   | j                          d {    y 7 wr   )r   r   s     r:   _on_close_messageszMessagePump._on_close_messagesn  s     ""$$$s   c                H
  K   d}t        j                         | _        t        j                  d       d{    | j
                  s	 | j                          d{   }| j
                  sc| j                  sW	 | j                         }||j                  |      sn2	 | j                          d{   }| j
                  s| j                  sW	 | j                  |       d{    	 | j&                  j)                  |       | j*                  j-                          t/               }| j*                  j1                         s(| j2                  || j4                  z
  | j2                  kD  ro|| _        | j
                  sCt7        j8                         }| j;                  d|      D ]  \  }}	 t=        ||       d{     | j?                          d{    	 | j
                  syy7 7 # t        $ r Y yt        $ r  t        $ r}|dd}~ww xY w# t        $ r Y Tw xY w7 v# t        $ r Y gw xY w7 V# t        $ r  t        $ rk}| j                  j                          d| _        | j"                  j%                  |       Y d}~| j&                  j)                  |       | j*                  j-                          t/               }| j*                  j1                         s(| j2                  || j4                  z
  | j2                  kD  r|| _        | j
                  svt7        j8                         }| j;                  d|      D ]M  \  }}	 t=        ||       d{  7   # t        $ r&}| j"                  j%                  |       Y d}~ n	d}~ww xY w | j?                          d{  7   yyyd}~ww xY w7 # t        $ r'}| j"                  j%                  |       Y d}~ +d}~ww xY w7  # | j&                  j)                  |       | j*                  j-                          t/               }| j*                  j1                         s(| j2                  || j4                  z
  | j2                  kD  r|| _        | j
                  svt7        j8                         }| j;                  d|      D ]M  \  }}	 t=        ||       d{  7   # t        $ r&}| j"                  j%                  |       Y d}~ n	d}~ww xY w | j?                          d{  7   w w w xY ww)z+Process messages until the queue is closed.Tr   Non_idle) ry   rz   r{   r   sleepro   r   r=   r   r  rn   r   can_replacer  r   rp   rw   r   r  r~   publishr   	task_doner#   emptyrv   ru   r   Idle_get_dispatch_methodsr   _flush_next_callbacks)	r   _rich_traceback_guardr   r  pendingcurrent_timeevent_clsmethods	            r:   r   z"MessagePump._process_messages_loopq  sa     $#--/mmA,,& $ 1 1 33 ||t}}"002G ?'*=*=g*F$($5$5$77G ||t}}7,,W555 ##++G4##--/#v &&,,.NN.$t6G&2DO<< &,0,F,F%u- &LD&&&,VU&; ; ;	& 44666m ,, 	 4$ !  &%& ) 
 8(  6!  ##'')#' **51##++G4##--/#v &&,,.NN.$t6G&2DO<< &,0,F,F%u- &LD&&&,VU&; ; ;#, & $ : :5 A %&& 44666 H /. !<#, & $ : :5 A %& 7+ ##++G4##--/#v &&,,.NN.$t6G&2DO<< &,0,F,F%u- &LD&&&,VU&; ; ;#, & $ : :5 A %&& 44666 H /s  4T"G+T"	G1 G.G1 !T":H 
T"H+ 2H(3H+ 7T"H> %H;&H> +C T",O;N?<O T"O5T")T".G1 1	H:T"<HHHT"	H%!T"$H%%T"(H+ +	H84T"7H88T";H> >N<<N7O8 C T"M(!M$"M('T"(	N1NT"NT".N1/T"7N<<O8 ?O	O2O-&T"-O22T"8CT:S	S

ST	S?	S:	4T:S?	?TTTT"c                  K   | j                   j                         }| j                   j                          |D ]B  }	  | j                  |j                   5  t        |j                         d{    ddd       D y7 # 1 sw Y   xY w# t        $ r&}| j                  j                  |       Y d}~ yd}~ww xY ww)z1Invoke pending callbacks in next callbacks queue.N)
rx   copyr   r   r   r   r   r  r   r  )r   	callbacksr   r  s       r:   r  z!MessagePump._flush_next_callbacks  s     ((--/	""$! 	H!T\\8#4#45 4 !2!23334	 44 4 **51sX   :B?BB/A?0B4B<B??BB
	B	B<B71B?7B<<B?c                  K   d}|j                   ry	 t        j                         } ||        | j                  |j
                   5  t        |t              r| j                  |       d{    nd| j                  j                  v rt               }| j                  |       d{    t               |z
  t        dz  kD  r^t        j                  d| j                   j"                   d|j$                   ddt         d	d
       n| j                  |       d{    | j&                  r| j)                          d{    ddd       y# t        $ r Y -w xY w7 7 7 E7 ## 1 sw Y   yxY ww)zqDispatch a message received from the message queue.

        Args:
            message: A message object
        TNdebugi  method=<.>z
Took over zms to process.z2
To avoid screen freezes, consider using a worker.)no_dispatchmessage_hook_context_varrG   r   r   r   rQ   r&   on_eventr   featuresr
   _on_messager$   r   warningrc   r5   handler_namerx   r  )r   r   r  r   starts        r:   r  zMessagePump._dispatch_message  s_     !%	"3779L !T\\7++, 	3'5)mmG,,,DHH---$&&w///>E)NT,AAKK"4>>#:#:";1"//03$^$4NCM	 &&w///##00222#	3 	3  		 - 0 02#	3 	3s   E4E !E4%E(-E .;E()E"*A4E(E$#E(E&E(	E4	EE4EE4 E("E($E(&E((E1-E4c           	   #    K   ddl m} t               }|j                  j                  D cg c]  }t        |t              s| }}| j                  j                  D ]s  }|j                  r yt        d|j                  j                  d            }|r|D ]  }	|j                  |	g       }
|
D ]  \  }}||v r|s(||j                  | |      f |j                  |       5|j                  sB|j                         D ]>  \  }}t        ||      }| ht!        ||      st#        d|d      t%        ||      r>  ||j                  | |      f |j                  |         |j                  j                  d|       xs |j                  j                  |      }|Ot        |d	d      r^||j                  | |      f v yc c}w w)
zGets handlers from the MRO

        Args:
            method_name: Handler method name.
            message: Message object.
        r   )WidgetzUdict[type[Message], list[tuple[Callable, dict[str, tuple[SelectorSet, ...]]]]] | NonerC   Nz!on decorator can't match against z as it is not a widget.rF   rD   )textual.widgetr2  rp   rc   __mro__
issubclassr'   _no_default_actionr   __dict__rG   __get__r   r   rO   rK   rQ   r    r%   )r   method_namer   r2  methods_dispatched_typemessage_mrorT   decorated_handlersmessage_classrY   r   r]   	attributeselectorr   s                   r:   r  z!MessagePump._get_dispatch_methods  s     	*,/E&0088
Jug<VE
 
 >>)) *	5C))!%g  !67"
 "%0 ?M155mRHH-5 ?)	!%77$("%v~~dC'@"@@.226:#*?? (7@7H ? 3	8'.w	'B#'<$)'1$'?*4*KI=Xo(p+& %& (-Xt'<$)? '*6>>$+D&D D 2 6 6v >+??8 \\%%+&78 CLL<L<L=F !'&-*N6>>$444U*	5
s*   )GGGC9G?A+G,G;Gc                B   K   | j                  |       d{    y7 w)zWCalled to process an event.

        Args:
            event: An Event object.
        N)r-  r   r  s     r:   r+  zMessagePump.on_event  s      u%%%s   c                  K   d}|j                   }d}| j                  ||      D ]]  \  }}t        j                  j	                  |j
                        |d| d|j                   d| d       d}t        ||       d{    _ |s1t        j                  j	                  |j
                        |d| d       |j                  r| j                  rx|j                  sk|j                  )|j                  | j                  k(  r|j                          | j                  r)| j                  r|j                  | j                         yyyyyy7 ˭w)	z[Called to process a message.

        Args:
            message: A Message object.
        TFz>>>r&  r'  r(  Nzmethod=None)r/  r  r   r  	verbosityverboser5   r   bubblerl   _stop_propagationr   stopr   r   
_bubble_to)r   r   r  r/  
dispatchedrT   r   s          r:   r-  zMessagePump._on_message!  s*     !%++ 
55lGL 	*KCII03<<.,q9	 J)))	* II0%}U >>dll73L3L*w$,,/N$$)9)9""4<<0 *:$	 4Ml> *s   A<E>E
?CEc                    | j                   r?| j                  j                         r$| j                  t	        j
                                yyy)z;Prompt the message pump to call idle if the queue is empty.N)rm   r   r  r   r   Promptr   s    r:   r   zMessagePump.check_idle@  s6    ==T00668hoo/0 9=r9   c                ,   K   | j                  |      S w)at  Post a message or an event to this message pump.

        This is an internal method for use where a coroutine is required.

        Args:
            message: A message object.

        Returns:
            True if the messages was posted successfully, False if the message was not posted
                (because the message pump was in the process of closing).
        )r   r   s     r:   _post_messagezMessagePump._post_messageE  s        ))s   c                   d}t        |d      st        d      | j                  s| j                  ry| j	                  |      sy|j
                  j                  | j                                | j                  t        j                         k7  rS| j                  j                  =| j                  j                  }|j                  | j                  j                  |       y| j                  j                  |       y)zPosts a message on to this widget's queue.

        Args:
            message: A message (including Event).

        Returns:
            `True` if the message was queued for processing, otherwise `False`.
        Tr   zJMessage is missing attributes; did you forget to call super().__init__() ?F)rJ   RuntimeErrorrn   ro   r   r   r   r   r{   ry   rz   r   _loopcall_soon_threadsafer   r   )r   r   _rich_traceback_omitloops       r:   r   zMessagePump.post_messageS  s      $w
+\  ==DLL))'2 	 < < >???i11338R88>>D%%d&9&9&D&DgN  **73r9   c                  K   | j                   j                  ry 	 | j                   j                   t        |j                         d {    y # t        $ r, | j                  j                  d|j                  d       Y y w xY w7 =w)NNot invoking timer callback  because there is no screen.)r   rn   r   r  r   r.  r   r   rB  s     r:   on_callbackzMessagePump.on_callbackq  sy     88	HHOO U^^$$$  	HH.u~~.@@\] 		
 	%s3   B	A B		B
B	2BB	BB	c                  K   | j                   j                  sy |j                          |j                          |j                  6	 | j                   j
                   	 t        |j                         d {    y y # t        $ r, | j                  j                  d|j                  d       Y y w xY w7 ># t        $ r }t        d|j                  d|       d }~ww xY ww)NrV  rW  zunable to run callback z; )r   rm   prevent_defaultrH  r   r   r  r   r.  r   r3   )r   r  r  s      r:   on_timerzMessagePump.on_timer}  s     xx  

>>%U^^,,, &    25>>2DD`a 	 - #-enn-?r%I sZ   AC#A= B7 6B57B7 ;C#=2B2/C#1B22C#5B7 7	C  CC  C#r   )r   zMessagePump | Nonere   None)re   zQueue[Message | None])re   zasyncio.Event)re   zlist[set[type[Message]]])re   zset[type[Message]])r\   type[Message]re   r   )r   r]  re   Generator[None, None, None])re   r   )re   r   )re   int)re   z'App[object]')re   r   )r   ri   re   r\  )re   r\  )r   r'   re   r   )r   r]  re   r\  )re   r'   )re   zMessage | None)
r   floatr   TimerCallback | NonerU   
str | Noner   r   re   r+   )r   r`  r   ra  rU   rb  r   r_  r   r   re   r+   )r   r1   r   r   rX   r   re   r   )r   r1   r   r   rX   r   re   r\  )r   zmessages.InvokeLaterre   r\  )T)r   r   re   r\  )re   r^  )r   zmessages.CloseMessagesre   r\  )r   r'   re   r\  )r9  rd   r   r'   re   z5Iterable[tuple[type, Callable[[Message], Awaitable]]])r  zevents.Eventre   r\  )r  zevents.Callbackre   r\  )r  zevents.Timerre   r\  )>r5   r6   r7   rf   r   r   r   r   propertyr|   r   r   r   r   r   r   r   r   r   r   textualr   r   r/   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r   r  r   r  r  r  r+  r-  r   rN  r   rX  r[  r8   r9   r:   ri   ri   s   s   38      5
E  (   ( ( + +   #kk# 
	 
	.   W W
      
<1<*2 *.&
  && '&
 & & 
&V *.
   '
    
B*$**",
 .:68A 3 3%;7z
"3H9595)095	>95v&1>1
*<
%r9   ri   )	metaclass)Orf   
__future__r   r   ry   r   r   r   r   
contextlibr   	functoolsr	   r#   r
   typingr   r   r   r   r   r   r   r   r   weakrefr   rd  r   r   r   r   textual._callbackr   textual._compatr   textual._contextr   r   r   r   r*  r   textual._onr    textual._queuer"   textual._timetextual.constantsr$   textual.css.matchr%   textual.eventsr&   textual.messager'   textual.reactiver(   r)   textual.signalr*   textual.timerr+   r,   typing_extensionsr-   r   r/   textual.css.modelr0   r1   __annotations__r  r3   r=   r>   r   r?   ri   r8   r9   r:   <module>r{     s    #   A A %  
 
 
  1 1 $ + N N E 8 "    , #   # ; ! .+- K) J	I 			 	 3;MN *t *Z\, \r9   