U
    f                  	   @  s  d Z 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	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ZddlZddlZddlmZ ee ddlZW 5 Q R X ee ddlZW 5 Q R X ee ddlZW 5 Q R X ddlmZmZmZmZmZ ddl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' e"rdddl(m)Z)m*Z*m+Z+m,Z,m-Z- ddl.m/Z/ d	d
l0m1Z1m2Z2m3Z3 d	dl4m5Z5m6Z6 ddgZ7dddgZ8e8dddg Z9e:d;e8< Z=e:d;e9Z>e:e=j?d Z@e:e>j?d ZAeB ZCdddddZDG dd deEZFG dd dZGd d! ZHG d"d deIZJG d#d$ d$eKZLd%d& ZMG d'd( d(eJZNG d)d* d*eJZOG d+d, d,ZPG d-d. d.ZQG d/d deJZRG d0d1 d1ZSdS )2a  
Path Pie

Implements ``path.Path`` - An object representing a
path to a file or directory.

Example::

    from path import Path
    d = Path('/home/guido/bin')

    # Globbing
    for f in d.files('*.py'):
        f.chmod(0o755)

    # Changing the working directory:
    with Path("somewhere"):
        # cwd in now `somewhere`
        ...

    # Concatenate paths with /
    foo_txt = Path("bar") / "foo.txt"
    )annotationsN)Number)BufferedRandomBufferedReaderBufferedWriterFileIOTextIOWrapper)IOTYPE_CHECKINGAnyBinaryIOCallableIteratoroverload)OpenBinaryModeOpenBinaryModeReadingOpenBinaryModeUpdatingOpenBinaryModeWritingOpenTextMode)Literal   )classesmasksmatchers)removeprefixremovesuffixPathTempDirz

   u    u    |   $$zNumber | datetime.datetimer   )valuereturnc                 C  s"   t | tr| n|  }t|d S )Ni ʚ;)
isinstancer   	timestampint)r$   Ztimestamp_s r)   1/tmp/pip-unpacked-wheel-qyyspjli/path/__init__.py_make_timestamp_nsa   s    r+   c                   @  s   e Zd ZdS )TreeWalkWarningN)__name__
__module____qualname__r)   r)   r)   r*   r,   f   s   r,   c                   @  s    e Zd ZdZdd Zdd ZdS )	Traversalap  
    Wrap a walk result to customize the traversal.

    `follow` is a function that takes an item and returns
    True if that item should be followed and False otherwise.

    For example, to avoid traversing into directories that
    begin with `.`:

    >>> traverse = Traversal(lambda dir: not dir.startswith('.'))
    >>> items = list(traverse(Path('.').walk()))

    Directories beginning with `.` will appear in the results, but
    their children will not.

    >>> dot_dir = next(item for item in items if item.is_dir() and item.startswith('.'))
    >>> any(item.parent == dot_dir for item in items)
    False
    c                 C  s
   || _ d S N)follow)selfr2   r)   r)   r*   __init__   s    zTraversal.__init__c                 c  sD   d }z| |}W n tk
r(   Y d S X |V  t| j|}qd S r1   )sendStopIteration	functoolspartialr2   )r3   walkertraverseitemr)   r)   r*   __call__   s    zTraversal.__call__N)r-   r.   r/   __doc__r4   r<   r)   r)   r)   r*   r0   j   s   r0   c                 C  s   dd | D S )zZ
    >>> list(_strip_newlines(['Hello World\r\n', 'foo']))
    ['Hello World', 'foo']
    c                 s  s   | ]}t d |V  qdS ) N)U_NL_ENDsub.0liner)   r)   r*   	<genexpr>   s     z"_strip_newlines.<locals>.<genexpr>r)   )linesr)   r)   r*   _strip_newlines   s    rF   c                      s  e Zd ZdZejZd; fdd	Zd<ddZe	e
jdd Zeje	d	d
 Z fddZ fddZdd Zdd ZeZdd ZeZdd Zdd Ze	dd Ze	dd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Z d)d* Z!d+d, Z"d-d. Z#d/d0 Z$e%d1d2 Z&d3d4 Z'e%d5d6 Z(e%d7d8 Z)d9d: Z*e%d;d< Z+e%e"d=d=d>Z,e%e#d=d=d?Z-d@dA Z.dBdC Z/dDdE Z0dFdG Z1dHdI Z2ej3dJdK Z4dLdM Z5dNdO Z6dPdQ Z7dRdS Z8d=dTdUZ9dVdW Z:d>dXdYZ;d?dZd[Z<d\d] Z=d^d_ Z>d@dadbZ?dcdd Z@dedf ZAdAdgdhZBdidj ZCdkdl ZDeEdBdndodpdpdpdqdrdsdtdudvZFeEdCdwdxdpdpdpdqdydzdtd{dvZFeEdDd|d}dpdpdpdqdyd~dtddvZFeEdEdd}dpdpdpdqdyddtddvZFeEdFdd}dpdpdpdqdyddtddvZFeEdGdwdodpdpdpdqdyddtddvZFeEdHddodpdpdpdqdyddtddvZFddv ZFdd ZGeEdIdodndodpdpdpdqdrdd	ddZHeEdJdodwdodpdpdpdqdrdd	ddZHeEdKdoddodpdpdpdqdrdd	ddZHdd ZHdLddZIdMddZJdd ZKdNddZLeEdOddpddpdqddddZMeEdPddddpdqddddZMd=d`ejNdfddZMdQddZOd=d`ePdfddZQeRdd ZSdd ZTdd ZUdd ZVdd ZWdd ZXdd ZYdd ZZdd Z[dd Z\dd Z]ddÄ Z^ddń Z_ddǄ Z`ddɄ Zadd˄ Zbe%eaebd=d̃Zcdd΄ ZdddЄ Zee%edeed=dуZfddӄ Zge%egd=d=dԃZhddք Zie%eid=d=d׃Zje%ddٜddۄZkdd݄ ZlddޜddZmdd Zndd Zodd Zpdd Zqder kreonder krepneqZse%esd=d=dZtder krddޜddZuevedrdd Zwevedrdd Zxdd Zydd ZzevedrdRddZ{dd Z|dd  Z}dSddZ~dTddZdUddZdVdd	Zd
d Zdd Zdd Zdd Zdd Zdd Zdd ZeZeZdddddZdd ZdWddqddddZdXd d!Zd"d# Zd$d% ZejZejZejZejZejZejZeved&rXejZejZd'd( Zd)d* ZeZdYejd+d, d-d.d/Zeved0rd1d2 Zeved3rҐd4d5 ZejdZd7d8Zeje	d9d: Z  ZS ([  r   a  
    Represents a filesystem path.

    For documentation on individual methods, consult their
    counterparts in :mod:`os.path`.

    Some methods are additionally included from :mod:`shutil`.
    The functions are linked directly into the class namespace
    such that they will be bound to the Path instance. For example,
    ``Path(src).copy(target)`` is equivalent to
    ``shutil.copy(src, target)``. Therefore, when referencing
    the docs for these methods, assume `src` references `self`,
    the Path instance.
    .c                   s   t  | |S r1   )super__new__)clsother	__class__r)   r*   rI      s    zPath.__new__c              	   C  s2   |d krt dtt |   W 5 Q R X d S )Nz$Invalid initial value for path: None)	TypeError
contextlibsuppressAttributeError	_validater3   rK   r)   r)   r*   r4      s    zPath.__init__c                 C  s*   | j d |j  }| f}d|i}t|||S )N_moduler-   type)rJ   rU   Zsubclass_namebasesnsr)   r)   r*   using_module   s    zPath.using_modulec                 C  s   | S )zV
        What class should be used to construct new instances from this class
        r)   rJ   r)   r)   r*   _next_class   s    zPath._next_classc                   s   t | j dt   dS )N())rW   r-   rH   __repr__r3   rL   r)   r*   r_      s    zPath.__repr__c                   s   |  t |S r1   )r\   rH   __add__)r3   ZmorerL   r)   r*   ra      s    zPath.__add__c                 C  s   |  || S r1   )r\   ra   rS   r)   r)   r*   __radd__   s    zPath.__radd__c                 C  s   |  | j| |S )zfp.__div__(rel) == fp / rel == fp.joinpath(rel)

        Join two path components, adding a separator character if
        needed.

        .. seealso:: :func:`os.path.join`
        r\   rU   joinr3   relr)   r)   r*   __div__   s    zPath.__div__c                 C  s   |  | j|| S )zfp.__rdiv__(rel) == rel / fp

        Join two path components, adding a separator character if
        needed.

        .. seealso:: :func:`os.path.join`
        rc   re   r)   r)   r*   __rdiv__   s    zPath.__rdiv__c                 C  s   |   | _t|  | S r1   )cwd_old_diroschdirr`   r)   r)   r*   	__enter__   s    

zPath.__enter__c                 G  s   t | j d S r1   )rk   rl   rj   )r3   rT   r)   r)   r*   __exit__   s    zPath.__exit__c                 C  s   | t  S )zgReturn the current working directory as a path object.

        .. seealso:: :func:`os.getcwd`
        )rk   getcwdr[   r)   r)   r*   ri      s    zPath.cwdc                 C  s   t jdtdd |  S )Nz.getcwd is deprecated; use cwd   
stacklevel)warningswarnDeprecationWarningri   r[   r)   r)   r*   ro      s    zPath.getcwdc                 C  s   |  | j| S )z$.. seealso:: :func:`os.path.abspath`)r\   rU   abspathr`   r)   r)   r*   absolute	  s    zPath.absolutec                 C  s   t jdtdd |  S )Nz$.abspath is deprecated; use absoluterp   rq   )rs   rt   ru   rw   r`   r)   r)   r*   rv     s    zPath.abspathc                 C  s   |  | j| S )z%.. seealso:: :func:`os.path.normcase`)r\   rU   normcaser`   r)   r)   r*   rx     s    zPath.normcasec                 C  s   |  | j| S )z%.. seealso:: :func:`os.path.normpath`)r\   rU   normpathr`   r)   r)   r*   ry     s    zPath.normpathc                 C  s   |  | j| S )z%.. seealso:: :func:`os.path.realpath`)r\   rU   realpathr`   r)   r)   r*   rz     s    zPath.realpathc                 C  s   |  | j| S )z'.. seealso:: :func:`os.path.expanduser`)r\   rU   
expanduserr`   r)   r)   r*   r{   !  s    zPath.expanduserc                 C  s   |  | j| S )z'.. seealso:: :func:`os.path.expandvars`)r\   rU   
expandvarsr`   r)   r)   r*   r|   %  s    zPath.expandvarsc                 C  s   |  | j| S )z4.. seealso:: :attr:`parent`, :func:`os.path.dirname`)r\   rU   dirnamer`   r)   r)   r*   r}   )  s    zPath.dirnamec                 C  s   |  | j| S )z3.. seealso:: :attr:`name`, :func:`os.path.basename`)r\   rU   basenamer`   r)   r)   r*   r~   -  s    zPath.basenamec                 C  s   |     S )zClean up a filename by calling :meth:`expandvars()`,
        :meth:`expanduser()`, and :meth:`normpath()` on it.

        This is commonly everything needed to clean up a filename
        read from a configuration file, for example.
        )r|   r{   ry   r`   r)   r)   r*   expand1  s    zPath.expandc                 C  s   | j | j\}}|S )zThe same as :meth:`name`, but with one file extension stripped off.

        >>> Path('/home/guido/python.tar.gz').stem
        'python.tar'
        )rU   splitextname)r3   baseextr)   r)   r*   stem:  s    z	Path.stemc                 C  s   |  || j S )zReturn a new path with the stem changed.

        >>> Path('/home/guido/python.tar.gz').with_stem("foo")
        Path('/home/guido/foo.gz')
        )	with_namesuffix)r3   r   r)   r)   r*   	with_stemD  s    zPath.with_stemc                 C  s   | j | \}}|S )z*The file extension, for example ``'.py'``.)rU   r   )r3   fr   r)   r)   r*   r   L  s    zPath.suffixc                 C  s   t jdtdd | jS )Nz.ext is deprecated; use suffixrp   rq   )rs   rt   ru   r   r`   r)   r)   r*   r   R  s    zPath.extc                 C  s$   | dstd||  | S )a  Return a new path with the file suffix changed (or added, if none)

        >>> Path('/home/guido/python.tar.gz').with_suffix(".foo")
        Path('/home/guido/python.tar.foo')

        >>> Path('python').with_suffix('.zip')
        Path('python.zip')

        >>> Path('filename.ext').with_suffix('zip')
        Traceback (most recent call last):
        ...
        ValueError: Invalid suffix 'zip'
        rG   zInvalid suffix )
startswith
ValueErrorstripext)r3   r   r)   r)   r*   with_suffix[  s    
zPath.with_suffixc                 C  s   | j | \}}| |S )z}The drive specifier, for example ``'C:'``.

        This is always empty on systems that don't use drive specifiers.
        rU   
splitdriver\   )r3   driverr)   r)   r*   r   n  s    z
Path.driveNz This path's parent directory, as a new Path object.

        For example,
        ``Path('/usr/local/lib/libpython.so').parent ==
        Path('/usr/local/lib')``

        .. seealso:: :meth:`dirname`, :func:`os.path.dirname`
        z The name of this file or directory without the full path.

        For example,
        ``Path('/usr/local/lib/libpython.so').name == 'libpython.so'``

        .. seealso:: :meth:`basename`, :func:`os.path.basename`
        c                 C  s   |  t| | j| S )zReturn a new path with the name changed.

        >>> Path('/home/guido/python.tar.gz').with_name("foo.zip")
        Path('/home/guido/foo.zip')
        )r\   r   r   r3   r   r)   r)   r*   r     s    zPath.with_namec                 C  s   | j | \}}| ||fS )z~Return two-tuple of ``.parent``, ``.name``.

        .. seealso:: :attr:`parent`, :attr:`name`, :func:`os.path.split`
        )rU   splitr\   )r3   parentchildr)   r)   r*   	splitpath  s    zPath.splitpathc                 C  s$   | j | \}}| || |fS )aC  Return two-tuple of ``.drive`` and rest without drive.

        Split the drive specifier from this path.  If there is
        no drive specifier, :samp:`{p.drive}` is empty, so the return value
        is simply ``(Path(''), p)``.  This is always the case on Unix.

        .. seealso:: :func:`os.path.splitdrive`
        r   )r3   r   rf   r)   r)   r*   r     s    	zPath.splitdrivec                 C  s   | j | \}}| ||fS )a  Return two-tuple of ``.stripext()`` and ``.ext``.

        Split the filename extension from this path and return
        the two parts.  Either part may be empty.

        The extension is everything from ``'.'`` to the end of the
        last path segment.  This has the property that if
        ``(a, b) == p.splitext()``, then ``a + b == p``.

        .. seealso:: :func:`os.path.splitext`
        )rU   r   r\   )r3   filenamer   r)   r)   r*   r     s    zPath.splitextc                 C  s   |   d S )zRemove one file extension from the path.

        For example, ``Path('/home/guido/python.tar.gz').stripext()``
        returns ``Path('/home/guido/python.tar')``.
        r   )r   r`   r)   r)   r*   r     s    zPath.stripextc                 G  s   |  | jj|f| S )a  
        Join first to zero or more :class:`Path` components,
        adding a separator character (:samp:`{first}.module.sep`)
        if needed.  Returns a new instance of
        :samp:`{first}._next_class`.

        .. seealso:: :func:`os.path.join`
        rc   )rJ   firstZothersr)   r)   r*   joinpath  s    
zPath.joinpathc                 C  s   t |  S )a  Return a list of the path components in this path.

        The first item in the list will be a Path.  Its value will be
        either :data:`os.curdir`, :data:`os.pardir`, empty, or the root
        directory of this path (for example, ``'/'`` or ``'C:\\'``).  The
        other items in the list will be strings.

        ``Path.joinpath(*result)`` will yield the original path.

        >>> Path('/foo/bar/baz').splitall()
        [Path('/'), 'foo', 'bar', 'baz']
        )list_partsr`   r)   r)   r*   splitall  s    zPath.splitallc                 C  s   t |  S )z[
        >>> Path('/foo/bar/baz').parts()
        (Path('/'), 'foo', 'bar', 'baz')
        )tupler   r`   r)   r)   r*   parts  s    z
Path.partsc                 C  s   t t|  S r1   )reversedr   _parts_iterr`   r)   r)   r*   r     s    zPath._partsc                 c  sD   | }|t jkr:|t jkr:|}| \}}||kr2q:|V  q|V  d S r1   )rk   curdirpardirr   )r3   locprevr   r)   r)   r*   r     s    zPath._parts_iterc                 C  s   |  |}|| S )zzReturn this path as a relative path,
        based from `start`, which defaults to the current working directory.
        )r\   	relpathto)r3   startri   r)   r)   r*   relpath  s    
zPath.relpathc           
      C  s   |   }| |  }|  }| }|d | j|d krF|S d}t||D ]$\}}|| j|krp qz|d7 }qTtjgt||  }|||d 7 }t|dkrtj	}	n| jj
| }	| |	S )zReturn a relative path from `self` to `dest`.

        If there is no relative path from `self` to `dest`, for example if
        they reside on different drives in Windows, then this returns
        ``dest.absolute()``.
        r   r   N)rw   r\   rx   r   rU   ziprk   r   lenr   rd   )
r3   destoriginZ	orig_listZ	dest_listiZ	start_segZdest_segsegmentsr   r)   r)   r*   r     s"    
zPath.relpathtoc                   s(   t |}t| fddt D S )a}  Yields items in this directory.

        Use :meth:`files` or :meth:`dirs` instead if you want a listing
        of just files or just subdirectories.

        The elements of the list are Path objects.

        With the optional `match` argument, a callable,
        only return items whose names match the given pattern.

        .. seealso:: :meth:`files`, :meth:`dirs`
        c                 3  s   | ]} | V  qd S r1   r)   )rB   r   r`   r)   r*   rD   1  s     zPath.iterdir.<locals>.<genexpr>)r   loadfilterrk   listdirr3   matchr)   r`   r*   iterdir#  s    
zPath.iterdirc                 C  s    t jdtdd t| j|dS )Nz#.listdir is deprecated; use iterdirrp   rq   )r   )rs   rt   ru   r   r   r   r)   r)   r*   r   3  s    zPath.listdirc                 O  s   dd | j ||D S )zList of this directory's subdirectories.

        The elements of the list are Path objects.
        This does not walk recursively into subdirectories
        (but see :meth:`walkdirs`).

        Accepts parameters to :meth:`iterdir`.
        c                 S  s   g | ]}|  r|qS r)   is_dirrB   pr)   r)   r*   
<listcomp>D  s      zPath.dirs.<locals>.<listcomp>r   r3   argskwargsr)   r)   r*   dirs;  s    	z	Path.dirsc                 O  s   dd | j ||D S )zList of the files in self.

        The elements of the list are Path objects.
        This does not walk into subdirectories (see :meth:`walkfiles`).

        Accepts parameters to :meth:`iterdir`.
        c                 S  s   g | ]}|  r|qS r)   is_filer   r)   r)   r*   r   O  s      zPath.files.<locals>.<listcomp>r   r   r)   r)   r*   filesF  s    	z
Path.filesstrictc                 c  s   t |}t|}z|  }W n< tk
r\ } z|d|  d|  W Y dS d}~X Y nX |D ]}d}||rx|V }|p|j}z
| }W n> tk
r } z |d| d|  W Y qbW 5 d}~X Y nX |rb|j||dE dH  qbdS )a  Iterator over files and subdirs, recursively.

        The iterator yields Path objects naming each child item of
        this directory and its descendants.  This requires that
        ``D.is_dir()``.

        This performs a depth-first traversal of the directory tree.
        Each directory is returned just before all its children.

        The `errors=` keyword argument controls behavior when an
        error occurs.  The default is ``'strict'``, which causes an
        exception.  Other allowed values are ``'warn'`` (which
        reports the error via :func:`warnings.warn()`), and ``'ignore'``.
        `errors` may also be an arbitrary callable taking a msg parameter.
        zUnable to list directory 'z': NzUnable to access ')errorsr   )Handlers_resolver   r   r   	Exceptionr   walk)r3   r   r   Z	childListexcr   r:   Zdo_traverser)   r)   r*   r   Q  s&    



z	Path.walkc                 O  s   dd | j ||D S )z#Iterator over subdirs, recursively.c                 s  s   | ]}|  r|V  qd S r1   r   rB   r;   r)   r)   r*   rD   {  s      z Path.walkdirs.<locals>.<genexpr>r   r   r)   r)   r*   walkdirsy  s    zPath.walkdirsc                 O  s   dd | j ||D S )z!Iterator over files, recursively.c                 s  s   | ]}|  r|V  qd S r1   r   r   r)   r)   r*   rD     s      z!Path.walkfiles.<locals>.<genexpr>r   r   r)   r)   r*   	walkfiles}  s    zPath.walkfilesc                 C  s6   t |d| jj}|p|}|| j}||}t||S )a  Return ``True`` if `self.name` matches the given `pattern`.

        `pattern` - A filename pattern with wildcards,
            for example ``'*.py'``. If the pattern contains a `normcase`
            attribute, it is applied to the name and path prior to comparison.

        `normcase` - (optional) A function used to normalize the pattern and
            filename before matching. Defaults to normcase from
            ``self.module``, :func:`os.path.normcase`.

        .. seealso:: :func:`fnmatch.fnmatch`
        rx   )getattrrU   rx   r   fnmatchfnmatchcase)r3   patternrx   Zdefault_normcaser   r)   r)   r*   r     s
    
zPath.fnmatchc                   s"   | j   fddt| | D S )a  Return a list of Path objects that match the pattern.

        `pattern` - a path relative to this directory, with wildcards.

        For example, ``Path('/users').glob('*/bin/*')`` returns a list
        of all the files users have in their :file:`bin` directories.

        .. seealso:: :func:`glob.glob`

        .. note:: Glob is **not** recursive, even when using ``**``.
                  To do recursive globbing see :func:`walk`,
                  :func:`walkdirs` or :func:`walkfiles`.
        c                   s   g | ]} |qS r)   r)   rB   sr[   r)   r*   r     s     zPath.glob.<locals>.<listcomp>)r\   globr3   r   r)   r[   r*   r     s    z	Path.globc                   s"   | j   fddt| | D S )a  Return an iterator of Path objects that match the pattern.

        `pattern` - a path relative to this directory, with wildcards.

        For example, ``Path('/users').iglob('*/bin/*')`` returns an
        iterator of all the files users have in their :file:`bin`
        directories.

        .. seealso:: :func:`glob.iglob`

        .. note:: Glob is **not** recursive, even when using ``**``.
                  To do recursive globbing see :func:`walk`,
                  :func:`walkdirs` or :func:`walkfiles`.
        c                 3  s   | ]} |V  qd S r1   r)   r   r[   r)   r*   rD     s     zPath.iglob.<locals>.<genexpr>)r\   r   iglobr   r)   r[   r*   r     s    z
Path.iglob.r   r(   z
str | Noneboolz Callable[[str, int], int] | Noner   )mode	bufferingencodingr   newlineclosefdopenerr%   c                 C  s   d S r1   r)   r3   r   r   r   r   r   r   r   r)   r)   r*   open  s    
z	Path.openr   z
Literal[0]zCallable[[str, int], int]r   c                 C  s   d S r1   r)   r   r)   r)   r*   r     s    
r   zLiteral[(-1, 1)]r   c                 C  s   d S r1   r)   r   r)   r)   r*   r     s    
r   r   c                 C  s   d S r1   r)   r   r)   r)   r*   r     s    
r   r   c                 C  s   d S r1   r)   r   r)   r)   r*   r     s    
r   c                 C  s   d S r1   r)   r   r)   r)   r*   r     s    
strzIO[Any]c                 C  s   d S r1   r)   r   r)   r)   r*   r     s    
c                 O  s   t | f||S )zOpen this file and return a corresponding file object.

        Keyword arguments work as in :func:`io.open`.  If the file cannot be
        opened, an :class:`OSError` is raised.
        )r   r   r)   r)   r*   r     s    c              
   C  s*   |  d}| W  5 Q R  S Q R X dS )z8Open this file, read all bytes, return them as a string.rbNr   readr3   r   r)   r)   r*   bytes  s    z
Path.byteszIterator[str])	sizer   r   r   r   r   r   r   r%   c	           	      C  s   d S r1   r)   	r3   r   r   r   r   r   r   r   r   r)   r)   r*   chunks  s    zPath.chunkszIterator[builtins.bytes]c	           	      C  s   d S r1   r)   r   r)   r)   r*   r   (  s    zIterator[str | builtins.bytes]c	           	      C  s   d S r1   r)   r   r)   r)   r*   r   5  s    c              	   /  s6   | j ||  t fdddE dH  W 5 Q R X dS )a  Returns a generator yielding chunks of the file, so it can
         be read piece by piece with a simple for loop.

        Any argument you pass after `size` will be passed to :meth:`open`.

        :example:

            >>> hash = hashlib.md5()
            >>> for chunk in Path("NEWS.rst").chunks(8192, mode='rb'):
            ...     hash.update(chunk)

         This will read the file by chunks of 8192 bytes.
        c                     s     pd S r1   )r   r)   r   r   r)   r*   <lambda>Q      zPath.chunks.<locals>.<lambda>N)r   iter)r3   r   r   r   r)   r   r*   r   B  s    Fc              	   C  s,   |  |rdnd}|| W 5 Q R X dS )zOpen this file and write the given bytes to it.

        Default behavior is to overwrite any existing file.
        Call ``p.write_bytes(bytes, append=True)`` to append instead.
        abwbN)r   write)r3   r   appendr   r)   r)   r*   write_bytesS  s    zPath.write_bytesc              
   C  s.   | j ||d}| W  5 Q R  S Q R X dS )zOpen this file, read it in, return the content as a string.

        Optional parameters are passed to :meth:`open`.

        .. seealso:: :meth:`lines`
        )r   r   Nr   )r3   r   r   r   r)   r)   r*   	read_text\  s    zPath.read_textc              
   C  s,   | j dd}| W  5 Q R  S Q R X dS )z*Return the contents of this file as bytes.r   r   Nr   r   r)   r)   r*   
read_bytesf  s    zPath.read_bytesc                 C  s$   t jdtdd td| ||S )zYLegacy function to read text.

        Converts all newline sequences to ``\n``.
        z".text is deprecated; use read_textrp   rq   r   )rs   rt   ru   	U_NEWLINEr@   r   )r3   r   r   r)   r)   r*   textk  s    z	Path.textNone)r   r   r   linesepr   r%   c                 C  s   d S r1   r)   r3   r   r   r   r   r   r)   r)   r*   
write_textw  s    zPath.write_textzbuiltins.bytesc                 C  s   d S r1   r)   r   r)   r)   r*   r     s    c                 C  s~   t |tr4|dk	rt||}||p,t |}n8tjdt	dd |dksPt
|dk	rht| |}|}| j||d dS )a  Write the given text to this file.

        The default behavior is to overwrite any existing file;
        to append instead, use the `append=True` keyword argument.

        There are two differences between :meth:`write_text` and
        :meth:`write_bytes`: newline handling and Unicode handling.
        See below.

        Parameters:

          `text` - str/bytes - The text to be written.

          `encoding` - str - The text encoding used.

          `errors` - str - How to handle Unicode encoding errors.
              Default is ``'strict'``.  See ``help(unicode.encode)`` for the
              options.  Ignored if `text` isn't a Unicode string.

          `linesep` - keyword argument - str/unicode - The sequence of
              characters to be used to mark end-of-line.  The default is
              :data:`os.linesep`.  Specify ``None`` to
              use newlines unmodified.

          `append` - keyword argument - bool - Specifies what to do if
              the file already exists (``True``: append to the end of it;
              ``False``: overwrite it).  The default is ``False``.


        --- Newline handling.

        ``write_text()`` converts all standard end-of-line sequences
        (``'\n'``, ``'\r'``, and ``'\r\n'``) to your platform's default
        end-of-line sequence (see :data:`os.linesep`; on Windows, for example,
        the end-of-line marker is ``'\r\n'``).

        To override the platform's default, pass the `linesep=`
        keyword argument. To preserve the newlines as-is, pass
        ``linesep=None``.

        This handling applies to Unicode text and bytes, except
        with Unicode, additional non-ASCII newlines are recognized:
        ``\x85``, ``\r\x85``, and ``\u2028``.

        --- Unicode

        If `text` isn't Unicode, then apart from newline handling, the
        bytes are written verbatim to the file.  The `encoding` and
        `errors` arguments are not used and must be omitted.

        If `text` is Unicode, it is first converted to :func:`bytes` using the
        specified `encoding` (or the default encoding if `encoding`
        isn't specified).  The `errors` argument applies only to this
        conversion.
        Nz)Writing bytes in write_text is deprecatedr   rq   )r   )r&   r   r   r@   encodesysgetdefaultencodingrs   rt   ru   AssertionError	B_NEWLINEr   )r3   r   r   r   r   r   r   r)   r)   r*   r     s    :
Tc                 C  s   t d| ||}||S )a  Open this file, read all lines, return them in a list.

        Optional arguments:
            `encoding` - The Unicode encoding (or character set) of
                the file.  The default is ``None``, meaning use
                ``locale.getpreferredencoding()``.
            `errors` - How to handle Unicode errors; see
                `open <https://docs.python.org/3/library/functions.html#open>`_
                for the options.  Default is ``None`` meaning "strict".
            `retain` - If ``True`` (default), retain newline characters,
                but translate all newline
                characters to ``\n``.  If ``False``, newline characters are
                omitted.

        .. seealso:: :meth:`text`
        r   )r   r@   r   
splitlines)r3   r   r   Zretainr   r)   r)   r*   rE     s    z
Path.linesc              	   C  s@   |rdnd}| j |||dd}|| || W 5 Q R X dS )a  Write the given lines of text to this file.

        By default this overwrites any existing file at this path.

        This puts a platform-specific newline sequence on every line.
        See `linesep` below.

            `lines` - A list of strings.

            `encoding` - A Unicode encoding to use.  This applies only if
                `lines` contains any Unicode strings.

            `errors` - How to handle errors in Unicode encoding.  This
                also applies only to Unicode strings.

            linesep - (deprecated) The desired line-ending.  This line-ending is
                applied to every line.  If a line already has any
                standard line ending (``'\r'``, ``'\n'``, ``'\r\n'``,
                ``u'\x85'``, ``u'\r\x85'``, ``u'\u2028'``), that will
                be stripped off and this will be used instead.  The
                default is os.linesep, which is platform-dependent
                (``'\r\n'`` on Windows, ``'\n'`` on Unix, etc.).
                Specify ``None`` to write the lines as-is, like
                ``.writelines`` on a file object.

        Use the keyword argument ``append=True`` to append lines to the
        file.  The default is to overwrite the file.
        awr>   )r   r   r   N)r   
writelines_replace_linesep)r3   rE   r   r   r   r   r   r   r)   r)   r*   write_lines  s    $zPath.write_linesc                   sB    t krtjdtdd ntj  d kr,| S  fddt| D S )Nzlinesep is deprecated   rq   c                 3  s   | ]}|  V  qd S r1   r)   rA   r   r)   r*   rD     s     z(Path._replace_linesep.<locals>.<genexpr>)_default_lineseprs   rt   ru   rk   r   rF   )rE   r   r)   r  r*   r    s    zPath._replace_linesepc                 C  s
   |  dS )zCalculate the md5 hash for this file.

        This reads through the entire file.

        .. seealso:: :meth:`read_hash`
        md5)	read_hashr`   r)   r)   r*   read_md5  s    zPath.read_md5c                 C  s,   t |}| jdddD ]}|| q|S )zReturns a hash object for the file at the current path.

        `hash_name` should be a hash algo name (such as ``'md5'``
        or ``'sha1'``) that's available in the :mod:`hashlib` module.
        i    r   r   )hashlibnewr   update)r3   	hash_namemchunkr)   r)   r*   _hash%  s    
z
Path._hashc                 C  s   |  | S )zCalculate given hash for this file.

        List of supported hashes can be obtained from :mod:`hashlib` package.
        This reads the entire file.

        .. seealso:: :meth:`hashlib.hash.digest`
        )r  digestr3   r  r)   r)   r*   r  0  s    zPath.read_hashc                 C  s   |  | S )zCalculate given hash for this file, returning hexdigest.

        List of supported hashes can be obtained from :mod:`hashlib` package.
        This reads the entire file.

        .. seealso:: :meth:`hashlib.hash.hexdigest`
        )r  	hexdigestr  r)   r)   r*   read_hexhash:  s    zPath.read_hexhashc                 C  s   | j | S )za
        >>> Path('.').isabs()
        False

        .. seealso:: :func:`os.path.isabs`
        )rU   isabsr`   r)   r)   r*   r  I  s    z
Path.isabsc                 C  s   | j | S )z#.. seealso:: :func:`os.path.exists`)rU   existsr`   r)   r)   r*   r  R  s    zPath.existsc                 C  s   t jdtdd |  S )Nzisdir is deprecated; use is_dirrp   rq   )rs   rt   ru   r   r`   r)   r)   r*   isdirV  s    z
Path.isdirc                 C  s   | j | S )z".. seealso:: :func:`os.path.isdir`)rU   r  r`   r)   r)   r*   r   ^  s    zPath.is_dirc                 C  s   t jdtdd |  S )Nz!isfile is deprecated; use is_filerp   rq   )rs   rt   ru   r   r`   r)   r)   r*   isfileb  s    zPath.isfilec                 C  s   | j | S )z#.. seealso:: :func:`os.path.isfile`)rU   r  r`   r)   r)   r*   r   j  s    zPath.is_filec                 C  s   | j | S )z#.. seealso:: :func:`os.path.islink`)rU   islinkr`   r)   r)   r*   r  n  s    zPath.islinkc                 C  s   | j | S )ze
        >>> Path('.').ismount()
        False

        .. seealso:: :func:`os.path.ismount`
        )rU   ismountr`   r)   r)   r*   r  r  s    zPath.ismountc                 C  s   | j | |S )z%.. seealso:: :func:`os.path.samefile`)rU   samefilerS   r)   r)   r*   r  {  s    zPath.samefilec                 C  s   | j | S )z4.. seealso:: :attr:`atime`, :func:`os.path.getatime`)rU   getatimer`   r)   r)   r*   r    s    zPath.getatimec                 C  s"   |   j}| jt||fd d S N)rY   statst_atime_nsutimer+   )r3   r$   Zmtime_nsr)   r)   r*   	set_atime  s    
zPath.set_atimea  
        Last access time of the file.

        >>> Path('.').atime > 0
        True

        Allows setting:

        >>> some_file = Path(getfixture('tmp_path')).joinpath('file.txt').touch()
        >>> MST = datetime.timezone(datetime.timedelta(hours=-7))
        >>> some_file.atime = datetime.datetime(1976, 5, 7, 10, tzinfo=MST)
        >>> some_file.atime
        200336400.0

        .. seealso:: :meth:`getatime`, :func:`os.path.getatime`
        c                 C  s   | j | S )z4.. seealso:: :attr:`mtime`, :func:`os.path.getmtime`)rU   getmtimer`   r)   r)   r*   r"    s    zPath.getmtimec                 C  s"   |   j}| j|t|fd d S r  r  )r3   r$   Zatime_nsr)   r)   r*   	set_mtime  s    
zPath.set_mtimea  
        Last modified time of the file.

        Allows setting:

        >>> some_file = Path(getfixture('tmp_path')).joinpath('file.txt').touch()
        >>> MST = datetime.timezone(datetime.timedelta(hours=-7))
        >>> some_file.mtime = datetime.datetime(1976, 5, 7, 10, tzinfo=MST)
        >>> some_file.mtime
        200336400.0

        .. seealso:: :meth:`getmtime`, :func:`os.path.getmtime`
        c                 C  s   | j | S )z4.. seealso:: :attr:`ctime`, :func:`os.path.getctime`)rU   getctimer`   r)   r)   r*   r$    s    zPath.getctimeze Creation time of the file.

        .. seealso:: :meth:`getctime`, :func:`os.path.getctime`
        c                 C  s   | j | S )z2.. seealso:: :attr:`size`, :func:`os.path.getsize`)rU   getsizer`   r)   r)   r*   r%    s    zPath.getsizezd Size of the file, in bytes.

        .. seealso:: :meth:`getsize`, :func:`os.path.getsize`
        zmasks.Permissions)r%   c                 C  s   t |  jS )z
        Permissions.

        >>> perms = Path('.').permissions
        >>> isinstance(perms, int)
        True
        >>> set(perms.symbolic) <= set('rwx-')
        True
        >>> perms.symbolic
        'r...'
        )r   ZPermissionsr  st_moder`   r)   r)   r*   permissions  s    zPath.permissionsc                 O  s   t j| f||S )z
        Return does the real user have access to this path.

        >>> Path('.').access(os.F_OK)
        True

        .. seealso:: :func:`os.access`
        )rk   accessr   r)   r)   r*   r(    s    	zPath.accessfollow_symlinksc                C  s   t j| |dS )z
        Perform a ``stat()`` system call on this path.

        >>> Path('.').stat()
        os.stat_result(...)

        .. seealso:: :meth:`lstat`, :func:`os.stat`
        r)  )rk   r  )r3   r*  r)   r)   r*   r    s    	z	Path.statc                 C  s
   t | S )z
        Like :meth:`stat`, but do not follow symbolic links.

        >>> Path('.').lstat() == Path('.').stat()
        True

        .. seealso:: :meth:`stat`, :func:`os.lstat`
        )rk   lstatr`   r)   r)   r*   r+    s    	z
Path.lstatc                 C  s4   t | t j}| }t d|\}}}|d | S )z
        Return the name of the owner of this file or directory. Follow
        symbolic links.

        Return a name of the form ``DOMAIN\User Name``; may be a group.

        .. seealso:: :attr:`owner`
        N\)win32securityZGetFileSecurityZOWNER_SECURITY_INFORMATIONZGetSecurityDescriptorOwnerZLookupAccountSid)r3   descZsidaccountdomaintypecoder)   r)   r*   Z__get_owner_windows  s    	 zPath.__get_owner_windowsc                 C  s   |   }t|jjS )z
        Return the name of the owner of this file or directory. Follow
        symbolic links.

        .. seealso:: :attr:`owner`
        )r  pwdgetpwuidst_uidpw_name)r3   str)   r)   r*   Z__get_owner_unix  s    zPath.__get_owner_unixc                 C  s   t dd S )Nz)Ownership not available on this platform.)NotImplementedErrorr`   r)   r)   r*   Z__get_owner_not_implemented  s    z Path.__get_owner_not_implementedr-  r2  zU Name of the owner of this file or directory.

        .. seealso:: :meth:`get_owner`grpc                C  s   | j |dj}t|jS )z@
            Return the group name of the file gid.
            r)  )r  st_gidr8  getgrgidgr_name)r3   r*  gidr)   r)   r*   group4  s    z
Path.groupstatvfsc                 C  s
   t | S )zkPerform a ``statvfs()`` system call on this path.

            .. seealso:: :func:`os.statvfs`
            )rk   r>  r`   r)   r)   r*   r>  =  s    zPath.statvfspathconfc                 C  s   t | |S )z .. seealso:: :func:`os.pathconf`)rk   r?  r   r)   r)   r*   r?  F  s    zPath.pathconfc                 O  s   t j| f|| | S )z_Set the access and modified times of this file.

        .. seealso:: :func:`os.utime`
        )rk   r   r   r)   r)   r*   r   M  s    z
Path.utimec                 C  s2   t |tr"t|}||  j}t| | | S )at  
        Set the mode. May be the new mode (os.chmod behavior) or a `symbolic
        mode <http://en.wikipedia.org/wiki/Chmod#Symbolic_modes>`_.

        >>> a_file = Path(getfixture('tmp_path')).joinpath('afile.txt').touch()
        >>> a_file.chmod(0o700)
        Path(...
        >>> a_file.chmod('u+x')
        Path(...

        .. seealso:: :func:`os.chmod`
        )r&   r   r   Zcompoundr  r&  rk   chmod)r3   r   maskr)   r)   r*   r@  U  s
    

z
Path.chmodchownc                 C  s*   dd }dd }t | |||| | S )zt
            Change the owner and group by names or numbers.

            .. seealso:: :func:`os.chown`
            c                 S  s   t | tr| S t| jS r1   )r&   r(   r2  getpwnampw_uid)uidr)   r)   r*   resolve_uidq  s    zPath.chown.<locals>.resolve_uidc                 S  s   t | tr| S t| jS r1   )r&   r(   r8  getgrnamgr_gid)r<  r)   r)   r*   resolve_gidt  s    zPath.chown.<locals>.resolve_gid)rk   rB  )r3   rF  r<  rG  rJ  r)   r)   r*   rB  j  s    z
Path.chownc                 C  s   t | | | |S )z.. seealso:: :func:`os.rename`)rk   renamer\   r3   r
  r)   r)   r*   rK  z  s    zPath.renamec                 C  s   t | | | |S )z.. seealso:: :func:`os.renames`)rk   renamesr\   rL  r)   r)   r*   rM    s    zPath.renames  c                 C  s   t | | | S )z.. seealso:: :func:`os.mkdir`)rk   mkdirr3   r   r)   r)   r*   rO    s    z
Path.mkdirc              	   C  s$   t t | | W 5 Q R X | S )z\Like :meth:`mkdir`, but does not raise an exception if the
        directory already exists.)rO   rP   FileExistsErrorrO  rP  r)   r)   r*   mkdir_p  s    zPath.mkdir_pc                 C  s   t | | | S )z .. seealso:: :func:`os.makedirs`)rk   makedirsrP  r)   r)   r*   rS    s    zPath.makedirsc              	   C  s$   t t | | W 5 Q R X | S )z_Like :meth:`makedirs`, but does not raise an exception if the
        directory already exists.)rO   rP   rQ  rS  rP  r)   r)   r*   
makedirs_p  s    zPath.makedirs_pc                 C  s   t |  | S )z.. seealso:: :func:`os.rmdir`)rk   rmdirr`   r)   r)   r*   rU    s    
z
Path.rmdirc              
   C  s@   t ttf}t|" t  |   W 5 Q R X W 5 Q R X | S )zlLike :meth:`rmdir`, but does not raise an exception if the
        directory is not empty or does not exist.)FileNotFoundErrorrQ  DirectoryNotEmptyrO   rP   	translaterU  )r3   Z
suppressedr)   r)   r*   rmdir_p  s
    

zPath.rmdir_pc                 C  s   t |  | S )z".. seealso:: :func:`os.removedirs`)rk   
removedirsr`   r)   r)   r*   rZ    s    
zPath.removedirsc              
   C  s8   t tt" t  |   W 5 Q R X W 5 Q R X | S )zqLike :meth:`removedirs`, but does not raise an exception if the
        directory is not empty or does not exist.)rO   rP   rQ  rW  rX  rZ  r`   r)   r)   r*   removedirs_p  s    
zPath.removedirs_pc                 C  s,   t t | t jt jB d t | d | S )zvSet the access/modified times of this file to the current time.
        Create the file if it does not exist.
        i  N)rk   closer   O_WRONLYO_CREATr   r`   r)   r)   r*   touch  s    z
Path.touchc                 C  s   t |  | S )z.. seealso:: :func:`os.remove`)rk   remover`   r)   r)   r*   r`    s    
zPath.removec              	   C  s"   t t |   W 5 Q R X | S )zXLike :meth:`remove`, but does not raise an exception if the
        file does not exist.)rO   rP   rV  unlinkr`   r)   r)   r*   remove_p  s    zPath.remove_p)targetr%   c                 C  s   t ||  dS )zg
        Create a hard link at self, pointing to target.

        .. seealso:: :func:`os.link`
        N)rk   link)r3   rc  r)   r)   r*   hardlink_to  s    zPath.hardlink_toc                 C  s   t | | | |S )zfCreate a hard link at `newpath`, pointing to this file.

        .. seealso:: :func:`os.link`
        )rk   rd  r\   )r3   newpathr)   r)   r*   rd    s    z	Path.link)rc  target_is_directoryr%   c                 C  s   t || | dS )zn
        Create a symbolic link at self, pointing to target.

        .. seealso:: :func:`os.symlink`
        N)rk   symlink)r3   rc  rg  r)   r)   r*   
symlink_to  s    zPath.symlink_toc                 C  s&   |dkr|   }t| | | |S )zCreate a symbolic link at `newlink`, pointing here.

        If newlink is not supplied, the symbolic link will assume
        the name self.basename(), creating the link in the cwd.

        .. seealso:: :func:`os.symlink`
        N)r~   rk   rh  r\   )r3   Znewlinkr)   r)   r*   rh    s    zPath.symlinkc                 C  s   |  tt| dS )zReturn the path to which this symbolic link points.

        The result may be an absolute or a relative path.

        .. seealso:: :meth:`readlinkabs`, :func:`os.readlink`
        z\\?\)r\   r   rk   readlinkr`   r)   r)   r*   rj    s    zPath.readlinkc                 C  s"   |   }| r|S | j|  S )zReturn the path to which this symbolic link points.

        The result is always an absolute path.

        .. seealso:: :meth:`readlink`, :func:`os.readlink`
        )rj  r  r   rw   )r3   r   r)   r)   r*   readlinkabs  s    zPath.readlinkabsmovec              	   C  s"   t t |   W 5 Q R X | S )z]Like :meth:`rmtree`, but does not raise an exception if the
        directory does not exist.)rO   rP   rV  rmtreer`   r)   r)   r*   rmtree_p  s    zPath.rmtree_pc                 C  s   t |  dS )z.. seealso:: :func:`os.chdir`N)rk   rl   r`   r)   r)   r*   rl   "  s    z
Path.chdirc                 C  s   g S r1   r)   )dircontentsr)   r)   r*   r   .  r   zPath.<lambda>)copy_functionignorec          
        s   |  |}|  t|  }|| dd |D   fdd}t||D ]T}||j }|rx| rx| }	|		| qJ|
 r|j||||d qJ||| qJ| | dS )a  
        Copy entire contents of self to dst, overwriting existing
        contents in dst with those in self.

        Pass ``symlinks=True`` to copy symbolic links as links.

        Accepts a ``copy_function``, similar to copytree.

        To avoid overwriting newer files, supply a copy function
        wrapped in ``only_newer``. For example::

            src.merge_tree(dst, copy_function=only_newer(shutil.copy2))
        c                 S  s   g | ]
}|j qS r)   r   r   r)   r)   r*   r   A  s     z#Path.merge_tree.<locals>.<listcomp>c                   s
   | j  kS r1   rs  )r;   Z_ignoredr)   r*   ignoredC  s    z Path.merge_tree.<locals>.ignored)symlinksrq  rr  N)r\   rT  r   r   	itertoolsfilterfalser   r  rj  rh  r   
merge_treecopystat)
r3   dstrv  rq  rr  sourcesru  sourcer   rc  r)   rt  r*   ry  (  s&    

zPath.merge_treechrootc                 C  s   t |  dS )z.. seealso:: :func:`os.chroot`N)rk   r~  r`   r)   r)   r*   r~  \  s    zPath.chroot	startfilec                 O  s   t j| f|| | S )z!.. seealso:: :func:`os.startfile`)rk   r  r   r)   r)   r*   r  b  s    zPath.startfiler   c              	   c  s>  t |drtd| |p$tjd  }|  | | t||||||d}t|	 j
}	tjtjB tjB }
|
ttddO }
t| |
|	}t|d|dd	 ||||d}ttt | |	 W 5 Q R X z^z||fV  W n: tk
r   |  |  |   ||   Y nX |  |  W 5 |  X d
S )ab  
        A context in which a file may be re-written in-place with
        new content.

        Yields a tuple of :samp:`({readable}, {writable})` file
        objects, where `writable` replaces `readable`.

        If an exception occurs, the old file is restored, removing the
        written data.

        Mode *must not* use ``'w'``, ``'a'``, or ``'+'``; only
        read-only-modes are allowed. A :exc:`ValueError` is raised
        on invalid modes.

        For example, to add line numbers to a file::

            p = Path(filename)
            assert p.is_file()
            with p.in_place() as (reader, writer):
                for number, line in enumerate(reader, 1):
                    writer.write('{0:3}: '.format(number)))
                    writer.write(line)

        Thereafter, the file at `filename` will have line numbers in it.
        zwa+z%Only read-only file modes can be usedZbak)r   r   r   r   O_BINARYr   r   r   r>   N)setintersectionr   rk   extseprb  rK  r   r  filenor&  r^  r]  O_TRUNCr   replacerO   rP   OSErrorrQ   r@  r   r\  )r3   r   r   r   r   r   Zbackup_extensionZ	backup_fnreadablepermZos_modefdwritabler)   r)   r*   in_placei  sL    #
	
zPath.in_placec                 C  s   t t| S )a  
        Return a SpecialResolver object suitable referencing a suitable
        directory for the relevant platform for the given
        type of content.

        For example, to get a user config directory, invoke:

            dir = Path.special().user.config

        Uses the `appdirs
        <https://pypi.python.org/pypi/appdirs/1.4.0>`_ to resolve
        the paths in a platform-friendly way.

        To create a config directory for 'My App', consider:

            dir = Path.special("My App").user.config.makedirs_p()

        If the ``appdirs`` module is not installed, invocation
        of special will raise an ImportError.
        )r7   r8   SpecialResolverr[   r)   r)   r*   special  s    zPath.special)rG   )rG   )rG   )N)N)Nr   )N).......).....)......)......)......).....)......).......)......)......)F)NN)Nr   )....)....)NNT)rC  rC  )rN  )rN  )rN  )rN  )F)N)F)r   rC  NNNN)r-   r.   r/   r=   rk   pathrU   rI   r4   classmethodr7   	lru_cacherZ   r   ClassPropertyr\   r_   ra   rb   rg   __truediv__rh   __rtruediv__rm   rn   ri   ro   rw   rv   rx   ry   rz   r{   r|   r}   r~   r   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   Zmultimethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rE   r  r  staticmethodr  r  r  r  r  r  r  r  r   r  r   r  r  r  r  r!  atimer"  r#  mtimer$  ctimer%  r   r'  r(  r  r+  Z_Path__get_owner_windowsZ_Path__get_owner_unixZ _Path__get_owner_not_implementedglobalsZ	get_ownerownerr=  hasattrr>  r?  r   r@  rB  rK  rM  rO  rR  rS  rT  rU  rY  rZ  r[  r_  r`  rb  ra  Zunlink_pre  rd  ri  rh  rj  rk  shutilcopyfilecopymoderz  copycopy2copytreerl  rm  rn  rl   Zcdry  r~  r  rO   contextmanagerr  r  __classcell__r)   r)   rL   r*   r      sx  

	
	




((                                               "     "     "	
   	   
   
J
(

	
		


	
	
	
2     Qc                   @  s   e Zd Zeejdd ZdS )rW  c               
   c  sL   z
d V  W n< t k
rF }  z| jtjkr4t| j |  W 5 d } ~ X Y nX d S r1   )r  errno	ENOTEMPTYrW  r   )r   r)   r)   r*   rX    s    
zDirectoryNotEmpty.translateN)r-   r.   r/   r  rO   r  rX  r)   r)   r)   r*   rW    s   rW  c                   s   t   fdd}|S )zg
    Wrap a copy function (like shutil.copy2) to return
    the dst if it's newer than the source.
    c                   s2   |  o| |  k}|r |S  | |f||S r1   )r  r"  )srcr{  r   r   Zis_newer_dst	copy_funcr)   r*   wrapper  s    zonly_newer.<locals>.wrapper)r7   wraps)r  r  r)   r  r*   
only_newer  s    r  c                   @  s   e Zd ZdZdd ZdS )
ExtantPathz
    >>> ExtantPath('.')
    ExtantPath('.')
    >>> ExtantPath('does-not-exist')
    Traceback (most recent call last):
    OSError: does-not-exist does not exist.
    c                 C  s   |   st|  dd S )Nz does not exist.)r  r  r`   r)   r)   r*   rR     s    zExtantPath._validateNr-   r.   r/   r=   rR   r)   r)   r)   r*   r    s   r  c                   @  s   e Zd ZdZdd ZdS )
ExtantFilea  
    >>> ExtantFile('.')
    Traceback (most recent call last):
    FileNotFoundError: . does not exist as a file.
    >>> ExtantFile('does-not-exist')
    Traceback (most recent call last):
    FileNotFoundError: does-not-exist does not exist as a file.
    c                 C  s   |   st|  dd S )Nz does not exist as a file.)r   rV  r`   r)   r)   r*   rR   	  s    zExtantFile._validateNr  r)   r)   r)   r*   r    s   	r  c                   @  s2   e Zd ZG dd dZdd Zdd Zdd Zd	S )
r  c                   @  s   e Zd Zdd Zdd ZdS )zSpecialResolver.ResolverScopec                 C  s   || _ || _d S r1   )pathsscope)r3   r  r  r)   r)   r*   r4     s    z&SpecialResolver.ResolverScope.__init__c                 C  s   | j | j|S r1   )r  get_dirr  )r3   class_r)   r)   r*   __getattr__  s    z)SpecialResolver.ResolverScope.__getattr__N)r-   r.   r/   r4   r  r)   r)   r)   r*   ResolverScope  s   r  c                 O  s(   t d}t| j||j||d d S )Nappdirs)
path_classr  )	importlibimport_modulevarsr  AppDirs)r3   r  r   r   r  r)   r)   r*   r4     s
    
 
zSpecialResolver.__init__c                 C  s   |  | |S r1   )r  )r3   r  r)   r)   r*   r    s    zSpecialResolver.__getattr__c                 C  s2   | d| d}t | j|}t| j}||S )zs
        Return the callable function from appdirs, but with the
        result wrapped in self.path_class
        rT   Z_dir)r   r  Multi	for_classr  detect)r3   r  r  Z	prop_namer$   Z	MultiPathr)   r)   r*   r  !  s    zSpecialResolver.get_dirN)r-   r.   r/   r  r4   r  r  r)   r)   r)   r*   r    s   r  c                   @  sB   e Zd ZdZedd Zedd Zdd Zej	edd	 Z
d
S )r  zS
    A mix-in for a Path which may contain multiple Path separated by pathsep.
    c                 C  s   d|j  }t|| |fi S )Nr  rV   )rJ   path_clsr   r)   r)   r*   r  1  s    
zMulti.for_classc                 C  s   t j|kr| j} | |S r1   )rk   pathsepr\   )rJ   inputr)   r)   r*   r  6  s    
zMulti.detectc                 C  s   t t| j| tjS r1   )r   mapr\   r   rk   r  r`   r)   r)   r*   __iter__<  s    zMulti.__iter__c                 C  s   t dd | jD S )z>
        Multi-subclasses should use the parent class
        c                 s  s   | ]}t |ts|V  qd S r1   )
issubclassr  )rB   r  r)   r)   r*   rD   E  s     
 z$Multi._next_class.<locals>.<genexpr>)next__mro__r[   r)   r)   r*   r\   ?  s    zMulti._next_classN)r-   r.   r/   r=   r  r  r  r  r   r  r\   r)   r)   r)   r*   r  ,  s   

r  c                      sJ   e Zd ZdZejedd Z fddZdd Z	dd	 Z
d
d Z  ZS )r   as  
    A temporary directory via :func:`tempfile.mkdtemp`, and
    constructed with the same parameters that you can use
    as a context manager.

    For example:

    >>> with TempDir() as d:
    ...     d.is_dir() and isinstance(d, Path)
    True

    The directory is deleted automatically.

    >>> d.is_dir()
    False

    .. seealso:: :func:`tempfile.mkdtemp`
    c                 C  s   t S r1   )r   r[   r)   r)   r*   r\   \  s    zTempDir._next_classc                   s   t j||}t | |S r1   )tempfilemkdtemprH   rI   )rJ   r   r   r}   rL   r)   r*   rI   a  s    zTempDir.__new__c                 O  s   d S r1   r)   r   r)   r)   r*   r4   e  s    zTempDir.__init__c                 C  s
   |  | S r1   )r\   r`   r)   r)   r*   rm   h  s    zTempDir.__enter__c                 C  s   |    d S r1   )rm  )r3   exc_type	exc_value	tracebackr)   r)   r*   rn   o  s    zTempDir.__exit__)r-   r.   r/   r=   r   r  r  r\   rI   r4   rm   rn   r  r)   r)   rL   r*   r   H  s   c                   @  s0   e Zd Zdd Zdd Zdd Zedd Zd	S )
r   c                  C  s    d S r1   r)   msgr)   r)   r*   r   t  s    zHandlers.strictc                 C  s   t j| tdd d S )Nrp   rq   )rs   rt   r,   r  r)   r)   r*   rt   w  s    zHandlers.warnc                 C  s   d S r1   r)   r  r)   r)   r*   rr  z  s    zHandlers.ignorec                 C  s,   t |s|ttkrtdt| ||S )Nzinvalid errors parameter)callabler  r   r   get)rJ   paramr)   r)   r*   r   }  s    zHandlers._resolveN)r-   r.   r/   r   rt   rr  r  r   r)   r)   r)   r*   r   s  s
   r   )Tr=   
__future__r   builtinsrO   datetimer  r   r7   r   r	  r  rw  rk   rer  r   r  rs   numbersr   rP   ImportErrorr-  r2  r8  ior   r   r   r   r   typingr	   r
   r   r   r   r   r   Z	_typeshedr   r   r   r   r   Ztyping_extensionsr   r>   r   r   r   Zcompat.py38r   r   __all__ZLINESEPSZ
U_LINESEPScompilerd   r   r   r   r   ZB_NL_ENDr?   objectr  r+   Warningr,   r0   rF   r   r   r  rW  r  r  r  r  r  r   r   r)   r)   r)   r*   <module>   s   $

$            K+