pathspec

repository·master·Indexed 42 days ago

https://github.com/cpburnz/python-pathspec

A utility library for gitignore-style pattern matching of file paths. It provides the PathSpec class for general matching and the GitIgnoreSpec class for replicating standard .gitignore behavior, including support for high-performance backends like hyperscan and re2.

Tokens
8K
Snippets
31
Records
51
Agent score
53%

What's inside pathspec

  1. Implement gitignore behavior with GitIgnoreSpec

    master
    For complex requirements that standard PathSpec cannot handle, use the pathspec.GitIgnoreSpec class (also aliased as pathspec.GitIgnoreSpec). This class is specifically designed to implement standard gitignore behavior, such as prioritizing patterns that match a file directly over patterns matching an ancestor directory.
  2. Configure matching backends in PathSpec

    master

    Starting from version 1.0.0, pathspec supports different backends to allow for faster regular expression matching. You can control which backend is used by passing the backend argument to the following constructors:

    • PathSpec()
    • PathSpec.from_lines()
    • GitIgnoreSpec()
    • GitIgnoreSpec.from_lines()

    Available backends include:

    • The default Python regex backend.
    • hyperscan: An optional backend using the hyperscan library. Install it via pip install 'pathspec[hyperscan]'.
    • re2: An optional backend using the google-re2 library. Install it via pip install 'pathspec[re2]'.
    # Example of specifying a backend (assuming hyperscan is installed)
    from pathspec import PathSpec
    
    spec = PathSpec(patterns=['*.txt'], backend='hyperscan')
  3. How to negate matches (finding ignored files)

    master

    By default, PathSpec and GitIgnoreSpec positively match files (they return what is included). To find files that should be ignored (e.g., to exclude .gitignore files from a backup), set negate=True in the matching methods.

    from pathspec import GitIgnoreSpec
    
    spec = GitIgnoreSpec.from_lines(['*.gitignore'])
    # Returns files that match the pattern (the ignored files)
    ignore_files = set(spec.match_tree_files('path/to/dir', negate=True))
    
    # Returns files that do NOT match the pattern (the kept files)
    keep_files = set(spec.match_tree_files('path/to/dir', negate=False))
  4. Compare backend performance for PathSpec and GitIgnoreSpec

    master

    PathSpec provides optional backends to improve matching performance. You can compare the performance of the native Python re module (referred to as the simple backend) against high-performance alternatives like hyperscan and re2.

    Benchmarks are typically measured using PathSpec.match_files() or GitIgnoreSpec.match_files() across varying numbers of patterns. Performance varies significantly based on the Python runtime (CPython vs. PyPy) and the hardware architecture.

  5. How to exclude files (negate matches)

    master

    By default, PathSpec and GitIgnoreSpec return files that match the patterns (positive matching). If you want to find files that are not matched by the patterns (e.g., to find all files except those ignored by a .gitignore), set negate=True in the matching methods.

    from pathspec import GitIgnoreSpec
    
    spec = GitIgnoreSpec.from_lines(['*.log'])
    # Returns files that match '*.log'
    matched_files = set(spec.match_tree_files('path/to/dir'))
    
    # Returns files that DO NOT match '*.log'
    keep_files = set(spec.match_tree_files('path/to/dir', negate=True))
  6. Migration guide for PathSpec v1.0.0

    master

    Version 1.0.0 introduced several breaking changes and deprecations. If you are upgrading, note the following:

    Breaking Changes

    • Backend Refactor: The protected method pathspec.pathspec.PathSpec._match_file() has been removed and replaced by the backend system. This only affects custom subclasses of PathSpec or GitIgnoreSpec.
    • Python Support: Support for Python 3.8 has been dropped.

    Deprecations

    • Pattern Naming: The term gitwildmatch has been renamed to gitignore.
      • pathspec.patterns.gitwildmatch is replaced by the pathspec.patterns.gitignore package.
      • pathspec.patterns.GitWildMatchPattern is now an alias for pathspec.patterns.gitignore.spec.GitIgnoreSpecPattern.
      • pathspec.patterns.gitwildmatch.GitWildMatchPatternError is now an alias for pathspec.patterns.gitignore.GitIgnorePatternError.
    • Behavioral Note: The gitignore pattern behaves slightly differently when used with PathSpec (following standard gitignore documentation) than when used with GitIgnoreSpec (which replicates specific Git edge cases).
  7. Build pathspec from source

    master

    To build from source, you need the build package (>=0.6.0) installed. Use the following commands to build and install the wheel:

    python -m build
    pip install dist/pathspec-*-py3-none-any.whl
  8. Install pathspec

    master

    You can install pathspec via PyPI using pip:

    pip install pathspec

    To build from source, you will need the build package (>=0.6.0):

    python -m build
    pip install dist/pathspec-*-py3-none-any.whl

    Optional Dependencies

    • google-re2: Enables the high-performance "re2" backend.
    • hyperscan: Enables the "hyperscan" backend.
    • typing-extensions: Improves type hint support.
    pip install pathspec
  9. Install optional backends for performance

    master

    To improve matching performance, you can install optional dependencies for specialized regular expression backends:

    • google-re2: Enables the re2 backend.
    • hyperscan: Enables the hyperscan backend.
    • typing-extensions: Improves type hints.
  10. Migrate from gitwildmatch to gitignore

    master

    When upgrading from version 0.12.1 to 1.0.0, the gitwildmatch pattern type has been replaced by gitignore. You should update your calls to PathSpec.from_lines to use the gitignore argument instead of gitwildmatch.

    Note that gitignore patterns have different matching behaviors than gitwildmatch:

    • Patterns like foo/* will no longer match files in subdirectories (e.g., foo/bar/hello.c will not match).
    • The exact pattern / now matches every file (equivalent to **).

    If you require the legacy gitwildmatch behavior, you can use GitIgnoreSpecPattern, though this is discouraged.

    # Old way (deprecated)
    spec = PathSpec.from_lines('gitwildmatch', patterns)
    
    # New way
    spec = PathSpec.from_lines('gitignore', patterns)
  11. Install PathSpec with hyperscan or re2 backends

    master

    To use high-performance matching backends, you can install pathspec with the corresponding optional dependencies:

    • For the hyperscan backend: pip install 'pathspec[hyperscan]'
    • For the re2 backend: pip install 'pathspec[re2]'

    If these libraries are installed in your environment, pathspec will attempt to use them automatically.

    pip install 'pathspec[hyperscan]'
    pip install 'pathspec[re2]'