o
    bM                     @   s  d Z ddlZddlZddlZddlZzddlmZmZmZm	Z	m
Z
mZmZmZmZmZmZmZ W n	 ey9   Y nw zddlmZ ddlmZ W n	 eyQ   Y nw ddlmZmZmZmZ ddlmZ d	d
 ejejfD Z	 i Z	 d+ddZ dd Z!d,ddZ"d,ddZ#e#Z$dd Z%dd Z&dd Z'dd Z(d+ddZ)d+ddZ*d+dd Z+d+d!d"Z,G d#d$ d$e-Z.G d%d& d&e-Z/G d'd( d(e0Z1G d)d* d*e0Z2dS )-zC
This module provides utility methods for dealing with path-specs.
    N)AnyAnyStrCallableDictIterableIteratorListOptionalSequenceSetTextUnion)PathLike)
Collection   )CollectionTypeIterableTypestring_typesunicode)Patternc                 C   s   g | ]}|r|t jkr|qS  )	posixpathsep).0r   r   r   L/var/www/secure340b-portal/env/lib/python3.10/site-packages/pathspec/util.py
<listcomp>(   s    r   c           	      C   s   t |tr|nt|}i }| D ];}|jdurJ||}|jrB|D ] }||v r9|r1|| j| q ||| jd< q t|g||< q q|D ]}||= qDq|S )a  
	Matches the files to the patterns, and returns which patterns matched
	the files.

	*patterns* (:class:`~collections.abc.Iterable` of :class:`~pathspec.pattern.Pattern`)
	contains the patterns to use.

	*files* (:class:`~collections.abc.Iterable` of :class:`str`) contains
	the normalized file paths to be matched against *patterns*.

	*all_matches* (:class:`boot` or :data:`None`) is whether to return all
	matches patterns (:data:`True`), or only the last matched pattern
	(:data:`False`). Default is :data:`None` for :data:`False`.

	Returns the matched files (:class:`dict`) which maps each matched file
	(:class:`str`) to the patterns that matched in order (:class:`.MatchDetail`).
	Nr   )
isinstancer   listincludematchpatternsappendMatchDetail)	r    filesZall_matches	all_filesreturn_filespatternresult_filesZresult_filefiler   r   r   detailed_match_files7   s"   

r)   c                 C   s   t | tot | ttf S )z
	Check whether the value is an iterable (excludes strings).

	*value* is the value to check,

	Returns whether *value* is a iterable (:class:`bool`).
	)r   r   r   bytes)valuer   r   r   _is_iterableb   s   	r,   c                 c   sT    |durt |std||du rd}ttj| di ||D ]}|V  q"dS )a  
	Walks the specified directory for all files and directories.

	*root* (:class:`str`) is the root directory to search.

	*on_error* (:class:`~collections.abc.Callable` or :data:`None`)
	optionally is the error handler for file-system exceptions. It will be
	called with the exception (:exc:`OSError`). Reraise the exception to
	abort the walk. Default is :data:`None` to ignore file-system
	exceptions.

	*follow_links* (:class:`bool` or :data:`None`) optionally is whether
	to walk symbolic links that resolve to directories. Default is
	:data:`None` for :data:`True`.

	Raises :exc:`RecursionError` if recursion is detected.

	Returns an :class:`~collections.abc.Iterator` yielding each file or
	directory entry (:class:`.TreeEntry`) relative to *root*.
	Non_error:{!r} is not callable.T )callable	TypeErrorformat_iter_tree_entries_nextospathabspathrooton_errorfollow_linksentryr   r   r   iter_tree_entriesn   s   r;   c                 c   s`    |durt |std||du rd}ttj| di ||D ]}||s-|jV  q"dS )a  
	Walks the specified directory for all files.

	*root* (:class:`str`) is the root directory to search for files.

	*on_error* (:class:`~collections.abc.Callable` or :data:`None`)
	optionally is the error handler for file-system exceptions. It will be
	called with the exception (:exc:`OSError`). Reraise the exception to
	abort the walk. Default is :data:`None` to ignore file-system
	exceptions.

	*follow_links* (:class:`bool` or :data:`None`) optionally is whether
	to walk symbolic links that resolve to directories. Default is
	:data:`None` for :data:`True`.

	Raises :exc:`RecursionError` if recursion is detected.

	Returns an :class:`~collections.abc.Iterator` yielding the path to
	each file (:class:`str`) relative to *root*.
	Nr-   Tr.   )r/   r0   r1   r2   r3   r4   r5   is_dirr6   r   r   r   iter_tree_files   s   
r=   c                 c   sx   t j| |}t j|}||vr|||< n	t||| |dt |D ]}t j||}t j| |}	zt |	}
W n tyV } z|durL|| W Y d}~q%d}~ww t	|
j
rd}zt |	}W n ty } z|durv|| W Y d}~q%d}~ww d}|
}t|j
r|s|st|||
|V  t| ||||D ]}|V  qq%t|j
s|rt|||
|V  q%||= dS )aq  
	Scan the directory for all descendant files.

	*root_full* (:class:`str`) the absolute path to the root directory.

	*dir_rel* (:class:`str`) the path to the directory to scan relative to
	*root_full*.

	*memo* (:class:`dict`) keeps track of ancestor directories
	encountered. Maps each ancestor real path (:class:`str`) to relative
	path (:class:`str`).

	*on_error* (:class:`~collections.abc.Callable` or :data:`None`)
	optionally is the error handler for file-system exceptions.

	*follow_links* (:class:`bool`) is whether to walk symbolic links that
	resolve to directories.

	Yields each entry (:class:`.TreeEntry`).
	)	real_path
first_pathsecond_pathNTF)r3   r4   joinrealpathRecursionErrorlistdirlstatOSErrorstatS_ISLNKst_modeS_ISDIR	TreeEntryr2   S_ISREG)Z	root_fullZdir_relmemor8   r9   Zdir_fullZdir_realZ	node_nameZnode_relZ	node_fullZ
node_lstateis_link	node_statr:   r   r   r   r2      sL   

r2   c                 C   s   t |  S )z
	Lookups a registered pattern factory by name.

	*name* (:class:`str`) is the name of the pattern factory.

	Returns the registered pattern factory (:class:`~collections.abc.Callable`).
	If no pattern factory is registered, raises :exc:`KeyError`.
	)_registered_patterns)namer   r   r   lookup_pattern  s   
rS   c                 C   s2   d}| D ]}|j dur|||fv r|j }q|S )a7  
	Matches the file to the patterns.

	*patterns* (:class:`~collections.abc.Iterable` of :class:`~pathspec.pattern.Pattern`)
	contains the patterns to use.

	*file* (:class:`str`) is the normalized file path to be matched
	against *patterns*.

	Returns :data:`True` if *file* matched; otherwise, :data:`False`.
	FN)r   r   )r    r(   matchedr&   r   r   r   
match_file  s   
rU   c                 C   sZ   t |tr|nt|}t }| D ]}|jdur*||}|jr%|| q|| q|S )a^  
	Matches the files to the patterns.

	*patterns* (:class:`~collections.abc.Iterable` of :class:`~pathspec.pattern.Pattern`)
	contains the patterns to use.

	*files* (:class:`~collections.abc.Iterable` of :class:`str`) contains
	the normalized file paths to be matched against *patterns*.

	Returns the matched files (:class:`set` of :class:`str`).
	N)r   r   r   setr   r   updatedifference_update)r    r#   r$   r%   r&   r'   r   r   r   match_files#  s   


rY   c                 C   s$   i }| D ]}||t |j|d< q|S )a  
	Normalizes the entry paths to use the POSIX path separator.

	*entries* (:class:`~collections.abc.Iterable` of :class:`.TreeEntry`)
	contains the entries to be normalized.

	*separators* (:class:`~collections.abc.Collection` of :class:`str`; or
	:data:`None`) optionally contains the path separators to normalize.
	See :func:`normalize_file` for more information.

	Returns a :class:`dict` mapping the each normalized file path (:class:`str`)
	to the entry (:class:`.TreeEntry`)
	
separators)normalize_filer4   )entriesr[   
norm_filesr:   r   r   r   _normalize_entries<  s   r_   c                 C   s`   |du rt }t| }|D ]	}||tj}q|dr#|dd }|S |dr.|dd }|S )a  
	Normalizes the file path to use the POSIX path separator (i.e.,
	``'/'``), and make the paths relative (remove leading ``'/'``).

	*file* (:class:`str` or :class:`pathlib.PurePath`) is the file path.

	*separators* (:class:`~collections.abc.Collection` of :class:`str`; or
	:data:`None`) optionally contains the path separators to normalize.
	This does not need to include the POSIX path separator (``'/'``), but
	including it will not affect the results. Default is :data:`None` for
	:data:`NORMALIZE_PATH_SEPS`. To prevent normalization, pass an empty
	container (e.g., an empty tuple ``()``).

	Returns the normalized file path (:class:`str`).
	N/r   z./   )NORMALIZE_PATH_SEPSstrreplacer   r   
startswith)r(   r[   	norm_filer   r   r   r   r\   Q  s   

r\   c                 C   s@   i }| D ]}t ||d}||v r|| | q|g||< q|S )a/  
	Normalizes the file paths to use the POSIX path separator.

	*files* (:class:`~collections.abc.Iterable` of :class:`str` or
	:class:`pathlib.PurePath`) contains the file paths to be normalized.

	*separators* (:class:`~collections.abc.Collection` of :class:`str`; or
	:data:`None`) optionally contains the path separators to normalize.
	See :func:`normalize_file` for more information.

	Returns a :class:`dict` mapping the each normalized file path
	(:class:`str`) to the original file paths (:class:`list` of
	:class:`str` or :class:`pathlib.PurePath`).
	rZ   )r\   r!   )r#   r[   r^   r4   rf   r   r   r   normalize_filesw  s   rg   c                 C   sT   t | tstd| t|std|| tv r$|s$t| t|  |t| < dS )aE  
	Registers the specified pattern factory.

	*name* (:class:`str`) is the name to register the pattern factory
	under.

	*pattern_factory* (:class:`~collections.abc.Callable`) is used to
	compile patterns. It must accept an uncompiled pattern (:class:`str`)
	and return the compiled pattern (:class:`.Pattern`).

	*override* (:class:`bool` or :data:`None`) optionally is whether to
	allow overriding an already registered pattern under the same name
	(:data:`True`), instead of raising an :exc:`AlreadyRegisteredError`
	(:data:`False`). Default is :data:`None` for :data:`False`.
	zname:{!r} is not a string.z%pattern_factory:{!r} is not callable.N)r   r   r0   r1   r/   rQ   AlreadyRegisteredError)rR   pattern_factoryoverrider   r   r   register_pattern  s   
rk   c                       sD   e Zd ZdZ fddZedd Zedd Zedd	 Z  Z	S )
rh   z|
	The :exc:`AlreadyRegisteredError` exception is raised when a pattern
	factory is registered under a name already in use.
	c                    s   t t| || dS )z
		Initializes the :exc:`AlreadyRegisteredError` instance.

		*name* (:class:`str`) is the name of the registered pattern.

		*pattern_factory* (:class:`~collections.abc.Callable`) is the
		registered pattern factory.
		N)superrh   __init__)selfrR   ri   	__class__r   r   rm     s   
zAlreadyRegisteredError.__init__c                 C   s   dj | j| jdS )4
		*message* (:class:`str`) is the error message.
		zG{name!r} is already registered for pattern factory:{pattern_factory!r}.)rR   ri   )r1   rR   ri   rn   r   r   r   message  s   zAlreadyRegisteredError.messagec                 C   
   | j d S )zB
		*name* (:class:`str`) is the name of the registered pattern.
		r   argsrr   r   r   r   rR     s   
zAlreadyRegisteredError.namec                 C   rt   )za
		*pattern_factory* (:class:`~collections.abc.Callable`) is the
		registered pattern factory.
		r   ru   rr   r   r   r   ri        
z&AlreadyRegisteredError.pattern_factory)
__name__
__module____qualname____doc__rm   propertyrs   rR   ri   __classcell__r   r   ro   r   rh     s    


rh   c                       sP   e Zd ZdZ fddZedd Zedd Zedd	 Zed
d Z	  Z
S )rC   zN
	The :exc:`RecursionError` exception is raised when recursion is
	detected.
	c                    s   t t| ||| dS )a+  
		Initializes the :exc:`RecursionError` instance.

		*real_path* (:class:`str`) is the real path that recursion was
		encountered on.

		*first_path* (:class:`str`) is the first path encountered for
		*real_path*.

		*second_path* (:class:`str`) is the second path encountered for
		*real_path*.
		N)rl   rC   rm   )rn   r>   r?   r@   ro   r   r   rm     s   zRecursionError.__init__c                 C   rt   )zx
		*first_path* (:class:`str`) is the first path encountered for
		:attr:`self.real_path <RecursionError.real_path>`.
		r   ru   rr   r   r   r   r?     rw   zRecursionError.first_pathc                 C   s   dj | j| j| jdS )rq   zDReal path {real!r} was encountered at {first!r} and then {second!r}.)realfirstsecond)r1   r>   r?   r@   rr   r   r   r   rs     s
   zRecursionError.messagec                 C   rt   )zV
		*real_path* (:class:`str`) is the real path that recursion was
		encountered on.
		r   ru   rr   r   r   r   r>     rw   zRecursionError.real_pathc                 C   rt   )zz
		*second_path* (:class:`str`) is the second path encountered for
		:attr:`self.real_path <RecursionError.real_path>`.
		ra   ru   rr   r   r   r   r@     rw   zRecursionError.second_path)rx   ry   rz   r{   rm   r|   r?   rs   r>   r@   r}   r   r   ro   r   rC     s    


rC   c                   @   s   e Zd ZdZdZdd ZdS )r"   z>
	The :class:`.MatchDetail` class contains information about
	r    c                 C   s
   || _ dS )z
		Initialize the :class:`.MatchDetail` instance.

		*patterns* (:class:`~collections.abc.Sequence` of :class:`~pathspec.pattern.Pattern`)
		contains the patterns that matched the file in the order they were
		encountered.
		Nr   )rn   r    r   r   r   rm   !  s   
zMatchDetail.__init__N)rx   ry   rz   r{   	__slots__rm   r   r   r   r   r"     s    r"   c                   @   sB   e Zd ZdZdZdd ZdddZddd	Zd
d ZdddZ	dS )rK   zR
	The :class:`.TreeEntry` class contains information about a file-system
	entry.
	_lstatrR   r4   _statc                 C   s"   || _ 	 || _	 || _	 || _dS )aR  
		Initialize the :class:`.TreeEntry` instance.

		*name* (:class:`str`) is the base name of the entry.

		*path* (:class:`str`) is the relative path of the entry.

		*lstat* (:class:`~os.stat_result`) is the stat result of the direct
		entry.

		*stat* (:class:`~os.stat_result`) is the stat result of the entry,
		potentially linked.
		Nr   )rn   rR   r4   rE   rG   r   r   r   rm   <  s   zTreeEntry.__init__Nc                 C   (   |du rd}|r| j n| j}t|jS )a<  
		Get whether the entry is a directory.

		*follow_links* (:class:`bool` or :data:`None`) is whether to follow
		symbolic links. If this is :data:`True`, a symlink to a directory
		will result in :data:`True`. Default is :data:`None` for :data:`True`.

		Returns whether the entry is a directory (:class:`bool`).
		NT)r   r   rG   rJ   rI   rn   r9   rP   r   r   r   r<   b     zTreeEntry.is_dirc                 C   r   )aE  
		Get whether the entry is a regular file.

		*follow_links* (:class:`bool` or :data:`None`) is whether to follow
		symbolic links. If this is :data:`True`, a symlink to a regular file
		will result in :data:`True`. Default is :data:`None` for :data:`True`.

		Returns whether the entry is a regular file (:class:`bool`).
		NT)r   r   rG   rL   rI   r   r   r   r   is_files  r   zTreeEntry.is_filec                 C   s   t | jjS )zC
		Returns whether the entry is a symbolic link (:class:`bool`).
		)rG   rH   r   rI   rr   r   r   r   
is_symlink  s   zTreeEntry.is_symlinkc                 C   s   |du rd}|r| j S | jS )a:  
		Get the cached stat result for the entry.

		*follow_links* (:class:`bool` or :data:`None`) is whether to follow
		symbolic links. If this is :data:`True`, the stat result of the
		linked file will be returned. Default is :data:`None` for :data:`True`.

		Returns that stat result (:class:`~os.stat_result`).
		NT)r   r   )rn   r9   r   r   r   rG     s   zTreeEntry.statN)
rx   ry   rz   r{   r   rm   r<   r   r   rG   r   r   r   r   rK   3  s    
&
rK   r   )NN)3r{   r3   os.pathr   rG   typingr   r   r   r   r   r   r   r	   r
   r   r   r   ImportErrorr   r   compatr   r   r   r   r&   r   r   altseprb   rQ   r)   r,   r;   r=   Z	iter_treer2   rS   rU   rY   r_   r\   rg   rk   	Exceptionrh   rC   objectr"   rK   r   r   r   r   <module>   sN   <
+

 "N


&
/>