B x ` F@s dZddlZddlZddlZddlZddlmZmZmZm Z ddej ej gDZ iZ d'ddZd d Zd(d d Zd)d dZeZddZddZddZddZd*ddZd+ddZd,ddZd-ddZGdd d eZGd!d"d"eZGd#d$d$eZGd%d&d&eZ dS).zC This module provides utility methods for dealing with path-specs. N) CollectionIterable string_typesunicodecCsg|]}|r|tjkr|qS) posixpathsep).0r rr1/tmp/pip-unpacked-wheel-y3tpd19o/pathspec/util.py sr c Cst|tr|nt|}i}x|D]~}|jdk r ||}|jrx^|D]@}||krv|rf||j|q|||jd<qDt|g||<qDWq x|D] }||=qWq W|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) isinstancerlistincludematchpatternsappend MatchDetail) rfilesZ all_matches all_files return_filespattern result_filesZ result_filefilerrr detailed_match_filess     rcCst|tot|ttf 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 rrbytes)valuerrr _is_iterableFsrccsV|dk rt|std||dkr*d}x&ttj|di||D] }|VqDWdS)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.Iterable` yielding each file or directory entry (:class:`.TreeEntry`) relative to *root*. Nzon_error:{!r} is not callable.T)callable TypeErrorformat_iter_tree_entries_nextospathabspath)rooton_error follow_linksentryrrr iter_tree_entriesQs r*ccsb|dk rt|std||dkr*d}x2ttj|di||D]}||sD|jVqDWdS)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.Iterable` yielding the path to each file (:class:`str`) relative to *root*. Nzon_error:{!r} is not callable.Tr)rr r!r"r#r$r%is_dir)r&r'r(r)rrr iter_tree_filesps r,c cstj||}tj|}||kr,|||<nt||||dxFt|D]6}tj||}tj||} yt| } Wn4tk r} z|dk r|| wLWdd} ~ XYnXt | j r d} yt| } Wn6tk r} z|dk r|| wLWdd} ~ XYnXnd} | } t | j rb|s.| sbt ||| | VxDt |||||D] }|VqPWqLt| j st| rLt ||| | VqLW||=dS)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)r#r$joinrealpathRecursionErrorlistdirlstatOSErrorstatS_ISLNKst_modeS_ISDIR TreeEntryr"S_ISREG)Z root_fullZdir_relmemor'r(Zdir_fullZdir_realZ node_nameZnode_relZ node_fullZ node_lstateZis_link node_statr)rrr r"s>  r"cCst|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)namerrr lookup_patterns rAcCs6d}x,|D]$}|jdk r |||fkr |j}q W|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)rr)rrmatchedrrrr match_files    rCcCs^t|tr|nt|}t}x<|D]4}|jdk r"||}|jrL||q"||q"W|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 rrsetrrupdatedifference_update)rrrrrrrrr match_filess     rGcCs(i}x|D]}||t|j|d<q W|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_filer$)entriesrH norm_filesr)rrr _normalize_entriess rLcCsJ|dkr t}t|}x|D]}||tj}qW|drF|dd}|S)aS Normalizes the file path to use the POSIX path separator (i.e., ``'/'``). *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`). Nz./)NORMALIZE_PATH_SEPSstrreplacerr startswith)rrHZ norm_filer rrr rI-s   rIcCs&i}x|D]}||t||d<q W|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 path (:class:`str`) )rH)rI)rrHrKr$rrr normalize_filesMs rRcCsTt|tstd|t|s.td||tkrH|sHt|t||t|<dS)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`. zname:{!r} is not a string.z%pattern_factory:{!r} is not callable.N)r rr r!rr?AlreadyRegisteredError)r@pattern_factoryoverriderrr register_patternas  rVcsDeZdZdZfddZeddZeddZedd ZZ S) rSz| The :exc:`AlreadyRegisteredError` exception is raised when a pattern factory is registered under a name already in use. cstt|||dS)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)superrS__init__)selfr@rT) __class__rr rXs zAlreadyRegisteredError.__init__cCsdj|j|jdS)z4 *message* (:class:`str`) is the error message. zG{name!r} is already registered for pattern factory:{pattern_factory!r}.)r@rT)r!r@rT)rYrrr messageszAlreadyRegisteredError.messagecCs |jdS)zB *name* (:class:`str`) is the name of the registered pattern. r)args)rYrrr r@szAlreadyRegisteredError.namecCs |jdS)za *pattern_factory* (:class:`~collections.abc.Callable`) is the registered pattern factory. r)r\)rYrrr rTsz&AlreadyRegisteredError.pattern_factory) __name__ __module__ __qualname____doc__rXpropertyr[r@rT __classcell__rr)rZr rSzs  rScsPeZdZdZfddZeddZeddZedd Zed d Z Z S) r2zN The :exc:`RecursionError` exception is raised when recursion is detected. cstt||||dS)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)rWr2rX)rYr-r.r/)rZrr rXs zRecursionError.__init__cCs |jdS)zx *first_path* (:class:`str`) is the first path encountered for :attr:`self.real_path `. r)r\)rYrrr r.szRecursionError.first_pathcCsdj|j|j|jdS)z4 *message* (:class:`str`) is the error message. zDReal path {real!r} was encountered at {first!r} and then {second!r}.)realfirstsecond)r!r-r.r/)rYrrr r[szRecursionError.messagecCs |jdS)zV *real_path* (:class:`str`) is the real path that recursion was encountered on. r)r\)rYrrr r-szRecursionError.real_pathcCs |jdS)zz *second_path* (:class:`str`) is the second path encountered for :attr:`self.real_path `. rM)r\)rYrrr r/szRecursionError.second_path) r]r^r_r`rXrar.r[r-r/rbrr)rZr r2s    r2c@seZdZdZdZddZdS)rz> The :class:`.MatchDetail` class contains information about )rcCs ||_dS)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. N)r)rYrrrr rXs zMatchDetail.__init__N)r]r^r_r` __slots__rXrrrr rsrc@sBeZdZdZdZddZdddZddd Zd d Zdd d Z dS)r:zR The :class:`.TreeEntry` class contains information about a file-system entry. )_lstatr@r$_statcCs||_||_||_||_dS)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. N)rgr@r$rh)rYr@r$r4r6rrr rXs zTreeEntry.__init__NcCs(|dkr d}|r|jn|j}t|jS)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)rhrgr6r9r8)rYr(r>rrr r+%s zTreeEntry.is_dircCs(|dkr d}|r|jn|j}t|jS)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)rhrgr6r;r8)rYr(r>rrr is_file5s zTreeEntry.is_filecCst|jjS)zC Returns whether the entry is a symbolic link (:class:`bool`). )r6r7rgr8)rYrrr is_symlinkEszTreeEntry.is_symlinkcCs|dkr d}|r|jS|jS)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)rhrg)rYr(rrr r6Ks zTreeEntry.stat)N)N)N) r]r^r_r`rfrXr+rirjr6rrrr r:s%  r:)N)NN)NN)N)N)N)N)!r`r#os.pathrr6compatrrrrr altseprNr?rrr*r,Z iter_treer"rArCrGrLrIrRrV ExceptionrSr2objectrr:rrrr s0 *  !M    +9