o
    ZhK                     @   st  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d ZddddddddZd	d
 Zdd Zeddddd ZeZejdd Zdd Zeddd Zejdd Zeddd Zejdd Zed d!d" Zejd#d$ Zed%d&d' Zejd(d) Zed*d+d, Zejd-d. Zed/d0d1 Zejd2d3 Z d4d5 Z!d6d7 Z"d:d8d9Z#dS );z4Event loop integration for the ZeroMQ-based kernels.    N)partial)Version)Applicationc                   C   s"   t jdkott 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 r
   r
   K/var/www/html/lang_env/lib/python3.10/site-packages/ipykernel/eventloops.py_use_appnope   s   "r   )inlineZnbaggZwebaggnotebookZipymplZwidgetNc                     s    fd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                    s2   D ]} t |< qdd  _ fdd}| _ S )z#Integration registration decorator.c                 S   s   d S Nr
   kernelr
   r
   r   <lambda>7   s    z9register_integration.<locals>.decorator.<locals>.<lambda>c                    s
   |  _ | S )zc@func.exit is now a decorator

            to register a function to be called on exit
            )	exit_hook)Z	exit_funcfuncr
   r   exit_decorator9   s   z?register_integration.<locals>.decorator.<locals>.exit_decorator)loop_mapr   exit)r   namer   toolkitnamesr   r   	decorator2   s   

z'register_integration.<locals>.decoratorr
   )r   r   r
   r   r   register_integration$   s   r   c                    s   dd l ddlm} ddlm  zddlm W n ty,   |d  fddY nw fddfd	d
}tds[j	t
j} |djjj_jj| njd  fdd}|t_ jd| d S )Nr   )	lru_cacheQtCore)enum_helperc                    s     | dd tj j S )N.r   )
attrgetter
rpartitionr   modules__package__)r   )r    operatorr
   r   r!   Q   s    z&_notify_stream_qt.<locals>.enum_helperc                      s    j d  jj  dS )fall back to main loopFN)_qt_notifier
setEnabledappqt_event_loopquitr
   r   r
   r   	exit_loopU   s   z$_notify_stream_qt.<locals>.exit_loopc                         j jddr   dS dS z2fall back to main loop when there's a socket event   limitNshell_streamflushr
   r.   r   r
   r   process_stream_eventsZ   s   
z0_notify_stream_qt.<locals>.process_stream_eventsr)   zQtCore.QSocketNotifier.TypeTc                    s\   t ds" j_jd jdj jj j	t
d|   dS )2schedule fall back to main loop in [delay] seconds	_qt_timerTzQtCore.Qt.TimerType  N)hasattrQTimerr+   r:   ZsetSingleShotZsetTimerTypeZPreciseTimertimeoutconnectstartintdelay)r    r!   r.   r   r
   r   _schedule_exitn   s   
z)_notify_stream_qt.<locals>._schedule_exit)r'   	functoolsr   IPython.external.qt_for_kernelr    r!   ImportErrorr<   r5   
getsockoptzmqFDZQSocketNotifierZReadr+   r,   r)   Z	activatedr?   r*   loop_qtrD   r=   Z
singleShot)r   r   r8   fdrD   r
   )r    r!   r.   r   r'   r   _notify_stream_qtG   s*   
		rM   qtqt5qt6c                 C   sL   t |  d| j_| jj}t|dr| n
|  d| j_dS  d| j_dS )z,Event loop for all supported versions of Qt.TexecFN)rM   r+   _in_event_loopr,   r<   rQ   exec_)r   elr
   r
   r   rK      s   rK   c                 C   s   | j   d S r   )r+   r   r   r
   r
   r   loop_qt_exit   s   rU   c                 C   s   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)rR   ZMainLoop)r+   r
   r
   r   _loop_wx   s   
rV   wxc                    s   ddl tdj fddG fdddj G  fdd	d	j}td
dr6tjjs<|dd_ddl}t	|
|jsP||j|j tj dS )z*Start a kernel with wx event loop support.r   Nr;   c                      s     j jddr j  dS dS )zwake from wxr1   r2   N)r5   r6   r+   ZExitMainLoopr
   r   r
   r   wake   s   
zloop_wx.<locals>.wakec                       s"   e Zd Z fddZdd ZdS )zloop_wx.<locals>.TimerFramec                    sB   j | d d | | _| j  | j| j || _d S )N)	Frame__init__TimertimerZStartZBindZ	EVT_TIMERon_timerr   )selfr   poll_intervalrW   r
   r   r[      s
   
z$loop_wx.<locals>.TimerFrame.__init__c                 S   s   |    d S r   r   )r_   eventr
   r
   r   r^      s   z$loop_wx.<locals>.TimerFrame.on_timerN)__name__
__module____qualname__r[   r^   r
   r`   r
   r   
TimerFrame   s    rf   c                       s   e Zd Z fddZdS )zloop_wx.<locals>.IPWxAppc                    s    | _ | j d dS )NFT)frameZShowr_   rf   rX   r
   r   OnInit   s   
zloop_wx.<locals>.IPWxApp.OnInitN)rc   rd   re   rj   r
   ri   r
   r   IPWxApp   s    rk   r+   F)redirect)rW   rA   _poll_intervalrZ   ZAppgetattr
isinstancer+   signalcallable	getsignalSIGINTdefault_int_handlerrV   )r   rk   rp   r
   )rf   r   ra   rX   rW   r   loop_wx   s   ru   c                 C   s   ddl }|  dS )zExit the wx loop.r   N)rW   ZExit)r   rW   r
   r
   r   loop_wx_exit   s   rv   tkc           	         s   ddl m}m} |  t drMG dd d} fddfdd	} fd
d}|t_| _ jj	
tj||  d|    dS ddlddl}|  j}tdj G fddd}| |_j  dS )z&Start a kernel with the Tk event loop.r   )READABLETkcreatefilehandlerc                   @   s   e Zd Zdd ZdS )z loop_tk.<locals>.BasicAppWrapperc                 S   s   || _ | j   d S r   )r+   withdraw)r_   r+   r
   r
   r   r[      s   z)loop_tk.<locals>.BasicAppWrapper.__init__N)rc   rd   re   r[   r
   r
   r
   r   BasicAppWrapper   s    r|   c                      s.    j jtj       `dS )r(   N)	rw   Zdeletefilehandlerr5   rH   rI   rJ   r-   destroyapp_wrapperr
   )r+   r   r
   r   r.      s   zloop_tk.<locals>.exit_loopc                     r/   r0   r4   )akwr7   r
   r   r8      s   
z&loop_tk.<locals>.process_stream_eventsc                    s     td|   dS )r9   r;   N)afterrA   rB   )r+   r.   r
   r   rD     s   zloop_tk.<locals>._schedule_exitNr;   c                       s,   e Zd Zdd Z fddZdd ZdS )z loop_tk.<locals>.TimedAppWrapperc                 S   s   || _ | j   || _d S r   )r+   r{   r   )r_   r+   r   r
   r
   r   r[   #  s   

z)loop_tk.<locals>.TimedAppWrapper.__init__c                    sN      }z	||   W n ty   jd Y nw | j| j d S )NzError in message handler)	get_event_looprun_until_completer   	Exceptionlog	exceptionr+   r   r^   )r_   loopasyncior   ra   r
   r   r^   (  s   z)loop_tk.<locals>.TimedAppWrapper.on_timerc                 S   s   |    | j  d S r   )r^   r+   mainlooprh   r
   r
   r   r@   0  s   z&loop_tk.<locals>.TimedAppWrapper.startN)rc   rd   re   r[   r^   r@   r
   r   r
   r   TimedAppWrapper"  s    r   )tkinterrx   ry   r<   loop_tkrD   r~   rw   rz   r5   rH   rI   rJ   r   r   r   nest_asyncioapplyZdo_one_iterationrA   rm   r@   )	r   rx   ry   r|   r8   rD   r   Zdoir   r
   )r+   r   r.   r   ra   r   r      s,   

r   c              	   C   s0   z| j j  | ` W dS  ttfy   Y dS w )zExit the tk loop.N)r~   r+   r}   RuntimeErrorAttributeErrorr   r
   r
   r   loop_tk_exit8  s   
r   Zgtkc                 C   &   ddl m} || }|  || _dS z6Start the kernel, coordinating with the GTK event loopr1   )GTKEmbedN)Zgui.gtkembedr   r@   _gtkr   r   Z
gtk_kernelr
   r
   r   loop_gtkB     
r   c                 C      | j   dS )zExit the gtk loop.Nr   stopr   r
   r
   r   loop_gtk_exitL     r   Zgtk3c                 C   r   r   )Zgui.gtk3embedr   r@   r   r   r
   r
   r   	loop_gtk3R  r   r   c                 C   r   )zExit the gtk3 loop.Nr   r   r
   r
   r   loop_gtk3_exit\  r   r   Zosxc                    s   ddl m}m tj  fdd}| jjs[z:z$z|t_|| j | jj	ddr0W W W  t_dS W n t
y9    w W n tyK   tdtjd Y nw W  t_n t_w | jjrdS dS )	znStart the kernel, coordinating with the Cocoa CFRunLoop event loop
    via the matplotlib MacOSX backend.
    r1   )r   r   c                    s0     | t u rtdtjd dS  | || dS )z.don't let KeyboardInterrupts look like crashesz%KeyboardInterrupt caught in CFRunLoopfileN)KeyboardInterruptprintr   
__stdout__)etypevaluetbZreal_excepthookr   r
   r   
handle_intk  s   zloop_cocoa.<locals>.handle_intr2   Nz"KeyboardInterrupt caught in kernelr   )_eventloop_macosr   r   r   
excepthookshellZexit_nowrm   r5   r6   BaseExceptionr   r   r   )r   r   r   r
   r   r   
loop_cocoab  s,   	

r   c                 C   s   ddl m} |  dS )zExit the cocoa loop.r1   )r   N)r   r   )r   r   r
   r
   r   loop_cocoa_exit  s   
r   r   c              
      s   ddl }|    rdS   r|  |  d _ fdd}t|| j} 	| j
tj|  | 	 d}z   W n tyL   Y q: ty_ } z|}W Y d}~nd}~ww  jrg   |durm|dS )z/Start a kernel with asyncio event loop support.r   NFc                    s   | j ddr   dS dS r0   )r6   r   )streamr   r
   r   r8     s   z+loop_asyncio.<locals>.process_stream_events)r   r   
is_running	is_closednew_event_loopset_event_loop_should_closer   r5   
add_readerrH   rI   rJ   	call_soonrun_foreverr   r   close)r   r   r8   Znotifiererrorer
   r   r   loop_asyncio  s6   

r   c                    sP   ddl }|   fdd}  r|  dS   s& |    dS dS )zExit hook for asyncior   Nc                     s(   t  dr  V  d _   d S )Nshutdown_asyncgensT)r<   r   r   r   r
   r   r
   r   
close_loop  s
   

z%loop_asyncio_exit.<locals>.close_loop)r   r   r   r   r   r   )r   r   r   r
   r   r   loop_asyncio_exit  s   

r   c                 C   s  t jdd}ddlm}m}m}m}m} | }|d|d|d|di}|dur<| dkr<|| | kr<t	d||  d	 dS |durX| dkrX|| | krWt	d
|  d| d dS n~| dkrzddl
}	dt jd< W nn ty   zddl}
dt jd< W n ty   dt jd< Y nw Y nLw | dkrzddl}dt jd< W n; ty   zddl}dt jd< W n ty   dt jd< Y nw Y nw | dkrdt jv rt jd= n
t	d|  d dS zW dS  ty } zdt jv rt jd= t	d|  W Y d}~dS d}~w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.
    ZQT_APINr   )QT_API_PYQT5QT_API_PYQT6QT_API_PYSIDE2QT_API_PYSIDE6
loaded_apirO   rP   rN   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 ""Zpyqt5Zpyside2Zpyqt6Zpyside6zUnrecognized Qt version: z". Should be "qt5", "qt6", or "qt".z$QT_API couldn't be set due to error )osenvirongetZIPython.external.qt_loadersr   r   r   r   r   r   PyQt5rG   PySide2PyQt6PySide6r   )guiZqt_apir   r   r   r   r   ZloadedZ
qt_env2guir   r   r   r   r   r
   r
   r   set_qt_api_env_from_gui  sz   

r   c                 C   sN   t |drdS t|  ddlm} ddlm} |dg|_||j|j_dS )z?Sets the `QT_API` environment variable if it isn't already set.r+   Nr   r   )get_app_qt4 )	r<   r   rF   r    ZIPython.lib.guisupportr   r+   Z
QEventLoopr,   )r   r   r    r   r
   r
   r   make_qt_app_for_kernel+  s   
r   c                 C   s   | t vrd| dt   }t||du r,t r"tt dd}|du r,d}t|| du rOt|dr:t	|d t|drDt	|d t|drNt	|d n
| 
d	rYt| | t |  }|ro|jduro|j|urod
}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+   r)   r:   rN   z'Cannot activate multiple GUI eventloops)r   keys
ValueErrorr   Zinitializedrn   instancer   r<   delattr
startswithr   Z	eventloop)r   r   r   msgr   r
   r
   r   
enable_gui<  s6   








r   r   )$__doc__r   r   r   rE   r   rI   Zpackaging.versionr   r   Ztraitlets.config.applicationr   r   r   r   rM   rK   Zloop_qt5r   rU   rV   ru   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   r
   r
   r
   r   <module>   sh    
#
@


4

O
	
	

	

&

(
\