a
    &0É_‹`  ã                   @   s  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZddlm	Z	 ddl
mZmZmZ ddlmZmZmZm
Z
mZ dd„ ZG d	d
„ d
eƒZG dd„ deƒZeZG dd„ deƒZG dd„ deeƒZeZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdS )é    )Úabsolute_importNé   )Ú_)ÚdelattrÚgetattrÚsetattr)ÚencodingÚerrorÚpathutilÚpycompatÚutilc                    s0   ‡ ‡fdd„}|ƒ s,t  t  ˆ¡ˆ¡ |ƒ  dS )z Avoid file stat ambiguity forcibly

    This function causes copying ``path`` file, if it is owned by
    another (see issue5418 and issue5584 for detail).
    c                     s$   t j ˆ¡} |  ˆ ¡ p"|  ˆˆ ¡S ©N)r   ÚfilestatÚfrompathZisambigZ
avoidambig)Znewstat©ÚoldstatÚpath© ú//usr/lib/python3/dist-packages/mercurial/vfs.pyÚcheckandavoid&   s    z"_avoidambig.<locals>.checkandavoidN)r   ÚrenameÚ
mktempcopy)r   r   r   r   r   r   Ú_avoidambig   s    r   c                   @   sÆ  e Zd ZdZdd„ Zdfdd„Zdd„ Zd	d
„ Zdd„ Zdgdd„Z	e
jdd„ ƒZdd„ Zdhdd„Zdidd„Zdjdd„Zdd„ Zdd„ Zdd „ Zd!d"„ Zdkd$d%„Zd&d'„ Zdld(d)„Zdmd*d+„Zdnd,d-„Zdod.d/„Zd0d1„ Zd2d3„ Zdpd4d5„Zdqd6d7„Zdrd8d9„Zdsd;d<„Z dtd=d>„Z!d?d@„ Z"dudAdB„Z#dvdEdF„Z$dwdGdH„Z%dIdJ„ Z&dxdKdL„Z'dMdN„ Z(dydOdP„Z)dzdQdR„Z*d{dSdT„Z+dUdV„ Z,d|dWdX„Z-d}dYdZ„Z.d~d[d\„Z/dd]d^„Z0d€d_d`„Z1ddadb„Z2e3j4d‚ddde„ƒZ5d#S )ƒÚabstractvfsz+Abstract base class; cannot be instantiatedc                 O   s   t dtt| ƒƒ ƒ‚dS )z7Prevent instantiation; don't call this from subclasses.úattempted instantiating N©ÚNotImplementedErrorÚstrÚtype)ÚselfÚargsÚkwargsr   r   r   Ú__init__5   s    zabstractvfs.__init__ó   rbc                 K   s   t ‚d S r   ©r   )r   r   Úmoder!   r   r   r   Ú__call__9   s    zabstractvfs.__call__c                 C   s   t ‚d S r   r$   ©r   r   r%   r   r   r   Ú
_auditpath<   s    zabstractvfs._auditpathc                 G   s   t ‚d S r   r$   ©r   r   Zinsidefr   r   r   Újoin?   s    zabstractvfs.joinc              
   C   sD   z|   |¡W S  ty> } z|jtjkr*‚ W Y d}~n
d}~0 0 dS )z3gracefully return an empty string for missing filesNó    )ÚreadÚIOErrorÚerrnoÚENOENT)r   r   Úinstr   r   r   ÚtryreadB   s    zabstractvfs.tryreadc              
   C   sH   z| j ||dW S  tyB } z|jtjkr.‚ W Y d}~n
d}~0 0 g S )z2gracefully return an empty array for missing files©r%   N)Ú	readlinesr-   r.   r/   )r   r   r%   r0   r   r   r   ÚtryreadlinesK   s    zabstractvfs.tryreadlinesc                 C   s   | j S )zéOpen ``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   r   r   r   ÚopenT   s    zabstractvfs.openc                 C   s6   | |dƒ}|  ¡ W  d   ƒ S 1 s(0    Y  d S )Nr#   )r,   )r   r   Úfpr   r   r   r,   ^   s    zabstractvfs.readc                 C   s8   | ||d}|  ¡ W  d   ƒ S 1 s*0    Y  d S )Nr2   )r3   )r   r   r%   r7   r   r   r   r3   b   s    zabstractvfs.readlinesFc                 K   sD   | |dfd|i|¤Ž}|  |¡W  d   ƒ S 1 s60    Y  d S )Nó   wbÚbackgroundclose©Úwrite)r   r   Údatar9   r!   r7   r   r   r   r;   f   s    zabstractvfs.writer8   c                 C   s<   | |||d}|  |¡W  d   ƒ S 1 s.0    Y  d S )N)r%   Ú
notindexed)Ú
writelines)r   r   r<   r%   r=   r7   r   r   r   r>   j   s    zabstractvfs.writelinesc                 C   s8   | |dƒ}|  |¡W  d   ƒ S 1 s*0    Y  d S )Ns   abr:   )r   r   r<   r7   r   r   r   Úappendn   s    zabstractvfs.appendc                 C   s   t j |¡S )z‚return base element of a path (as os.path.basename would do)

        This exists to allow handling of strange encoding if needed.)Úosr   Úbasename©r   r   r   r   r   rA   r   s    zabstractvfs.basenamec                 C   s   t  |  |¡|¡S r   )r@   Úchmodr*   r'   r   r   r   rC   x   s    zabstractvfs.chmodc                 C   s   t j |¡S )z„return dirname element of a path (as os.path.dirname would do)

        This exists to allow handling of strange encoding if needed.)r@   r   ÚdirnamerB   r   r   r   rD   {   s    zabstractvfs.dirnameNc                 C   s   t j |  |¡¡S r   )r@   r   Úexistsr*   rB   r   r   r   rE      s    zabstractvfs.existsc                 C   s
   t  |¡S r   )r   Úfstat)r   r7   r   r   r   rF   „   s    zabstractvfs.fstatc                 C   s   t j |  |¡¡S r   )r@   r   Úisdirr*   rB   r   r   r   rG   ‡   s    zabstractvfs.isdirc                 C   s   t j |  |¡¡S r   )r@   r   Úisfiler*   rB   r   r   r   rH   Š   s    zabstractvfs.isfilec                 C   s   t j |  |¡¡S r   )r@   r   Úislinkr*   rB   r   r   r   rI      s    zabstractvfs.islinkc                 C   s>   z|   |¡}W n ty"   Y dS 0 |j}t |¡p<t |¡S )zhreturn whether path is a regular file or a symlink

        Unlike isfile, this doesn't follow symlinks.F)ÚlstatÚOSErrorÚst_modeÚstatÚS_ISREGÚS_ISLNK)r   r   Ústr%   r   r   r   Úisfileorlink   s    zabstractvfs.isfileorlinkc                 G   s   t jj|Ž S )zÊjoin 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.)r@   r   r*   )r   Úpathsr   r   r   Úreljoin›   s    zabstractvfs.reljoinc                 C   s   t j |¡S )z‚split top-most element of a path (as os.path.split would do)

        This exists to allow handling of strange encoding if needed.)r@   r   ÚsplitrB   r   r   r   rT   ¢   s    zabstractvfs.splitc                 C   s   t j |  |¡¡S r   )r@   r   Úlexistsr*   rB   r   r   r   rU   ¨   s    zabstractvfs.lexistsc                 C   s   t  |  |¡¡S r   )r@   rJ   r*   rB   r   r   r   rJ   «   s    zabstractvfs.lstatc                 C   s   t  |  |¡¡S r   )r@   Úlistdirr*   rB   r   r   r   rV   ®   s    zabstractvfs.listdirTc                 C   s   t  |  |¡|¡S r   )r   Úmakedirr*   )r   r   r=   r   r   r   rW   ±   s    zabstractvfs.makedirc                 C   s   t  |  |¡|¡S r   )r   Úmakedirsr*   r'   r   r   r   rX   ´   s    zabstractvfs.makedirsc                 C   s   t  ||  |¡¡S r   )r   Úmakelockr*   )r   Úinfor   r   r   r   rY   ·   s    zabstractvfs.makelockc                 C   s   t  |  |¡¡S r   )r@   Úmkdirr*   rB   r   r   r   r[   º   s    zabstractvfs.mkdirr+   ó   tmpc                 C   sJ   t j|||  |¡d\}}t |¡\}}|r>|tj ||¡fS ||fS d S )N)ÚsuffixÚprefixÚdir)r   Úmkstempr*   r   rT   r@   r   )r   r]   r^   r_   ÚfdÚnameZdnameÚfnamer   r   r   r`   ½   s    ÿ
zabstractvfs.mkstempc                 C   s   t  |  |¡||¡S r   )r   rV   r*   )r   r   rM   Úskipr   r   r   ÚreaddirÇ   s    zabstractvfs.readdirc                 C   s   t  |  |¡¡S r   )r   Úreadlockr*   rB   r   r   r   rf   Ê   s    zabstractvfs.readlockc                 C   s`   |   |d¡ |  |¡}|  |¡}|o.tj |¡}|rT|jrTt ||¡}t||ƒ |S t ||¡S )a¼  Rename 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)r(   r*   r   r   r   rM   r   r   )r   ÚsrcÚdstÚ
checkambigZsrcpathZdstpathr   Zretr   r   r   r   Í   s    



zabstractvfs.renamec                 C   s   t  |  |¡¡S r   )r   Úreadlinkr*   rB   r   r   r   rk   ã   s    zabstractvfs.readlinkc                 C   s   t  |  |¡¡S )z@Remove a leaf directory and all empty intermediate ones
        )r   Ú
removedirsr*   rB   r   r   r   rl   æ   s    zabstractvfs.removedirsc                 C   s   t  |  |¡¡S )zRemove an empty directory.)r@   Úrmdirr*   rB   r   r   r   rm   ë   s    zabstractvfs.rmdirc                 C   s(   |rdd„ }nd}t j|  |¡||dS )zqRemove a directory tree recursively

        If ``forcibly``, this tries to remove READ-ONLY files, too.
        c                 S   sP   | t jur‚ t  |¡}|jtj@ dkr(‚ t  |t |j¡tjB ¡ t  |¡ d S )Nr   )r@   ÚremoverM   rL   ÚS_IWRITErC   ÚS_IMODE)Zfunctionr   ÚexcinfoÚsr   r   r   Úonerrorö   s    

z#abstractvfs.rmtree.<locals>.onerrorN)Úignore_errorsrs   )ÚshutilÚrmtreer*   )r   r   rt   Zforciblyrs   r   r   r   rv   ï   s    
ÿzabstractvfs.rmtreec                 C   s   t  |  |¡||¡S r   )r   Úsetflagsr*   )r   r   ÚlÚxr   r   r   rw     s    zabstractvfs.setflagsc                 C   s   t  |  |¡¡S r   )r@   rM   r*   rB   r   r   r   rM   	  s    zabstractvfs.statc                 C   s   t  |  |¡¡S r   )r   Úunlinkr*   rB   r   r   r   rz     s    zabstractvfs.unlinkc                 C   s   t  |  |¡¡ dS )z7Attempt to remove a file, ignoring missing file errors.N)r   Ú	tryunlinkr*   rB   r   r   r   r{     s    zabstractvfs.tryunlinkc                 C   s   t j|  |¡||dS )N)Úignoremissingrm   )r   Ú
unlinkpathr*   )r   r   r|   rm   r   r   r   r}     s    ÿzabstractvfs.unlinkpathc                 C   s   t  |  |¡|¡S r   )r@   Úutimer*   )r   r   Útr   r   r   r~     s    zabstractvfs.utimec                 c   sX   t j |  d¡¡}tt |¡ƒ}t j|  |¡|dD ]\}}}||d… ||fV  q4dS )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)rs   )r@   r   Únormpathr*   Úlenr
   ZnormasprefixÚwalk)r   r   rs   ÚrootZ	prefixlenÚdirpathÚdirsÚfilesr   r   r   r‚     s    	zabstractvfs.walkéÿÿÿÿc              	   c   s   t t ¡ tjƒsdV  dS t| d| ƒ}t|ddƒr@t tdƒ¡‚t||d0}z||_	|V  W d|_	nd|_	0 W d  ƒ n1 s‚0    Y  dS )zþAllow 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.
        NÚvfsÚ_backgroundfileclosers-   can only have 1 active background file closer)Úexpectedcount)
Ú
isinstanceÚ	threadingÚcurrentThreadÚ_MainThreadr   r	   ÚAbortr   Úbackgroundfilecloserr‰   )r   ÚuirŠ   rˆ   Zbfcr   r   r   Úbackgroundclosing+  s(    þÿÿÿÿzabstractvfs.backgroundclosing)r#   )r#   )r#   )F)r8   F)N)N)N)N)N)N)N)N)NT)NN)N)r+   r\   N)NNN)F)N)N)NFF)N)N)N)NFT)NN)NN)r‡   )6Ú__name__Ú
__module__Ú__qualname__Ú__doc__r"   r&   r(   r*   r1   r4   r   Úpropertycacher6   r,   r3   r;   r>   r?   rA   rC   rD   rE   rF   rG   rH   rI   rQ   rS   rT   rU   rJ   rV   rW   rX   rY   r[   r`   re   rf   r   rk   rl   rm   rv   rw   rM   rz   r{   r}   r~   r‚   Ú
contextlibÚcontextmanagerr’   r   r   r   r   r   2   sb   
	
	
	


























r   c                   @   s`   e Zd ZdZddd„Zejdd„ ƒZejdd	„ ƒZd
d„ Z	dd„ Z
ddd„Zdd„ Zdd„ ZdS )rˆ   ak  Operate 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.
    TFc                 C   sd   |rt  |¡}|rtj |¡}|| _|| _|rBtj| j|d| _	nddd„| _	d | _
d | _i | _d S )N)Úcachedc                 S   s   dS ©NTr   )r   r%   r   r   r   Ú<lambda>j  r+   zvfs.__init__.<locals>.<lambda>)N)r   Ú
expandpathr@   r   ÚrealpathÚbaseÚ_auditr
   ZpathauditorÚauditÚ
createmodeÚ_trustnlinkÚoptions)r   rŸ   r¡   Zcacheauditedr   rž   r   r   r   r"   Y  s    
zvfs.__init__c                 C   s   t  | j¡S r   )r   Z	checklinkrŸ   r5   r   r   r   Ú_cansymlinko  s    zvfs._cansymlinkc                 C   s   t  | j¡S r   )r   Z	checkexecrŸ   r5   r   r   r   Ú_chmods  s    z
vfs._chmodc                 C   s*   | j d u s| jsd S t || j d@ ¡ d S )Ni¶  )r¢   r¦   r@   rC   )r   rb   r   r   r   Ú_fixfilemodew  s    zvfs._fixfilemodec                 C   s`   | j r\tj |¡r.| | j¡r.tj || j¡}t |¡}|rNt	 
d||f ¡‚| j||d d S )Ns   %s: %rr2   )r    r@   r   ÚisabsÚ
startswithrŸ   Úrelpathr   Zcheckosfilenamer	   r   r¡   )r   r   r%   Úrr   r   r   r(   |  s    
zvfs._auditpathó   rc	              
   C   s   |r|   ||¡ |  |¡}	d|vr*|d7 }d}
|dvrxt |	¡\}}|rx|rx|rdt || j|¡ tj|	|| j|dS z\d|v r’t |	¡ d}
n@t |	¡& t 	|	¡}
|
dk r´d}
W d	  ƒ n1 sÈ0    Y  W nR t
tfy& } z4|jtjkrø‚ d}
|rt || j|¡ W Y d	}~n
d	}~0 0 |
dkrx| jd	u rT|
dkpPt |	¡| _|
dksf| jsxt t |	¡|	¡ t |	|¡}|
dkr˜|  |	¡ |rÂ|dv rºt td
ƒ| ¡‚t|ƒ}|rütt ¡ tjƒrü| jsðt tdƒ¡‚t|| jƒ}|S )a«  Open ``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).
        ó   br‡   ©r¬   r#   )rj   rg   r   r   é   Ns>   implementation error: mode %s is not valid for checkambig=TruesS   backgroundclose can only be used when a backgroundclosing context manager is active)r(   r*   r   rT   rX   r¢   Zatomictempfilerz   Z	posixfileZnlinksrK   r-   r.   r/   r£   Z
checknlinkr   r   r§   r	   r   r   Úcheckambigatclosingr‹   rŒ   r   rŽ   r‰   Údelayclosedfile)r   r   r%   Z
atomictempr=   r9   rj   Z	auditpathZmakeparentdirsÚfZnlinkrD   rA   Úer7   r   r   r   r&   …  s~    )


ÿ

&&



ÿüÿþÿÿÿþzvfs.__call__c              
   C   s¤   |   |¡ |  |¡}t |¡ t tj |¡| j¡ | j	r”zt 
||¡ W q  ty } z.t|jtdƒ|t |j¡f |ƒ‚W Y d }~q d }~0 0 n|  ||¡ d S )Ns   could not symlink to %r: %s)r¡   r*   r   r{   rX   r@   r   rD   r¢   r¥   ÚsymlinkrK   r.   r   r   Z
strtolocalÚstrerrorr;   )r   rh   ri   ZlinknameÚerrr   r   r   r´   û  s     


ÿüzvfs.symlinkc                 G   s&   |rt jj| j|g|¢R Ž S | jS d S r   )r@   r   r*   rŸ   r)   r   r   r   r*     s    zvfs.joinN)TFFF)r¬   FFFFTT)r“   r”   r•   r–   r"   r   r—   r¥   r¦   r§   r(   r&   r´   r*   r   r   r   r   rˆ   N  s,       ú


       ÷
vrˆ   c                   @   s6   e Zd Zdd„ Zdd„ Zedd„ ƒZejdd„ ƒZdS )	Úproxyvfsc                 C   s
   || _ d S r   )rˆ   ©r   rˆ   r   r   r   r"     s    zproxyvfs.__init__c                 C   s   | j  ||¡S r   )rˆ   r(   r'   r   r   r   r(     s    zproxyvfs._auditpathc                 C   s   | j jS r   ©rˆ   r¤   r5   r   r   r   r¤      s    zproxyvfs.optionsc                 C   s   || j _d S r   r¹   )r   Úvaluer   r   r   r¤   $  s    N)r“   r”   r•   r"   r(   Úpropertyr¤   Úsetterr   r   r   r   r·     s   
r·   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	Ú	filtervfsz4Wrapper vfs for filtering filenames with a function.c                 C   s   t  | |¡ || _d S r   )r·   r"   Ú_filter)r   rˆ   Úfilterr   r   r   r"   ,  s    zfiltervfs.__init__c                 O   s   | j |  |¡g|¢R i |¤ŽS r   )rˆ   r¾   )r   r   r    r!   r   r   r   r&   0  s    zfiltervfs.__call__c                 G   s6   |r&| j  |  | j j|g|¢R Ž ¡¡S | j  |¡S d S r   )rˆ   r*   r¾   rS   r)   r   r   r   r*   3  s    "zfiltervfs.joinN©r“   r”   r•   r–   r"   r&   r*   r   r   r   r   r½   )  s   r½   c                   @   s*   e Zd ZdZdd„ Zd
dd„Zdd„ Zd	S )Úreadonlyvfsz#Wrapper vfs preventing any writing.c                 C   s   t  | |¡ d S r   )r·   r"   r¸   r   r   r   r"   @  s    zreadonlyvfs.__init__r¬   c                 O   s0   |dvrt  tdƒ¡‚| j||g|¢R i |¤ŽS )Nr®   s   this vfs is read only)r	   r   r   rˆ   )r   r   r%   r    Úkwr   r   r   r&   C  s    zreadonlyvfs.__call__c                 G   s   | j j|g|¢R Ž S r   )rˆ   r*   r)   r   r   r   r*   H  s    zreadonlyvfs.joinN)r¬   rÀ   r   r   r   r   rÁ   =  s   
rÁ   c                   @   sH   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dS )ÚclosewrapbasezaBase class of wrapper, which hooks closing

    Do not instantiate outside of the vfs layer.
    c                 C   s   t  | d|¡ d S )NÚ_origfh)ÚobjectÚ__setattr__©r   Úfhr   r   r   r"   R  s    zclosewrapbase.__init__c                 C   s   t | j|ƒS r   )r   rÄ   ©r   Úattrr   r   r   Ú__getattr__U  s    zclosewrapbase.__getattr__c                 C   s   t | j||ƒS r   )r   rÄ   )r   rÊ   rº   r   r   r   rÆ   X  s    zclosewrapbase.__setattr__c                 C   s   t | j|ƒS r   )r   rÄ   rÉ   r   r   r   Ú__delattr__[  s    zclosewrapbase.__delattr__c                 C   s   | j  ¡  | S r   )rÄ   Ú	__enter__r5   r   r   r   rÍ   ^  s    
zclosewrapbase.__enter__c                 C   s   t dtt| ƒƒ ƒ‚d S ©Nr   r   ©r   Úexc_typeÚ	exc_valueÚexc_tbr   r   r   Ú__exit__b  s    zclosewrapbase.__exit__c                 C   s   t dtt| ƒƒ ƒ‚d S rÎ   r   r5   r   r   r   Úclosee  s    zclosewrapbase.closeN)r“   r”   r•   r–   r"   rË   rÆ   rÌ   rÍ   rÓ   rÔ   r   r   r   r   rÃ   L  s   rÃ   c                       s0   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Z‡  ZS )r±   zfProxy for a file object whose close is delayed.

    Do not instantiate outside of the vfs layer.
    c                    s"   t t| ƒ |¡ t | d|¡ d S )NÚ_closer)Úsuperr±   r"   rÅ   rÆ   )r   rÈ   Zcloser©Ú	__class__r   r   r"   o  s    zdelayclosedfile.__init__c                 C   s   | j  | j¡ d S r   ©rÕ   rÔ   rÄ   rÏ   r   r   r   rÓ   s  s    zdelayclosedfile.__exit__c                 C   s   | j  | j¡ d S r   rÙ   r5   r   r   r   rÔ   v  s    zdelayclosedfile.close)r“   r”   r•   r–   r"   rÓ   rÔ   Ú__classcell__r   r   r×   r   r±   i  s   r±   c                   @   s:   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )r   zCCoordinates background closing of file handles on multiple threads.r‡   c           
      C   sÆ   d| _ d| _g | _d | _tj}| dd|¡}|s4d S | dd¡}|dkrT||k rTd S | dd¡}| dd¡}| d| ¡ tj	j
|d	| _d
| _ t|ƒD ](}tj| jdd}	| j |	¡ |	 ¡  q˜d S )NFs   workers   backgroundcloses   backgroundcloseminfilecountr   s   backgroundclosemaxqueues   backgroundclosethreadcounts0   starting %d threads for background file closing
)ÚmaxsizeTZbackgroundcloser)Útargetrb   )Ú_runningÚ_enteredÚ_threadsÚ_threadexceptionr   Z	iswindowsZ
configboolZ	configintÚdebugÚqueueZQueueÚ_queueÚrangerŒ   ZThreadÚ_workerr?   Ústart)
r   r‘   rŠ   ZdefaultenabledZenabledZminfilecountZmaxqueueZthreadcountÚir   r   r   r   r"   }  s,    ÿzbackgroundfilecloser.__init__c                 C   s
   d| _ | S r›   )rÞ   r5   r   r   r   rÍ   £  s    zbackgroundfilecloser.__enter__c                 C   s   d| _ | jD ]}| ¡  qd S )NF)rÝ   rß   r*   )r   rÐ   rÑ   rÒ   r   r   r   r   rÓ   §  s    
zbackgroundfilecloser.__exit__c              
   C   st   zL| j jddd}z| ¡  W n* tyH } z|| _W Y d}~n
d}~0 0 W q  tjjyl   | jshY qpY q 0 q dS )zMain routine for worker thread.Tgš™™™™™¹?©ÚblockZtimeoutN)	rã   ÚgetrÔ   Ú	Exceptionrà   r   râ   ZEmptyrÝ   ©r   rÈ   r³   r   r   r   rå   ¯  s     zbackgroundfilecloser._workerc                 C   sR   | j st tdƒ¡‚| jr*| j}d| _|‚| js<| ¡  dS | jj|ddd dS )zSchedule a file for closing.s1   can only call close() when context manager activeNTrè   )	rÞ   r	   r   r   rà   rÝ   rÔ   rã   Zputrì   r   r   r   rÔ   ¿  s    ÿzbackgroundfilecloser.closeN)r‡   )	r“   r”   r•   r–   r"   rÍ   rÓ   rå   rÔ   r   r   r   r   r   z  s   
&r   c                       s8   e Zd ZdZ‡ fdd„Zdd„ Zdd„ Zdd	„ Z‡  ZS )
r°   a"  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.
    c                    s,   t t| ƒ |¡ t | dtj |j¡¡ d S )NÚ_oldstat)	rÖ   r°   r"   rÅ   rÆ   r   r   r   rb   rÇ   r×   r   r   r"   á  s    zcheckambigatclosing.__init__c                 C   s   | j }|jrt| jj|ƒ d S r   )rí   rM   r   rÄ   rb   )r   r   r   r   r   Ú_checkambigå  s    zcheckambigatclosing._checkambigc                 C   s   | j  |||¡ |  ¡  d S r   )rÄ   rÓ   rî   rÏ   r   r   r   rÓ   ê  s    zcheckambigatclosing.__exit__c                 C   s   | j  ¡  |  ¡  d S r   )rÄ   rÔ   rî   r5   r   r   r   rÔ   î  s    
zcheckambigatclosing.close)	r“   r”   r•   r–   r"   rî   rÓ   rÔ   rÚ   r   r   r×   r   r°   Ö  s
   
r°   ) Z
__future__r   r˜   r.   r@   ru   rM   rŒ   Zi18nr   r   r   r   r   Ú r   r	   r
   r   r   rÅ   r   rˆ   Zopenerr·   r½   ZfilteropenerrÁ   rÃ   r±   r   r°   r   r   r   r   Ú<module>   s0   	   I\