o
    iO                     @   s~  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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.d/ Zejd0d1 Zed2d3d4 Z e jd5d6 Z!d7d8 Z"d9d: Z#d=d;d<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
   O/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/ipykernel/eventloops.py_use_appnope   s   "r   )inlinenbaggwebaggnotebookipymplwidgetNc                     s    fdd}|S )ac  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 yield the asyncio loop when a
    message is received by the main shell zmq stream or 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>8   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)	exit_funcfuncr
   r   exit_decorator:   s   z?register_integration.<locals>.decorator.<locals>.exit_decorator)loop_mapr   exit)r   namer   toolkitnamesr   r   	decorator3   s   

z'register_integration.<locals>.decoratorr
   )r    r!   r
   r   r   register_integration$   s   r"   c                 C   s$   | j r| jj}|d }|jS | jS r   )_supports_kernel_subshellsshell_channel_threadmanager"get_shell_channel_to_subshell_pair	to_streamshell_stream)r   r%   socket_pairr
   r
   r   get_shell_streamH   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}t||}t	dsb|
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.   [   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_loop_   s   z$_notify_stream_qt.<locals>.exit_loopc                       | j ddr   dS dS z2fall back to main loop when there's a socket event   limitNflush)r(   argskwargsr;   r
   r   process_stream_events_wrapd   s   
z5_notify_stream_qt.<locals>.process_stream_events_wrapr6   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QTimerr8   rH   setSingleShotsetTimerTypePreciseTimertimeoutconnectstartintdelay)r-   r.   r;   r   r
   r   _schedule_exit{   s   
z)_notify_stream_qt.<locals>._schedule_exit)r4   	functoolsr+   IPython.external.qt_for_kernelr-   r.   ImportErrorr*   r   rJ   
getsockoptzmqFDQSocketNotifierReadr8   r9   r6   	activatedrP   r7   loop_qtrU   rK   
singleShot)r   r+   rF   r(   process_stream_eventsfdrU   r
   )r-   r.   r;   r   r4   r   _notify_stream_qtQ   s.   	

	rc   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)rc   r8   _in_event_loopr9   rJ   rg   exec_)r   elr
   r
   r   r_      s   r_   c                 C   s   | j   d S r   )r8   r   r   r
   r
   r   loop_qt_exit   s   rk   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)rh   MainLoop)r8   r
   r
   r   _loop_wx   s   
rm   wxc                    s   ddl tdj tfddG fdddj G  fdd	d	j}td
dr;tjjsA|dd_ddl	}t
||jsU|	|j|j tj dS )z*Start a kernel with wx event loop support.r   NrI   c                    s   | j ddr j  dS dS )zwake from wxr>   r?   N)rB   r8   ExitMainLoopr(   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timerStartBind	EVT_TIMERon_timerr   )selfr   poll_intervalrn   r
   r   rt      s
   
z$loop_wx.<locals>.TimerFrame.__init__c                 S   s   |    d S r   r   )r{   eventr
   r
   r   rz      s   z$loop_wx.<locals>.TimerFrame.on_timerN)__name__
__module____qualname__rt   rz   r
   r|   r
   r   
TimerFrame   s    r   c                       s   e Zd Z fddZdS )zloop_wx.<locals>.IPWxAppc                    s     t | _| jd dS )NFT)r   frameShowr{   r   r(   rq   r
   r   OnInit   s   zloop_wx.<locals>.IPWxApp.OnInitN)r   r   r   r   r
   r   r
   r   IPWxApp   s    r   r8   F)redirect)rn   rR   _poll_intervalr*   rs   Appgetattr
isinstancer8   signalcallable	getsignalSIGINTdefault_int_handlerrm   )r   r   r   r
   )r   r   r}   r(   rq   rn   r   loop_wx   s   r   c                 C   s   ddl }|  dS )zExit the wx loop.r   N)rn   Exit)r   rn   r
   r
   r   loop_wx_exit   s   r   tkc           	         s  ddl m}m} |  t drUG dd d} fddfdd	} fd
d}|t_| _tt|} j	
tj||  d|    dS ddlddl}|  tdj t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   )r8   withdraw)r{   r8   r
   r
   r   rt     s   z)loop_tk.<locals>.BasicAppWrapper.__init__N)r   r   r   rt   r
   r
   r
   r   BasicAppWrapper  s    r   c                      s,    j tj       `dS )r5   N)r   deletefilehandlerrY   rZ   r[   r:   destroyapp_wrapperr
   )r8   r   r(   r
   r   r;     s   zloop_tk.<locals>.exit_loopc                    r<   r=   rA   )r(   akwrE   r
   r   rF     s   
z+loop_tk.<locals>.process_stream_events_wrapc                    s     td|   dS )rG   rI   N)afterrR   rS   )r8   r;   r
   r   rU     s   zloop_tk.<locals>._schedule_exitNrI   c                       s4   e Zd Zd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   )r8   r(   r   )r{   r8   r(   r
   r
   r   rt   4  s   z)loop_tk.<locals>.TimedAppWrapper.__init__c                    s   | j jdd d S )Nr>   r?   )r(   rB   r   r
   r
   r   r   9  s   z%loop_tk.<locals>.TimedAppWrapper.funcc                    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	exceptionr8   r   rz   )r{   loopasyncior   r}   r
   r   rz   <  s   z)loop_tk.<locals>.TimedAppWrapper.on_timerc                 S   s   |    | j  d S r   )rz   r8   mainloopr   r
   r
   r   rQ   D  s   z&loop_tk.<locals>.TimedAppWrapper.startN)r   r   r   rt   r   rz   rQ   r
   r   r
   r   TimedAppWrapper3  s
    r   )tkinterr   r   rJ   loop_tkrU   r   r*   r   r   r   rY   rZ   r[   r   r   r   nest_asyncioapplyrR   r   rQ   )	r   r   r   r   rF   rU   ra   r   r   r
   )r8   r   r;   r   r}   r(   r   r      s,   


r   c              	   C   sB   z| j j  | j j  | ` d| _W dS  ttfy    Y dS w )zExit the tk loop.N)r   r8   r:   r   	eventloopRuntimeErrorAttributeErrorr   r
   r
   r   loop_tk_exitL  s   r   gtkc                 C   &   ddl m} || }|  || _dS z6Start the kernel, coordinating with the GTK event loopr>   )GTKEmbedN)gui.gtkembedr   rQ   _gtkr   r   
gtk_kernelr
   r
   r   loop_gtkX     
r   c                 C      | j   dS )zExit the gtk loop.Nr   stopr   r
   r
   r   loop_gtk_exitb     r   gtk3c                 C   r   r   )gui.gtk3embedr   rQ   r   r   r
   r
   r   	loop_gtk3h  r   r   c                 C   r   )zExit the gtk3 loop.Nr   r   r
   r
   r   loop_gtk3_exitr  r   r   osxmacosxc                    s   ddl m}m tj t| } fdd}| jjs^z9z#z|t_|| j |j	ddr3W W W  t_dS W n t
y<    w W n tyN   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.
    r>   )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real_excepthookr   r
   r   
handle_int  s   zloop_cocoa.<locals>.handle_intr?   Nz"KeyboardInterrupt caught in kernelr   )_eventloop_macosr   r   r   
excepthookr*   shellexit_nowr   rB   BaseExceptionr   r   r   )r   r   r(   r   r
   r   r   
loop_cocoax  s.   	

r   c                 C   s   ddl m} |  dS )zExit the cocoa loop.r>   )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| }t||} 	|
tj|  | 	 d}z   W n tyN   Y q< tya } z|}W Y d}~nd}~ww  jri   |duro|dS )z/Start a kernel with asyncio event loop support.r   NFc                    s   | j ddr   dS dS r=   )rB   r   rp   r   r
   r   ra     s   z+loop_asyncio.<locals>.process_stream_events)r   r   
is_running	is_closednew_event_loopset_event_loop_should_closer*   r   
add_readerrY   rZ   r[   	call_soonrun_foreverr   r   close)r   r   ra   r(   notifiererrorer
   r   r   loop_asyncio  s8   


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)rJ   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.
    QT_APINr   )QT_API_PYQT5QT_API_PYQT6QT_API_PYSIDE2QT_API_PYSIDE6
loaded_apire   rf   rd   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".z$QT_API couldn't be set due to error )osenvirongetIPython.external.qt_loadersr   r   r   r   r   r   PyQt5rX   PySide2PyQt6PySide6r   )guiqt_apir   r   r   r   r   loaded
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.r8   Nr   r,   )get_app_qt4 )	rJ   r  rW   r-   IPython.lib.guisupportr  r8   
QEventLoopr9   )r   r   r-   r  r
   r
   r   make_qt_app_for_kernelC  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.r8   r6   rH   rd   z'Cannot activate multiple GUI eventloops)r   keys
ValueErrorr   initializedr   instancer   rJ   delattr
startswithr  r   )r   r   r   msgr   r
   r
   r   
enable_guiT  s6   








r  r   )%__doc__r   r   r   rV   r   rZ   packaging.versionr   r   traitlets.config.applicationr   r   r   r"   r*   rc   r_   loop_qt5r   rk   rm   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r
   r
   r
   r   <module>   sj    
$	
C


6

T

	

	

'

)
\