
    Chi                        S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
Jr  SSKJrJr  SSKJrJr  SSKJr  SSKJrJrJr  SSKrSSKJr  SS	KJr  SS
KJr  SrSrSr " S S5      r  " S S5      r! " S S\5      r"g)z.Wrappers for forwarding stdout/stderr over zmq    N)b2a_hex)defaultdictdeque)StringIO
TextIOBase)local)AnyCallableOptional)extract_header)IOLoop)	ZMQStream   i  c                       \ rS rSrSrSS jrS rS rS rS r	\
S 5       rS	 rS
 rS rS rS rS rS rS rS r\
S 5       rS rS rS rSrg)IOPubThread(   zAn 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                 h   Xl         SU l        [        U 5      U l        [        R
                  " 5       U l        X l        [        SS9U l	        U(       a  U R                  5         [        R                  " 5       U l        [        5       U l        0 U l        [        R"                  " 5       U l        SU l        SU l        U R+                  5         [        R,                  " U R.                  SS9U l        SU R0                  l        SU R0                  l        SU R0                  l        SU R0                  l        g)zCreate 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.
F)make_current
   NIOPub)targetnameT)socket_stoppedBackgroundSocketbackground_socketosgetpid_master_pid
_pipe_flagr   io_loop_setup_pipe_in	threadingr   _localr   _events_event_pipesLock_event_pipe_gc_lock_event_pipe_gc_seconds_event_pipe_gc_task_setup_event_pipeThread_thread_mainthreaddaemonpydev_do_not_traceis_pydev_daemon_threadr   )selfr   pipes      eC:\Users\julio\OneDrive\Documentos\Trabajo\Ideas Frescas\venv\Lib\site-packages\ipykernel/iostream.py__init__IOPubThread.__init__1   s     !1$!799;51!oo'27'9;3<>>3C -/#@D  &&d.?.?gN!)-&-1*"    c                   ^  U 4S jnT R                   R                  U5        T R                  (       d  T R                   R                  5         T R                  bM  U 4S jnT R                  (       d  T R                   R                  U5        OT R                  R                  5         T R                   R                  SS9  g)z.The inner loop that's actually run in a threadc                  X   > [         R                  " T R                  5       5      T l        g N)asyncioensure_future_run_event_pipe_gcr*   r2   s   r4   _start_event_gc1IOPubThread._thread_main.<locals>._start_event_gcT   s    '.'<'<T=T=T=V'WD$r7   Nc                  B   >#    T R                   R                  5         g 7fr:   )r*   cancelr>   s   r4   _cancel)IOPubThread._thread_main.<locals>._cancel`   s     ((//1s   T)all_fds)r!   run_syncr   startr*   rB   close)r2   r?   rC   s   `  r4   r-   IOPubThread._thread_mainQ   s    	X 	o.}} LL ##/2 ==%%g.((//14(r7   c                    U R                   R                  nUR                  [        R                  5      nSUl        [        [        R                  " S5      5      R                  S5      nSU-  =o@l	        UR                  U5        [        X R                  5      U l        U R                  R                  U R                  5        g)zLCreate the PULL socket listening for events that should fire in this thread.r      asciizinproc://%sN)r   contextzmqPULLlingerr   r   urandomdecode_event_interfacebindr   r!   _event_pulleron_recv_handle_event)r2   ctxpipe_in_uuidifaces        r4   r+   IOPubThread._setup_event_pipej   s    kk!!**SXX&

2'..w7(5(==%U&w=""4#5#56r7   c                    #     [         R                  " U R                  5      I Sh  vN    U R                  5       I Sh  vN   MC   N N! [         a%  n[        SU 3[        R                  S9   SnAN0SnAff = f7f)z&Task to run event pipe gc continuouslyNz)Exception in IOPubThread._event_pipe_gc: file)r;   sleepr)   _event_pipe_gc	Exceptionprintsys
__stderr__)r2   es     r4   r=   IOPubThread._run_event_pipe_gcv   sj     -- ; ;<<<\))+++ <+ \A!ECNN[\sJ   %A=AA=A  A	A A=	A 
A:A50A=5A::A=c                 <  #    U R                   (       d  gU R                     [        U R                   R                  5       5       H9  u  pUR	                  5       (       a  M  UR                  5         U R                   U	 M;     SSS5        g! , (       d  f       g= f7f)z.run a single garbage collection on event pipesN)r&   r(   listitemsis_aliverH   )r2   r.   r   s      r4   ra   IOPubThread._event_pipe_gc   sj       %%"&t'8'8'>'>'@"A((LLN))&1 #B &%%s"   B<B!!B	B
BBc                     U R                   R                  nU$ ! [         a    U R                  R                  nUR                  [
        R                  5      nSUl        UR                  U R                  5        XR                   l        U R                     XR                  [        R                  " 5       '   SSS5         U$ ! , (       d  f        U$ = ff = f)zSthread-local event pipe for signaling events that should be processed in the threadr   N)r$   
event_pipeAttributeErrorr   rM   rN   PUSHrP   connectrS   r(   r&   r#   current_thread)r2   rn   rX   s      r4   _event_pipeIOPubThread._event_pipe   s    	K//J   	K++%%CCHH-J !Jt445%/KK" ))@J!!)":":"<= *) *)	Ks(    A=C"C9C
C	CCc                     [        U R                  5      n[        U5       H$  nU R                  R                  5       nU" 5         M&     g)zHandle 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)lenr%   rangepopleft)r2   msgn_events_event_fs        r4   rW   IOPubThread._handle_event   s7     t||$xAll**,GI !r7   c                    U R                   R                  n[        R                  " S5      U l        UR                  [
        R                  5      nSUl         UR                  S5      U l	        [        X R                   5      U l        U R"                  R%                  U R&                  5        g	! [
        R                   a<  n[        R                  " SU-  S-   SS9  SU l        UR                  5          S	nAg	S	nAff = f)
z7setup listening pipe for IOPub from forked subprocessesrK   r   ztcp://127.0.0.1z)Couldn't bind IOPub Pipe to 127.0.0.1: %sz'
subprocess output will be unavailable.   
stacklevelFN)r   rM   r   rQ   
_pipe_uuidrN   rO   rP   bind_to_random_port
_pipe_portZMQErrorwarningswarnr    rH   r   r!   _pipe_inrV   _handle_pipe_msg)r2   rX   rY   rf   s       r4   r"   IOPubThread._setup_pipe_in   s    kk!! **R.**SXX&
	%99:KLDO "'<<8d334 || 	MM;a?<=
 $DOMMO	s   B/ /C?2C::C?c                     U R                   (       a  U R                  5       (       d  gUS   U R                  :w  a  [        SU[        R
                  S9  gU R                  USS 5        g)z'handle a pipe message from a subprocessNr   zBad pipe message: %sr^   r   )r    _is_master_processr   rc   rd   re   send_multipartr2   ry   s     r4   r   IOPubThread._handle_pipe_msg   sR    d&=&=&?&?q6T__$(#CNNCCG$r7   c                     [         R                  " 5       nUR                  [         R                  5      nSUl        UR                  SU R                  -  5        X4$ )Ni  ztcp://127.0.0.1:%i)rN   Contextr   rp   rP   rq   r   )r2   rX   pipe_outs      r4   _setup_pipe_outIOPubThread._setup_pipe_out   sF    kkm::chh'-?@}r7   c                 F    [         R                  " 5       U R                  :H  $ r:   r   r   r   r>   s    r4   r   IOPubThread._is_master_process       yy{d....r7   c                 f    U R                   (       a  U R                  5       (       a  [        $ [        $ )z8check for forks, and switch to zmq pipeline if necessary)r    r   MASTERCHILDr>   s    r4   _check_mp_modeIOPubThread._check_mp_mode   s!    $"9"9";";Mr7   c                     SU R                   l        U R                   R                  5         [        R                  " U R
                  5        g)zStart the IOPub threadr   N)r.   r   rG   atexitregisterstopr>   s    r4   rG   IOPubThread.start   s0    " 			"r7   c                    SU l         U R                  R                  5       (       d  gU R                  R	                  U R                  R
                  5        U R                  R                  SS9  U R                  R                  5       (       a  Sn[        U5      eU R                  R                  5        H  u  p#UR                  5         M     g)zStop the IOPub threadTN   )timeoutz,IOPub thread did not terminate in 30 seconds)r   r.   rk   r!   add_callbackr   joinTimeoutErrorr&   rj   rH   )r2   ry   _threadrn   s       r4   r   IOPubThread.stop   s    {{##%%!!$,,"3"34$;;!!@Cs## $(#4#4#:#:#<G $=r7   c                 j    U R                   (       a  gU R                  R                  5         SU l        g)zClose the IOPub thread.N)closedr   rH   r>   s    r4   rH   IOPubThread.close   s#    ;;r7   c                     U R                   S L $ r:   )r   r>   s    r4   r   IOPubThread.closed   s    {{d""r7   c                     U R                   R                  5       (       a7  U R                  R                  U5        U R                  R                  S5        gU" 5         g)zdSchedule a function to be called in our IO thread.

If the thread is not running, call immediately.
r7   N)r.   rk   r%   appendrs   send)r2   fs     r4   scheduleIOPubThread.schedule  sB    
 ;;!!LL"!!#&Cr7   c                 8   ^ ^^ T R                  UUU 4S j5        g)z|send_multipart schedules actual zmq send in my thread.

If my thread isn't running (e.g. forked process), send immediately.
c                  (   > TR                   " T 0 TD6$ r:   )_really_send)argskwargsr2   s   r4   <lambda>,IOPubThread.send_multipart.<locals>.<lambda>  s    d//@@r7   N)r   r2   r   r   s   ```r4   r   IOPubThread.send_multipart  s    
 	@Ar7   c                 H   U R                   (       a  gU R                  5       nU[        :w  a!  U R                  R                  " U/UQ70 UD6  gU R                  5       u  pVUR                  " U R                  /UQ/UQ70 UD6  UR                  5         UR                  5         g)z)The callback that actually sends messagesN)	r   r   r   r   r   r   r   rH   term)r2   ry   r   r   mp_moderX   r   s          r4   r   IOPubThread._really_send  s    ;;%%'eKK&&s<T<V<
 !002MC##T__$;s$;MdMfMNNHHJr7   )rS   r(   r)   r*   r&   rU   r%   r$   r   r    r   r   r   r   r   r!   r   r.   N)F)__name__
__module____qualname____firstlineno____doc__r5   r-   r+   r=   ra   propertyrs   rW   r"   r   r   r   r   rG   r   rH   r   r   r   r   __static_attributes__ r7   r4   r   r   (   s    #@)2
7\	2  $50%/#$ # #
Br7   r   c                   N   ^  \ rS rSrSrSrS rU 4S jrU 4S jrS r	S r
S	rU =r$ )
r   i*  z>Wrapper around IOPub thread that provides zmq send[_multipart]Nc                     Xl         g)zInitialize the socket.N	io_thread)r2   r   s     r4   r5   BackgroundSocket.__init__/  s    "r7   c                   > UR                  S5      (       a%  UR                  S5      (       a  [        TU ]  U5        U R                  c   e[        U R                  R                  U5      (       a@  [        R                  " SU SU 3[        SS9  [        U R                  R                  U5      $ [        TU ]  U5      $ )z2Wrap socket attr access for backward-compatibility__zAccessing zmq Socket attribute O on BackgroundSocket is deprecated since ipykernel 4.3.0 use .io_thread.socket.r   r   )
startswithendswithsuper__getattr__r   hasattrr   r   r   DeprecationWarninggetattr)r2   attr	__class__s     r4   r   BackgroundSocket.__getattr__3  s    ??4  T]]4%8%8G%~~)))4>>(($//MM1$ 8**.1 # 4>>00$77w"4((r7   c                 (  > US:X  d,  UR                  S5      (       a&  UR                  S5      (       a  [        TU ]  X5        g[        R
                  " SU SU 3[        SS9  U R                  c   e[        U R                  R                  X5        g)zSet an attribute on the socket.r   r   zSetting zmq Socket attribute r   r   r   N)
r   r   r   __setattr__r   r   r   r   setattrr   )r2   r   valuer   s      r4   r   BackgroundSocket.__setattr__D  s    ;4??4#8#8T]]4=P=PG,MM/v 6**.1 # >>---DNN))47r7   c                 0    U R                   " U//UQ70 UD6$ )zSend a message to the socket.)r   )r2   ry   r   r   s       r4   r   BackgroundSocket.sendS  s    ""C5:4:6::r7   c                 X    U R                   c   eU R                   R                  " U0 UD6$ )zSchedule send in IO thread)r   r   r   s      r4   r   BackgroundSocket.send_multipartW  s,    ~~)))~~,,d=f==r7   r   )r   r   r   r   r   r   r5   r   r   r   r   r   __classcell__)r   s   @r4   r   r   *  s)    HI#)"8;> >r7   r   c                   "   \ rS rSr% SrSrSrSrSrSr	\
\   \S'   S rS	 r  S$S
SS.S jjr\S 5       r\R$                  S 5       rS rS rS rS rS r\S 5       rS rS rS rS\S\
\   4S jrS rS r S r!S r"\S  5       r#S! r$S" r%S#r&g)%	OutStreami]  zhA file like object that publishes the stream to a 0MQ PUB socket.

Output is handed off to an IO Thread
r   g?NzUTF-8_excc                 f    [        U SS5      b  U R                  $ Sn[        R                  " U5      e)zN
Things like subprocess will peak and write to the fileno() of stderr/stdout.
_original_stdstream_copyNfileno)r   r   ioUnsupportedOperationr   s     r4   r   OutStream.filenol  s6     43T:F000%%c**r7   c                     [         R                  " U R                  [        5      nU(       a  U R                  (       a  U R                  UR                  SS95        [         R
                  " U R                  U5        [         R                  " U R                  [        5      nU(       a  U R                  (       a  M~  gggg! [         a    [        R                  " 5       U l         gf = f)a:  
We've redirected standards streams 0 and 1 into a pipe.

We need to watch in a thread and redirect them to the right places.

1) the ZMQ channels to show in notebook interfaces,
2) the original stdout/err, to capture errors in terminals.

We cannot schedule this on the ioloop thread, as this might be blocking.

replace)errorsN)r   read_fidPIPE_BUFFER_SIZE_should_watchwriterR   r   rb   rd   exc_infor   )r2   btss     r4   _watch_pipe_fdOutStream._watch_pipe_fdu  s    	'''$))%56C$,,

3::Y:7866<ggdii)9: $,,,#,#  	'DI	's   B9C $C('C(TF)watchfdisattyc                \   Ub  [         R                  " S[        SS9  Xl        [	        U[
        5      (       d8  [         R                  " SU-  [        SS9  [        U5      nUR                  5         X l        X0l        SUR                  5       -   U l
        [        R                  " S5      U l        U R                  R                  0 5        0 U l        0 U l        0 U l        [$        R&                  " 5       U l        SU l        SU l        UR.                  U l        [2        R4                  " 5       U l        [9        [:        5      U l        SU l        [A        U5      U l!        SU l"        [G        5       U l$        U(       a\  [J        RL                  RO                  S	5      (       d$  [J        RL                  RO                  S
5      (       a  S[$        RP                  ;  d  US:X  a  SU l"        U RS                  U5        U(       a  [U        US5      (       a  [U        US5      (       ap  U RD                  (       aX   URW                  5       nUbD  XRZ                  :X  a5  [\        R^                  " [\        R`                  " U Rb                  S5      5      nXPl        gSn	[e        U	5      eg! [X         a    Sn Njf = f)a  
Parameters
----------
session : object
    the session object
pub_thread : threading.Thread
    the publication thread
name : str {'stderr', 'stdout'}
    the name of the standard stream to replace
pipe : object
    the pipe object
echo : bool
    whether to echo output
watchfd : bool (default, True)
    Watch the file descriptor corresponding to the replaced stream.
    This is useful if you know some underlying code will write directly
    the file descriptor by its number. It will spawn a watching thread,
    that will swap the give file descriptor for a pipe, read from the
    pipe, and insert this into the current Stream.
isatty : bool (default, False)
    Indication of whether this stream has terminal capabilities (e.g. can handle colors)

NzKpipe argument to OutStream is deprecated and ignored since ipykernel 4.2.3.r   r   zISince IPykernel 4.3, OutStream should be created with IOPubThread, not %rs   stream.parent_headerFlinuxdarwinPYTEST_CURRENT_TESTforceTr   r   wz(echo argument must be a file-like object)3r   r   r   session
isinstancer   rG   
pub_threadr   encodetopiccontextvars
ContextVar_parent_headerset_thread_to_parent_thread_to_parent_header_parent_header_globalr   r   r   _flush_pending_subprocess_flush_pendingr!   _io_loopr#   RLock_buffer_lockr   r   _buffersechobool_isattyr   r   r$   rd   platformr   environ_setup_stream_redirectsr   r   rb   _original_stdstream_fdr   TextIOWrapperFileIOr   
ValueError)
r2   r  r  r   r3   r  r   r   echo_fdry   s
             r4   r5   OutStream.__init__  s4   D MM]" *k22MM&(23"	 %Z0J$	$++-/
FQF\F\G
 	#!#(*%%'"99;#).&"**%OO-#H-	F|"g ((11S\\5L5LX5V5V*"**< '!!%D((.tV$$w)?)? %%'"&++- *w:U:U/U  "//II $ = = #  !	@ o%-  % '"&'s   0J J+*J+c                 P    U R                   R                  5       $ ! [         a     [        R                  " 5       R
                  nXR                  ;   a   U R                  U   nXR                  ;   a  M   U R                  U   s $ ! [         a    U R                  s s $ f = ff = fr:   )
r  getLookupErrorr#   rr   identr  r  KeyErrorr  )r2   identitys     r4   r   OutStream.parent_header  s    	2&&**,, 	22$335;; "8"88#55h?H "8"88 44X>> 21112	2s3    
B%AB5BB%B!B% B!!B%c                 D    Xl         U R                  R                  U5      $ r:   )r  r  r  )r2   r   s     r4   r   r)    s    %*"""&&u--r7   c                     U R                   $ )zXReturn a bool indicating whether this is an 'interactive' stream.

Returns:
    Boolean
)r  r>   s    r4   r   OutStream.isatty  s     ||r7   c                    [         R                  " 5       u  p#[        [        U5      R	                  5       =o@l        [         R                  " U5      U l        [         R                  " X45        X l	        S U l
        [        R                  " U R                  S9U l        SU R                  l        U R                  R!                  5         g )N)r   T)r   r3   r   rd   r   r  dupr   dup2r   r   r#   r,   r   watch_fd_threadr/   rG   )r2   r   prpwfnos        r4   r  !OutStream._setup_stream_redirects  s    ,3C,>,E,E,GG)(*s%
		(//t7J7JK&*#""$r7   c                 F    [         R                  " 5       U R                  :H  $ r:   r   r>   s    r4   r   OutStream._is_master_process&  r   r7   c                 $    [        U5      U l        g)zSet the parent header.N)r   r   )r2   parents     r4   
set_parentOutStream.set_parent)  s    +F3r7   c                    U R                   (       a  SU l         [        R                  " U R                  S5        U R                  R                  5         [        R                  " U R                  U R                  5        [        R                  " U R                  5        U R                  (       a&  U R                  u  pn[        R                  " XU5        SU l        g)zClose the stream.F    N)r   r   r   r  r0  r   r/  r   rH   r   	tracebackprint_exceptionr  )r2   etyper   tbs       r4   rH   OutStream.close-  s    !&D HHT00%8  %%'GGD1143N3NOHHT22399#yyE"%%eB7r7   c                     U R                   S L $ r:   )r  r>   s    r4   r   OutStream.closed=  s    $&&r7   c                 z   ^  T R                   (       a  gST l         U 4S jnT R                  R                  U5        g)zeschedule a flush in the IO thread

call this on write, to indicate that flush should be called soon.
NTc                  f   > T R                   R                  T R                  T R                  5        g r:   )r  
call_laterflush_interval_flushr>   s   r4   _schedule_in_thread6OutStream._schedule_flush.<locals>._schedule_in_threadK  s!    MM$$T%8%8$++Fr7   )r  r  r   )r2   rI  s   ` r4   _schedule_flushOutStream._schedule_flushA  s4    
 "	G 	  !45r7   c                 ~   U R                   (       Ga  U R                   R                  Gb  U R                   R                  R                  5       (       a  U R                   R                  R                  [        R
                  " 5       R                  :w  a  U R                   R                  U R                  5        [        R                  " 5       nU R                   R                  UR                  5        UR                  U R                  5      (       d  [        S[        R                  S9  ggU R                  5         g)zCtrigger actual zmq send

send will happen in the background thread
NzIOStream.flush timed outr^   )r  r.   rk   r&  r#   rr   r   rH  Eventr  waitflush_timeoutrc   rd   re   )r2   evts     r4   flushOutStream.flushP  s     OOO&&2&&//11&&,,	0H0H0J0P0PP OO$$T[[1//#COO$$SWW-88D..// 0s~~F 0
 KKMr7   c                    SU l         SU l        U R                  b   U R                  R                  5         U R                  5        H  u  p#U(       d  M  [        R                  " 5       U R                  l        U R                  US.nU R                  R                  SXBS9nU R                   H  nU" U5      nUb  M      g   U R                  R!                  U R"                  UU R$                  S9  M     g! [         aC  nU R                  [
        R                  La  [        SU 3[
        R                  S9   SnAGNSnAff = f)	zThis 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).
FNzFlush failed: r^   )r   textstream)r8  )r&  )r  r  r  rR  OSErrorrd   re   rc   _flush_buffersr   r   r  pidr   ry   _hooksr   r  r	  )r2   rf   r8  datacontentry   hooks          r4   rH  OutStream._flushh  s    $).&99 E		!
 !//1LFt $&99; #'99d;ll&&x&H
 !KKDs)C{ (
 !!OO** " # 2	  E99CNN2N1#.S^^DEs   C7 7
E8D??Estringreturnc                 >   U R                   n[        U[        5      (       d  S[        U5       3n[	        U5      eU R
                  b   U R
                  R                  U5        U R                  c  Sn[        U5      eU R                  5       (       + nU R                     U R                  [!        UR#                  5       5         R                  U5        SSS5        U(       a?  U R$                  (       a  gSU l        U R                  R'                  U R(                  5        OU R+                  5         [-        U5      $ ! [         aC  nU R
                  [        R                  La  [        SU 3[        R                  S9   SnAGN"SnAff = f! , (       d  f       N= f)zWrite to current stream after encoding if necessary

Returns
-------
len : int
    number of items from input parameter written to stream.

z"write() argument must be str, not NzWrite failed: r^   I/O operation on closed fileT)r   r  strtype	TypeErrorr  r   rW  rd   re   rc   r  r   r   r  r  	frozensetrj   r  r   rH  rK  rv   )r2   r_  r8  ry   rf   is_childs         r4   r   OutStream.write  s:    ##&#&&6tF|nECC. 99 E		'
 ??"0CS/!..00MM)FLLN34::6B  ---1D*OO$$T[[1  "6{/  E99CNN2N1#.S^^DE s$   	D> 6F>
F8FF
Fc                 l    U R                   c  Sn[        U5      eU H  nU R                  U5        M     g)zWrite lines to the stream.Nrb  )r  r   r   )r2   sequencery   r_  s       r4   
writelinesOutStream.writelines  s1    ??"0CS/!FJJv r7   c                     g)z$Test whether the stream is writable.Tr   r>   s    r4   writableOutStream.writable  s    r7   c              #      #    U R                  5       nUR                  5        H4  u  p#UR                  5       nUR                  5         [	        U5      U4v   M6     g7f)z<clear the current buffer and return the current buffer data.N)_rotate_buffersrj   getvaluerH   dict)r2   buffersfrozen_parentbufferr[  s        r4   rX  OutStream._flush_buffers  sK     &&(%,]]_!M??$DLLN}%t++ &5s   AAc                     U R                      U R                  n[        [        5      U l        SSS5        U$ ! , (       d  f       W$ = f)z@Returns the current buffer and replaces it with an empty buffer.N)r  r  r   r   )r2   old_bufferss     r4   rq  OutStream._rotate_buffers  s>    --K'1DM    s	   !8
Ac                     [        U R                  S5      (       d  / U R                  l        U R                  R                  $ )Nhooks)r   r$   r|  r>   s    r4   rZ  OutStream._hooks  s/    t{{G,, "DKK{{   r7   c                 :    U R                   R                  U5        g)a  
Registers a hook with the thread-local storage.

Parameters
----------
hook : Any callable object

Returns
-------
Either a publishable message, or `None`.
The hook callable must return a message from
the __call__ method if they still require the
`session.send` method to be called after transformation.
Returning `None` will halt that execution path, and
session.send will not be called.
N)rZ  r   r2   r]  s     r4   register_hookOutStream.register_hook  s    " 	4 r7   c                 \     U R                   R                  U5        g! [         a     gf = f)z
Un-registers a hook with the thread-local storage.

Parameters
----------
hook : Any callable object which has previously been
    registered as a hook.

Returns
-------
bool - `True` if the hook was removed, `False` if it wasn't
    found.
TF)rZ  remover   r  s     r4   unregister_hookOutStream.unregister_hook  s.    	KKt$ 		s    
++)r  r  r   r   r  r  r  r$   r   r   r  r  r  r   r  r  r  r  r   r   r  r  r	  r0  )NN)'r   r   r   r   r   rP  rG  r	  encodingr   r   r	   __annotations__r   r   r5   r   r   setterr   r  r   r9  rH   r   rK  rR  rH  rc  intr   rk  rn  rX  rq  rZ  r  r  r   r   r7   r4   r   r   ]  s    MNEHD(3-+'6 l& l&\ 2 2$ . .%/4  ' '60%N)C )HSM )V, ! !!&r7   r   )#r   r;   r   r
  r   r   rd   r#   r=  r   binasciir   collectionsr   r   r   r   r   typingr	   r
   r   rN   jupyter_client.sessionr   tornado.ioloopr   zmq.eventloop.zmqstreamr   r   r   r   r   r   r   r   r7   r4   <module>r     s{    4
    	 	 
     * #  * * 
 1 ! - 
	  D0> 0>fd
 dr7   