
    q&fW                        d dl 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	m
ZmZmZmZmZmZmZ ddlmZmZ ddlmZ ej0                  Zd	 Zd
 Z G d dej6                        Z ej:                  ej<                         G d d             Z ej:                  ej@                  ejB                         G d dejD                               Z#y)    N)futures   )_)bin)bundle2changegroupencodingerrorpushkeypycompatutilwireprototypes)
repositoryr   )hashutilc                 Z      fd}t        |d        t        |d j                         |S )a  annotation for batchable methods

    Such methods must implement a coroutine as follows:

    @batchable
    def sample(self, one, two=None):
        # Build list of encoded arguments suitable for your wire protocol:
        encoded_args = [('one', encode(one),), ('two', encode(two),)]
        # Return it, along with a function that will receive the result
        # from the batched request.
        return encoded_args, decode

    The decorator returns a function which wraps this coroutine as a plain
    method, but adds the original method as an attribute called "batchable",
    which is used by remotebatch to split the call into separate encoding and
    decoding phases.
    c                       | i |\  }}|s|S | d   }t        j                  j                        }|j                  ||      } ||      S )Nr   )r   bytesurl__name__
_submitone)argsoptsencoded_args_or_resdecodeselfcmdencoded_resfs          ;/usr/lib/python3/dist-packages/mercurial/wireprotov1peer.pyplainzbatchable.<locals>.plain5   sZ    &'&6&6#V&&Aw

+ooc+>?k""    	batchabler   )setattrr   )r   r   s   ` r   r!   r!   "   s+    &# E;"E:qzz*Lr    c                    t         j                  g }| D ]Y  \  }}t        fd|D              sJ dj                  fd|j	                         D              }|j                  d||fz         [ dj                  |      S )z;Return a ``cmds`` argument value for the ``batch`` command.c              3   4   K   | ]  } |      |k(    y wN ).0k	escapeargs     r   	<genexpr>z"encodebatchcmds.<locals>.<genexpr>L   s     79Q<1$7s      ,c              3   J   K   | ]  \  }}d  |       |      fz    yw)s   %s=%sNr&   )r'   r(   vr)   s      r   r*   z"encodebatchcmds.<locals>.<genexpr>N   s,      
8<1H	!il33
s    #s   %s %s   ;)r   escapebatchargalljoinitemsappend)reqcmdsopargsdictr   r)   s        @r   encodebatchcmdsr8   C   s    --ID 	+H 7h7777yy 
@H@P
 
 	HDz)*	+ 99T?r    c                       e Zd ZdZddZy)unsentfuturea0  A Future variation to represent an unsent command.

    Because we buffer commands and don't submit them immediately, calling
    ``result()`` on an unsent future could deadlock. Futures for buffered
    commands are represented by this type, which wraps ``result()`` to
    call ``sendcommands()``.
    Nc                     | j                         r t        j                  j                  | |      S | j                  j                          | j                  |      S r%   )doner   Futureresult_peerexecutorsendcommands)r   timeouts     r   r>   zunsentfuture.result_   sE    99;>>((w77'')
 {{7##r    r%   )r   
__module____qualname____doc__r>   r&   r    r   r:   r:   V   s    	$r    r:   c                   6    e Zd Zd Zd Zd Zd Zd Zd Zd Z	y)	peerexecutorc                     || _         d| _        d| _        g | _        t	        j
                         | _        d | _        d | _        y )NF)	_peer_sent_closed_callsweakrefWeakSet_futures_responseexecutor
_responsef)r   peers     r   __init__zpeerexecutor.__init__m   s;    

)!%r    c                     | S r%   r&   r   s    r   	__enter__zpeerexecutor.__enter__v   s    r    c                 $    | j                          y r%   )close)r   exctypeexcvaleeexctbs       r   __exit__zpeerexecutor.__exit__y   s    

r    c                      j                   rt        j                  d       j                  rt        j                  d      t	         j
                  t        j                        d       st        j                  dz         fd}t	        dd      r |       }t        |_	         |_
        |S  j                  rt        j                  dz         |       } j                          |S )Ns4   callcommand() cannot be used after commands are sents*   callcommand() cannot be used after close()sA   cannot call command %s: method of same name not available on peerc                      t        j                         } j                  j                  |        j                  j                  | f       | S r%   )r   r=   rN   addrK   r3   )r   r   commandfnr   s    r   addcallz)peerexecutor.callcommand.<locals>.addcall   sA     AMMa KKr156Hr    r!   FsX   %s is not batchable and cannot be called on a command executor along with other commands)rI   r
   ProgrammingErrorrJ   getattrrH   r   sysstrr:   	__class__r?   rK   r@   )r   r_   r   ra   r   r`   s   ```  @r   callcommandzpeerexecutor.callcommand|   s    ::((G  <<((= 
 TZZ!94@(($% 	 2{E*	A 'AK"AO  {{,,:<CD 
 	A r    c                 r   | j                   ry | j                  sy d| _         | j                  D ]/  }t        |t              st
        j                  |_        d |_        1 | j                  }d | _        t        |      dk(  rI|d   \  }}}}|j                         sy 	  |di t        j                  |      }|j                  |       y g }g }|D ]  \  }}}}|j                         s	  |j$                  |j&                  fi t        j                  |      \  }	}
|
s|j                  |	       a|j)                  ||	f       |j)                  ||t$        |
f        |sy | j*                  j-                  |      }t        j.                  d      | _        | j0                  j3                  | j4                  ||      | _        y # t        $ r. t        j                  |t!        j"                         dd         Y y w xY w# t        $ r/ t        j                  |t!        j"                         dd         Y  y w xY w)NTr   r   r&   )rI   rK   rN   
isinstancer:   r   r=   re   r?   lenset_running_or_notify_cancelr   	strkwargs
set_result	Exceptionfuture_set_exception_infosysexc_infor!   __self__r3   rH   _submitbatchThreadPoolExecutorrO   submit_readbatchresponserP   )r   r   callsr_   r   r`   r>   requestsstatesr   r   wireresultss               r   r@   zpeerexecutor.sendcommands   s   ::{{
  	'A!\*%nn"&	'
  u:?#(8 GT2q 113%7h0067 V$ $) 	? GT2q113.:bllKK/#+#5#5d#;/+#V 01*= >?w9f=>#	?&  jj--h7 ")!;!;A!>0077##V[
a  J221cllnQR6HI J4  221cllnQR6HIs$   G *3G>4G;:G;>4H65H6c           
         | j                          | j                  ry d| _        | j                  sy 	 | j                  j                          | j                  j                  d       d | _        d | _        | j                  D ]A  }|j                         r|j                  t        j                  t        d      d              C d | _        y # | j                  j                  d       d | _        d | _        | j                  D ]A  }|j                         r|j                  t        j                  t        d      d              C d | _        w xY w)NT)wait"   unfulfilled batch command response)r@   rJ   rP   r>   rO   shutdownrN   r<   set_exceptionr
   ResponseErrorr   )r   r   s     r   rW   zpeerexecutor.close  s&   <<	!OO""$""+++6"DO%)D" ]] vvxOO++CDd !DM ""+++6"DO%)D" ]] vvxOO++CDd !DMs   C A
E8Ec           	      V   |D ]-  \  }}}}	 t        |      }	  ||      }|j                  |       / y # t        $ r. t        j                  |t        j                         dd         Y gw xY w# t        $ r1 |j                  t        j                  t        d      d              Y w xY w)Nr   r|   )nextrl   rm   r   rn   ro   rp   StopIterationr~   r
   r   r   )	r   rx   ry   r_   r   r!   r   remoteresultr>   s	            r   ru   zpeerexecutor._readbatchresponse%  s     .4 	))GQ	6)#K0)#L1F LL()	)" ! N66q#,,.:LMN !  ''?@$	s    A.44A+*A+.7B('B(N)
r   rB   rC   rR   rU   r[   rf   r@   rW   ru   r&   r    r   rF   rF   k   s)    5nP
d!@)r    rF   c                       e Zd ZdZd Zd Zd Zd Zed        Z	ed        Z
ed        Zed	        Zed
        Zed        Zd Zd Zd Zd Zd Zd Zd Zd Zd ZddZd Zd Zd Zd Zd Zd Zy)wirepeerzClient-side interface for communicating with a peer repository.

    Methods commonly call wire protocol commands of the same name.

    See also httppeer.py and sshpeer.py for protocol-specific
    implementations of this interface.
    c                     t        |       S r%   )rF   rT   s    r   commandexecutorzwirepeer.commandexecutorK  s    D!!r    c                     | j                  d      r| j                  d      S | j                  dt        d             | j                  d      S )Ns   clonebundles_manifests   clonebundless   clone bundles)capable_call
requirecapr   rT   s    r   clonebundleszwirepeer.clonebundlesP  sB    <<01::677OOOQ/?-@A::o..r    c                      y r%   r&   )r   streams     r   _finish_inline_clone_bundlez$wirepeer._finish_inline_clone_bundleW  s    r    c              #      K   | j                  d|      }t        j                  |      }t        j                  ||      D ]  }|  | j	                  |       y w)Ns   get_cached_bundle_inline)path)limit)_callstreamr   uvarintdecodestreamfilechunkiterr   )r   r   r   lengthchunks        r   get_cached_bundle_inlinez!wirepeer.get_cached_bundle_inlineZ  s_     !!"=D!I))&1 ''f= 	EK	 	((0s   AAc                 v      j                  dt        d              fd}dt        j                  |      i|fS )Ns   lookups   look up remote revisionc                     | d d j                  dd      \  }}t        |      rt        |      S j                  t	        j
                  |             y )N    r   )splitintr   _abortr
   	RepoError)dsuccessdatar   s      r   r   zwirepeer.lookup.<locals>.decodeh  sC    crFLLq1MGT7|4y EOOD12r       key)r   r   r	   	fromlocal)r   keyr   s   `  r   lookupzwirepeer.lookupd  s9    	1%?#@A	3 **3/0&88r    c                       fd}i |fS )Nc                     	 t        j                  | d d       S # t        $ r1 j                  t	        j
                  t        d      |              Y y w xY w)Nr      unexpected response:)r   
decodelist
ValueErrorr   r
   r   r   )r   r   s    r   r   zwirepeer.heads.<locals>.decodes  sP    P%003B88 PE//2I0JANOPs    7AAr&   r   r   s   ` r   headszwirepeer.headsq  s    	P 6zr    c                 @      fd}dt        j                  |      i|fS )Nc                     	 t        j                  |       D cg c]  }t        t        |             c}S c c}w # t        $ r1 j                  t        j                  t        d      |              Y y w xY w)Nr   )	r   iterbytestrboolr   r   r   r
   r   r   )r   br   s     r   r   zwirepeer.known.<locals>.decode}  s`    P.6.B.B1.EFSVFFF PE//2I0JANOPs   = 8= = 7A76A7   nodes)r   
encodelist)r   nodesr   s   `  r   knownzwirepeer.known{  s&    	P .33E:;VCCr    c                       fd}i |fS )Nc                 `   	 i }| j                         D ]Y  }|j                  dd      \  }}t        j                  t        j                  |            }t        j                  |      }|||<   [ |S # t        $ r1 j                  t        j                  t        d      |              Y y w xY w)Nr   r   r   )
splitlinesr   r	   tolocalurlrequnquoter   r   	TypeErrorr   r
   r   r   )r   	branchmap
branchpart
branchnamebranchheadsr   s        r   r   z"wirepeer.branchmap.<locals>.decode  s    	P	"#,,. 8J.8.>.>tQ.G+J!)!1!1&..2L!MJ"0";";K"HK,7Ij)	8
 !  PE//2I0JANOPs   A/A3 37B-,B-r&   r   s   ` r   r   zwirepeer.branchmap  s    
	P 6zr    c                       j                  d      si d fS  j                  j                  dz          fd}dt        j                        i|fS )N   pushkeys   preparing listkeys for "%s"
c                     j                   j                  dt        |       fz         t        j                  |       S )Ns$   received listkey for "%s": %i bytes
)uidebugri   
pushkeymod
decodekeys)r   	namespacer   s    r   r   z!wirepeer.listkeys.<locals>.decode  s7    GGMM8Is1v;NN ((++r    	   namespacer   r   r   r	   r   )r   r   r   s   `` r   listkeyszwirepeer.listkeys  sP    ||J't8O6BC	, h00;<fDDr    c                      j                  d      sy j                  j                  d||fz          fd}t        j                  |      t        j                  |      t        j                  |      t        j                  |      d|fS )Nr   )FNs   preparing pushkey for "%s:%s"
c                 *   | j                  dd      \  } }	 t        t        |             } |j                  d      D ]'  }j                  j                  t        d      |       ) | S # t        $ r  t	        j
                  t        d      |       w xY w)N   
r   "   push failed (unexpected response):T   remote: )
r   r   r   r   r
   r   r   r   r   status)r   outputlr   s      r   r   z wirepeer.pushkey.<locals>.decode  s    q)IAvQL
 &&t, 2q~q12H  ));<a s   A) ))B)r   r   s   olds   newr   )r   r   r   oldnewr   s   `     r   r   zwirepeer.pushkey  s    ||J'8Is;KKL
	 #,,Y7&&s+&&s+&&s+	

  	r    c                 $    | j                  d      S )Ns
   stream_out)r   rT   s    r   
stream_outzwirepeer.stream_out  s    ..r    c                    t        j                  |      }| j                  dt        d             i }|j	                  d      xs
 t               }|j                         D ]  \  }}|	t        j                  j	                  |      }|t        j                  d|z        |dk(  rt        j                  |      }n^|dk(  rdj                  |      }nG|dk(  rdj                  t        |            }n'|d	k(  rd
t        |      z  }n|dk7  rt        d|z        |||<     | j                   di t        j"                  |      }t%        d |D              r t'        j(                  | j*                  |      S t-        j.                  |d      S )N	   getbundle   look up remote changess
   bundlecapss$   Unexpectedly None keytype for key %sr   s   csvr+   s   scsvs   booleans   %is   plains    unknown getbundle option type %sc              3   >   K   | ]  }|j                  d         yw)s   HG2N)
startswith)r'   caps     r   r*   z%wirepeer.getbundle.<locals>.<genexpr>  s     =3v&=s      UN)r   )r   byteskwargsr   r   getsetr2   r   GETBUNDLE_ARGUMENTSr
   rb   r   r1   sortedr   KeyError_callcompressablerk   anyr   getunbundlerr   changegroupmodcg1unpacker)	r   sourcekwargsr   
bundlecapsr   valuekeytyper   s	            r   	getbundlezwirepeer.getbundle  ss   %%f-a(A&BCZZ.7#%
 ,,. 	JC}$88<<SAG,,;cA  H$&11%8F"		%(G#		&-0J&U+H$BWLMMDI%	& #D""L83E3Ed3KL=*=>''33!--a77r    c           
         |dgk7  rb| j                  d      rQt        j                  dt        j                  dj                  t        |                  j                         g      }nt        j                  |      }t        |d      r| j                  d||      \  }}|dk(  rt        j                  t        d      |      	 t        |      }|j                  d
      D ]'  }| j                   j#                  t        d      |       ) |S | j%                  d||      }t'        j(                  | j                   |      }|S # t        $ r  t        j                  t        d	      |      w xY w)a  Send cg (a readable file-like object representing the
        changegroup to push, typically a chunkbuffer object) to the
        remote server as a bundle.

        When pushing a bundle10 stream, return an integer indicating the
        result of the push (see changegroup.apply()).

        When pushing a bundle20 stream, return a bundle20 stream.

        `url` is the url the client thinks it's pushing to, which is
        visible to hooks.
        s   forces   unbundlehashs   hashedr    deltaheaders   unbundle)r   s   push failed:r   Tr   )r   r   r   r   sha1r1   r   digesthasattr	_callpushr
   r   r   r   r   r   r   r   _calltwowaystreamr   r   )r   bundler   urlretr   r   r   s           r   unbundlezwirepeer.unbundle  sM    XJ4<<#@"--HMM#((6%=*ABIIKLE #--e4E6=)..fE.JKCcz))!O*<fEE#h &&t, 2q~q12 
 ++Ku+MF&&tww7C
  ));<c s   E )E-c                 N   t        j                  |      }| j                  d|      }	 |j                         D cg c]   }t	        t        j
                  |            " }}|S c c}w # t        $ r1 | j                  t        j                  t        d      |             Y y w xY w)Ns   branches)r   r   )r   r   r   r   tupler   r   r   r
   r   r   )r   r   nr   r   brs         r   brancheszwirepeer.branches
  s    %%e,JJ{!J,	L?@||~N!%11!45NBNI O 	LKK++A.E,FJK	Ls"   A* %A%!A* %A* *7B$#B$c           
         d}g }t        dt        |      |      D ]u  }dj                  ||||z    D cg c]  }t        j                  |d       c}      }| j                  d|      }	 |j                  d |j                         D               w |S c c}w # t        $ r1 | j                  t        j                  t        d      |             Y w xY w)	N   r   r      -s   between)pairsc              3   V   K   | ]!  }|xr t        j                  |      xs g  # y wr%   )r   r   )r'   r   s     r   r*   z#wirepeer.between.<locals>.<genexpr>  s0       6.33A6<"<s   ')r   )rangeri   r1   r   r   r   extendr   r   r   r
   r   r   )r   r  batchripr   r   s           r   betweenzwirepeer.between  s    q#e*e, 	PA		 #1q5y1 #--a6A 

:Q
/AP \\^ 	P   PE//2I0JANOPs   B
+&B7CCc                 ~    t        j                  |      }| j                  d|      }t        j                  |d      S )Ns   changegroup)rootsr   )r   r   r   r   r   )r   r   r   r   r   s        r   r   zwirepeer.changegroup'  s:    %%e,"">";))!U33r    c                     | j                  dt        d             t        j                  |      }t        j                  |      }| j	                  d||      }t        j                  |d      S )Ns   changegroupsubsetr   )basesr   r   )r   r   r   r   r   r   r   )r   r  r   r   r   s        r   changegroupsubsetzwirepeer.changegroupsubset,  sh    ,a0I.JK))%0))%0"" U # 
 ))!U33r    c              #     K   | j                   }|j                  rN|j                  dd      r<|j                  d       |D ]&  \  }}d}|j                  ||t	        |      fz         ( t
        j                  }| j                  dt        |            }|j                  d      }|g}	|rd|vr+|r)|j                  d      }|	j                  |       d|vr|r)d	j                  |	      }
d|
v r$|
j                  dd
      \  }}
 ||       d|
v r$|j                  d      }|
|g}	|r |d	j                  |	             yw)zqrun batch request <req> on the server

        Returns an iterator of the raw responses from the server.
        s   devels   debug.peer-requests$   devel-peer-request: batched-content
s+   devel-peer-request:    - %s (%d arguments)
s   batch)r5   i   r.   r    r   N)r   	debugflag
configboolr   ri   r   unescapebatchargr   r8   readr3   r1   r   )r   r4   r   r6   r   msgunescapeargrspr   workmergedones               r   rr   zwirepeer._submitbatch7  sA    
 WW<<BMM(4IJHH=> 0DECI./0 %55xoc.BCwe#E" e# XXd^F&.$ll43V!#&& &. HHTNEE?D  #((4.))s   CE8EE+Ec                 N     | j                   |fi t        j                  |      S r%   )r   r   rk   )r   r6   r   s      r   r   zwirepeer._submitoneT  s#    tzz"9 2 24 899r    Nc                 L    i }|||d<   |||d<    | j                   d||d|S )Nthreefour)r  two)s   debugwireargs)r   )r   r  r"  r   r!  fiver   s          r   debugwireargszwirepeer.debugwireargsW  s@    !DMDLtzzEEEEr    c                     t               )zexecute <cmd> on the server

        The command is expected to return a simple string.

        returns the server reply as a string.NotImplementedErrorr   r   r   s      r   r   zwirepeer._call`  s     "##r    c                     t               )a  execute <cmd> on the server

        The command is expected to return a stream. Note that if the
        command doesn't return a stream, _callstream behaves
        differently for ssh and http peers.

        returns the server reply as a file like object.
        r&  r(  s      r   r   zwirepeer._callstreamh       "##r    c                     t               )aE  execute <cmd> on the server

        The command is expected to return a stream.

        The stream may have been compressed in some implementations. This
        function takes care of the decompression. This is the only difference
        with _callstream.

        returns the server reply as a file like object.
        r&  r(  s      r   r   zwirepeer._callcompressables  s     "##r    c                     t               )zexecute a <cmd> on server

        The command is expected to be related to a push. Push has a special
        return method.

        returns the server reply as a (ret, output) tuple. ret is either
        empty (error) or a stringified int.
        r&  r   r   fpr   s       r   r   zwirepeer._callpush  r*  r    c                     t               )zqexecute <cmd> on server

        The command will send a stream to the server and get a stream in reply.
        r&  r-  s       r   r   zwirepeer._calltwowaystream  s    
 "##r    c                     t               )zBclearly abort the wire protocol connection and raise the exceptionr&  )r   	exceptions     r   r   zwirepeer._abort  s    !##r    )NNN)r   rB   rC   rD   r   r   r   r   r!   r   r   r   r   r   r   r   r   r   r  r  r   r  rr   r   r$  r   r   r   r   r   r   r&   r    r   r   r   ?  s    "
/1 
9 
9   D D   E E  0/8<'ZL(4
4*::F$	$$	$$$r    r   )$ro   rL   
concurrentr   i18nr   noder    r   r   r   r	   r
   r   r   r   r   r   
interfacesr   interfaceutilutilsr   r   r!   r8   r=   r:   implementeripeercommandexecutorrF   ipeercommandsipeerlegacycommandsrQ   r   r&   r    r   <module>r=     s        	 	 	 	B&$7>> $* :::;P) P) <P)f j<<R$z R$R$r    