B
    U[.                 @   sz  d Z ddlmZ ddlZddlZddlZddlZddlmZ	 ddl
mZ dd Zdd	 Zddddddd
Zdd Zdd Zeddd Zedddd Zej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/d0 Zejd1d2 Zed3d4d5 Z e jd6d7 Z!d:d8d9Z"dS );z4Event loop integration for the ZeroMQ-based kernels.    )partialN)LooseVersion)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VZmac_ver r	   r	   3lib/python3.7/site-packages/ipykernel/eventloops.py_use_appnope   s    r   c                sx   ddl m}  fdd}tj}|||jj jj	| |
 j}|d |j	| |d d S )Nr   )QtCorec                  s$   j ddr d  j  dS )z2fall back to main loop when there's a socket event   )limitFN)flushZ
setEnabledappquitr	   )kernelnotifierstreamr	   r
   process_stream_events   s    
z0_notify_stream_qt.<locals>.process_stream_eventsT)ZIPython.external.qt_for_kernelr   
getsockoptzmqFDZQSocketNotifierZReadr   Z	activatedZconnectZQTimerZsetSingleShotZtimeoutstart)r   r   r   r   fdtimerr	   )r   r   r   r
   _notify_stream_qt   s    

r   )ZinlineZnbaggZ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                s6   xD ]} t |< qW dd  _ fdd}| _ S )Nc             S   s   d S )Nr	   )r   r	   r	   r
   <lambda>R   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_decoratorT   s    z?register_integration.<locals>.decorator.<locals>.exit_decorator)loop_mapr   exit)r   namer    )toolkitnames)r   r
   	decoratorN   s    

z'register_integration.<locals>.decoratorr	   )r$   r%   r	   )r$   r
   register_integrationA   s    r&   c             C   s   d| _ |   d| _ dS )zInner-loop for running the Qt 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)_in_event_loopZexec_)r   r	   r	   r
   _loop_qtb   s    r(   Zqt4c             C   sL   ddl m} |dg| _| jd x| jD ]}t| | q,W t| j dS )z1Start a kernel with PyQt4 event loop integration.r   )get_app_qt4 FN)ZIPython.lib.guisupportr)   r   ZsetQuitOnLastWindowClosedshell_streamsr   r(   )r   r)   sr	   r	   r
   loop_qt4n   s    r-   ZqtZqt5c             C   s   dt jd< t| S )z1Start a kernel with PyQt5 event loop integration.Zpyqt5ZQT_API)osenvironr-   )r   r	   r	   r
   loop_qt5}   s    
r0   c             C   s   | j   d S )N)r   r"   )r   r	   r	   r
   loop_qt_exit   s    r1   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)r'   ZMainLoop)r   r	   r	   r
   _loop_wx   s    r2   wxc                s   ddl t r&jr&ddlm} |  tdj fddG fdddj G  fd	d
d
j}t	ddrt
jjs|dd_ddl}t||js||j|j tj dS )z*Start a kernel with wx event loop support.r   N)nopei  c                 s.   x( j D ]} | jddr j  dS qW dS )zwake from wxr   )r   N)r+   r   r   Z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__ZTimerr   ZStartZBindZ	EVT_TIMERon_timerr   )selfr   )poll_intervalr3   r	   r
   r8      s
    z$loop_wx.<locals>.TimerFrame.__init__c             S   s   |    d S )N)r   )r:   Zeventr	   r	   r
   r9      s    z$loop_wx.<locals>.TimerFrame.on_timerN)__name__
__module____qualname__r8   r9   r	   )r;   r3   r	   r
   
TimerFrame   s   r?   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:   )r?   r5   r	   r
   OnInit   s    
zloop_wx.<locals>.IPWxApp.OnInitN)r<   r=   r>   rA   r	   )r?   r5   r	   r
   IPWxApp   s   rB   r   F)Zredirect)r3   r   Z_darwin_app_napZappnoper4   int_poll_intervalr7   ZAppgetattr
isinstancer   signalcallable	getsignalSIGINTdefault_int_handlerr2   )r   r4   rB   rG   r	   )r?   r   r;   r5   r3   r
   loop_wx   s    		rL   c             C   s   dd l }|  d S )Nr   )r3   ZExit)r   r3   r	   r	   r
   loop_wx_exit   s    rM   tkc                s   ddl m}m}  fdd}|  | _ | j  xB| jD ]8}t||}d|_ j	|
tj||  d| q:W    dS )z&Start a kernel with the Tk event loop.r   )TkREADABLEc                s,   | j ddr( j| tj    dS )z2fall back to main loop when there's a socket eventr   )r   N)r   rN   Zdeletefilehandlerr   r   r   r   )r   akw)r   r	   r
   r      s    z&loop_tk.<locals>.process_stream_eventsr   N)ZtkinterrO   rP   r   Zwithdrawr+   r   r<   rN   Zcreatefilehandlerr   r   r   Zaftermainloop)r   rO   rP   r   r   r   r	   )r   r
   loop_tk   s    

rT   c             C   s   | j   d S )N)r   Zdestroy)r   r	   r	   r
   loop_tk_exit   s    rU   Zgtkc             C   s&   ddl m} || }|  || _dS )z6Start the kernel, coordinating with the GTK event loopr   )GTKEmbedN)Zgui.gtkembedrV   r   _gtk)r   rV   
gtk_kernelr	   r	   r
   loop_gtk   s    rY   c             C   s   | j   d S )N)rW   stop)r   r	   r	   r
   loop_gtk_exit  s    r[   Zgtk3c             C   s&   ddl m} || }|  || _dS )z6Start the kernel, coordinating with the GTK event loopr   )rV   N)Zgui.gtk3embedrV   r   rW   )r   rV   rX   r	   r	   r
   	loop_gtk3	  s    r\   c             C   s   | j   d S )N)rW   rZ   )r   r	   r	   r
   loop_gtk3_exit  s    r]   Zosxc                s   ddl m}m tj  fdd}x| jjszpyHy4|t_|| j x| jD ]}|j	ddrLdS qLW W n    Y nX W n" t
k
r   tdtjd Y nX W d t_X q&W dS )	znStart the kernel, coordinating with the Cocoa CFRunLoop event loop
    via the matplotlib MacOSX backend.
    r   )rS   rZ   c                s.     | t krtdtjd n | || dS )z.don't let KeyboardInterrupts look like crashesz%KeyboardInterrupt caught in CFRunLoop)fileN)KeyboardInterruptprintr   
__stdout__)etypevaluetb)real_excepthookrZ   r	   r
   
handle_int   s    zloop_cocoa.<locals>.handle_int)r   Nz"KeyboardInterrupt caught in kernel)r^   )_eventloop_macosrS   rZ   r   
excepthookshellZexit_nowrD   r+   r   r_   r`   ra   )r   rS   rf   r   r	   )re   rZ   r
   
loop_cocoa  s     	

rj   c             C   s   ddl m} |  d S )Nr   )rZ   )rg   rZ   )r   rZ   r	   r	   r
   loop_cocoa_exit?  s    rk   asyncioc          
      s   ddl }|    rdS   r6|  |  d _ fdd}x:| jD ]0}|t	j
}t||} ||  | qPW xld}y   W n: tk
r   wY n& tk
r } z|}W dd}~X Y nX  jr   |dk	r|P qW dS )z/Start a kernel with asyncio event loop support.r   NFc                s   | j ddr   dS )z2fall back to main loop when there's a socket eventr   )r   N)r   rZ   )r   )loopr	   r
   r   U  s    z+loop_asyncio.<locals>.process_stream_events)rl   get_event_loop
is_running	is_closedZnew_event_loopZset_event_loop_should_closer+   r   r   r   r   Z
add_readerZ	call_soonZrun_foreverr_   	Exceptionclose)r   rl   r   r   r   r   errorer	   )rm   r
   loop_asyncioE  s6    

rv   c                sP   ddl }|  |j fdd}  r2|  n  sL |    dS )zExit hook for asyncior   Nc               3   s*   t  dr  E d H  d _   d S )Nshutdown_asyncgensT)hasattrrw   rq   rZ   r	   )rm   r	   r
   
close_loopu  s    
z%loop_asyncio_exit.<locals>.close_loop)rl   rn   	coroutinero   rp   Zrun_until_completers   )r   rl   ry   r	   )rm   r
   loop_asyncio_exito  s    
r{   c             C   s   | t kr d| t  f }t||dkrPt r@tt dd}|dkrPtdt |  }|rx|jdk	rx|j|k	rxtd||_dS )z#Enable integration with a given GUIz)Invalid GUI request %r, valid ones are:%sNr   z\You didn't specify a kernel, and no IPython Application with a kernel appears to be running.z'Cannot activate multiple GUI eventloops)	r!   keys
ValueErrorr   ZinitializedrE   instanceRuntimeErrorZ	eventloop)Zguir   ru   rm   r	   r	   r
   
enable_gui  s    r   )N)#__doc__	functoolsr   r.   r   r   r   Zdistutils.versionr   r   Ztraitlets.config.applicationr   r   r   r!   r&   r(   r-   r0   r"   r1   r2   rL   rM   rT   rU   rY   r[   r\   r]   rj   rk   rv   r{   r   r	   r	   r	   r
   <module>   sF   !>

'*