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
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, ...).
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++`.
pip install pathspec google-re2
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) - - - -

Compile gitignore-style patterns with PathSpec (documented semantics) or GitIgnoreSpec (true Git edge-case semantics), match individual paths or walk a directory tree.

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)