o ]Lbc@sddlmZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z m Z m Z ddlmZmZmZm Z mZddZGd d d eZGd d d eZeZGd ddeZGdddeeZeZGdddeZGdddeZGdddeZGdddeZGdddeZdS))absolute_importN)_)delattrgetattrsetattr)encodingerrorpathutilpycompatutilcs4fdd}|stt|dSdS)zAvoid file stat ambiguity forcibly This function causes copying ``path`` file, if it is owned by another (see issue5418 and issue5584 for detail). cs$tj}| p|SN)r filestatfrompathisambig avoidambig)newstatoldstatpath//usr/lib/python3/dist-packages/mercurial/vfs.py checkandavoid&s z"_avoidambig..checkandavoidN)r rename mktempcopy)rrrrrr _avoidambigs  rc@seZdZdZdZddZdkddZdd Zd d Zd d Z dkddZ e j ddZ ddZdkddZdlddZdmddZddZddZd d!Zd"d#Zdnd%d&Zd'd(Zdnd)d*Zdnd+d,Zdnd-d.Zdnd/d0Zd1d2Zd3d4Zd5d6Zdnd7d8Zdnd9d:Z dnd;d<Z!dod>d?Z"dpd@dAZ#dBdCZ$dndDdEZ%dqdHdIZ&drdJdKZ'dLdMZ(dldNdOZ)dPdQZ*dndRdSZ+dndTdUZ,dsdVdWZ-dXdYZ.dndZd[Z/dnd\d]Z0dnd^d_Z1dtd`daZ2dpdbdcZ3dpdddeZ4e5j6dudgdhZ7didjZ8d$S)v abstractvfsz+Abstract base class; cannot be instantiated/cOtdtt|)z7Prevent instantiation; don't call this from subclasses.attempted instantiating NotImplementedErrorstrtype)selfargskwargsrrr__init__=zabstractvfs.__init__rbcKtr r!)r$rmoder&rrr__call__Azabstractvfs.__call__cCr*r r+r$rr,rrr _auditpathDr.zabstractvfs._auditpathcGr*r r+r$rinsidefrrrjoinGr.zabstractvfs.joinc CsBz||WSty }z|jtjkrWYd}~dSd}~ww)z3gracefully return an empty string for missing filesN)readIOErrorerrnoENOENT)r$rinstrrrtryreadJs   zabstractvfs.tryreadc CsFz|j||dWSty"}z|jtjkrWYd}~gSd}~ww)z2gracefully return an empty array for missing filesr,N) readlinesr6r7r8)r$rr,r9rrr tryreadlinesSs  zabstractvfs.tryreadlinescCs|jS)zOpen ``path`` file, which is relative to vfs root. Newly created directories are marked as "not to be indexed by the content indexing service", if ``notindexed`` is specified for "write" mode access. )r-r$rrropen\szabstractvfs.opencCs6||d }|WdS1swYdS)Nr))r5)r$rfprrrr5fs $zabstractvfs.readcCs8|||d }|WdS1swYdS)Nr;)r<)r$rr,r@rrrr<js$zabstractvfs.readlinesFcKsD||dfd|i| }||WdS1swYdS)Nwbbackgroundclosewrite)r$rdatarBr&r@rrrrDns$zabstractvfs.writerAcCs<||||d }||WdS1swYdS)N)r, notindexed) writelines)r$rrEr,rFr@rrrrGrs$zabstractvfs.writelinescCs8||d }||WdS1swYdS)NsabrC)r$rrEr@rrrappendvs $zabstractvfs.appendcC tj|S)zreturn base element of a path (as os.path.basename would do) This exists to allow handling of strange encoding if needed.)osrbasenamer$rrrrrKz zabstractvfs.basenamecCt|||Sr )rJchmodr3r/rrrrOzabstractvfs.chmodcCrI)zreturn dirname element of a path (as os.path.dirname would do) This exists to allow handling of strange encoding if needed.)rJrdirnamerLrrrrQrMzabstractvfs.dirnameNcCtj||Sr )rJrexistsr3rLrrrrSrPzabstractvfs.existscCs t|Sr )r fstat)r$r@rrrrT zabstractvfs.fstatcCrRr )rJrisdirr3rLrrrrVrPzabstractvfs.isdircCrRr )rJrisfiler3rLrrrrWrPzabstractvfs.isfilecCrRr )rJrislinkr3rLrrrrXrPzabstractvfs.islinkcCs>z||}Wn tyYdSw|j}t|pt|S)zhreturn whether path is a regular file or a symlink Unlike isfile, this doesn't follow symlinks.F)lstatOSErrorst_modestatS_ISREGS_ISLNK)r$rstr,rrr isfileorlinks zabstractvfs.isfileorlinkcGs`d}t|D]\}}tj|s||jr|}q|dkr#||d}dd|D}|j|S)NrcSsg|]}|r|qSrr).0prrr sz%abstractvfs._join..) enumeraterJrisabs startswith_dir_sepr3)r$pathsroot_idxidxrbrrr_joins  zabstractvfs._joincGs |j|S)zjoin various elements of a path together (as os.path.join would do) The vfs base is not injected so that path stay relative. This exists to allow handling of strange encoding if needed.)rk)r$rhrrrreljoins zabstractvfs.reljoincCrI)zsplit top-most element of a path (as os.path.split would do) This exists to allow handling of strange encoding if needed.)rJrsplitrLrrrrmrMzabstractvfs.splitcCrRr )rJrlexistsr3rLrrrrnrPzabstractvfs.lexistscCt||Sr )rJrYr3rLrrrrYzabstractvfs.lstatcCror )rJlistdirr3rLrrrrqrpzabstractvfs.listdirTcCrNr )r makedirr3)r$rrFrrrrrrPzabstractvfs.makedircCrNr )r makedirsr3r/rrrrsrPzabstractvfs.makedirscCst|||Sr )r makelockr3)r$inforrrrrtrPzabstractvfs.makelockcCror )rJmkdirr3rLrrrrvrpzabstractvfs.mkdirr4tmpcCsFtj||||d\}}t|\}}|r|tj||fS||fS)N)suffixprefixdir)r mkstempr3r rmrJr)r$rxryrzfdnamednamefnamerrrr{s  zabstractvfs.mkstempcCt||||Sr )r rqr3)r$rr\skiprrrreaddirzabstractvfs.readdircCror )r readlockr3rLrrrrrpzabstractvfs.readlockcCs`||d||}||}|otj|}|r*|jr*t||}t|||St||S)aRename from src to dst checkambig argument is used with util.filestat, and is useful only if destination file is guarded by any lock (e.g. repo.lock or repo.wlock). To avoid file stat ambiguity forcibly, checkambig=True involves copying ``src`` file, if it is owned by another. Therefore, use checkambig=True only in limited cases (see also issue5418 and issue5584 for detail). w)r0r3r rrr\rr)r$srcdst checkambigsrcpathdstpathrretrrrrs      zabstractvfs.renamecCror )r readlinkr3rLrrrrrpzabstractvfs.readlinkcCro)z7Remove a leaf directory and all empty intermediate ones)r removedirsr3rLrrrrzabstractvfs.removedirscCro)zRemove an empty directory.)rJrmdirr3rLrrrrrzabstractvfs.rmdircCs(|rdd}nd}tj||||dS)zqRemove a directory tree recursively If ``forcibly``, this tries to remove READ-ONLY files, too. cSsP|tjurt|}|jtj@dkrt|t|jtjBt|dS)Nr)rJremover\r[S_IWRITErOS_IMODE)functionrexcinfosrrronerrors  z#abstractvfs.rmtree..onerrorN) ignore_errorsr)shutilrmtreer3)r$rrforciblyrrrrrs    zabstractvfs.rmtreecCrr )r setflagsr3)r$rlxrrrrrzabstractvfs.setflagscCror )rJr\r3rLrrrr\rpzabstractvfs.statcCror )r unlinkr3rLrrrrrpzabstractvfs.unlinkcCst||dS)z7Attempt to remove a file, ignoring missing file errors.N)r tryunlinkr3rLrrrr r(zabstractvfs.tryunlinkcCstj||||dS)N) ignoremissingr)r unlinkpathr3)r$rrrrrrr$s zabstractvfs.unlinkpathcCrNr )rJutimer3)r$rtrrrr)rPzabstractvfs.utimeccsZtj|d}tt|}tj|||dD]\}}}||d||fVqdS)a/Yield (dirpath, dirs, files) tuple for each directories under path ``dirpath`` is relative one from the root of this vfs. This uses ``os.sep`` as path separator, even you specify POSIX style ``path``. "The root of this vfs" is represented as empty ``dirpath``. N)r)rJrnormpathr3lenr normasprefixwalk)r$rrroot prefixlendirpathdirsfilesrrrr,s  zabstractvfs.walkc cstttjsdVdSt|d|}t|ddr!ttdt||d}z ||_ |VWd|_ nd|_ wWddS1sCwYdS)zAllow files to be closed asynchronously. When this context manager is active, ``backgroundclose`` can be passed to ``__call__``/``open`` to result in the file possibly being closed asynchronously, on a background thread. Nvfs_backgroundfileclosers-can only have 1 active background file closer) expectedcount) isinstance threadingcurrent_thread _MainThreadrr Abortrbackgroundfilecloserr)r$uirrbfcrrrbackgroundclosing<s,   "zabstractvfs.backgroundclosingcCdS)z1generic hook point to lets fncache steer its stewNrrLrrr register_file^zabstractvfs.register_file)r))F)rAFr NT)NN)r4rwN)NNN)NFF)NFTr)9__name__ __module__ __qualname____doc__rgr'r-r0r3r:r=r propertycacher?r5r<rDrGrHrKrOrQrSrTrVrWrXr`rkrlrmrnrYrqrrrsrtrvr{rrrrrrrrr\rrrrr contextlibcontextmanagerrrrrrrr2sj                                 !rc@sveZdZdZ    dddZejddZejdd Zd d Z d d Z       dddZ ddZ ddZ dS)rakOperate files relative to a base directory This class is used to hide the details of COW semantics and remote file access from higher level code. 'cacheaudited' should be enabled only if (a) vfs object is short-lived, or (b) the base directory is managed by hg and considered sort-of append-only. See pathutil.pathauditor() for details. TFcCsd|rt|}|rtj|}||_||_|r!tj|j|d|_ nddd|_ d|_ d|_ i|_ dS)N)cachedcSrrr)rr,rrr~rzvfs.__init__..r ) r expandpathrJrrealpathbase_auditr pathauditoraudit createmode _trustnlinkoptions)r$rr cacheauditedrrrrrr'ms    z vfs.__init__cC t|jSr )r checklinkrr>rrr _cansymlink zvfs._cansymlinkcCrr )r checkexecrr>rrr_chmodrz vfs._chmodcCs*|jdus|js dSt||jd@dS)Ni)rrrJrO)r$r}rrr _fixfilemodeszvfs._fixfilemodecCsd|jr0tj|r||jrtj||j}t|}|r't d||f|j ||ddSdS)Ns%s: %rr;) rrJrrerfrrelpathr checkosfilenamer rr)r$rr,rrrrr0s zvfs._auditpathrc  Cs|r|||||} d|vr|d7}d} |dvrt| \} } | r|r:|r0t| |j|tj| ||j|dSz.d|vrGt| d} n t| t | } | dkrXd} Wd n1sbwYWn't t fy} z| j t j kryd} |rt| |j|WYd } ~ nd } ~ ww| dkr|jd ur| dkpt| |_| dks|jstt| | t| |}| dkr|| |r|dvrttd |t|}|rtttjr|jsttd t||j}|S) aOpen ``path`` file, which is relative to vfs root. By default, parent directories are created as needed. Newly created directories are marked as "not to be indexed by the content indexing service", if ``notindexed`` is specified for "write" mode access. Set ``makeparentdirs=False`` to not create directories implicitly. If ``backgroundclose`` is passed, the file may be closed asynchronously. It can only be used if the ``self.backgroundclosing()`` context manager is active. This should only be specified if the following criteria hold: 1. There is a potential for writing thousands of files. Unless you are writing thousands of files, the performance benefits of asynchronously closing files is not realized. 2. Files are opened exactly once for the ``backgroundclosing`` active duration and are therefore free of race conditions between closing a file on a background thread and reopening it. (If the file were opened multiple times, there could be unflushed data because the original file handle hasn't been flushed/closed yet.) ``checkambig`` argument is passed to atomictempfile (valid only for writing), and is useful only if target file is guarded by any lock (e.g. repo.lock or repo.wlock). To avoid file stat ambiguity forcibly, checkambig=True involves copying ``path`` file opened in "append" mode (e.g. for truncation), if it is owned by another. Therefore, use combination of append mode and checkambig=True only in limited cases (see also issue5418 and issue5584 for detail). brrr))rrrrNs>implementation error: mode %s is not valid for checkambig=TruesSbackgroundclose can only be used when a backgroundclosing context manager is active)r0r3r rmrsratomictempfiler posixfilenlinksrZr6r7r8r checknlinkrrrr rrcheckambigatclosingrrrrrdelayclosedfile)r$rr, atomictemprFrBr auditpathmakeparentdirsfnlinkrQrKer@rrrr-s)          z vfs.__call__c Cs||||}t|ttj||j|j rDz t ||WdSt yC}zt |j t d|t|jf|d}~ww|||dS)Nscould not symlink to %r: %s)rr3r rrsrJrrQrrsymlinkrZr7rr strtolocalstrerrorrD)r$rrlinknameerrrrrrs$   z vfs.symlinkcGs(|r|j|g}|||j|S|jSr )rextendrk)r$rr2partsrrrr3#s    zvfs.joinN)TFFF)rFFFFTT)rrrrr'r rrrrr0r-rr3rrrrrbs.      v rc@s6eZdZddZddZeddZejddZdS) proxyvfscCs ||_dSr )rr$rrrrr'0rUzproxyvfs.__init__cCs|j||Sr )rr0r/rrrr03zproxyvfs._auditpathcCs|jjSr rrr>rrrr6szproxyvfs.optionscCs ||j_dSr r)r$valuerrrr:rN)rrrr'r0propertyrsetterrrrrr/s rc@s(eZdZdZddZddZddZdS) filtervfsz4Wrapper vfs for filtering filenames with a function.cCst||||_dSr )rr'_filter)r$rfilterrrrr'Bs  zfiltervfs.__init__cOs|j||g|Ri|Sr )rr)r$rr%r&rrrr-Fszfiltervfs.__call__cGs2|r|j||jj|g|RS|j|Sr )rr3rrlr1rrrr3Is" zfiltervfs.joinNrrrrr'r-r3rrrrr?s  rc@s*eZdZdZddZd ddZddZd S) readonlyvfsz#Wrapper vfs preventing any writing.cCst||dSr )rr'rrrrr'Vrpzreadonlyvfs.__init__rcOs0|dvr ttd|j||g|Ri|S)Nrsthis vfs is read only)r rrr)r$rr,r%kwrrrr-Yszreadonlyvfs.__call__cGs|jj|g|RSr )rr3r1rrrr3^rzreadonlyvfs.joinN)rrrrrrrSs   rc@sHeZdZdZddZddZddZdd Zd d Zd d Z ddZ dS) closewrapbasezaBase class of wrapper, which hooks closing Do not instantiate outside of the vfs layer. cCst|d|dS)N_origfh)object __setattr__r$fhrrrr'hrPzclosewrapbase.__init__cC t|j|Sr )rrr$attrrrr __getattr__k zclosewrapbase.__getattr__cCst|j||Sr )rr)r$rrrrrrnrzclosewrapbase.__setattr__cCrr )rrrrrr __delattr__qr zclosewrapbase.__delattr__cCs|j|Sr )r __enter__r>rrrr ts zclosewrapbase.__enter__cCrNrr r$exc_type exc_valueexc_tbrrr__exit__xrzclosewrapbase.__exit__cCrr r r>rrrclose{rzclosewrapbase.closeN) rrrrr'r rr r rrrrrrrbs rcs0eZdZdZfddZddZddZZS)rzfProxy for a file object whose close is delayed. Do not instantiate outside of the vfs layer. cs"tt||t|d|dS)N_closer)superrr'rr)r$rcloser __class__rrr'szdelayclosedfile.__init__cC|j|jdSr rrrrrrrrrPzdelayclosedfile.__exit__cCrr rr>rrrrrPzdelayclosedfile.close)rrrrr'rr __classcell__rrrrrs  rc@s:eZdZdZdddZddZddZd d Zd d Zd S)rzCCoordinates background closing of file handles on multiple threads.rc Csd|_d|_g|_d|_tj}|dd|}|sdS|dd}|dkr*||kr*dS|dd}|dd}|d|tj j |d |_ d |_t |D]}t j|jd d } |j| | qLdS) NFsworkersbackgroundclosesbackgroundcloseminfilecountrsbackgroundclosemaxqueuesbackgroundclosethreadcounts0starting %d threads for background file closing )maxsizeTbackgroundcloser)targetr})_running_entered_threads_threadexceptionr iswindows configbool configintdebugqueueQueue_queuerangerThread_workerrHstart) r$rrdefaultenabledenabled minfilecountmaxqueue threadcountirrrrr's.      zbackgroundfilecloser.__init__cCs d|_|Sr)r r>rrrr szbackgroundfilecloser.__enter__cCsd|_|jD]}|qdS)NF)rr!r3)r$rrrrrrrrs  zbackgroundfilecloser.__exit__c Cst z&|jjddd}z|Wnty%}z ||_WYd}~nd}~wwWntjjy8|js6YdSYnwq)zMain routine for worker thread.Tg?blocktimeoutN) r)getr Exceptionr"r r'Emptyrr$rrrrrr,s  zbackgroundfilecloser._workercCsR|js ttd|jr|j}d|_||js|dS|jj|ddddS)zSchedule a file for closing.s1can only call close() when context manager activeNTr4) r r rrr"rrr)putr:rrrrszbackgroundfilecloser.closeNr) rrrrr'r rr,rrrrrrs & rcs8eZdZdZfddZddZddZdd ZZS) ra"Proxy for a file object, to avoid ambiguity of file stat See also util.filestat for detail about "ambiguity of file stat". This proxy is useful only if the target file is guarded by any lock (e.g. repo.lock or repo.wlock) Do not instantiate outside of the vfs layer. cs,tt||t|dtj|jdS)N_oldstat) rrr'rrr rrr}rrrrr'szcheckambigatclosing.__init__cCs"|j}|jrt|jj|dSdSr )r<r\rrr})r$rrrr _checkambigszcheckambigatclosing._checkambigcCs|j||||dSr )rrr=rrrrrs zcheckambigatclosing.__exit__cCs|j|dSr )rrr=r>rrrrs  zcheckambigatclosing.close) rrrrr'r=rrrrrrrrs  r) __future__rrr7rJrr\ri18nrr rrrrr r r rrrropenerrr filteropenerrrrrrrrrrs2   2K\