pathspec
raw JSON → 1.0.4 verified Tue May 12 auth: no python install: verified quickstart: verified
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.
pip install pathspec Common errors
error ModuleNotFoundError: No module named 'pathspec' ↓
cause The `pathspec` library is not installed in the Python environment where the code is being run.
fix
Install the library using pip:
pip install pathspec error ImportError: cannot import name 'GitWildMatchPatternError' from 'pathspec.patterns.gitwildmatch' ↓
cause The `GitWildMatchPatternError` class (and the `pathspec.patterns.gitwildmatch` module) was deprecated and removed in `pathspec` version 1.0.0 and later, replaced by `GitIgnorePatternError` in `pathspec.patterns.gitignore.spec`.
fix
Update your import statement to use
from pathspec.patterns.gitignore.spec import GitIgnorePatternError and adjust your code accordingly. If you need the exact prior behavior, refer to GitIgnoreSpecPattern. error Using PathSpec.from_lines('gitwildmatch', ...) results in unexpected filtering behavior or deprecation warnings ↓
cause In `pathspec` version 1.0.0 and later, the 'gitwildmatch' backend's behavior was split and changed. Using `PathSpec.from_lines('gitwildmatch', ...)` now aliases to 'gitignore', which may not match the exact behavior of Git's `wildmatch` patterns as in previous versions or `git`. For more precise control, dedicated backends like `GitIgnoreSpec` were introduced.
fix
For Git's behavior, use
from pathspec import GitIgnoreSpec and then GitIgnoreSpec.from_lines(...). For behavior aligning with .gitignore documentation, use PathSpec.from_lines('gitignore', ...). If you explicitly need the exact behavior of the old GitWildMatchPattern, use PathSpec.from_lines(GitIgnoreSpecPattern, ...). 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. ↓
fix Use spec.match_tree_files('path/to/dir', negate=True) to obtain files to keep, mirroring .gitignore exclusion logic.
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. ↓
fix Use GitIgnoreSpec.from_lines() whenever you need to replicate what 'git status' / 'git ls-files' would show.
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. ↓
fix Replace PathSpec.from_lines('gitwildmatch', ...) with PathSpec.from_lines('gitignore', ...) and import from pathspec.patterns.gitignore.spec.GitIgnoreSpecPattern if you reference the class directly.
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. ↓
fix Remove overrides of PathSpec._match_file(). Use the public match_file() / match_files() / match_tree_files() API or implement a custom backend instead.
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. ↓
fix Upgrade to >=0.10.1.
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. ↓
fix Always pass the root directory as the first argument and let the library normalise paths, or pre-normalise with os.path.relpath(). Do not feed absolute paths to match_file().
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'. ↓
fix Install 'pip install google-re2', not 'pip install re2'.
breaking The `google-re2` package, an optional backend for `pathspec`, requires a C++ compiler (like g++) to be available in the environment to build its native extensions. In minimal environments (e.g., -slim Docker images), these build tools are often missing, leading to installation failure. ↓
fix Ensure a C++ compiler is installed in your environment before attempting to install `google-re2`. For Debian/Ubuntu-based systems, this typically means `apt-get install build-essential`. For RHEL/CentOS, `yum install gcc-c++` or `dnf install gcc-c++`.
breaking Building the 'google-re2' package, which provides the optional 're2' backend for pathspec, requires a C++ compiler (e.g., g++) and associated build tools. In minimal environments (like Alpine Linux), these tools might be missing, leading to compilation failure. ↓
fix Install a C++ compiler and build essentials in your environment. For Alpine Linux, this typically means running `apk add build-base` or `apk add g++`.
Install
pip install pathspec google-re2 Install compatibility verified last tested: 2026-05-12
python os / libc status wheel install import disk
3.10 alpine (musl) - - 0.07s 18.2M
3.10 alpine (musl) - - - -
3.10 slim (glibc) - - 0.04s 19M
3.10 slim (glibc) - - 0.05s 20M
3.11 alpine (musl) - - 0.12s 20.1M
3.11 alpine (musl) - - - -
3.11 slim (glibc) - - 0.09s 21M
3.11 slim (glibc) - - 0.09s 22M
3.12 alpine (musl) - - 0.10s 12.0M
3.12 alpine (musl) - - - -
3.12 slim (glibc) - - 0.10s 12M
3.12 slim (glibc) - - 0.11s 14M
3.13 alpine (musl) - - 0.09s 11.6M
3.13 alpine (musl) - - - -
3.13 slim (glibc) - - 0.09s 12M
3.13 slim (glibc) - - 0.09s 14M
3.9 alpine (musl) - - 0.07s 17.7M
3.9 alpine (musl) - - - -
3.9 slim (glibc) - - 0.07s 18M
3.9 slim (glibc) - - - -
Imports
- PathSpec
from pathspec import PathSpec - GitIgnoreSpec wrong
from pathspec import PathSpec; spec = PathSpec.from_lines('gitwildmatch', lines)correctfrom pathspec import GitIgnoreSpec - GitWildMatchPattern wrong
from pathspec.patterns import GitWildMatchPatterncorrectfrom pathspec.patterns.gitignore.spec import GitIgnoreSpecPattern
Quickstart verified last tested: 2026-04-23
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)