o ]LbV@sddlmZddlZddlZddlmZddlmZddlm Z m Z ddl m Z m ZmZmZmZmZmZmZddlmZmZdd lmZejZd d Zd d ZGdddejjZe ej!Gddde"Z#e ej$ej%Gdddej&Z'dS))absolute_importN)_)bin)getattrsetattr)bundle2 changegroupencodingerrorpushkeypycompatutilwireprototypes) repositoryr)hashutilcs*fdd}t|dt|dj|S)aannotation 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. csB|i|\}}|s |S|d}tj}|||}||S)Nr)r bytesurl__name__ _submitone)argsoptsencoded_args_or_resdecodeselfcmd encoded_resf;/usr/lib/python3/dist-packages/mercurial/wireprotov1peer.pyplain9s  zbatchable..plain batchabler)rr)rr rrrr!&s  r!csltjg}|D])\}}tfdd|DsJdfddt|D}|d||fqd|S)z;Return a ``cmds`` argument value for the ``batch`` command.c3s|] }||kVqdSNr).0k escapeargrr Psz"encodebatchcmds..,c3s(|]\}}d||fVqdS)s%s=%sNr)r#r$vr%rrr'Rs  s%s %s;)rescapebatchargalljoinr iteritemsappend)reqcmdsopargsdictrrr%rencodebatchcmdsGs  r4c@seZdZdZdddZdS) unsentfuturea0A 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()``. NcCs,|r tjj||S|j||Sr")doner futuresFutureresult _peerexecutor sendcommands)rtimeoutrrrr9ds  zunsentfuture.resultr")r __module__ __qualname____doc__r9rrrrr5[sr5c@sDeZdZddZddZddZddZd d Zd d Zd dZ dS) peerexecutorcCs2||_d|_d|_g|_t|_d|_d|_dS)NF) _peer_sent_closed_callsweakrefWeakSet_futures_responseexecutor _responsef)rpeerrrr__init__rs  zpeerexecutor.__init__cCs|Sr"rrrrr __enter__{szpeerexecutor.__enter__cCs |dSr")close)rexctypeexcvaleeexctbrrr__exit__~s zpeerexecutor.__exit__csjrtdjrtdtjtds#tdfdd}tddr=|}t|_ |_ |Sj rGtd|} |S) Ns4callcommand() cannot be used after commands are sents*callcommand() cannot be used after close()sAcannot call command %s: method of same name not available on peercs.tj}j|j|f|Sr")r r7r8rGaddrDr/rrcommandfnrrraddcalls  z)peerexecutor.callcommand..addcallr!FsX%s is not batchable and cannot be called on a command executor along with other commands) rBr ProgrammingErrorrCrrAr sysstrr5 __class__r:rDr;)rrUrrWrrrTr callcommands< zpeerexecutor.callcommandc Cs|jrdS|js dSd|_|jD]}t|trtjj|_d|_ q|j}d|_t |dkrd|d\}}}}| s:dSz |dit |}Wnt y\t|tddYdSw||dSg}g}|D]L\}}}}| suqjz|j|jfit |\} } Wnt yt|tddYdSw| s|| qj||| f|||t| fqj|sdS|j|} tjd|_|j|j|| |_dS)NTrrr)rBrDrG isinstancer5r r7r8rZr:lenset_running_or_notify_cancel strkwargs Exceptionfuture_set_exception_infosysexc_info set_resultr!__self__r/rA _submitbatchThreadPoolExecutorrHsubmit_readbatchresponserI) rrcallsrUrrVr9requestsstatesrr wireresultsrrrr;sd           zpeerexecutor.sendcommandsc Cs||jr dSd|_|jsdSz-|jW|jjddd|_d|_|jD]}|s9|t t ddq(d|_dS|jjddd|_d|_|jD]}|s`|t t ddqOd|_w)NT)wait"unfulfilled batch command response) r;rCrIr9rHshutdownrGr6 set_exceptionr ResponseErrorr)rrrrrrN s@    zpeerexecutor.closec Cs|D]B\}}}}zt|}Wnty"|ttddYqwz||}Wnty>t|t ddYqw| |qdS)Nror) next StopIterationrqr rrrr`r rarbrcrd) rrlrmrUrr!r remoteresultr9rrrri*s"     zpeerexecutor._readbatchresponseN) rr=r>rKrMrRr[r;rNrirrrrr@ps 7R r@c@seZdZdZddZddZeddZedd Zed d Z ed d Z eddZ eddZ ddZ ddZddZddZddZddZddZd d!Zd"d#Zd3d%d&Zd'd(Zd)d*Zd+d,Zd-d.Zd/d0Zd1d2Zd$S)4wirepeerzClient-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. cCst|Sr")r@rLrrrcommandexecutorPszwirepeer.commandexecutorcCs|dtd|dS)Ns clonebundless clone bundles) requirecapr_callrLrrr clonebundlesUs zwirepeer.clonebundlescs.dtdfdd}dt|i|fS)Nslookupslook up remote revisioncs<|dddd\}}t|rt|St|dS)N r)splitintr_abortr RepoError)dsuccessdatarLrrr]szwirepeer.lookup..decodekey)rxrr fromlocal)rkeyrrrLrlookupYs zwirepeer.lookupcfdd}i|fS)Nc s@z t|ddWStyttd|YdSw)Nr{unexpected response:)r decodelist ValueErrorrr rrrrrLrrrhs  zwirepeer.heads..decoderrrrrLrheadsfs zwirepeer.headscsfdd}dt|i|fS)Nc sBz ddt|DWSty ttd|YdSw)NcSsg|]}tt|qSr)boolr~r#brrr tsz2wirepeer.known..decode..r)r iterbytestrrrr rrrrrLrrrrs  zwirepeer.known..decodenodesr encodelist)rnodesrrrLrknownps zwirepeer.knowncr)Nc svz%i}|D]}|dd\}}tt|}t|}|||<q|WSty: t t d|YdSw)Nr|rr) splitlinesr}r tolocalurlrequnquoterr TypeErrorrr rrr)r branchmap branchpart branchname branchheadsrLrrr|s    z"wirepeer.branchmap..decoderrrrLrrzs  zwirepeer.branchmapcsBds idfSjdfdd}dti|fS)Npushkeyspreparing listkeys for "%s" cs"jdt|ft|S)Ns$received listkey for "%s": %i bytes )uidebugr] pushkeymod decodekeysr namespacerrrrs z!wirepeer.listkeys..decode namespacecapablerrr r)rrrrrrlistkeyss zwirepeer.listkeyscsXdsdSjd||ffdd}t|t|t|t|d|fS)Nr)FNspreparing pushkey for "%s:%s" csf|dd\}}ztt|}Wntyttd|w|dD] }j td|q%|S)N r"push failed (unexpected response):Tremote: ) r}rr~rr rrrrrstatus)routputlrLrrrs z wirepeer.pushkey..decode)rrsoldsnewr)rrroldnewrrrLrr s   zwirepeer.pushkeycCs |dS)Ns stream_out) _callstreamrLrrr stream_outs zwirepeer.stream_outc Ks"t|}|dtdi}|dpt}t|D]S\}}|dur%qtj|}|dur6t d||dkr@t |}n+|dkrJd |}n!|dkrVd t |}n|d krad t|}n |d krktd ||||<q|jdit|}td d|Drt|j|St|dS)N getbundlelook up remote changess bundlecapss$Unexpectedly None keytype for key %srscsvr(sscsvsbooleans%isplains unknown getbundle option type %scss|]}|dVqdS)sHG2N) startswith)r#caprrrr'sz%wirepeer.getbundle..UN)r)r byteskwargsrxrgetsetr.rGETBUNDLE_ARGUMENTSr rXrr-sortedrKeyError_callcompressabler_anyr getunbundlerrchangegroupmod cg1unpacker) rsourcekwargsr bundlecapsrvaluekeytyperrrr getbundles6       zwirepeer.getbundlec Cs|dgkr|drtdtdt|g}nt|}t |drf|j d||d\}}|dkr=t t d|zt|}WntyRt t d |w|d D] }|jt d |qX|S|jd||d}t|j|}|S) aSend 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. sforces unbundlehashshasheds deltaheadersunbundle)rs push failed:rTr)rrrrsha1r-rdigestr safehasattr _callpushr rrrr~rrrr_calltwowaystreamrr)rbundlerurlretrrstreamrrrunbundles,    zwirepeer.unbundlec Cs\t|}|jd|d}z dd|D}|WSty-|ttd|YdSw)Nsbranches)rcSsg|] }tt|qSr)tuplerrrrrrrsz%wirepeer.branches..r) rrryrrrr rrr)rrnrbrrrrbranchess  zwirepeer.branchesc Csd}g}tdt||D];}ddd||||D}|jd|d}z|dd |DWq tyH|t t d |Yq w|S) Nrr|cSsg|]}t|dqS)-r)r#prrrr s z$wirepeer.between..sbetween)pairscss"|] }|r t|p gVqdSr")rr)r#rrrrr's  z#wirepeer.between..r) r xranger]r-ryextendrrrr rrr)rrbatchrirrrrrbetweens"  zwirepeer.betweencCs$t|}|jd|d}t|dS)Ns changegroup)rootsr)rrrrr)rrrrrrrrr s  zwirepeer.changegroupcCs@|dtdt|}t|}|jd||d}t|dS)Nschangegroupsubsetr)basesrr)rxrrrrrr)rrrrrrrrchangegroupsubset!s   zwirepeer.changegroupsubsetc cs|j}|jr&|ddr&|d|D]\}}d}|||t|fqtj}|jdt|d}| d}|g} |rwd|vrR|rR| d}| |d|vrR|sBd | } d| vrl| dd \} } || Vd| vs[| d}| |g} |s<|d | Vd S) zqrun batch request on the server Returns an iterator of the raw responses from the server. sdevelsdebug.peer-requests$devel-peer-request: batched-content s+devel-peer-request: - %s (%d arguments) sbatch)r1ir*rrN) r debugflag configboolrr]runescapebatchargrr4readr/r-r}) rr0rr2rmsg unescapeargrspchunkworkmergedonerrrrf,s2          zwirepeer._submitbatchcCs|j|fit|Sr")ryr r_)rr2rrrrrIszwirepeer._submitoneNcCs:i}|dur ||d<|dur||d<|jd||d|S)Nthreefour debugwireargs)rtwo)r)ry)rrrrrfiverrrr debugwireargsLs zwirepeer.debugwireargscKt)zexecute on the server The command is expected to return a simple string. returns the server reply as a string.NotImplementedErrorrrrrrrryUszwirepeer._callcKr)a execute 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. rrrrrr] zwirepeer._callstreamcKr)aEexecute 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. rrrrrrhs zwirepeer._callcompressablecKr)zexecute a 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. rrrfprrrrrurzwirepeer._callpushcKr)zqexecute on server The command will send a stream to the server and get a stream in reply. rrrrrrszwirepeer._calltwowaystreamcCr)zBclearly abort the wire protocol connection and raise the exceptionr)r exceptionrrrrszwirepeer._abort)NNN)rr=r>r?rwrzr!rrrrrr rrrrrr rrfrrryrrrrrrrrrrvDs@      -       rv)( __future__rrbrEi18nrnoderr rrrr rr r r rrr interfacesr interfaceutilutilsrrr!r4r7r8r5 implementeripeercommandexecutorobjectr@ ipeercommandsipeerlegacycommandsrJrvrrrrs(   ( ! T