pathspec
pathspec is a utility library for gitignore-style pattern matching of file paths, implementing Git's wildmatch/gitignore specification. Current stable version is 1.0.4 (released 2025). The project is actively maintained by Caleb P. Burns and releases roughly a few times per year. It is a zero-dependency pure-Python library widely used by tools such as Black, pip, and Poetry for .gitignore-based file filtering.
Warnings
- gotcha GitIgnoreSpec and PathSpec both POSITIVELY match files by default — meaning match_tree_files() returns the files that ARE ignored, not the files to keep. Pass negate=True to get the files that should be kept.
- gotcha PathSpec and GitIgnoreSpec implement gitignore differently. PathSpec follows the documented spec strictly; GitIgnoreSpec replicates Git's actual behaviour, including allowing files to be re-included from an otherwise excluded directory. Using PathSpec for exact git parity will produce wrong results on such edge cases.
- deprecated The pattern name 'gitwildmatch' and the class pathspec.patterns.GitWildMatchPattern are deprecated since 1.0.0. 'gitwildmatch' is now an alias for 'gitignore', and GitWildMatchPattern is an alias for GitIgnoreSpecPattern.
- breaking In v1.0.0 the protected method PathSpec._match_file() was removed and replaced by the backends system. Any custom PathSpec subclass overriding _match_file() will silently break.
- breaking v0.10.0 introduced a regression that broke a common wildcard matching pattern used by Black and other tools; v0.10.1 fixed it. Pinning to exactly 0.10.0 will cause subtle mis-matches.
- gotcha match_tree_files() (and the deprecated match_tree()) require paths to be RELATIVE to the root directory. Passing absolute paths or paths with a leading slash will fail to match patterns correctly.
- gotcha The 're2' optional backend refers to google-re2 (PyPI package google-re2), NOT the unrelated abandoned 're2' package on PyPI. Installing the wrong package will silently fall back to 'simple'.
Install
-
pip install pathspec -
pip install pathspec google-re2
Imports
- PathSpec
from pathspec import PathSpec
- GitIgnoreSpec
from pathspec import GitIgnoreSpec
- GitWildMatchPattern
from pathspec.patterns.gitignore.spec import GitIgnoreSpecPattern
Quickstart
from pathspec import PathSpec, GitIgnoreSpec
# --- PathSpec: documented gitignore behaviour ---
patterns = [
'*.pyc',
'__pycache__/',
'dist/',
'!dist/keep_this.txt', # negation re-includes a file
]
spec = PathSpec.from_lines('gitignore', patterns)
# Match a list of paths
files = ['src/main.py', 'src/main.pyc', '__pycache__/x.pyc', 'dist/output.whl']
matched = list(spec.match_files(files))
print('Matched (excluded):', matched)
# -> ['src/main.pyc', '__pycache__/x.pyc', 'dist/output.whl']
# --- GitIgnoreSpec: replicates Git's actual edge-case behaviour ---
# Use this when you need to mirror exactly what `git` itself would ignore.
git_spec = GitIgnoreSpec.from_lines(patterns)
# Walk a real directory tree and get files to KEEP (negate=True flips results)
import os, tempfile, pathlib
with tempfile.TemporaryDirectory() as tmpdir:
# create sample files
for p in ['a.py', 'a.pyc', '__pycache__/x.pyc']:
full = pathlib.Path(tmpdir) / p
full.parent.mkdir(parents=True, exist_ok=True)
full.write_text('')
keep = set(git_spec.match_tree_files(tmpdir, negate=True))
ignore = set(git_spec.match_tree_files(tmpdir))
print('Keep:', keep)
print('Ignore:', ignore)