ó
Û¤[c           @  sn  d  Z  d d l m Z d d l Z d d l m Z d d l m Z y d d l m	 Z
 Wn! e k
 ry d d l m	 Z
 n Xd d l Z d d l Z d d l Z d d l Z d d l m Z m Z d d l 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 Z d Z  d e! f d „  ƒ  YZ" d e! f d „  ƒ  YZ# d e f d „  ƒ  YZ$ d S(   s.   Wrappers for forwarding stdout/stderr over zmqiÿÿÿÿ(   t   print_functionN(   t   b2a_hex(   t   deque(   t	   lock_held(   t   StringIOt
   TextIOBase(   t   IOLoop(   t	   ZMQStream(   t   extract_header(   t	   py3compat(   t   unicode_typei    i   t   IOPubThreadc           B  s¶   e  Z d  Z e d „ Z d „  Z d „  Z e d „  ƒ Z d „  Z	 d „  Z
 d „  Z d „  Z d	 „  Z d
 „  Z d „  Z d „  Z d „  Z e d „  ƒ Z d „  Z d „  Z d „  Z RS(   s   An object for sending IOPub messages in a background thread

    Prevents a blocking main thread from delaying output from threads.

    IOPubThread(pub_socket).background_socket is a Socket-API-providing object
    whose IO is always run in a thread.
    c         C  s¢   | |  _  t |  ƒ |  _ t j ƒ  |  _ | |  _ t d t ƒ |  _	 | rU |  j
 ƒ  n  t j ƒ  |  _ t ƒ  |  _ |  j ƒ  t j d |  j ƒ |  _ t |  j _ d S(   s  Create IOPub thread

        Parameters
        ----------

        socket: zmq.PUB Socket
            the socket on which messages will be sent.
        pipe: bool
            Whether this process should listen for IOPub messages
            piped from subprocesses.
        t   make_currentt   targetN(   t   sockett   BackgroundSockett   background_sockett   ost   getpidt   _master_pidt
   _pipe_flagR   t   Falset   io_loopt   _setup_pipe_int	   threadingt   localt   _localR   t   _eventst   _setup_event_pipet   Threadt   _thread_maint   threadt   Truet   daemon(   t   selfR   t   pipe(    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   __init__2   s    		
c         C  s1   |  j  j ƒ  |  j  j ƒ  |  j  j d t ƒ d S(   s.   The inner loop that's actually run in a threadt   all_fdsN(   R   R   t   startt   closeR    (   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR   K   s    c         C  s   |  j  j } | j  t j ƒ } d | _ t t j d ƒ ƒ j d ƒ } d | } |  _	 | j
 | ƒ t | |  j ƒ |  _ |  j j |  j ƒ d S(   sL   Create the PULL socket listening for events that should fire in this thread.i    i   t   asciis   inproc://%sN(   R   t   contextt   zmqt   PULLt   lingerR   R   t   urandomt   decodet   _event_interfacet   bindR   R   t   _event_pullert   on_recvt   _handle_event(   R"   t   ctxt   pipe_int   _uuidt   iface(    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR   Q   s    	c         C  sk   y |  j  j } WnT t k
 rf |  j j } | j t j ƒ } d | _ | j |  j	 ƒ | |  j  _ n X| S(   sS   thread-local event pipe for signaling events that should be processed in the threadi    (
   R   t
   event_pipet   AttributeErrorR   R)   R*   t   PUSHR,   t   connectR/   (   R"   R8   R4   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   _event_pipe]   s    	c         C  s@   t  |  j ƒ } x* t | ƒ D] } |  j j ƒ  } | ƒ  q Wd S(   sÅ   Handle an event on the event pipe

        Content of the message is ignored.

        Whenever *an* event arrives on the event stream,
        *all* waiting events are processed in order.
        N(   t   lenR   t   ranget   popleft(   R"   t   msgt   n_eventst   it   event_f(    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR3   k   s    
c         C  s½   |  j  j } t j d ƒ |  _ | j  t j ƒ } d | _ y | j d ƒ |  _	 Wn? t j
 k
 r } t j d | d ƒ t |  _ | j ƒ  d SXt | |  j ƒ |  _ |  j j |  j ƒ d S(   s7   setup listening pipe for IOPub from forked subprocessesi   i    s   tcp://127.0.0.1s)   Couldn't bind IOPub Pipe to 127.0.0.1: %ss'   
subprocess output will be unavailable.N(   R   R)   R   R-   t
   _pipe_uuidR*   R+   R,   t   bind_to_random_portt
   _pipe_portt   ZMQErrort   warningst   warnR   R   R'   R   R   t   _pipe_inR2   t   _handle_pipe_msg(   R"   R4   R5   t   e(    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR   z   s    		
c         C  s]   |  j  s |  j ƒ  r d S| d |  j k rH t d | d t j ƒd S|  j | d ƒ d S(   s'   handle a pipe message from a subprocessNi    s   Bad pipe message: %st   filei   (   R   t   _is_master_processRD   t   printt   syst
   __stderr__t   send_multipart(   R"   R@   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyRK      s    c         C  sE   t  j ƒ  } | j t  j ƒ } d | _ | j d |  j ƒ | | f S(   Ni¸  s   tcp://127.0.0.1:%i(   R*   t   ContextR   R:   R,   R;   RF   (   R"   R4   t   pipe_out(    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   _setup_pipe_out™   s
    	c         C  s   t  j ƒ  |  j k S(   N(   R   R   R   (   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyRN   ¡   s    c         C  s"   |  j  s |  j ƒ  r t St Sd S(   s8   check for forks, and switch to zmq pipeline if necessaryN(   R   RN   t   MASTERt   CHILD(   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   _check_mp_mode¤   s    c         C  s!   |  j  j ƒ  t j |  j ƒ d S(   s   Start the IOPub threadN(   R   R&   t   atexitt   registert   stop(   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR&   «   s    c         C  s_   |  j  j ƒ  s d S|  j j |  j j ƒ |  j  j ƒ  t |  j d ƒ r[ |  j j j	 ƒ  n  d S(   s   Stop the IOPub threadNR8   (
   R   t   is_aliveR   t   add_callbackR[   t   joint   hasattrR   R8   R'   (   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR[   ²   s    c         C  s   |  j  j ƒ  d  |  _  d  S(   N(   R   R'   t   None(   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR'   »   s    c         C  s   |  j  d  k S(   N(   R   R`   (   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   closed¿   s    c         C  s=   |  j  j ƒ  r2 |  j j | ƒ |  j j d ƒ n | ƒ  d S(   st   Schedule a function to be called in our IO thread.

        If the thread is not running, call immediately.
        t    N(   R   R\   R   t   appendR<   t   send(   R"   t   f(    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   scheduleÃ   s    c           s    ˆ j  ‡  ‡ ‡ f d †  ƒ d S(   s”   send_multipart schedules actual zmq send in my thread.
        
        If my thread isn't running (e.g. forked process), send immediately.
        c             s   ˆ j  ˆ  ˆ Ž  S(   N(   t   _really_send(    (   t   argst   kwargsR"   (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   <lambda>Ô   s    N(   Rf   (   R"   Rh   Ri   (    (   Rh   Ri   R"   s1   lib/python2.7/site-packages/ipykernel/iostream.pyRR   Ï   s    c         O  sx   |  j  ƒ  } | t k r1 |  j j | | | Ž nC |  j ƒ  \ } } | j |  j g | | | Ž | j ƒ  | j ƒ  d S(   s)   The callback that actually sends messagesN(   RX   RW   R   RR   RU   RD   R'   t   term(   R"   R@   Rh   Ri   t   mp_modeR4   RT   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyRg   Ö   s    
(   t   __name__t
   __module__t   __doc__R   R$   R   R   t   propertyR<   R3   R   RK   RU   RN   RX   R&   R[   R'   Ra   Rf   RR   Rg   (    (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR   )   s$   															R   c           B  sA   e  Z d  Z d Z d „  Z d „  Z d „  Z d „  Z d „  Z	 RS(   s>   Wrapper around IOPub thread that provides zmq send[_multipart]c         C  s   | |  _  d  S(   N(   t	   io_thread(   R"   Rq   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR$   ë   s    c         C  s“   | j  d ƒ r7 | j d ƒ r7 t t |  ƒ j | ƒ n  t |  j j | ƒ ry t j	 d | t
 d d ƒt |  j j | ƒ St t |  ƒ j | ƒ d S(   s2   Wrap socket attr access for backward-compatibilityt   __s5   Accessing zmq Socket attribute %s on BackgroundSockett
   stackleveli   N(   t
   startswitht   endswitht   superR   t   __getattr__R_   Rq   R   RH   RI   t   DeprecationWarningt   getattr(   R"   t   attr(    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyRw   î   s    c         C  sz   | d k s* | j  d o$ | j d ƒ ƒ rF t t |  ƒ j | | ƒ n0 t j d | t d d ƒt |  j	 j
 | | ƒ d  S(   NRq   Rr   s3   Setting zmq Socket attribute %s on BackgroundSocketRs   i   (   Rt   Ru   Rv   R   t   __setattr__RH   RI   Rx   t   setattrRq   R   (   R"   Rz   t   value(    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR{   ù   s
    *c         O  s   |  j  | g | | Ž S(   N(   RR   (   R"   R@   Rh   Ri   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyRd     s    c         O  s   |  j  j | | Ž  S(   s   Schedule send in IO thread(   Rq   RR   (   R"   Rh   Ri   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyRR     s    N(
   Rm   Rn   Ro   R`   Rq   R$   Rw   R{   Rd   RR   (    (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR   ç   s   				t	   OutStreamc           B  s§   e  Z d  Z d Z d Z d Z d Z d d d „ Z d „  Z	 d „  Z
 d „  Z e d „  ƒ Z d	 „  Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   st   A file like object that publishes the stream to a 0MQ PUB socket.
    
    Output is handed off to an IO Thread
    i
   gš™™™™™É?s   UTF-8c         C  s  | d  k	 r t j d t ƒ n  | |  _ t | t ƒ sj t j d | t d d ƒt | ƒ } | j ƒ  n  | |  _ | |  _	 d t
 j | ƒ |  _ i  |  _ t j ƒ  |  _ t |  _ | j |  _ |  j ƒ  d  |  _ | rt | d ƒ rt | d ƒ r| |  _ qt d ƒ ‚ n  d  S(	   Ns4   pipe argument to OutStream is deprecated and ignoreds4   OutStream should be created with IOPubThread, not %rRs   i   s   stream.t   readt   writes(   echo argument must be a file like object(   R`   RH   RI   Rx   t   sessiont
   isinstanceR   R&   t
   pub_threadt   nameR	   t
   cast_bytest   topict   parent_headerR   R   R   R   t   _flush_pendingR   t   _io_loopt   _new_buffert   echoR_   t
   ValueError(   R"   R   Rƒ   R„   R#   R‹   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR$     s,    	
					
	c         C  s   t  j ƒ  |  j k S(   N(   R   R   R   (   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyRN   3  s    c         C  s   t  | ƒ |  _ d  S(   N(   R   R‡   (   R"   t   parent(    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt
   set_parent6  s    c         C  s   d  |  _ d  S(   N(   R`   Rƒ   (   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR'   9  s    c         C  s   |  j  d  k S(   N(   Rƒ   R`   (   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyRa   <  s    c           s9   ˆ  j  r d St ˆ  _  ‡  f d †  } ˆ  j j | ƒ d S(   su   schedule a flush in the IO thread

        call this on write, to indicate that flush should be called soon.
        Nc             s   ˆ  j  j ˆ  j ˆ  j ƒ d  S(   N(   R‰   t
   call_latert   flush_intervalt   _flush(    (   R"   (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   _schedule_in_threadJ  s    (   Rˆ   R    Rƒ   Rf   (   R"   R’   (    (   R"   s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   _schedule_flush@  s
    		c         C  s‰   |  j  j j ƒ  r{ |  j  j |  j ƒ t ƒ  s… t j ƒ  } |  j  j | j ƒ | j	 |  j
 ƒ sx t d d t j ƒqx q… n
 |  j ƒ  d S(   sS   trigger actual zmq send

        send will happen in the background thread
        s   IOStream.flush timed outRM   N(   Rƒ   R   R\   Rf   R‘   t   import_lock_heldR   t   Eventt   sett   waitt   flush_timeoutRO   RP   RQ   (   R"   t   evt(    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   flushN  s    	c      	   C  sã   t  |  _ |  j d	 k	 rs y |  j j ƒ  Wqs t k
 ro } |  j t j k	 rp t d j	 | ƒ d t j ƒqp qs Xn  |  j
 ƒ  } | rß t j ƒ  |  j _ i |  j d 6| d 6} |  j j |  j d d | d |  j d |  j ƒn  d	 S(
   s³   This is where the actual send happens.

        _flush should generally be called in the IO thread,
        unless the thread has been destroyed (e.g. forked subprocess).
        s   Flush failed: {}RM   u   nameu   textu   streamt   contentR   t   identN(   R   Rˆ   R‹   R`   Rš   t   OSErrorRP   RQ   RO   t   formatt   _flush_bufferR   R   R   t   pidR„   Rd   Rƒ   R‡   R†   (   R"   RL   t   dataR›   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR‘   d  s    	c           s  ˆ  j  d  k	 rm y ˆ  j  j ˆ ƒ Wqm t k
 ri } ˆ  j  t j k	 rj t d j | ƒ d t j ƒqj qm Xn  ˆ  j d  k r‹ t	 d ƒ ‚ n| t
 ˆ t ƒ s² ˆ j ˆ  j d ƒ ‰ n  ˆ  j ƒ  } ˆ  j j ‡  ‡ f d †  ƒ | rý d ˆ k rˆ  j ƒ  qn
 ˆ  j ƒ  d  S(   Ns   Write failed: {}RM   s   I/O operation on closed filet   replacec             s   ˆ  j  j ˆ ƒ S(   N(   t   _bufferR€   (    (   R"   t   string(    s1   lib/python2.7/site-packages/ipykernel/iostream.pyRj     s    s   
(   R‹   R`   R€   R   RP   RQ   RO   Rž   Rƒ   RŒ   R‚   R
   R.   t   encodingRN   Rf   Rš   R“   (   R"   R¤   RL   t   is_child(    (   R"   R¤   s1   lib/python2.7/site-packages/ipykernel/iostream.pyR€   ~  s"    c         C  s@   |  j  d  k r t d ƒ ‚ n x | D] } |  j | ƒ q% Wd  S(   Ns   I/O operation on closed file(   Rƒ   R`   RŒ   R€   (   R"   t   sequenceR¤   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt
   writelinesš  s    c         C  s   t  S(   N(   R    (   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   writable¡  s    c         C  sE   d } |  j  d k	 rA |  j  } |  j ƒ  | j ƒ  } | j ƒ  n  | S(   sƒ   clear the current buffer and return the current buffer data.
        
        This should only be called in the IO thread.
        u    N(   R£   R`   RŠ   t   getvalueR'   (   R"   R¡   t   buf(    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyRŸ   ¤  s    	
c         C  s   t  ƒ  |  _ d  S(   N(   R   R£   (   R"   (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyRŠ   ±  s    N(   Rm   Rn   Ro   R˜   R   R`   R†   R¥   R$   RN   RŽ   R'   Rp   Ra   R“   Rš   R‘   R€   R¨   R©   RŸ   RŠ   (    (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyR~   	  s$   										(%   Ro   t
   __future__R    RY   t   binasciiR   t   collectionsR   t	   importlibR   R”   t   ImportErrort   impR   RP   R   RH   t   ioR   R   R*   t   zmq.eventloop.ioloopR   t   zmq.eventloop.zmqstreamR   t   jupyter_client.sessionR   t   ipython_genutilsR	   t   ipython_genutils.py3compatR
   RV   RW   t   objectR   R   R~   (    (    (    s1   lib/python2.7/site-packages/ipykernel/iostream.pyt   <module>   s0   ¾"