pycache_skip
Skip pipeline steps when their inputs have not changed.
uv add pycache_skip
What it does
cache_skip wraps a pipeline step function and skips re-execution when all
inputs are unchanged. It stores a compact state file (.input_state.json)
alongside each output directory. On subsequent calls it compares the current
inputs against the stored state and only reruns the function when something
actually changed.
Usage
Basic example (single input directory)
from pathlib import Path
from cache_skip import cache_skip, Dirmaker
dm = Dirmaker(Path("/data/pipeline/run-001"))
@cache_skip
def step_transform(raw: Path, *, _output: Path) -> Path:
# heavy transformation ...
return _output
# First call — runs the function and records input state.
step_transform(Path("/data/raw"), _output=dm.path_for("transform"))
# Second call — skips the function, returns the output path immediately.
step_transform(Path("/data/raw"), _output=dm.path_for("transform"))
Example with non-Path args
Non-Path arguments (dates, strings, ints, etc.) are also part of the cache
key. Changing them triggers a rerun.
import datetime as dt
@cache_skip(track_dependencies=False)
def step_build_config(
schedule_date: dt.date,
template: Path,
*,
_output: Path,
) -> Path:
...
# Changing schedule_date from 2025-01-01 to 2025-01-02 invalidates the cache.
Dirmaker companion
Dirmaker allocates named output directories under a staging root. Use
path_for(name) to resolve the path without side effects (for @cache_skip),
or new_output_dir(name) to delete and recreate explicitly.
dm = Dirmaker(Path("/data/pipeline/run-001"))
# Pass path to decorator — decorator manages deletion on rerun.
step_transform(raw, _output=dm.path_for("transform"))
# Or manage the directory yourself:
out = dm.new_output_dir("transform") # deletes existing, creates fresh
How invalidation works
Three-tier change detection on every call after the first:
-
Args hash — all non-
Path, non-_outputarguments are hashed viarepr(). A change in any scalar argument (date, string, int, …) triggers a rerun immediately. -
Dependency hash — the source files of the decorated function and all modules it imports (static AST analysis) are hashed. Editing the function's source code triggers a rerun. Disable with
track_dependencies=False. -
File content hash — every file under each input
Pathis compared. Metadata (mtime, inode, size) is checked first as a fast path. If metadata is identical the stored hash is trusted. If metadata drifted but content hash matches, the state file is updated silently without a rerun (handlesrsync/cp -pcopies with timestamp noise).
track_dependencies
@cache_skip(track_dependencies=False)
def step(...):
...
Set track_dependencies=False to skip module source hashing. Useful when the
function imports large, rarely-changing libraries and startup cost matters, or
in tests.
Comparison with auto_skip
cache_skip is a simpler, self-contained alternative to auto_skip:
| Feature | cache_skip |
auto_skip |
|---|---|---|
| Input detection | explicit Path args |
strace / audit hooks |
| Non-Path args | hashed | ignored |
| Module dep tracking | static AST | runtime import list |
| External deps | xxhash, loguru |
heavier stack |
| Output format | dir with .input_state.json |
opaque cache store |
Metadata
Release files for pycache-skip 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pycache_skip-0.1.2.tar.gz | 43.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pycache_skip-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 56.0 kB
Release files / pycache_skip-0.1.2.tar.gz
| Download URL | pycache_skip-0.1.2.tar.gz |
|---|---|
| Size | 43.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
65c8dc207cff7b725a40f1691eb02017afe42a26225f99f91c3fea08abbbf451
|
|
BLAKE2b-256 checksum How to use checksums |
e0bcaabc3bd529ac056ee93e5d93ff3d7cd9b36fe5a867dfe4ecfa5d331ce214
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|
Release files / pycache_skip-0.1.2-py3-none-any.whl
| Download URL | pycache_skip-0.1.2-py3-none-any.whl |
|---|---|
| Size | 13.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ebb166cd3c7a5b0fea80c942b17079093d4108553a69e458f33e5c3d17ef1aa0
|
|
BLAKE2b-256 checksum How to use checksums |
1f55b719f8f3d5b7d89c3ed62917de24c53932764a10ca87c8f0f2bab48667ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.9
|
Security for pycache-skip 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.