Path Utilities partis.pyproj.path#

class PathMatcher(pattern, negate=False, dironly=False, relative=False)[source]#

Bases: object

Pattern matching similar to ‘.gitignore’

Parameters:
  • pattern (str) – See notes below on pattern formatting.

  • negate (bool) – A match to this pattern negates an existing match of the same name.

  • dironly (bool) – This pattern is to only match the name of a directory.

  • relative (bool) – This pattern is to match relative paths instead of just the base name.

Notes

  • https://git-scm.com/docs/gitignore#_pattern_format

  • 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 path matches this pattern

nt(path)[source]#

Convenience method to force match as a Windows path

posix(path)[source]#

Convenience method to force match as a POSIX path

class PathFilter(patterns=None, start=None)[source]#

Bases: object

A combination of file patters applied relative to a given ‘start’ directory

Parameters:
filter(dir, fnames, dnames=None, feasible=None)[source]#

Filter a list of names in a directory

Parameters:
  • dir (PathLike | PurePath) – Directory containing dnames and fnames.

  • fnames (list[str]) – List of file (non-directory) names in dir.

  • dnames (None | list[str]) –

    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(test, vals)[source]#

Separates a single list into two lists

Parameters:
  • test (callable) –

  • vals (list) –

Returns:

x, y ((list, list)) – The first list contains elememts of vals where test returned true. The second list contains all other elements.

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

subdir(start, path, check=True)[source]#

Relative path, restricted to sub-directories.

Parameters:
  • start (PurePath) – Starting directory.

  • path (PurePath) – Directory to compute relative path to, must be a sub-directory of start.

Returns:

rpath (PurePath) – Relative path from start to path.

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.

inv_path(path)[source]#
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:
  • start (str) – Starting directory, already translated by tr_path().

  • dir (str) – Directory to compute relative path to, must be a sub-directory of start, already translated by tr_path().

  • names (list[str]) – List of names in dir

Returns:

list[tuple[str, str]] – List of names joined with path relative to start

tr_join(*args)[source]#

Joins paths already translated by tr_path().

tr_subdir(start, path)[source]#

Relative path, restricted to sub-directories.

Parameters:
  • start (str) – Starting directory, already translated by tr_path().

  • path (str) – Directory to compute relative path to, must be a sub-directory of start, already translated by tr_path().

Returns:

rpath (str) – Relative path from start to path.

class GRef(ori, case, start, end)[source]#

Bases: GRef

reduce_any(pid, sid, n, i, working)[source]#
Parameters:
  • pid (int) – Pattern id, may be the same for all segments, but unique among all patterns that might be combined.

  • sid (int) – Segment id, unique only within an overall pattern.

  • n (int) – Number of ‘*’ in the segment sid

  • i (int) – Current ‘*’ within the segment sid

  • working (list[GCase]) – Expressions preceeding the ‘*’ at i

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}'.

class GPath(iterable=(), /)[source]#

Bases: list

exception PatternError(msg, pat, segs)[source]#

Bases: ValueError

tr_glob(pat, pid=0)[source]#

Notes