
    k7i:                        S SK r S SKrS SKrS SKrS SKJrJr  S SKJr  S SK	J
r
  S SKJrJr  S SKrS SKJr  S SKJrJr  S SKJr  S S	KJrJr  S S
KJr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%J&r&J'r'  \RP                  " \)5      r*/ SQr+\S 5       r, " S S\5      r-S SS.S\-4S jjjr. " S S\$5      r/ " S S5      r0 " S S5      r1 " S S\5      r2\S SS.S jj5       r3g)!    N)asynccontextmanagercontextmanager)count)Optional)ValueError)Channel)AuthenticatorBEGIN)get_bus)FileDescriptorfds_buf_size)ParserMessageTypeMessage)	ProxyBase
unwrap_msg)message_bus   )MessageFiltersFilterHandleReplyMatcherRouterClosedcheck_replyable)open_dbus_connectionopen_dbus_routerProxyc               #     #     S v   g ! [          ap  n U R                  [        R                  [        R                  1;   a  [        R
                  " S5      S e[        R                  " SR                  U 5      5      U eS n A ff = f7f)Nzthis socket was already closedzsocket connection broken: {})OSErrorerrnoEBADFENOTSOCKtrioClosedResourceErrorBrokenResourceErrorformat)excs    I/home/james-whalen/.local/lib/python3.13/site-packages/jeepney/io/trio.py)_translate_socket_errors_to_stream_errorsr)   ,   sn     	 99enn55**+KLRVV**.55c:s%   B	 B
BA+A>>BBc                       \ rS rSrSrSS jrSS.S\4S jjrS\4S	 jr	SS\
4S
 jjrS\4S jrS rS rS r\S 5       rSrg)DBusConnection;   av  A plain D-Bus connection with no matching of replies.

This doesn't run any separate tasks: sending and receiving are done in
the task that calls those methods. It's suitable for implementing servers:
several worker tasks can receive requests and send replies.
For a typical client pattern, see :class:`DBusRouter`.

Implements trio's channel interface for Message objects.
c                     Xl         X l        [        5       U l        [	        SS9U l        S U l        [        R                  " 5       U l	        [        R                  " 5       U l
        S U l        g )Nr   )start)socket
enable_fdsr   parserr   outgoing_serialunique_namer#   Lock	send_lock	recv_lock_leftover_to_send)selfr/   r0   s      r(   __init__DBusConnection.__init__E   sK    $h$1~!%    Nserialmessagec                h  #    U R                    ISh  vN   Uc  [        U R                  5      nU R                  (       a  [        R                  " S5      OSnUR                  X#S9nU R                  XC5      I Sh  vN   SSS5      ISh  vN   g N~ N N	! , ISh  vN  (       d  f       g= f7f)z.Serialise and send a :class:`~.Message` objectNi)fds)r5   nextr2   r0   array	serialise
_send_data)r8   r>   r=   rA   datas        r(   sendDBusConnection.sendO   sw     >>>~d223&*oo%++c"4C$$V$5D//$,,, ">>
 - ">>>sW   B2BB2A%B<B=BB2BB2BB2B/B!B/+B2rF   c                   #    U R                   R                  (       a  [        R                  " S5      e[	        5          U R
                  (       a#  U R                  U R
                  5      I S h  vN   [        U5       nU(       aZ  U R                   R                  U/[        R                   R                  [        R                   R                  U4/5      I S h  vN nO#U R                   R                  U5      I S h  vN nU R                  X5      I S h  vN   S S S 5        S S S 5        g  N NT N2 N! , (       d  f       N= f! , (       d  f       g = f7f)Nz!can't send data after sending EOF)r/   did_shutdown_SHUT_WRr#   r$   r)   r7   _send_remainder
memoryviewsendmsg
SOL_SOCKET
SCM_RIGHTSrG   )r8   rF   rA   sents       r(   rE   DBusConnection._send_dataZ   s     ;;++**+NOO68%%**4+A+ABBBD!T!%!4!4dV..0F0F? > " D "&!1!1$!77D**4666 " 98 C 86 "! 98s}   <E0E.D-/E>AD5D/#D5>D1?D5D3D5E$	E-E/D51D53D55
E	?E
EEc                 0  #     U[        U5      :  aF  XS   nU R                  R                  U5      I S h  vN nS S S 5        UW-  nU[        U5      :  a  MF  S U l        g  N*! , (       d  f       N.= f! [        R
                   a    XS  U l        e f = f7fN)lenr/   rG   r7   r#   	Cancelled)r8   rF   already_sent	remainingrP   s        r(   rK   DBusConnection._send_remainderm   s     	T*-(I!%!1!1)!<<D )$ T* &*D" = )( ~~ 	 &*-%8D"	sH   BA4 A#A!A#A4 A4  B!A##
A1-A4 4BBreturnc                 ~  #    U R                    ISh  vN    U R                  R                  5       nUb  UsSSS5      ISh  vN   $ U R                  5       I Sh  vN u  p#U(       d  [        R
                  " S5      eU R                  R                  X#5        M   N N[ ND! , ISh  vN  (       d  f       g= f7f)z5Return the next available message from the connectionNzSocket closed at the other end)r6   r1   get_next_message
_read_datar#   EndOfChanneladd_data)r8   msgbrA   s       r(   receiveDBusConnection.receive{   s     >>>kk224?	 ">>  $00++,LMM$$Q,  " 1 ">>sb   B=BB= B#B=BB=	B#B!A B#B=B=!B##B:)B,*B:6B=c                 V  #    U R                   (       a  U R                  R                  5       n[        5          U R                  R                  U[        5       5      I S h  vN u  p#pES S S 5        W[        [        R                  SS5      -  (       a  U R                  5         [        S5      eW[        R                  " W5      4$ [        5          U R                  R                  S5      I S h  vN nS S S 5        U/ 4$  N! , (       d  f       N= f N#! , (       d  f       W/ 4$ = f7f)N
MSG_CTRUNCr   z&Unable to receive all file descriptorsi   )r0   r1   bytes_desiredr)   r/   recvmsgr   getattrr#   _closeRuntimeErrorr   from_ancdatarecv)r8   nbytesrF   ancdataflags_s         r(   r\   DBusConnection._read_data   s     ??[[..0F:<040C0CLN1 +'u = wt{{L!<<"#KLL44W=== ;<![[--d33 =8O+ =< 4 =<8OsY   6D)(D D !D(A(D)D/D0D4D) D
DD)D
D&
D)c                 F    U R                   R                  5         S U l        g rS   )r/   closer7   r8   s    r(   rh   DBusConnection._close   s    !%r;   c                 ,   #    U R                  5         g7f)zClose the D-Bus connectionN)rh   rs   s    r(   acloseDBusConnection.aclose   s     s   c                l  #    [         R                  " 5        ISh  vN n[        U 5      nUR                  U5      I Sh  vN    U7v   UR	                  5       I Sh  vN   SSS5      ISh  vN   g NW N5 N! UR	                  5       I Sh  vN    f = f N)! , ISh  vN  (       d  f       g= f7f)a)  Temporarily wrap this connection as a :class:`DBusRouter`

To be used like::

    async with conn.router() as req:
        reply = await req.send_and_get_reply(msg)

While the router is running, you shouldn't use :meth:`receive`.
Once the router is closed, you can use the plain connection again.
N)r#   open_nursery
DBusRouterr.   rv   )r8   nurseryrouters      r(   r|   DBusConnection.router   s~      $$&&'%F,,w'''&mmo%% '&&' &fmmo%% '&&&s   B4A4B4 B A6BA:BA8B#B4.B/B46B8B:BB
BBB4B1 B#!B1-B4)r7   r0   r2   r1   r6   r5   r/   r3   )F)r   )__name__
__module____qualname____firstlineno____doc__r9   r   rG   bytesrE   rL   rK   ra   r\   rh   rv   r   r|   __static_attributes__ r;   r(   r+   r+   ;   sd    & 6: -' -7U 7&* -w -"&
 & &r;   r+   Fr0   rY   c                  #    [        U 5      n[        R                  " U5      I Sh  vN n[        USS9n[	        [
        S5      (       aO  UR
                  R                  S/[
        R                  [
        R                  [        S5      4/5      I Sh  vN   OUR                  S5      I Sh  vN   U HC  nUR                  U5      I Sh  vN   UR                  UR                  5       I Sh  vN 5        ME     UR                  [        5      I Sh  vN   [        UR
                  US9nUR                  5        ISh  vN nUR!                  ["        R$                  " 5       5      I Sh  vN nUR&                  S   Ul        SSS5      ISh  vN   U$  GNq GN N N N N Nd N: N! , ISh  vN  (       d  f       U$ = f7f)	z@Open a plain D-Bus connection

:return: :class:`DBusConnection`
NF)r0   inc_null_byte	SCM_CREDS    i   r   r   )r   r#   open_unix_socketr
   hasattrr/   rM   rN   r   r   send_allfeedreceive_somer   r+   r|   send_and_get_replyr   Hellobodyr3   )	busr0   bus_addrsockauthrreq_dataconnr|   replys	            r(   r   r      sa    
 s|H%)%:%:8%DDD ZuEEv{##kk!!Gv((&*:*:E#JGH
 	
 	

 mmE"""mmH%%%

**,,-  --
$++*=D {{}}//0A0A0CDD ::a= } K3  E	

 	#%, D }} Ks   %GFA,GFG.F/GF "G/F"
0$GF$,GF&G(F,-F(.F,GF*GGG G"G$G&G(F,*G,G2F53G?Gc                   R   ^  \ rS rSrS\4U 4S jjr\S 5       rS rS r	S r
SrU =r$ )	TrioFilterHandle   filtersc                 2   > [         TU ]  XU5        X0l        g rS   )superr9   send_channel)r8   r   rulesend_chnrecv_chn	__class__s        r(   r9   TrioFilterHandle.__init__   s    1$r;   c                     U R                   $ rS   queuers   s    r(   receive_channel TrioFilterHandle.receive_channel   s    zzr;   c                 t   #    U R                  5         U R                  R                  5       I S h  vN   g  N7frS   )rr   r   rv   rs   s    r(   rv   TrioFilterHandle.aclose   s&     

&&(((s   .868c                 "   #    U R                   $ 7frS   r   rs   s    r(   
__aenter__TrioFilterHandle.__aenter__   s     zzs   c                 @   #    U R                  5       I S h  vN   g  N7frS   )rv   )r8   exc_typeexc_valexc_tbs       r(   	__aexit__TrioFilterHandle.__aexit__   s     kkms   )r   )r~   r   r   r   r   r9   propertyr   rv   r   r   r   __classcell__r   s   @r(   r   r      s7    % %  ) r;   r   c                   0    \ rS rSrSrS rS rS rS rSr	g)	Future   z4A very simple Future for trio based on `trio.Event`.c                 F    S U l         [        R                  " 5       U l        g rS   )_outcomer#   Event_eventrs   s    r(   r9   Future.__init__   s    jjlr;   c                 X    [        U5      U l        U R                  R                  5         g rS   )r   r   r   set)r8   results     r(   
set_resultFuture.set_result   s    fr;   c                 X    [        U5      U l        U R                  R                  5         g rS   )r   r   r   r   )r8   r'   s     r(   set_exceptionFuture.set_exception   s    c
r;   c                    #    U R                   R                  5       I S h  vN   U R                  R                  5       $  N7frS   )r   waitr   unwraprs   s    r(   get
Future.get   s3     kk   }}##%% 	!s   A?A)r   r   N)
r~   r   r   r   r   r9   r   r   r   r   r   r;   r(   r   r      s    >#&r;   r   c                       \ rS rSrSrSrSrS\4S jr\	S 5       r
SS.S jrS	\4S
 jrSSS.S\\R                      4S jjrS\R$                  4S jrS rS\4S jr\R,                  4S jrSrg)rz   i  z|A client D-Bus connection which can wait for replies.

This runs a separate receiver task and dispatches received messages.
Nr   c                 L    Xl         [        5       U l        [        5       U l        g rS   )_connr   _repliesr   _filters)r8   r   s     r(   r9   DBusRouter.__init__
  s    
$&(r;   c                 .    U R                   R                  $ rS   )r   r3   rs   s    r(   r3   DBusRouter.unique_name  s    zz%%%r;   r<   c                R   #    U R                   R                  XS9I Sh  vN   g N7f)z/Send a message, don't wait for a reply
        r<   N)r   rG   )r8   r>   r=   s      r(   rG   DBusRouter.send  s      jjoogo555s   '%'rY   c                 r  #    [        U5        U R                  c  [        S5      e[        U R                  R
                  5      nU R                  R                  U[        5       5       nU R                  XS9I Sh  vN   UR                  5       I Sh  vN sSSS5        $  N% N! , (       d  f       g= f7f)ztSend a method call message and wait for the reply

Returns the reply message (method return or error message type).
NzThis DBusRouter has stoppedr<   )r   _rcv_cancel_scoper   rB   r   r2   r   catchr   rG   r   )r8   r>   r=   	reply_futs       r(   r   DBusRouter.send_and_get_reply  s     
 	 !!)<==djj001]]  2i))G)333#--/) 323) 32sB   A'B7)B&<B"=B&B$B&
B7"B&$B&&
B40B7r   )channelbufsizer   c                l    Uc  [         R                  " U5      u  p$OSn[        U R                  XU5      $ )a  Create a filter for incoming messages

Usage::

    async with router.filter(rule) as receive_channel:
        matching_msg = await receive_channel.receive()

    # OR:
    send_chan, recv_chan = trio.open_memory_channel(1)
    async with router.filter(rule, channel=send_chan):
        matching_msg = await recv_chan.receive()

If the channel fills up,
The sending end of the channel is closed when leaving the ``async with``
block, whether or not it was passed in.

:param jeepney.MatchRule rule: Catch messages matching this rule
:param trio.MemorySendChannel channel: Send matching messages here
:param int bufsize: If no channel is passed in, create one with this size
N)r#   open_memory_channelr   r   )r8   r   r   r   recv_channels        r(   filterDBusRouter.filter'  s6    * ?$($<$<W$E!G\LtlKKr;   r{   c                    #    U R                   b  [        S5      eUR                  U R                  5      I S h  vN U l         g  N
7f)Nz+DBusRouter receiver task is already running)r   ri   r.   	_receiver)r8   r{   s     r(   r.   DBusRouter.startD  s8     !!-LMM'.}}T^^'D!D!Ds   7AAAc                    #    U R                   b!  U R                   R                  5         SU l         [        R                  " S5      I Sh  vN   g N7f)z Stop the sender & receiver tasksNr   )r   cancelr#   sleeprs   s    r(   rv   DBusRouter.acloseI  s@      !!-""))+%)D" jjms   AA
AAr_   c                     U R                   R                  U5      (       a  gU R                  R                  U5       H  n UR                  R                  U5        M!     g! [        R                   a     M;  f = f)zHandle one received messageN)r   dispatchr   matchesr   send_nowaitr#   
WouldBlock)r8   r_   r   s      r(   	_dispatchDBusRouter._dispatchV  sd    ==!!#&&mm++C0F##//4 1 ?? s   A!!A98A9c           	      P  #    [         R                  " 5        nSU l        UR                  U5          U R                  R                  5       I Sh  vN nU R                  U5        M5   N! SU l        U R                  R                  5         [         R                  " S5       nU R                  R                  R                  5        H-  nSUl        UR                  R                  5       I Sh  vN    M/     SSS5        f ! , (       d  f       f = f= f! , (       d  f       g= f7f)z'Receiver loop - runs in a separate taskTNF   )r#   CancelScope
is_runningstartedr   ra   r   r   drop_allmove_on_afterr   r   valuesshieldr   rv   )r8   task_statuscscoper_   cleanup_scoper   s         r(   r   DBusRouter._receivera  s     6"DO'; $

 2 2 44CNN3' 4 #(&&( ''*m"&--"7"7">">"@/3,$1188::: #A +**  sX   D&DA*A(A**8D"AD	.C1/	D	8	D
DDD
D#D&)r   r   r   r   r   )r~   r   r   r   r   _nursery_mgrr   r+   r9   r   r3   rG   r   r   r   r#   MemorySendChannelr   Nurseryr.   rv   r   TASK_STATUS_IGNOREDr   r   r   r;   r(   rz   rz     s     L)^ )
 & & -1 6
+7 + IMVW Lx0F0F'G L:E4<< E
		W 	 +/*B*B ;r;   rz   c                   2   ^  \ rS rSrSrU 4S jrS rSrU =r$ )r   iw  a  A trio proxy for calling D-Bus methods

You can call methods on the proxy object, such as ``await bus_proxy.Hello()``
to make a method call over D-Bus and wait for a reply. It will either
return a tuple of returned data, or raise :exc:`.DBusErrorResponse`.
The methods available are defined by the message generator you wrap.

:param msggen: A message generator object.
:param ~trio.DBusRouter router: Router to send and receive messages.
c                 p   > [         TU ]  U5        [        U[        5      (       d  [	        S5      eX l        g )Nz)Proxy can only be used with DBusRequester)r   r9   
isinstancerz   	TypeError_router)r8   msggenr|   r   s      r(   r9   Proxy.__init__  s.     &*--GHHr;   c                    ^ ^ UU 4S jnU$ )Nc                     >#    T" U 0 UD6nUR                   R                  [        R                  L d   eTR                  R                  U5      I S h  vN n[        U5      $  N7frS   )headermessage_typer   method_callr  r   r   )argskwargsr_   r   make_msgr8   s       r(   inner!Proxy._method_call.<locals>.inner  sZ     D+F+C::**k.E.EEEE,,99#>>Ee$$ ?s   AA%A#A%r   )r8   r  r  s   `` r(   _method_callProxy._method_call  s    	% r;   )r  )	r~   r   r   r   r   r9   r  r   r   r   s   @r(   r   r   w  s    	 r;   r   c               <  #    [        XS9I Sh  vN nU ISh  vN   UR                  5        ISh  vN nU7v   SSS5      ISh  vN   SSS5      ISh  vN   g NN NE N. N! , ISh  vN  (       d  f       N0= f N'! , ISh  vN  (       d  f       g= f7f)a{  Open a D-Bus 'router' to send and receive messages.

Use as an async context manager::

    async with open_dbus_router() as req:
        ...

:param str bus: 'SESSION' or 'SYSTEM' or a supported address.
:return: :class:`DBusRouter`

This is a shortcut for::

    conn = await open_dbus_connection()
    async with conn:
        async with conn.router() as req:
            ...
r   N)r   r|   )r   r0   r   rtrs       r(   r   r     sY     & &cAADt;;==CI != tt B === ttts   BA
BA BBA"BA&BA$	BBB B B"B$B&A=	,A/-A=	9B BBB	BB)SESSION)4rC   r    loggingr/   
contextlibr   r   	itertoolsr   typingr   outcomer   r   r#   trio.abcr	   jeepney.authr
   r   jeepney.busr   jeepney.fdsr   r   jeepney.low_levelr   r   r   jeepney.wrappersr   r   jeepney.bus_messagesr   commonr   r   r   r   r   	getLoggerr~   log__all__r)   r+   r   r   r   rz   r   r   r   r;   r(   <module>r)     s        :       -  4 : : 2 ,  !& 
 
{&W {&|E n D| (& &&r; r;jI 6   r;   