o ]Lb@sddlmZddlmZddlmZmZmZmZddlm Z ddZ Gdd d e Z Gd d d e Z Gd d d e ZddZGddde ZGddde ZGdddeZGdddeZdddZGddde ZGdddeZdS) )absolute_import)getattr)encodingerrorpycompatutil) stringutilcCstt|jdS)N_)rsysbytestype__name__lstrip)or4/usr/lib/python3/dist-packages/mercurial/smartset.py _typenamesrc@seZdZddZeZddZddZdZdZdd Z d d Z d d Z ddZ ddZ ddZddZddZddZd*ddZddZdd Zd!d"Zd+d$d%Zd&d'Zd(d)ZdS),abstractsmartsetcCt)z!True if the smartset is not emptyNotImplementedErrorselfrrr __nonzero__zabstractsmartset.__nonzero__cCr)zprovide fast membership testingr)rrevrrr __contains__rzabstractsmartset.__contains__cCr)z:iterate the set in the order it is supposed to be iteratedrrrrr__iter__#rzabstractsmartset.__iter__NcCr)z/True if the set will iterate in ascending orderrrrrr isascending/rzabstractsmartset.isascendingcCr)z0True if the set will iterate in descending orderrrrrr isdescending3rzabstractsmartset.isdescendingcCr)z3True if the set will iterate in topographical orderrrrrristopo7rzabstractsmartset.istopocs>|jdur t|n |D]ntdfdd|_S)z%return the minimum element in the setNarg is an empty sequencecSNrrvrrDz&abstractsmartset.min..)fastascmin ValueErrorrrr$rr);s   zabstractsmartset.mincs<|jdur t|S|D]ntdfdd|_S)z%return the maximum element in the setNr!cr"r#rrr$rrr&Pr'z&abstractsmartset.max..)fastdescmaxr*rrr$rr,Gs  zabstractsmartset.maxcCr)zireturn the first element in the set (user iteration perspective) Return None if the set is emptyrrrrrfirstSzabstractsmartset.firstcCr)zhreturn the last element in the set (user iteration perspective) Return None if the set is emptyrrrrrlastYr.zabstractsmartset.lastcCr)zkreturn the length of the smartsets This can be expensive on smartset that could be lazy otherwise.rrrrr__len___r.zabstractsmartset.__len__cCr)z$reverse the expected iteration orderrrrrrreverseerzabstractsmartset.reverseFcCr)z:get the set to iterate in an ascending or descending orderrrr1rrrsortirzabstractsmartset.sortcCs t|tr|S|j|j|ddS)z{Returns a new object with the intersection of the two collections. This is part of the mandatory API for smartset.Fcondreprcache) isinstance fullreposetfilterrrotherrrr__and__ms zabstractsmartset.__and__cCs t||S)ztReturns a new object with the union of the two collections. This is part of the mandatory API for smartset.)addsetr:rrr__add__us zabstractsmartset.__add__cs"|j|jfddd|fddS)z{Returns a new object with the substraction of the two collections. This is part of the mandatory API for smartset.cs | Sr#r)rcrrr&s z*abstractsmartset.__sub__..sFr4)rr9r:rr@r__sub__{szabstractsmartset.__sub__TcCs&|r t|dr t|}t|||S)a1Returns this smartset filtered by condition as a new smartset. `condition` is a callable which takes a revision number and returns a boolean. Optional `condrepr` provides a printable representation of the given `condition`. This is part of the mandatory API for smartset.s__code__)r safehasattr cachefunc filteredset)r conditionr5r6rrrr9s  zabstractsmartset.filtercCs&|dks|dkr td|||S)zAReturn new smartset that contains selected elements from this setrsnegative index not allowed)rProgrammingError_slice)rstartstoprrrslices  zabstractsmartset.slicecCszg}t|}t|D] }t|d}|durnq t||D]}t|d}|dur-n||q t|d|||fdS)Nsslice=%d:%d %r)datarepr)iterrxrangenextappendbaseset)rrIrJysitxyrrrrHs   zabstractsmartset._sliceFNT)r __module__ __qualname__r__bool__rrr(r+rrr r)r,r-r/r0r1r3r<r>rBr9rKrHrrrrrs.      rcseZdZdZd1ddZejddZejd d Zejd d Z d dZ ddZ ddZ ejddZ ddZeZd2ddZddZddZddZdd Zd!d"Zd#d$Zd%d&Zfd'd(Zd)d*Zd+d,Zd-d.Zejd/d0ZZS)3rQaBasic data structure that represents a revset and contains the basic operation that it should be able to perform. Every method in this class should be implemented by any smartset class. This class could be constructed by an (unordered) set, or an (ordered) list-like object. If a set is provided, it'll be sorted lazily. >>> x = [4, 0, 7, 6] >>> y = [5, 6, 7, 3] Construct by a set: >>> xs = baseset(set(x)) >>> ys = baseset(set(y)) >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]] [[0, 4, 6, 7, 3, 5], [6, 7], [0, 4]] >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]] ['addset', 'baseset', 'baseset'] Construct by a list-like: >>> xs = baseset(x) >>> ys = baseset(i for i in y) >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]] [[4, 0, 7, 6, 5, 3], [7, 6], [4, 0]] >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]] ['addset', 'filteredset', 'filteredset'] Populate "_set" fields in the lists so set optimization may be used: >>> [1 in xs, 3 in ys] [False, True] Without sort(), results won't be changed: >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]] [[4, 0, 7, 6, 5, 3], [7, 6], [4, 0]] >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]] ['addset', 'filteredset', 'filteredset'] With sort(), set optimization could be used: >>> xs.sort(reverse=True) >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]] [[7, 6, 4, 0, 5, 3], [7, 6], [4, 0]] >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]] ['addset', 'baseset', 'baseset'] >>> ys.sort() >>> [list(i) for i in [xs + ys, xs & ys, xs - ys]] [[7, 6, 4, 0, 3, 5], [7, 6], [4, 0]] >>> [type(i).__name__ for i in [xs + ys, xs & ys, xs - ys]] ['addset', 'baseset', 'baseset'] istopo is preserved across set operations >>> xs = baseset(set(x), istopo=True) >>> rs = xs & ys >>> type(rs).__name__ 'baseset' >>> rs._istopo True rNFcCsFd|_||_t|tr||_d|_n t|tst|}||_||_dS)z datarepr: a tuple of (format, obj, ...), a function or an object that provides a printable representation of the given data. NT) _ascending_istopor7set_setlist_list _datarepr)rdatarLr rrr__init__s   zbaseset.__init__cC t|jSr#)r]r`rrrrr^s z baseset._setcCs|jdd}||Sr#)r`r3)rasclistrrr_asclistszbaseset._asclistcCsd|jvsJt|jS)Nr^)__dict__r_r^rrrrr`s z baseset._listcCs.|jdur t|jS|jrt|jSt|jSr#)r[rMr`rfreversedrrrrrs    zbaseset.__iter__cCrdr#)rMrfrrrrr( zbaseset.fastasccCrdr#)rhrfrrrrr+rizbaseset.fastdesccCs|jjSr#)r^rrrrrrszbaseset.__contains__cCs tt|Sr#)boollenrrrrr zbaseset.__nonzero__cCst| |_d|_dSNF)rjr[r\r2rrrr3s  z baseset.sortcCs*|jdur |jn|j |_d|_dSrm)r[r`r1r\rrrrr1!s    zbaseset.reversecCsd|jvr t|jSt|jS)Nr`)rgrkr`r^rrrrr0(s   zbaseset.__len__cCs t|dkrdS|jduo|jS)zyReturns True if the collection is ascending order, False if not. This is part of the mandatory API for smartset.rTNrkr[rrrrr.s zbaseset.isascendingcCs"t|dkrdS|jduo|j S)zzReturns True if the collection is descending order, False if not. This is part of the mandatory API for smartset.rTNrnrrrrr6s zbaseset.isdescendingcCst|dkrdS|jS)zlIs the collection is in topographical order or not. This is part of the mandatory API for smartset.rT)rkr\rrrrr >s zbaseset.istopocC6|r|jdur |jdS|jr|jdS|jdSdS)Nrr[r`rfrrrrr-F    z baseset.firstcCro)Nrprrqrrrrr/Prrz baseset.lastcsjt|tur)d|jvr)d|jvr)|jdur)tt|j||j|jd}|j|_|Sttt|||}|S)Nr^)rbr )r rQrgr[rr^r\super)rr;ops __class__rr _fastsetopZs    zbaseset._fastsetopcC ||dS)Ns__and__rxr:rrrr<jrlzbaseset.__and__cCry)Ns__sub__rzr:rrrrBmrlzbaseset.__sub__cCsv|jdurt|j|||jdS|j}|js*tt||dtt||d}}t||||jd}|j|_|S)N)r r)r[rQr`r\rfr,rk)rrIrJrbrurrrrHps &zbaseset._slicecCsTdddd|j}t|j}|s!|j}|jdur|j}t|}dt|||fS)N-+NFTs <%s%s %s>) r[r buildreprrar`rfrbytereprr)rdrulrrr__repr__|s   zbaseset.__repr__)rNFrV) r rXrY__doc__rcr propertycacher^rfr`rr(r+rrrZr3r1r0rrr r-r/rxr<rBrHr strmethodr __classcell__rrrvrrQs< ;       rQc@seZdZdZdddfddZddZd d Zd d Zed dZ eddZ ddZ e Z ddZ d&ddZddZddZddZddZd d!Zd"d#Zejd$d%ZdS)'rEzDuck type for baseset class which iterates lazily over the revisions in the subset and contains a function which tests for membership in the revset cCdSrWr)rTrrrr&r'zfilteredset.NcCs||_||_||_dS)a! condition: a function that decide whether a revision in the subset belongs to the revset or not. condrepr: a tuple of (format, obj, ...), a function or an object that provides a printable representation of the given condition. N)_subset _condition _condrepr)rsubsetrFr5rrrrcs zfilteredset.__init__cCs||jvo ||Sr#)rrrrTrrrrzfilteredset.__contains__cCs ||jSr#) _iterfilterrrrrrrrlzfilteredset.__iter__ccs$|j}|D] }||r|VqdSr#)r)rrScondrTrrrrzfilteredset._iterfilterc"jjdur dSfddS)Nc Sr#rrrSrrrr& z%filteredset.fastasc..)rr(rrrrr(zfilteredset.fastasccr)Ncrr#rrrrrr&rz&filteredset.fastdesc..)rr+rrrrr+rzfilteredset.fastdesccCspd}|r |jnd|r|jnd|j|jg}|D] }|dur$|}nq|dur-|}n|}|D]}dSdSNTF)rr(rr+)rfast candidates candidaterSr?rrrrs"zfilteredset.__nonzero__cCstdd|D}t|S)Ncss|]}|VqdSr#r).0r?rrr sz&filteredset.__len__..)rQrk)rrrrrr0szfilteredset.__len__FcCs|jj|ddS)Nr1)rr3r2rrrr3zfilteredset.sortcCs|jdSr#)rr1rrrrr1zfilteredset.reversecC |jSr#)rrrrrrrrizfilteredset.isascendingcCrr#)rrrrrrrrizfilteredset.isdescendingcCrr#)rr rrrrr rizfilteredset.istopocC|D]}|SdSr#rrrrrr-zfilteredset.firstcCsRd}|r |j}n|r|j}|dur |D]}|SdSd}|D]}q$|Sr#)rr+rr(rrSrTrrrr/s zfilteredset.lastcCs>t|jg}t|j}|r||dt|d|fS)Ns<%s %s>s, ) rrrr rrrPrjoin)rxsrurrrrs   zfilteredset.__repr__rV)r rXrYrrcrrrpropertyr(r+rrZr0r3r1rrr r-r/rrrrrrrrEs,    rEc cst}|rt}d}d}z& |durt|}|durt|}|||}|V||kr+d}||kr1d}q tyV|}|durD|V|}n|durK|V|D]}|VqMYdSw)zproduce an ordered iteration from two iterators with the same order The ascending is used to indicated the iteration direction. N)r,r)rO StopIteration) ascendingiter1iter2choiceval1val2nrSvalrrr _iterordereds<  rc@seZdZdZd&ddZddZddZeZej d d Z d d Z d dZ e ddZe ddZddZd'ddZddZddZddZddZd d!Zd"d#Zejd$d%ZdS)(r=a Represent the addition of two sets Wrapper structure for lazily adding two structures without losing much performance on the __contains__ method If the ascending attribute is set, that means the two structures are ordered in either an ascending or descending way. Therefore, we can add them maintaining the order by iterating over both at the same time >>> xs = baseset([0, 3, 2]) >>> ys = baseset([5, 2, 4]) >>> rs = addset(xs, ys) >>> bool(rs), 0 in rs, 1 in rs, 5 in rs, rs.first(), rs.last() (True, True, False, True, 0, 4) >>> rs = addset(xs, baseset([])) >>> bool(rs), 0 in rs, 1 in rs, rs.first(), rs.last() (True, True, False, 0, 2) >>> rs = addset(baseset([]), baseset([])) >>> bool(rs), 0 in rs, rs.first(), rs.last() (False, False, None, None) iterate unsorted: >>> rs = addset(xs, ys) >>> # (use generator because pypy could call len()) >>> list(x for x in rs) # without _genlist [0, 3, 2, 5, 4] >>> assert not rs._genlist >>> len(rs) 5 >>> [x for x in rs] # with _genlist [0, 3, 2, 5, 4] >>> assert rs._genlist iterate ascending: >>> rs = addset(xs, ys, ascending=True) >>> # (use generator because pypy could call len()) >>> list(x for x in rs), list(x for x in rs.fastasc()) # without _asclist ([0, 2, 3, 4, 5], [0, 2, 3, 4, 5]) >>> assert not rs._asclist >>> len(rs) 5 >>> [x for x in rs], [x for x in rs.fastasc()] ([0, 2, 3, 4, 5], [0, 2, 3, 4, 5]) >>> assert rs._asclist iterate descending: >>> rs = addset(xs, ys, ascending=False) >>> # (use generator because pypy could call len()) >>> list(x for x in rs), list(x for x in rs.fastdesc()) # without _asclist ([5, 4, 3, 2, 0], [5, 4, 3, 2, 0]) >>> assert not rs._asclist >>> len(rs) 5 >>> [x for x in rs], [x for x in rs.fastdesc()] ([5, 4, 3, 2, 0], [5, 4, 3, 2, 0]) >>> assert rs._asclist iterate ascending without fastasc: >>> rs = addset(xs, generatorset(ys), ascending=True) >>> assert rs.fastasc is None >>> [x for x in rs] [0, 2, 3, 4, 5] iterate descending without fastdesc: >>> rs = addset(generatorset(xs), ys, ascending=False) >>> assert rs.fastdesc is None >>> [x for x in rs] [5, 4, 3, 2, 0] NcCs(||_||_d|_||_d|_d|_dSr#)_r1_r2_iterr[_genlistrf)rrevs1revs2rrrrrcps  zaddset.__init__cCrdr#)rkr`rrrrr0xrizaddset.__len__cCst|jp t|jSr#)rjrrrrrrr{rzaddset.__nonzero__cCs|js tt||_|jSr#)rrQrMrrrrr`sz addset._listcsjdurjr tjSfdd}|Sjr d}nd}t|}|dur.|Stj|}|durDttjj d}n|}tj|}|dur]ttjj d}n|}tj||S)aIterate over both collections without repeating elements If the ascending attribute is not set, iterate over the first one and then over the second one checking for membership on the first one so we dont yield any duplicates. If the ascending attribute is set, iterate over both collections at the same time, yielding only one value at a time in the given order. Nc3s:jD]}|Vqjj}jD] }||s|VqdSr#)rrr)r?inr1rrrarbitraryordergens  z*addset.__iter__..arbitraryordergensfastascsfastdescr) r[rrM_trysetasclistrrsortedrr)rrattrrSrrrrrrs*      zaddset.__iter__cCs,|jdur|jdurt|j|_dSdSdS)z9populate the _asclist attribute if possible and necessaryN)rrfrrrrrrszaddset._trysetasclistcH||jdur |jjS|jj|jjdfvrdSfddS)NctdSrWrrrrrrr&z addset.fastasc..)rrfrrr(rrrrrr(  zaddset.fastasccr)Ncrrmrrrrrr&rz!addset.fastdesc..)rrf __reversed__rr+rrrrrr+rzaddset.fastdesccCs||jvp ||jvSr#)rrrrrrrrzaddset.__contains__FcCs | |_dS)zSort the added set For this we use the cached list with all the generated values and if we know they are ascending or descending we can sort them in a smart way. Nr[r2rrrr3s z addset.sortcCs|jduo|jSr#rrrrrrszaddset.isascendingcCs|jduo|j Sr#rrrrrrrzaddset.isdescendingcCrrmrrrrrr z addset.istopocCs&|jdur |jdS|j |_dSr#)r[r`r1rrrrr1s zaddset.reversecCrr#rrrrrr-rz addset.firstcCs||}||Sr#)r1r-)rrrrrr/sz addset.lastcCs*dddd|j}dt|||j|jfS)Nr{r|r}r~s <%s%s %r, %r>)r[rrrrrrrrrszaddset.__repr__r#rV)r rXrYrrcr0rrZrrr`rrrr(r+rr3rrr r1r-r/rrrrrrrr=(s0 G 1   r=cseZdZdZd$fdd Zd$ddZddZeZd d Zd d Z d dZ ddZ ddZ d%ddZ ddZddZddZddZddZd d!Zejd"d#ZZS)& generatorsetaWrap a generator for lazy iteration Wrapper structure for generators that provides lazy membership and can be iterated more than once. When asked for membership it generates values until either it finds the requested one or has gone through all the elements in the generator >>> xs = generatorset([0, 1, 4], iterasc=True) >>> assert xs.last() == xs.last() >>> xs.last() # cached 4 Ncs,|dur|}n|r t}nt}tt||Sr#)_generatorsetasc_generatorsetdescrsr__new__)clsgeniterasctyprvrrrs zgeneratorset.__new__cCs(||_d|_i|_g|_d|_d|_dS)zM gen: a generator producing the values for the generatorset. NFT)_genrf_cacher _finishedr[)rrrrrrrcs  zgeneratorset.__init__cCs |jrdS|D]}dSdSr)r _consumegenrr?rrrr#s  zgeneratorset.__nonzero__cCs>||jvr |j|S|D] }||krdSqd|j|<dSrrrrrTrrrrr/s    zgeneratorset.__contains__cCs8|jr|j}n|j}|dur|S|D]}qt|Sr#)r[r(r+rrMrrrrr;s zgeneratorset.__iter__cs@|jrt|jS|j|ttfdd}|S)Nc3sNd} |kr|VnzVWn ty!YdSw|d7}q)NrTr)r)i_len_nextgenlistnextgenrrrVs   z#generatorset._iterator..gen)rrMrrrkrO)rrrrr _iteratorHs   zgeneratorset._iteratorccsr|j}|jj}|jD] }d||<|||Vq |js7d|_|jdd}|||_|j|_|j |_ dSdSrW) rrrPrrr3rfrr(rr+)rr6ritemascrrrrds  zgeneratorset._consumegencCs|D]}qt|jSr#)rrkrrrrrr0ss  zgeneratorset.__len__FcC | |_dSr#rr2rrrr3xrlzgeneratorset.sortcC|j |_dSr#rrrrrr1{rzgeneratorset.reversecC|jSr#rrrrrr~zgeneratorset.isascendingcC|j Sr#rrrrrrzgeneratorset.isdescendingcCrrmrrrrrr rzgeneratorset.istopocC>|jr|j}n|j}|dur|D]}q|St|dSr#)r[r(r+rr-rOrrrrr-  zgeneratorset.firstcCrr#)r[r+r(rr/rOrrrrr/rzgeneratorset.lastcCs ddd|j}dt||fS)Nr|r}FTs<%s%s>)r[rrrrrrszgeneratorset.__repr__r#rV)r rXrYrrrcrrZrrrrr0r3r1rrr r-r/rrrrrrrvrrs(        rc@eZdZdZejZddZdS)rz@Special case of generatorset optimized for ascending generators.cCsJ||jvr |j|S|D]}||krdS||krnqd|j|<dSrrrrrrr    z_generatorsetasc.__contains__N)r rXrYrrrr(rrrrrr rc@r)rzASpecial case of generatorset optimized for descending generators.cCsJ||jvr |j|S|D]}||krdS||krnqd|j|<dSrrrrrrrrz_generatorsetdesc.__contains__N)r rXrYrrrr+rrrrrrrrNcCs@|durt|}||k}|s|d|d}}t||||jjS)zCreate a spanset that represents a range of repository revisions start: first revision included the set (default to 0) end: first revision excluded (last+1) (default to len(repo)) Spanset will be descending if `end` < `start`. Nr)rk_spanset changelog filteredrevs)reporIendrrrrspansets rcseZdZdZddZd%ddZddZd d Zd d Zd dZ ddZ ddZ ddZ ddZ e ZddZddZddZddZdd Zfd!d"Zejd#d$ZZS)&ra\Duck type for baseset class which represents a range of revisions and can work lazily and without having all the range in memory Note that spanset(x, y) behave almost like xrange(x, y) except for two notable points: - when x < y it will be automatically descending, - revision filtered with this repoview will be skipped. cCs||_||_||_||_dSr#)_start_endr[ _hiddenrevs)rrIrr hiddenrevsrrrrcs z_spanset.__init__FcCrr#rr2rrrr3rlz _spanset.sortcCrr#rrrrrr1rz_spanset.reversecCrrmrrrrrr rz_spanset.istopoccs$|j}|D] }||vr|VqdSr#)r)r iterrangerur?rrrrrz_spanset._iterfiltercCs|jr|S|Sr#r[r(r+rrrrrsz_spanset.__iter__cCs(t|j|j}|jr||St|Sr#)rrNrrrrrMrrrrrr( s z_spanset.fastasccCs2t|jd|jdd}|jr||St|S)Nrrp)rrNrrrrrMrrrrr+s z_spanset.fastdesccCs0|j}|j|ko|jkno|o||v Sr#)rrr)rrhiddenrrrrs z_spanset.__contains__cCs|D]}dSdSrrrrrrrsz_spanset.__nonzero__cCs||js t|j|jSd}|j}|j}|jD]}||kr"|ks/n||kr-|kr3nq|d7}qt|j|j|S)Nrr)rabsrr)rcountrIrrrrrr0"s .z_spanset.__len__cCrr#rrrrrr.rz_spanset.isascendingcCrr#rrrrrr1rz_spanset.isdescendingcC*|jr|j}n|j}|D]}|SdSr#rrrrrr-4  z_spanset.firstcCrr#)r[r+r(rrrrr/=rz _spanset.lastcsz|jr tt|||S|jr"t|j||j}t|j||j}nt|j||j}t|j||j}t|||j|jSr#) rrsrrHr[r)rrr,)rrIrJrTrUrvrrrHFsz_spanset._slicecCs(ddd|j}dt|||j|jfS)Nr|r}rs <%s%s %d:%d>)r[rrrrrrrrRsz_spanset.__repr__rV)r rXrYrrcr3r1r rrr(r+rrrZr0rrr-r/rHrrrrrrrvrrs*    rcs(eZdZdZfddZddZZS)r8za set containing all revisions in the repo This class exists to host special optimization and magic to handle virtual revisions such as "null". cs"tt|dt|d|jjdS)NrT)rsr8rcrkrr)rrrvrrrc_s zfullreposet.__init__cCs.t|ds t||j}|j|d|S)zAs self contains the whole repo, all of the other set should also be in self. Therefore `self & other = other`. This boldly assumes the other contains valid revs only. s isascendingr)rrCrQrr3rr:rrrr<ds zfullreposet.__and__)r rXrYrrcr<rrrrvrr8Xs r8)rN) __future__rrrrrrutilsr robjectrrQrErr=rrrrrr8rrrrs(   dx%Y) x