Path Utilities partis.pyproj.path#
- class PathMatcher(pattern, negate=False, dironly=False, relative=False)[source]#
Bases:
objectPattern matching similar to ‘.gitignore’
- Parameters:
Notes
An optional prefix “!” which negates the pattern; any matching file excluded by a previous pattern will become included again. It is not possible to re-include a file if a parent directory of that file is excluded. Git doesn’t list excluded directories for performance reasons, so any patterns on contained files have no effect, no matter where they are defined. Put a backslash (”") in front of the first “!” for patterns that begin with a literal “!”, for example, “!important!.txt”.
The slash / is used as the directory separator. Separators may occur at the beginning, middle or end of the .gitignore search pattern.
If there is a separator at the beginning or middle (or both) of the pattern, then the pattern is relative to the directory level of the particular .gitignore file itself. Otherwise the pattern may also match at any level below the .gitignore level.
If there is a separator at the end of the pattern then the pattern will only match directories, otherwise the pattern can match both files and directories.
For example, a pattern doc/frotz/ matches doc/frotz directory, but not a/doc/frotz directory; however frotz/ matches frotz and a/frotz that is a directory (all paths are relative from the .gitignore file).
An asterisk “*” matches anything except a slash. The character “?” matches any one character except “/”.
The range notation, e.g. [a-zA-Z], can be used to match one of the characters in a range. See fnmatch(3) and the FNM_PATHNAME flag for a more detailed description. This logic rests on the idea that a character class cannot be an empty set. e.g. [] would not match anything, so is not allowed. This means that []] is valid since the the first pair “[]” cannot close a valid set. Likewise, [!] cannot complement an empty set, since this would be equivalent to *, meaning it should instead match “!”. [!] -> match “!” [!!] -> match any character that is not “!” []] -> match “]” [!]] -> match any character that is not “]” []!] -> match “]” or “!”
Two consecutive asterisks (“**”) in patterns matched against full pathname may have special meaning:
A leading “**” followed by a slash means match in all directories. For example, “/foo” matches file or directory “foo” anywhere, the same as pattern “foo”. “/foo/bar” matches file or directory “bar” anywhere that is directly under directory “foo”.
A trailing “/” matches everything inside. For example, “abc/” matches all files inside directory “abc”, relative to the location of the .gitignore file, with infinite depth.
A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, “a/**/b” matches “a/b”, “a/x/b”, “a/x/y/b” and so on.
The meta-characters “*”, “?”, and “[” may be escaped by backslash.
- match(path)[source]#
- Parameters:
path¶ (str | pathlib.PurePath) –
- Returns:
matched (bool) – True if the
pathmatches this pattern
- class PathFilter(patterns=None, start=None)[source]#
Bases:
objectA combination of file patters applied relative to a given ‘start’ directory
- Parameters:
patterns¶ (list[str | PathMatcher]) –
start¶ (None | pathlib.PurePath) –
- filter(dir, fnames, dnames=None, feasible=None)[source]#
Filter a list of names in a directory
- Parameters:
dir¶ (PathLike | PurePath) – Directory containing
dnamesandfnames.fnames¶ (list[str]) – List of file (non-directory) names in
dir.List of directory names in
dir.Note
If None, any fnames ending with ‘/’ will be used as (directory) dnames.
feasible¶ (None | set[str]) – The current feasible set of names (from either dnames or fnames) that have been matched.
- Returns:
feasible (set[str]) – Updated feasible set of matched names. It is possible that the input feasible set contains names that are not in the output if a pattern negates an existing match.
- partition_dir(dir, names)[source]#
Separates a list of names into those that are directorys and all others.
- combine_ignore_patterns(*patterns)[source]#
Creates a callable as
ignore- Parameters:
*patterns¶ (PathMatcher) –
- Returns:
callable(dir, names) -> matches
- exception PathError[source]#
Bases:
ValueError
- exception PathPatternError[source]#
Bases:
ValueError
- tr_path(path)[source]#
Translates path to be compatible with the translated regex.match
- Parameters:
path¶ (PurePath) –
- Returns:
tr_path (str) – Translated path, with each path segment separated by
SEP.
- tr_rel_join(start, dir, names)[source]#
Creates paths relative to a ‘start’ path for a list of names in a ‘dir’ ‘start’ and ‘dir’ must already be translated by
tr_path().- Parameters:
- Returns:
list[tuple[str, str]] – List of names joined with path relative to start
- reduce_any(pid, sid, n, i, working)[source]#
- Parameters:
- Returns:
regex (str)
Notes
Adapted according to: bpo-40480: “fnmatch” exponential execution time https://github.com/python/cpython/pull/19908 https://github.com/python/cpython/pull/20049
Each ‘*’ (any) is grouped with the succeeding non-‘*’ into a ‘lazy’ non-capturing group. Since this match does not depend on the rest of the expressions, it does not need to backtrack to account for failures later on. A positive lookahead references the match and then asserts it as the new pattern. Each successive ‘*’ group will absorb anything missed by the previous one until the last ‘*’ is reached. The last ‘*’ must be allowed to backtrack, since no more ‘*’ exist to make up for misses (doesn’t really matter if the last is ‘greedy’ or ‘lazy’).
>>> p = re.compile(r'\A(?=(?P<g1>.*?A))(?P=g1)\Z') >>> bool(p.match('xxxA')) True >>> bool(p.match('xxxAxxxA')) False
This fails because a lazy match to the first ‘xxxA’ misses the second ‘xxxA’. For 3 ‘*’, there should be 2 lazy+lookahead, and the last will be unconditional
n: 3 pattern: ...*...*...*... i: 0 1 2 3 working: 000 111 222 333 groups: [ ][ ]
Groups are named according to
f'p{pid}s{sid}g{i-1}'.
- exception PatternError(msg, pat, segs)[source]#
Bases:
ValueError