o
    pfP!                     @   s   d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
 ddlmZ dd	lmZ ed
ddgZedg dZedddgZejr\ddlmZmZmZmZmZmZ ddlmZ edZd ddZdd Zdd ZG dd deZ G dd deZ!dS )!z1Useful functions for working with glob patterns.
    )unicode_literalsN)
namedtuple   )wildcard)	make_repr)LRUCache)iteratepath	GlobMatchpathinfoCounts)filesdirectoriesdata
LineCountslines	non_blank)IteratorListOptionalPatternTextTuple)FSi  Tc                 C   s   d}d}dg}t | D ]}|dkr|d d}n|dtj||d  |d	7 }qd
d| | dr7dnd }||t||rEdfS tjfS )Nr   F z**z.*/?T/case_sensitiver   z(?ms)^z/$$)	r   appendr   
_translatejoinendswithrecompile
IGNORECASE)patternr   levels	recursivere_patterns	componentre_glob r,   @/home/ertert/spirit/venv/lib/python3.10/site-packages/fs/glob.py_translate_glob   s$   

 r.   c                 C   s\   zt | df \}}}W n ty&   t| dd\}}}|||ft | df< Y nw t||S )aA  Compare a glob pattern with a path (case sensitive).

    Arguments:
        pattern (str): A glob pattern.
        path (str): A path.

    Returns:
        bool: ``True`` if the path matches the pattern.

    Example:

        >>> from fs.glob import match
        >>> match("**/*.py", "/fs/glob.py")
        True

    Tr   _PATTERN_CACHEKeyErrorr.   boolmatchr&   r
   r'   r(   
re_patternr,   r,   r-   r3   4   s   r3   c                 C   s\   zt | df \}}}W n ty&   t| dd\}}}|||ft | df< Y nw t||S )zCompare a glob pattern with a path (case insensitive).

    Arguments:
        pattern (str): A glob pattern.
        path (str): A path.

    Returns:
        bool: ``True`` if the path matches the pattern.

    FTr   r/   r4   r,   r,   r-   imatchN   s   r6   c                   @   sT   e Zd ZdZ				dddZdd Zdd
dZdd Zdd Zdd Z	dd Z
dS )GlobberzA generator of glob results.r   NTc                 C   s(   || _ || _|| _|| _|| _|| _dS )a  Create a new Globber instance.

        Arguments:
            fs (~fs.base.FS): A filesystem object
            pattern (str): A glob pattern, e.g. ``"**/*.py"``
            path (str): A path to a directory in the filesystem.
            namespaces (list): A list of additional info namespaces.
            case_sensitive (bool): If ``True``, the path matching will be
                case *sensitive* i.e. ``"FOO.py"`` and ``"foo.py"`` will be
                different, otherwise path matching will be case *insensitive*.
            exclude_dirs (list): A list of patterns to exclude when searching,
                e.g. ``["*.git"]``.

        N)fsr&   r
   
namespacesr   exclude_dirs)selfr8   r&   r
   r9   r   r:   r,   r,   r-   __init__e   s   
zGlobber.__init__c              	   C   s6   t | jj| j| j| jdf| jd f| jdf| jd fdS )Nr   T)r
   r9   r   r:   )	r   	__class____name__r8   r&   r
   r9   r   r:   r;   r,   r,   r-   __repr__   s   zGlobber.__repr__breadthc                 c   s    zt | j| jf \}}}W n ty"   t| j| jd\}}}Y nw | jjj| j|p-| j	|r1d n||| j
dD ]\}}|jrC|d7 }||rNt||V  q8d S )Nr   )r
   r9   	max_depthsearchr:   r   )r0   r&   r   r1   r.   r8   walkr   r
   r9   r:   is_dirr3   r	   )r;   rC   r9   r'   r(   r5   r
   r   r,   r,   r-   
_make_iter   s.   


zGlobber._make_iterc                 C   s   |   S )z6Get an iterator of :class:`fs.glob.GlobMatch` objects.)rF   r?   r,   r,   r-   __iter__   s   zGlobber.__iter__c                 C   sT   d}d}d}| j dgdD ]\}}|jr|d7 }n|d7 }||j7 }qt|||dS )zCount files / directories / data in matched paths.

        Example:
            >>> my_fs.glob('**/*.py').count()
            Counts(files=2, directories=0, data=55)

        Returns:
            `~Counts`: A named tuple containing results.

        r   details)r9   r   )r   r   r   )rF   rE   sizer   )r;   r   r   r   _pathr   r,   r,   r-   count   s   
zGlobber.countc                 C   sX   d}d}|   D ]\}}|jr%| j|dD ]}|d7 }| r$|d7 }qqt||dS )zCount the lines in the matched files.

        Returns:
            `~LineCounts`: A named tuple containing line counts.

        Example:
            >>> my_fs.glob('**/*.py').count_lines()
            LineCounts(lines=4, non_blank=3)

        r   rbr   )r   r   )rF   is_filer8   openrstripr   )r;   r   r   r
   r   liner,   r,   r-   count_lines   s   zGlobber.count_linesc                 C   sF   d}| j ddD ]\}}|jr| j| n| j| |d7 }q|S )zRemove all matched paths.

        Returns:
            int: Number of file and directories removed.

        Example:
            >>> my_fs.glob('**/*.pyc').remove()
            2

        r   depth)rC   r   )rF   rE   r8   
removetreeremove)r;   removesr
   r   r,   r,   r-   rT      s   
zGlobber.remover   NTN)rA   N)r>   
__module____qualname____doc__r<   r@   rF   rG   rK   rQ   rT   r,   r,   r,   r-   r7   b   s    

r7   c                   @   s2   e Zd ZdZdgZdd Zdd Z	dd
dZdS )BoundGlobberzA `~fs.glob.Globber` object bound to a filesystem.

    An instance of this object is available on every Filesystem object
    as the `~fs.base.FS.glob` property.

    r8   c                 C   s
   || _ dS )znCreate a new bound Globber.

        Arguments:
            fs (FS): A filesystem object to bind to.

        N)r8   )r;   r8   r,   r,   r-   r<      s   
zBoundGlobber.__init__c                 C   s   t | jj| jS )N)r   r=   r>   r8   r?   r,   r,   r-   r@     s   zBoundGlobber.__repr__r   NTc                 C   s   t | j|||||dS )a  Match resources on the bound filesystem againsts a glob pattern.

        Arguments:
            pattern (str): A glob pattern, e.g. ``"**/*.py"``
            namespaces (list): A list of additional info namespaces.
            case_sensitive (bool): If ``True``, the path matching will be
                case *sensitive* i.e. ``"FOO.py"`` and ``"foo.py"`` will
                be different, otherwise path matching will be case **insensitive**.
            exclude_dirs (list): A list of patterns to exclude when searching,
                e.g. ``["*.git"]``.

        Returns:
            `Globber`: An object that may be queried for the glob matches.

        )r9   r   r:   )r7   r8   )r;   r&   r
   r9   r   r:   r,   r,   r-   __call__  s   zBoundGlobber.__call__rV   )r>   rW   rX   rY   	__slots__r<   r@   r[   r,   r,   r,   r-   rZ      s    
rZ   )T)"rY   
__future__r   typingr#   collectionsr   r   r   _reprr   lrucacher   r
   r   r	   r   r   TYPE_CHECKINGr   r   r   r   r   r   baser   r0   r.   r3   r6   objectr7   rZ   r,   r,   r,   r-   <module>   s0     
 