
    xdF                        d Z ddlZddlZddlZddlmZ ddlZddlmZ	 ddl
mZ d ZddddddddZd Zd	 Z ed
dd          d             ZeZej        d             Zd Z ed          d             Zej        d             Z ed          d             Zej        d             Z ed          d             Zej        d             Z ed          d             Zej        d             Z ed          d             Zej        d             Z ed          d              Zej        d!             Z d" Z!d# Z"d%d$Z#dS )&z4Event loop integration for the ZeroMQ-based kernels.    N)partial)Version)Applicationc                      t           j        dk    o6t          t          j                    d                   t          d          k    S )zhShould we use appnope for dealing with OS X app nap?

    Checks if we are on OS X 10.9 or greater.
    darwinr   z10.9)sysplatformVmac_ver     4lib/python3.11/site-packages/ipykernel/eventloops.py_use_appnoper      s7    
 <8#M(*:*<*<Q*?(@(@AfII(MMr   )inlinenbaggwebaggnotebookipymplwidgetNc                        fd}|S )a0  Decorator to register an event loop to integrate with the IPython kernel

    The decorator takes names to register the event loop as for the %gui magic.
    You can provide alternative names for the same toolkit.

    The decorated function should take a single argument, the IPython kernel
    instance, arrange for the event loop to call ``kernel.do_one_iteration()``
    at least every ``kernel._poll_interval`` seconds, and start the event loop.

    :mod:`ipykernel.eventloops` provides and registers such functions
    for a few common event loops.
    c                 P     D ]} t           |<   d  _         fd}| _         S )z#Integration registration decorator.c                     d S Nr   kernels    r   <lambda>z9register_integration.<locals>.decorator.<locals>.<lambda>7   s     r   c                     | _         | S )zc@func.exit is now a decorator

            to register a function to be called on exit
            )	exit_hook)	exit_funcfuncs    r   exit_decoratorz?register_integration.<locals>.decorator.<locals>.exit_decorator9   s    
 'DNr   )loop_mapr   exit)r    namer!   toolkitnamess   `  r   	decoratorz'register_integration.<locals>.decorator2   sO      	" 	"D!HTNN,,	 	 	 	 	 #	r   r   )r%   r&   s   ` r   register_integrationr'   $   s$        $ r   c                     dd l ddlm} ddlm 	 ddlm} n'# t          $ r  |d           fd            }Y nw xY w fd}t           d          sx j        	                    t          j                  }                    | |d          j         j        j                   _         j        j                            |           n j                            d	           t           d
          sX                     j                   _         j                            d	            j        j                            |            j                            d           d S )Nr   )	lru_cache)QtCore)enum_helperc                                           |                     d          d                   t          j        j                           S )N.r   )
attrgetter
rpartitionr   modules__package__)r$   r*   operators    r   r+   z&_notify_stream_qt.<locals>.enum_helperQ   s<    ?8&&ts';';A'>??FL^@_```r   c                       j                             d          r: j                            d            j        j                                         dS dS )2fall back to main loop when there's a socket event   limitFN)shell_streamflush_qt_notifier
setEnabledappqt_event_loopquitr   s   r   process_stream_eventsz0_notify_stream_qt.<locals>.process_stream_eventsU   s_     $$1$-- 	,**5111J$))+++++	, 	,r   r:   zQtCore.QSocketNotifier.TypeT	_qt_timer)r2   	functoolsr)   IPython.external.qt_for_kernelr*   r+   ImportErrorhasattrr8   
getsockoptzmqFDQSocketNotifierReadr<   r=   r:   	activatedconnectr;   QTimerr@   setSingleShottimeoutstart)r   r)   r+   r?   fdr*   r2   s   `    @@r   _notify_stream_qtrQ   G   s   OOO######555555a>>>>>>> a a a	4	a 	a 	a 	a 	a 
	a 	a 	aa, , , , , 6>** - ++CF33$449::?AY
 
 	%--.CDDDD&&t,,, 6;'' @!==44&&t,,, (()>???
1s    !A A qtqt5qt6c                     t          |            d| j        _        | j        j        }t	          |d          r|                                n|                                 d| j        _        dS )z,Event loop for all supported versions of Qt.TexecFN)rQ   r<   _in_event_loopr=   rD   rV   exec_)r   els     r   loop_qtrZ   v   sa     f !%FJ 
	!BV$$4BGGIII"((** %FJr   c                 8    | j                                          d S r   )r<   r#   r   s    r   loop_qt_exitr\      s    
JOOr   c                 J    d| _         |                                  d| _         dS )zInner-loop for running the Wx eventloop

    Pulled from guisupport.start_event_loop in IPython < 5.2,
    since IPython 5.2 only checks `get_ipython().active_eventloop` is defined,
    rather than if the eventloop is actually running.
    TFN)rW   MainLoop)r<   s    r   _loop_wxr_      s'     CLLNNNCr   wxc                     ddl t          d j        z             fd G fddj                   G fddj                  }t           d	d          rt           j        j                  s |d
           _        ddl}t          |
                    |j                            s |                    |j        |j                   t           j                   dS )z*Start a kernel with wx event loop support.r   N  c                  t     j                             d          r j                                         dS dS )zwake from wxr5   r6   N)r8   r9   r<   ExitMainLoopr   s   r   wakezloop_wx.<locals>.wake   sB    $$1$-- 	J##%%%F	 	r   c                   "    e Zd Z fdZd ZdS )loop_wx.<locals>.TimerFramec                     j                             | d d                               |           | _        | j                                       |                     j        | j                   || _        d S )N)	Frame__init__TimertimerStartBind	EVT_TIMERon_timerr    )selfr    poll_intervalr`   s     r   rk   z$loop_wx.<locals>.TimerFrame.__init__   sg    HdD"---$DJJ]+++IIblDM222DIIIr   c                 .    |                                   d S r   )r    )rr   events     r   rq   z$loop_wx.<locals>.TimerFrame.on_timer   s    IIKKKKKr   N)__name__
__module____qualname__rk   rq   )rs   r`   s   r   
TimerFramerg      sB        	 	 	 	 	 		 	 	 	 	r   ry   c                       e Zd Z fdZdS )loop_wx.<locals>.IPWxAppc                 \               | _         | j                             d           dS )NFT)frameShow)rr   ry   re   s    r   OnInitzloop_wx.<locals>.IPWxApp.OnInit   s-    #D))DJJOOE"""4r   N)rv   rw   rx   r   )ry   re   s   r   IPWxAppr{      s3        	 	 	 	 	 	 	 	r   r   r<   F)redirect)r`   int_poll_intervalrj   Appgetattr
isinstancer<   signalcallable	getsignalSIGINTdefault_int_handlerr_   )r   r   r   ry   rs   re   r`   s   `  @@@@r   loop_wxr      sR    III v4455M    
 
 
 
 
 
 
 
RX 
 
 
       "&    FE4(( -Z
BF-K-K -We,,,

 MMMF$$V]3344 AfmV%?@@@VZr   c                 6    ddl }|                                 dS )zExit the wx loop.r   N)r`   Exit)r   r`   s     r   loop_wx_exitr      s     IIIGGIIIIIr   tkc                    	
 ddl m}m}  |            	t          	d          r G d d          }	 fd} |	           _        t          | j                  }d|_        	j        	                     j        
                    t          j                  ||           	                    d|           	                                 dS ddl
ddl}|                                  j        }t'          d	 j        z             G 
 fd
d          } |	|           _         j                                         dS )z&Start a kernel with the Tk event loop.r   )READABLETkcreatefilehandlerc                       e Zd Zd ZdS ) loop_tk.<locals>.BasicAppWrapperc                 F    || _         | j                                          d S r   )r<   withdraw)rr   r<   s     r   rk   z)loop_tk.<locals>.BasicAppWrapper.__init__   s#    !!#####r   N)rv   rw   rx   rk   r   r   r   BasicAppWrapperr      s#        $ $ $ $ $r   r   c                     |                      d          rcj                            |                     t          j                                                                                               `dS dS r4   r5   r6   N)	r9   r   deletefilehandlerrE   rF   rG   r>   destroyapp_wrapper)streamakwr<   r   s      r   r?   z&loop_tk.<locals>.process_stream_events   so    ||!|$$ '(():):36)B)BCCC


&&&	' 'r   notifierNrb   c                   *    e Zd Zd Z fdZd ZdS ) loop_tk.<locals>.TimedAppWrapperc                 T    || _         | j                                          || _        d S r   )r<   r   r    )rr   r<   r    s      r   rk   z)loop_tk.<locals>.TimedAppWrapper.__init__  s(    !!### 			r   c                                                     }	 |                    |                                            n*# t          $ r j                            d           Y nw xY w| j                            | j                   d S )NzError in message handler)	get_event_looprun_until_completer    	Exceptionlog	exceptionr<   afterrq   )rr   loopasyncior   rs   s     r   rq   z)loop_tk.<locals>.TimedAppWrapper.on_timer  s    --//E++DIIKK8888  E E EJ(()CDDDDDE}dm<<<<<s   '? $A&%A&c                 `    |                                   | j                                         d S r   )rq   r<   mainloop)rr   s    r   rO   z&loop_tk.<locals>.TimedAppWrapper.start  s)    !!#####r   N)rv   rw   rx   rk   rq   rO   )r   r   rs   s   r   TimedAppWrapperr     sV        ! ! !
= = = = = = =$ $ $ $ $r   r   )tkinterr   r   rD   r   r   r8   rv   r   r   rE   rF   rG   r   r   r   nest_asyncioapplydo_one_iterationr   r   rO   )r   r   r   r   r?   r   r   doir   r<   r   rs   s   `        @@@r   loop_tkr      s    %$$$$$$$
"$$C s'(( 9#	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$
	' 	' 	' 	' 	' 	' -_S110&2EFF&  !4!?!?!G!GS[\\\		!X 	%D6#8899	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$$ -_S#66  """""r   c                 x    	 | j         j                                         | ` dS # t          t          f$ r Y dS w xY w)zExit the tk loop.N)r   r<   r   RuntimeErrorAttributeErrorr   s    r   loop_tk_exitr     sR    &&(((.)   s    $ 99gtkc                 ^    ddl m}  ||           }|                                 || _        dS z6Start the kernel, coordinating with the GTK event loopr5   )GTKEmbedN)gui.gtkembedr   rO   _gtkr   r   
gtk_kernels      r   loop_gtkr   '  sB     '&&&&&&!!JFKKKr   c                 8    | j                                          dS )zExit the gtk loop.Nr   stopr   s    r   loop_gtk_exitr   1       Kr   gtk3c                 ^    ddl m}  ||           }|                                 || _        dS r   )gui.gtk3embedr   rO   r   r   s      r   	loop_gtk3r   7  sB     ('''''&!!JFKKKr   c                 8    | j                                          dS )zExit the gtk3 loop.Nr   r   s    r   loop_gtk3_exitr   A  r   r   osxc                    ddl m}m t          j        fd}| j        j        s	 	 |t          _         || j                   | j        	                    d          r	 t          _        dS n# t          $ r  w xY wn+# t          $ r t          dt          j                   Y nw xY wt          _        n# t          _        w xY w| j        j        dS dS )znStart the kernel, coordinating with the Cocoa CFRunLoop event loop
    via the matplotlib MacOSX backend.
    r5   )r   r   c                                   | t           u rt          dt          j                   dS  | ||           dS )z.don't let KeyboardInterrupts look like crashesz%KeyboardInterrupt caught in CFRunLoopfileN)KeyboardInterruptprintr   
__stdout__)etypevaluetbreal_excepthookr   s      r   
handle_intzloop_cocoa.<locals>.handle_intP  sR     	%%%9OOOOOOOE5"-----r   r6   Nz"KeyboardInterrupt caught in kernelr   )_eventloop_macosr   r   r   
excepthookshellexit_nowr   r8   r9   BaseExceptionr   r   r   )r   r   r   r   r   s      @@r   
loop_cocoar   G  sJ   
 10000000nO. . . . . . l# -	-!+.///&,,1,55  -CNNN !   
 ! 	M 	M 	M6S^LLLLLL	M
 -CNN_CN,,,,% l# - - - - -s;   7A2 1B 2A>>B B: %B*'B: )B**B: :Cc                 &    ddl m}  |             dS )zExit the cocoa loop.r5   )r   N)r   r   )r   r   s     r   loop_cocoa_exitr   n  s%     '&&&&&DFFFFFr   r   c                 r   ddl }|                                                                rdS                                 r)|                                |                               d_        fd}t          || j                  }	                    | j        
                    t          j                  |                               |           	 d}	                                  n$# t          $ r Y %t           $ r}|}Y d}~nd}~ww xY wj        r                                 ||dS )z/Start a kernel with asyncio event loop support.r   NFc                 `    |                      d          r                                 dS dS r   )r9   r   )r   r   s    r   r?   z+loop_asyncio.<locals>.process_stream_events  s4    <<a<   	IIKKKKK	 	r   )r   r   
is_running	is_closednew_event_loopset_event_loop_should_closer   r8   
add_readerrE   rF   rG   	call_soonrun_foreverr   r   close)r   r   r?   r   errorer   s         @r   loop_asyncior   v  sm    NNN!!##D ~~ %%%''t$$$D    
 ,f.ABBHOOF'2236::HEEENN8	  	 	 	H 	 	 	EEEEEE	 	JJLLLKs   C4 4
D 	D	DDc                     ddl }|                                fd}                                r |             dS                                 s+                    |                                            dS dS )zExit hook for asyncior   Nc                    K   t           d          r                                 W V  d _                                          d S )Nshutdown_asyncgensT)rD   r   r   r   )r   s   r   
close_loopz%loop_asyncio_exit.<locals>.close_loop  sN      4-.. 	,))++++++!		r   )r   r   r   r   r   r   )r   r   r   r   s      @r   loop_asyncio_exitr     s     NNN!!##D      
^^ 
+++

 r   c                    t           j                            dd          }ddlm}m}m}m}m}  |            }|d|d|d|di}|-| dk    r'||         | k    rt          d||          d	           dS |+| dk    r%||         | k    rt          d
|  d| d           dS n| dk    rY	 ddl
}	dt           j        d<   n# t          $ r7 	 ddl}
dt           j        d<   n# t          $ r dt           j        d<   Y nw xY wY nw xY w| dk    rY	 ddl}dt           j        d<   n{# t          $ r7 	 ddl}dt           j        d<   n# t          $ r dt           j        d<   Y nw xY wY n;w xY w| dk    rdt           j        v rt           j        d= nt          d|  d           dS 	 ddlm}m} dS # t$          $ r8}dt           j        v rt           j        d= t          d|            Y d}~dS d}~ww xY w)a  
    Sets the QT_API environment variable by trying to import PyQtx or PySidex.

    The user can generically request `qt` or a specific Qt version, e.g. `qt6`.
    For a generic Qt request, we let the mechanism in IPython choose the best
    available version by leaving the `QT_API` environment variable blank.

    For specific versions, we check to see whether the PyQt or PySide
    implementations are present and set `QT_API` accordingly to indicate to
    IPython which version we want. If neither implementation is present, we
    leave the environment variable set so IPython will generate a helpful error
    message.

    Notes
    -----
    - If the environment variable is already set, it will be used unchanged,
      regardless of what the user requested.
    QT_APINr   )QT_API_PYQT5QT_API_PYQT6QT_API_PYSIDE2QT_API_PYSIDE6
loaded_apirS   rT   rR   z9Cannot switch Qt versions for this session; you must use r-   zRequest for "zC" will be ignored because `QT_API` environment variable is set to ""pyqt5pyside2pyqt6pyside6zUnrecognized Qt version: z". Should be "qt5", "qt6", or "qt".r*   QtGuiz$QT_API couldn't be set due to error )osenvirongetIPython.external.qt_loadersr   r   r   r   r   r   PyQt5rC   PySide2PyQt6PySide6rB   r*   r  r   )guiqt_apir   r   r   r   r   loaded
qt_env2guir
  r  r  r  r*   r  r   s                   r   set_qt_api_env_from_guir    s	   & Z^^Hd++F              Z\\F 	ee	J cTkkj.@C.G.G_*U[J\___```cTkkf$$= = =39= = =   F % %<<
3'.
8$$ 3 3 33"NNN+4BJx((" 3 3 3+2BJx(((33 E\\
3'.
8$$ 3 3 33"NNN+4BJx((" 3 3 3+2BJx(((33 D[[2:%%Jx(UcUUUVVVF@@@@@@@@@@   rz!!
8$<<<===s   &B: :
C;CC;C52C;4C55C;:C;D 
E$D87E8EEEEEF 
G!)-GG!c                 6   t          |d          rdS t          |            ddlm}m} ddlm}  |dg          |_        t          |j        |j	                  r|j        
                    d           |                    |j                  |j        _        dS )z?Sets the `QT_API` environment variable if it isn't already set.r<   Nr   r  )get_app_qt4 F)rD   r  rB   r*   r  IPython.lib.guisupportr  r<   r   QApplicationsetQuitOnLastWindowClosed
QEventLoopr=   )r  r   r*   r  r  s        r   make_qt_app_for_kernelr    s    vu  	C    =<<<<<<<222222cU##FJ&*e011 4
,,U333%00<<FJr   c                    | t           vr.d| dt                                            }t          |          |Ht          j                    r"t          t          j                    dd          }|d}t          |          | !t          |d          rt          |d           n%| 
                    d          rt          | |           t           |          }|r!|j        |j        |urd}t          |          ||_        dS )	z#Enable integration with a given GUIzInvalid GUI request z, valid ones are:Nr   z\You didn't specify a kernel, and no IPython Application with a kernel appears to be running.r<   rR   z'Cannot activate multiple GUI eventloops)r"   keys
ValueErrorr   initializedr   instancer   rD   delattr
startswithr  	eventloop)r  r   r   msgr   s        r   
enable_guir$  $  s   
(L3LL8==??LLmm~"$$ 	E[133XtDDF>S  s###
{65!! 	#FE""">>$ 	0"3///C=D   ,1A1M1M73Fr   r   )$__doc__r  r	   r   rA   r   rF   packaging.versionr   r
   traitlets.config.applicationr   r   r"   r'   rQ   rZ   loop_qt5r#   r\   r_   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r$  r   r   r   <module>r)     s   : :
 
			  



       



 * * * * * * 4 4 4 4 4 4N N N 
      F, , ,^ dE5))
& 
& *)
&  	  	 	 	 d1 1 1h 	   dB# B# B#J 	   e   
  
 f     
 e#- #- #-L    i  % % ! %P   (Y Y Yx= = =(     r   