o
    pfc4                     @   s  d Z ddlmZmZ ddlZddlZddlmZ ejr%ddlm	Z	m
Z
mZ g dZedejjZd	d
 Zdd Zd5d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"d# Zd$d% Zd&d' Zd(d) Z d*d+ Z!d,d- Z"d.d/ Z#d0d1 Z$e%d2Z&d3d4 Z'dS )6aA  Useful functions for working with PyFilesystem paths.

This is broadly similar to the standard `os.path` module but works
with paths in the canonical format expected by all FS objects (that is,
separated by forward slashes and with an optional leading slash).

See :ref:`paths` for an explanation of PyFilesystem paths.

    )print_functionunicode_literalsN   )IllegalBackReference)ListTextTuple)abspathbasenamecombinedirnameforcedirfrombaseisabsisbase	isdotfileisparent	issamedir
iswildcarditeratepathjoinnormpathpartsrecursepathrelativefromrelpathsplitsplitextz(^|/)\.\.?($|/)|//c                 C   s   | dv r| S t | s| dS | drdnd}g }z| dD ]}|dv r/|dkr.|  q || q W n tyA   t| w |d| S )a  Normalize a path.

    This function simplifies a path by collapsing back-references
    and removing duplicated separators.

    Arguments:
        path (str): Path to normalize.

    Returns:
        str: A valid FS path.

    Example:
        >>> normpath("/foo//bar/frob/../baz")
        '/foo/bar/baz'
        >>> normpath("foo/../../bar")
        Traceback (most recent call last):
            ...
        fs.errors.IllegalBackReference: path 'foo/../../bar' contains back-references outside of filesystem

    / ..)	_requires_normalizationrstrip
startswithr   popappend
IndexErrorr   r   )pathprefix
components	component r+   @/home/ertert/spirit/venv/lib/python3.10/site-packages/fs/path.pyr   2   s$   
r   c                 C   s   t t| } | s
g S | dS )zIterate over the individual components of a path.

    Arguments:
        path (str): Path to iterate over.

    Returns:
        list: A list of path components.

    Example:
        >>> iteratepath('/foo/bar/baz')
        ['foo', 'bar', 'baz']

    r   )r   r   r   r'   r+   r+   r,   r   ^   s   
r   Fc                 C   s   | dv rdgS t t| d } dg}| j}|j}d}t| }||k r7|d|}|| d|  |d7 }||k s"|r@|ddd S |S )aN  Get intermediate paths from the root to the given path.

    Arguments:
        path (str): A PyFilesystem path
        reverse (bool): Reverses the order of the paths
            (default `False`).

    Returns:
        list: A list of paths.

    Example:
        >>> recursepath('a/b/c')
        ['/', '/a', '/a/b', '/a/b/c']

    r   r   N)r	   r   findr%   len)r'   reversepathsr/   r%   poslen_pathr+   r+   r,   r   s   s    
r   c                 C   
   |  dS )zCheck if a path is an absolute path.

    Arguments:
        path (str): A PyFilesytem path.

    Returns:
        bool: `True` if the path is absolute (starts with a ``'/'``).

    r   r#   r-   r+   r+   r,   r      s   
r   c                 C   s   |  ds	d|  S | S )a/  Convert the given path to an absolute path.

    Since FS objects have no concept of a *current directory*, this
    simply adds a leading ``/`` character if the path doesn't already
    have one.

    Arguments:
        path (str): A PyFilesytem path.

    Returns:
        str: An absolute path.

    r   r6   r-   r+   r+   r,   r	      s   
r	   c                 C   r5   )a1  Convert the given path to a relative path.

    This is the inverse of `abspath`, stripping a leading ``'/'`` from
    the path if it is present.

    Arguments:
        path (str): A path to adjust.

    Returns:
        str: A relative path.

    Example:
        >>> relpath('/a/b')
        'a/b'

    r   )lstripr-   r+   r+   r,   r      s   
r   c                  G   sX   d}g }| D ]}|r|d dkr|dd= d}| | qtd|}|r*t|}|S )a]  Join any number of paths together.

    Arguments:
        *paths (str): Paths to join, given as positional arguments.

    Returns:
        str: The joined path.

    Example:
        >>> join('foo', 'bar', 'baz')
        'foo/bar/baz'
        >>> join('foo/bar', '../baz')
        'foo/baz'
        >>> join('foo/bar', '/baz')
        '/baz'

    Fr   r   NT)r%   r   r   r	   )r2   absoluterelpathspr'   r+   r+   r,   r      s   

r   c                 C   s$   | s|  S d| d| dS )a  Join two paths together.

    This is faster than :func:`~fs.path.join`, but only works when the
    second path is relative, and there are no back references in either
    path.

    Arguments:
        path1 (str): A PyFilesytem path.
        path2 (str): A PyFilesytem path.

    Returns:
        str: The joint path.

    Example:
        >>> combine("foo/bar", "baz")
        'foo/bar/baz'

    z{}/{}r   )r7   formatr"   path1path2r+   r+   r,   r      s   r   c                 C   s<   t | }|d}|drdndg}|r||d7 }|S )zSplit a path in to its component parts.

    Arguments:
        path (str): Path to split in to parts.

    Returns:
        list: List of components

    Example:
        >>> parts('/foo/bar/baz')
        ['/', 'foo', 'bar', 'baz']

    r   z./)r   stripr#   r   )r'   _pathr)   _partsr+   r+   r,   r     s   
r   c                 C   s0   d| vrd| fS |  dd}|d pd|d fS )a  Split a path into (head, tail) pair.

    This function splits a path into a pair (head, tail) where 'tail' is
    the last pathname component and 'head' is all preceding components.

    Arguments:
        path (str): Path to split

    Returns:
        (str, str): a tuple containing the head and the tail of the path.

    Example:
        >>> split("foo/bar")
        ('foo', 'bar')
        >>> split("foo/bar/baz")
        ('foo/bar', 'baz')
        >>> split("/foo/bar/baz")
        ('/foo/bar', 'baz')

    r   r   r   r   )rsplit)r'   r   r+   r+   r,   r   $  s   r   c                 C   sb   t | \}}|dr|ddkr| dfS d|vr| dfS |dd\}}t||} | d| fS )a~  Split the extension from the path.

    Arguments:
        path (str): A path to split.

    Returns:
        (str, str): A tuple containing the path and the extension.

    Example:
        >>> splitext('baz.txt')
        ('baz', '.txt')
        >>> splitext('foo/bar/baz.txt')
        ('foo/bar/baz', '.txt')
        >>> splitext('foo/bar/.foo')
        ('foo/bar/.foo', '')

    .r   r   )r   r#   countrB   r   )r'   parent_pathpathnameextr+   r+   r,   r   @  s   
r   c                 C   s   t | dS )aN  Detect if a path references a dot file.

    Arguments:
        path (str): Path to check.

    Returns:
        bool: `True` if the resource name starts with a ``'.'``.

    Example:
        >>> isdotfile('.baz')
        True
        >>> isdotfile('foo/bar/.baz')
        True
        >>> isdotfile('foo/bar.baz')
        False

    rC   )r
   r#   r-   r+   r+   r,   r   ]  s   r   c                 C      t | d S )a  Return the parent directory of a path.

    This is always equivalent to the 'head' component of the value
    returned by ``split(path)``.

    Arguments:
        path (str): A PyFilesytem path.

    Returns:
        str: the parent directory of the given path.

    Example:
        >>> dirname('foo/bar/baz')
        'foo/bar'
        >>> dirname('/foo/bar')
        '/foo'
        >>> dirname('/foo')
        '/'

    r   r   r-   r+   r+   r,   r   s     r   c                 C   rH   )a  Return the basename of the resource referenced by a path.

    This is always equivalent to the 'tail' component of the value
    returned by split(path).

    Arguments:
        path (str): A PyFilesytem path.

    Returns:
        str: the name of the resource at the given path.

    Example:
        >>> basename('foo/bar/baz')
        'baz'
        >>> basename('foo/bar')
        'bar'
        >>> basename('foo/bar/')
        ''

    r   rI   r-   r+   r+   r,   r
     rJ   r
   c                 C   s   t t| t t|kS )a  Check if two paths reference a resource in the same directory.

    Arguments:
        path1 (str): A PyFilesytem path.
        path2 (str): A PyFilesytem path.

    Returns:
        bool: `True` if the two resources are in the same directory.

    Example:
        >>> issamedir("foo/bar/baz.txt", "foo/bar/spam.txt")
        True
        >>> issamedir("foo/bar/baz/txt", "spam/eggs/spam.txt")
        False

    )r   r   r<   r+   r+   r,   r     s   r   c                 C   s"   t t| }t t|}||S )a(  Check if ``path1`` is a base of ``path2``.

    Arguments:
        path1 (str): A PyFilesytem path.
        path2 (str): A PyFilesytem path.

    Returns:
        bool: `True` if ``path2`` starts with ``path1``

    Example:
        >>> isbase('foo/bar', 'foo/bar/baz/egg.txt')
        True

    )r   r	   r#   )r=   r>   _path1_path2r+   r+   r,   r     s   
r   c                 C   sv   |  d}| d}|r|d dkr|  |r|d dkst|t|kr(dS t||D ]\}}||kr8 dS q-dS )a  Check if ``path1`` is a parent directory of ``path2``.

    Arguments:
        path1 (str): A PyFilesytem path.
        path2 (str): A PyFilesytem path.

    Returns:
        bool: `True` if ``path1`` is a parent directory of ``path2``

    Example:
        >>> isparent("foo/bar", "foo/bar/spam.txt")
        True
        >>> isparent("foo/bar/", "foo/bar")
        True
        >>> isparent("foo/barry", "foo/baz/bar")
        False
        >>> isparent("foo/bar/baz/", "foo/baz/bar")
        False

    r   r.   r   FT)r   r$   r0   zip)r=   r>   bits1bits2bit1bit2r+   r+   r,   r     s   

r   c                 C   s   |  ds	| d S | S )a]  Ensure the path ends with a trailing forward slash.

    Arguments:
        path (str): A PyFilesytem path.

    Returns:
        str: The path, ending with a slash.

    Example:
        >>> forcedir("foo/bar")
        'foo/bar/'
        >>> forcedir("foo/bar/")
        'foo/bar/'
        >>> forcedir("foo/spam.txt")
        'foo/spam.txt/'

    r   )endswithr-   r+   r+   r,   r     s   
r   c                 C   s"   t | |s	td|t| d S )a,  Get the final path of ``path2`` that isn't in ``path1``.

    Arguments:
        path1 (str): A PyFilesytem path.
        path2 (str): A PyFilesytem path.

    Returns:
        str: the final part of ``path2``.

    Example:
        >>> frombase('foo/bar/', 'foo/bar/baz/egg')
        'baz/egg'

    zpath1 must be a prefix of path2N)r   
ValueErrorr0   r<   r+   r+   r,   r   	  s   
r   c                 C   sh   t t| }t t|}d}t||D ]\}}||kr n|d7 }qddgt||  ||d  S )aj  Return a path relative from a given base path.

    Insert backrefs as appropriate to reach the path from the base.

    Arguments:
        base (str): Path to a directory.
        path (str): Path to make relative.

    Returns:
        str: the path to ``base`` from ``path``.

    >>> relativefrom("foo/bar", "baz/index.html")
    '../../baz/index.html'

    r   r   r   r    N)listr   rM   r   r0   )baser'   
base_parts
path_partscommoncomponent_acomponent_br+   r+   r,   r     s   
$r   z*?[]!{}c                 C   s   | dusJ t |  S )a  Check if a path ends with a wildcard.

    Arguments:
        path (str): A PyFilesystem path.

    Returns:
        bool: `True` if path ends with a wildcard.

    Example:
        >>> iswildcard('foo/bar/baz.*')
        True
        >>> iswildcard('foo/bar')
        False

    N)_WILD_CHARS
isdisjointr-   r+   r+   r,   r   >  s   r   )F)(__doc__
__future__r   r   typingreerrorsr   TYPE_CHECKINGr   r   r   __all__compileUNICODEsearchr!   r   r   r   r   r	   r   r   r   r   r   r   r   r   r
   r   r   r   r   r   r   	frozensetr[   r   r+   r+   r+   r,   <module>   s>    
,
&""