impl

A utility for file path filtering using Git-style pattern matching with configurable include and exclude rules.

class pathpick.impl.PathPick(include_spec: PathSpec | None, exclude_spec: PathSpec | None)[source]

PathPick is a utility class that provides file and directory path matching functionality using GitWildMatchPattern syntax from the pathspec Python library.

This class allows you to:

  • Define include and exclude patterns for paths

  • Check if a specific path matches your criteria

  • Filter collections of paths based on your patterns

The pattern matching follows Git’s wildcard pattern syntax, which is similar to but not identical to standard glob patterns. The patterns are matched against the relative path using forward slash (/) as the directory separator.

Pattern Syntax Examples

Basic Patterns

  • *.py: Matches any Python file, regardless of location
    • Matches: test.py, folder/test.py, folder/subfolder/test.py

    • Does not match: folder, test.txt

Root-level Patterns

  • /*.py: Matches any Python file, but ONLY at the root level
    • Matches: test.py

    • Does not match: folder/test.py, folder/subfolder/test.py

Directory-specific Patterns

  • folder/*.py: Matches any Python file in the root level of folder/ only
    • Matches: folder/test.py

    • Does not match: test.py, folder/subfolder/test.py

Directory Pattern Variations

  • folder*: Matches the folder itself and anything inside it recursively
    • Matches: folder, folder/test.py, folder/subfolder, folder/subfolder/test.py

    • Does not match: test.py

  • folder/*: Matches anything inside folder/ recursively, but NOT the folder itself
    • Matches: folder/test.py, folder/subfolder, folder/subfolder/test.py

    • Does not match: folder, test.py

  • folder/*.*: Matches any FILE in the root level of folder/ only
    • Matches: folder/test.py, folder/doc.txt

    • Does not match: folder, folder/subfolder, folder/subfolder/test.py

Recursive Patterns

  • folder/**/*.*: Matches any FILE in folder/ RECURSIVELY
    • Matches: folder/test.py, folder/subfolder/test.py

    • Does not match: folder, folder/subfolder, test.py

  • folder/*.py: Matches Python files in the root level of folder/ only
    • Matches: folder/test.py

    • Does not match: folder, test.py, folder/subfolder/test.py

  • folder/**/*.py: Matches Python files in folder/ RECURSIVELY
    • Matches: folder/test.py, folder/subfolder/test.py

    • Does not match: folder, folder/subfolder, test.py

Multiple Patterns

You can specify multiple patterns as a list. A path will match if it matches ANY of the patterns:

  • ["folder1/*.py", "folder2/*.py"]: Matches Python files in either folder1 or folder2
    • Matches: folder1/test.py, folder2/test.py

    • Does not match: folder3/test.py, test.py

Usage Examples

# Create a matcher that includes Python files but excludes test files
matcher = PathMatcher.new(
   include=["**/*.py"],
   exclude=["**/test_*.py", "**/tests/*"]
)

# Check if a path matches
matcher.is_match("src/module.py")  # True
matcher.is_match("tests/test_module.py")  # False

# Filter a list of paths
paths = ["src/module.py", "src/main.py", "tests/test_module.py"]
filtered = [p for p in paths if matcher.is_match(p)]  # ["src/module.py", "src/main.py"]

Common Pattern Use Cases

  1. Include all files in a directory (recursively):
    • ["directory/**/*"]

  2. Include specific file types in all directories:
    • ["**/*.py", "**/*.md"]

  3. Exclude specific directories:
    • exclude=["**/temp/*", "**/logs/*"]

  4. Include everything except specific file types:
    • include=["**/*"]

    • exclude=["**/*.log", "**/*.tmp"]

  5. Include only root level files:
    • ["/*.*"]

Note: This class uses the pathspec Python library under the hood, which provides the implementation of Git’s wildcard pattern matching. For more advanced pattern matching details, refer to the pathspec documentation or Git’s documentation on gitignore patterns.

classmethod new(include: list[str], exclude: list[str])[source]

Create a new PathMatcher instance with the given include and exclude patterns.

is_match(path: str) bool[source]

Determines if a path should be included based on include/exclude patterns.

The matching logic follows these rules:

  1. If no include patterns are specified, all paths are eligible for inclusion

  2. If include patterns exist, the path must match at least one include pattern

  3. If the path matches any exclude pattern, it is rejected regardless of include matches

Parameters:

path – A path string using forward slash (/) as directory separator. Should not start or end with slash.

Examples:

  • file.txt

  • folder

  • folder/file.txt

  • folder/subfolder/file.txt

Returns:

True if the path should be included, False otherwise