Install & Compatibility
Where this runs
tested against v1.4.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 0.238s · 18.4MB
glibcpy 3.10–3.95 runs
installs and imports cleanly · install 1.9s · import 0.194s · 19MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
walk
✓ from trailrunner import walk
run
✓ from trailrunner import run
walk_and_run
✓ from trailrunner import walk_and_run
This quickstart demonstrates how to use `walk_and_run` to find files within a directory, respecting `.gitignore` rules, and apply a custom function to each found file. It creates a dummy project structure to illustrate the functionality.
import os
from pathlib import Path
from trailrunner import walk_and_run
# Create a dummy directory structure for demonstration
os.makedirs("my_project/src", exist_ok=True)
os.makedirs("my_project/tests", exist_ok=True)
with open("my_project/src/app.py", "w") as f:
f.write("print('Hello from app.py')")
with open("my_project/tests/test_app.py", "w") as f:
f.write("print('Running tests')")
with open("my_project/.gitignore", "w") as f:
f.write("*.tmp\n")
with open("my_project/temp.tmp", "w") as f:
f.write("temp file") # This should be ignored
def process_file(path: Path) -> str:
"""A simple function to process a file path."""
return f"Processed: {path.name}"
# Walk the 'my_project' directory and run 'process_file' on each non-ignored file
# trailrunner respects .gitignore for exclusions
results = walk_and_run([Path("my_project")], process_file)
print("--- Trailrunner Results ---")
for path, result in results.items():
print(f"{path}: {result}")
# Expected output for existing files, excluding 'temp.tmp'
# (Order may vary due to multiprocessing)
# my_project/src/app.py: Processed: app.py
# my_project/tests/test_app.py: Processed: test_app.py
Debug
Known issues
breakingPython 3.6 support was dropped in Trailrunner v1.1.0 and again in v1.3.0. Users on Python 3.6 must upgrade to Python 3.7 or newer to use current versions of Trailrunner.fixUpgrade your Python environment to 3.7 or higher.
affects: >=1.1.0, >=1.3.0
gotchaAs of v1.4.0, Trailrunner modified its path resolution behavior to "Always resolve and exclude paths relative to project root". This ensures that paths are walked and excluded in a manner more consistent with `git`'s behavior, preventing exclusions based on path segments outside the project root.fixReview existing scripts that rely on previous path exclusion behavior, especially those operating near the project root or with complex `.gitignore` rules, to ensure compatibility with the new logic.
affects: 1.4.0
gotchaVersion 1.1.0 introduced a new, class-based API (`Trailrunner` class) internally. While the `walk()`, `run()`, and `walk_and_run()` functions continue to exist as simple wrappers around this new class, direct interaction with the `Trailrunner` class for advanced use cases (e.g., custom configuration or extensibility) might require familiarization with the new object-oriented structure.fixFor advanced use cases, consult the documentation for the `Trailrunner` class. For basic usage, the wrapper functions `walk`, `run`, and `walk_and_run` remain stable and functional.
affects: >=1.1.0
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'trailrunner'
The `trailrunner` library is not installed in the current Python environment.
fixpip install trailrunner
AttributeError: 'Trailrunner' object has no attribute 'run'
The primary method for starting the file traversal is `walk()`, not `run()`, on a `Trailrunner` instance.
fixrunner = Trailrunner()
runner.walk(path='.', on_file=my_processing_function)
TypeError: 'str' object is not callable
The `on_file` argument of the `Trailrunner.walk` method expects a callable function, but a non-callable type (e.g., a string) was provided.
fixdef process_file(file_path): print(file_path)
runner = Trailrunner()
runner.walk(path='.', on_file=process_file)
AttributeError: Can't pickle local object '<lambda>'
When `Trailrunner` utilizes a process pool for concurrent execution, the `on_file` function must be picklable, which local lambdas or nested functions often are not.
fixdef process_file_globally(file_path): print(file_path)
runner = Trailrunner()
runner.walk(path='.', on_file=process_file_globally)
Upgrade
Version history
1.4.0latest on PyPI · released Mar 27, 2023
Audit
Dependencies
pathspecrequiredUsed for parsing .gitignore files and excluding paths.