AI-powered Python performance analyzer that detects algorithmic bottlenecks
Project description
LoopSleuth
A Rust-based CLI tool that analyzes Python code for performance issues using local LLM inference.
Installation
Get started in 3 commands:
# 1. Install LoopSleuth
pip install loopsleuth
# 2. Download a model interactively
loopsleuth download-model
# 3. Run analysis!
loopsleuth -m ~/.loopsleuth/models/qwen*.gguf ./src
That's it! The download-model command will show you available models, download your choice to ~/.loopsleuth/models/, and show you how to use it.
Quick Start Guide: See docs/QUICKSTART.md for a complete walkthrough.
Features
- Fully Configurable: Define checks, customize prompts, and set defaults via TOML configuration file
- 8 Built-in Performance Checks: Detects multiple types of performance issues beyond just quadratic complexity
- Parses Python code using Ruff's parser (fast and accurate)
- Extracts functions from Python modules
- Analyzes each function using a local LLM (llama.cpp)
- Supports both single files and entire directories
- Intelligent caching - Uses SQLite to cache analysis results per check, avoiding redundant LLM calls for unchanged functions
- Flexible check selection - Run all checks, specific checks, or exclude certain checks
Performance Checks
LoopSleuth includes 8 built-in performance checks:
General Performance
- quadratic - Detects O(nยฒ) or worse time complexity (nested loops, etc.)
- linear-in-loop - Detects hidden O(n) operations in loops (
x in list,.remove(),.index()) - n-plus-one - Detects repeated expensive operations in loops (file I/O, network, model loading)
- expensive-sort-key - Detects O(n) key functions in sort/sorted operations
- unbounded-alloc - Detects growing allocations in loops (string concat, repeated cat)
- growing-container - Detects loops that grow containers while iterating
ML-Specific
- conversion-churn - Detects repeated CPU/GPU or tensor/array conversions in loops
- ml-footguns - Detects ML-specific issues (repeated tokenization, mask rebuilding)
Configuration
LoopSleuth uses a TOML configuration file (loopsleuth.toml) to define performance checks. You can:
- Customize existing checks
- Add your own custom checks
- Modify LLM prompts for better detection
- Set default CLI options
Configuration File Locations
LoopSleuth looks for configuration in this order:
- Path specified with
--configflag ~/.config/loopsleuth/loopsleuth.toml(user config)- Built-in defaults (bundled with the tool)
Configuration Format
[settings]
# Optional: Set default CLI options (can be overridden by command-line flags)
# Recommended: Use the 7B model for best accuracy
model = "~/.loopsleuth/models/Qwen2.5-Coder-7B-Instruct-128K-Q4_K_M.gguf"
threads = 4
max_tokens = 512
context_size = 4096
[[check]]
key = "my-custom-check"
name = "My Custom Check"
description = "Detects my specific performance pattern"
category = "performance"
keyword = "MY_ISSUE" # Keyword LLM should include if issue detected
detection_prompt = """<|im_start|>system
You are a code analyzer...
Use {function_source} placeholder for the function code.
<|im_end|>
<|im_start|>user
Analyze: {function_source}
<|im_end|>
<|im_start|>assistant
"""
solution_prompt = """<|im_start|>system
Provide solutions...
<|im_end|>
<|im_start|>user
Fix this: {function_source}
<|im_end|>
<|im_start|>assistant
"""
Using Custom Configuration
# Print default config to create your own
loopsleuth --print-default-config > my-loopsleuth.toml
# Edit my-loopsleuth.toml to customize checks or add new ones
# Use your custom config
loopsleuth --config my-loopsleuth.toml -m ~/.loopsleuth/models/qwen*.gguf ./src
# Or place it in ~/.config/loopsleuth/loopsleuth.toml for automatic loading
mkdir -p ~/.config/loopsleuth
cp my-loopsleuth.toml ~/.config/loopsleuth/loopsleuth.toml
Adding Custom Checks
-
Get the default configuration:
loopsleuth --print-default-config > ~/.config/loopsleuth/loopsleuth.toml
-
Add a new check section:
[[check]] key = "database-in-loop" name = "Database Queries in Loop" description = "Detects database queries inside loops" category = "performance" keyword = "DB_IN_LOOP" detection_prompt = """...""" solution_prompt = """..."""
-
Run with your custom check:
loopsleuth -m ~/.loopsleuth/models/qwen*.gguf ./src --checks database-in-loop
Model Management
After installation, use these commands to manage models:
# Download a model interactively
loopsleuth download-model
# List downloaded models
loopsleuth list-models
# Use short form
loopsleuth download
Recommended models:
- Qwen2.5-Coder (7B) โญ - Best for code analysis, excellent accuracy (~4.7GB)
- Qwen2.5-Coder (3B) - Faster but less accurate; not recommended for n-plus-one check (~2GB)
- Devstral Small 2 (24B) - Highest accuracy, requires more RAM (~15GB)
- Qwen2.5 (3B) - General purpose, good balance (~2GB)
- Qwen2.5 (0.5B) - Very fast, lower accuracy (~400MB)
The interactive download command will guide you through selecting and downloading the best model for your needs. Note: The 7B model provides significantly better results than the 3B model, especially for detecting N+1 problems and generating accurate code fixes.
Building from Source
For development or if you prefer to build from source:
Prerequisites:
- Rust toolchain from rustup.rs
- CMake (
brew install cmakeon macOS,apt-get install cmakeon Linux)
# Clone the repository
git clone https://github.com/tarekziade/loopsleuth.git
cd loopsleuth
# Build the project
cargo build --release
# Download the recommended model (7B)
mkdir -p models
pip install huggingface_hub
hf download unsloth/Qwen2.5-Coder-7B-Instruct-128K-GGUF \
Qwen2.5-Coder-7B-Instruct-128K-Q4_K_M.gguf \
--local-dir ./models
# Run
./target/release/loopsleuth -m ./models/Qwen2.5-Coder-7B*.gguf ./src
Note: The first build takes several minutes as it compiles llama.cpp from source. Subsequent builds are much faster.
For detailed build instructions and troubleshooting, see docs/PYTHON_INSTALL.md
Usage
Basic Usage
Analyze a single Python file (runs all checks by default):
# Using the recommended 7B model
loopsleuth -m ~/.loopsleuth/models/Qwen2.5-Coder-7B*.gguf example.py
# Or use the 3B model for faster (but less accurate) analysis
loopsleuth -m ~/.loopsleuth/models/qwen2.5-coder-3b*.gguf example.py
Analyze an entire directory (recursive):
loopsleuth -m ~/.loopsleuth/models/Qwen2.5-Coder-7B*.gguf ./src
The tool automatically finds all .py files in subdirectories and groups results by file.
Check Selection
List all available checks:
loopsleuth --list-checks
Run specific checks only:
loopsleuth -m ~/.loopsleuth/models/qwen*.gguf ./src --checks quadratic,linear-in-loop
Run all checks except specific ones:
loopsleuth -m ~/.loopsleuth/models/qwen*.gguf ./src --exclude conversion-churn,ml-footguns
Note: By default, all 8 checks are run. Use --checks to select specific checks or --exclude to skip certain checks.
Options
Required
-m, --model <MODEL>- Path to the GGUF model file (required unless using --list-checks)<PATH>- Path to Python file or directory to analyze (required unless using --list-checks)
Check Selection
--list-checks- List all available checks and exit--checks <CHECKS>- Comma-separated list of checks to run (e.g., "quadratic,linear-in-loop")--exclude <CHECKS>- Comma-separated list of checks to exclude from analysis
Configuration
--config <FILE>- Path to custom checks configuration file (TOML format)--print-default-config- Print the built-in default configuration and exit
LLM Options
-t, --threads <THREADS>- Number of threads for inference (default: 4)--max-tokens <MAX_TOKENS>- Maximum tokens to generate (default: 512)--context-size <SIZE>- Context window size in tokens (default: 4096)-v, --verbose- Show verbose llama.cpp output (useful for debugging)
Output Options
-o, --output <FILE>- Save analysis report to HTML file-d, --details- Show detailed report in stdout (always included in file output)--skip-large <N>- Skip functions larger than N lines (0 = no limit)
Cache Options
--no-cache- Disable caching (forces re-analysis of all functions)--clear-cache- Clear the cache before running analysis--cache-dir <DIR>- Specify cache directory (default:.loopsleuth_cache)
Note:
- The tool shows a real-time progress bar with function names and status
- Cached results are shown with a ๐พ icon for instant retrieval
- For extremely large functions (>500 lines), consider using
--skip-large N - If you get "Function too large" warnings, increase
--context-sizeto 8192 or higher
Example
# List all available checks
loopsleuth --list-checks
# Print default configuration
loopsleuth --print-default-config > my-loopsleuth.toml
# Run with custom configuration
loopsleuth --config my-loopsleuth.toml -m ~/.loopsleuth/models/qwen*.gguf ./tests/checks/quadratic.py
# Run all checks (default)
loopsleuth -m ~/.loopsleuth/models/qwen*.gguf ./tests/checks/quadratic.py
# Run specific checks only
loopsleuth -m ~/.loopsleuth/models/qwen*.gguf ./tests/checks/quadratic.py --checks quadratic,linear-in-loop
# Run all except ML-specific checks
loopsleuth -m ~/.loopsleuth/models/qwen*.gguf ./tests/checks/quadratic.py --exclude conversion-churn,ml-footguns
# Full analysis in terminal
loopsleuth -m ~/.loopsleuth/models/qwen*.gguf ./tests/checks/quadratic.py --details
# Save detailed report to file
loopsleuth -m ~/.loopsleuth/models/qwen*.gguf ./tests/checks/quadratic.py --output report.html
For developers: If you're building from source, use cargo run --release -- instead of loopsleuth, or use make example.
Output Format
LoopSleuth provides flexible output for different use cases:
Default: Concise Summary
A quick overview showing:
- Total functions analyzed
- Checks run
- Count of functions with issues (any check)
- List of issues grouped by function
Perfect for: Quick checks, CI/CD pipelines, daily development
With --details: Full Report to stdout
Each function with issues includes:
- ๐ Full source code
- โ ๏ธ Analysis for each detected issue
- ๐ก Optimization suggestions with examples for each issue
Perfect for: Deep analysis, learning, immediate review
With --output FILE: Save HTML Report
Generate a complete HTML file that can be:
- Committed to your repository
- Attached to pull requests
- Shared in code reviews
- Used as documentation
Note: File output always includes full details regardless of --details flag
Sample output:
๐ง Initializing LoopSleuth...
โ๏ธ Setting up LLM backend...
๐ฆ Loading model: ./models/Qwen2.5-Coder-7B-Instruct-128K-Q4_K_M.gguf...
โ
Ready! (context: 4096 tokens)
๐ Scanning 1 Python file(s)...
๐ฌ Running 3 check(s): quadratic, linear-in-loop, unbounded-alloc
๐ Analyzing 4 function(s)...
[โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ] 100% [4/4] | Issues: 3 | ๐ [unbounded-alloc] clean_function
โ
Analysis complete!
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ LOOPSLEUTH ANALYSIS SUMMARY โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Total functions analyzed: 4
๐ Checks run: 3 (quadratic, linear-in-loop, unbounded-alloc)
โ ๏ธ Functions with issues: 3
โ Functions clean: 1
๐พ Cache entries: 12 (expected: 12 = 4 functions ร 3 checks), 8 with issues
๐ด ISSUES DETECTED:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โข quadratic_example (test.py:1)
- Quadratic Complexity
- Linear Operations in Loops
- Unbounded Allocations
โข linear_in_loop_example (test.py:10)
- Quadratic Complexity
- Linear Operations in Loops
โข string_concat_example (test.py:17)
- Quadratic Complexity
- Linear Operations in Loops
- Unbounded Allocations
๐ก Tip: Use --details to see full analysis or --output FILE to save report
How It Works
- File Discovery: Walks through the specified path to find all
.pyfiles - Parsing: Uses RustPython's parser to build an AST
- Function Extraction: Extracts all function definitions (including class methods)
- Check Selection: Determines which checks to run based on CLI flags (default: all 8 checks)
- For each function, run all selected checks:
- Cache Check: Computes SHA256 hash of function source code + check key and checks SQLite cache
- Cache Hit: Instantly returns cached analysis results (shown with ๐พ icon)
- Cache Miss: Proceeds to LLM analysis
- Two-Stage LLM Analysis (per check, when not in cache):
- Stage 1 - Detection: Constructs a check-specific prompt asking the LLM to analyze for that issue
- Runs inference using llama.cpp to identify the issue
- Stage 2 - Solution: If issue detected, makes a second LLM call to:
- Explain why the code has this issue
- Propose specific optimization strategies
- Provide optimized code examples
- Cache Storage: Stores analysis results in SQLite with composite key (function_hash, check_key)
- Cache Check: Computes SHA256 hash of function source code + check key and checks SQLite cache
- Reporting: Displays findings grouped by function, showing all detected issues with solutions
Caching Benefits
The intelligent caching system provides significant benefits:
- Speed: Instant results for unchanged functions (no LLM calls needed)
- Cost: Saves computation time on repeated analyses
- Consistency: Same function always gets same analysis (deterministic)
- Automatic Invalidation: Cache key is based on function source code hash - any code change automatically invalidates cache entry
- Persistent: Cache survives across runs (stored in
.loopsleuth_cache/by default) - Zero Configuration: Works automatically - just run the tool
Example speed improvement:
- First run on 100 functions with 8 checks: ~40-60 minutes
- Second run (all cached): ~10-20 seconds
- Incremental run (95% cached): ~2-5 minutes
- Single check (quadratic only): ~5-8 minutes first run, instant when cached
Cache behavior:
- Results cached per (function, check) combination
- Functions identified by SHA256 hash of source code
- Changing even a single character in a function invalidates its cache entries for all checks
- Cache automatically migrates from old single-check schema to new multi-check schema
- Cache is stored in SQLite database (
.loopsleuth_cache/analysis_cache.db) - Cache statistics shown in summary: "๐พ Cache entries: X (expected: Y = N functions ร M checks), Z with issues"
Common Patterns Detected
Performance Issues
- Quadratic complexity: Nested loops, repeated linear operations
- Linear-in-loop:
x in list,.remove(),.index(),.pop(0)in loops - N+1 problem: File I/O, network calls, model loading in loops
- Expensive sort keys: O(n) key functions in sorting
- Unbounded allocations: String concatenation, repeated concatenation in loops
- Growing containers: Appending to lists while iterating
ML-Specific Issues
- Conversion churn: Repeated
.cpu(),.cuda(),.numpy()conversions - ML anti-patterns: Repeated tokenization, mask rebuilding, Python loops over tensors
Model Recommendations
| Model | Size | Speed | Accuracy | Best For |
|---|---|---|---|---|
| Qwen2.5-Coder (7B) โญ | ~4.7GB | Fast | Excellent | Recommended - Best accuracy, minimal false positives |
| Qwen2.5-Coder (3B) | ~2GB | Fast | Good | Faster but less accurate (not recommended for n-plus-one) |
| Devstral Small 2 (24B) | ~15GB | Slower | Excellent | Production, very detailed analysis |
| Qwen2.5 (3B) | ~2GB | Fast | Good | General purpose |
| Qwen2.5 (0.5B) | ~400MB | Very Fast | Fair | Quick checks, testing |
Note: The 7B model eliminates most false positives seen with the 3B model, especially for N+1 detection. It also generates more accurate code diffs and solutions.
Performance
- Model loading: ~1-3 seconds (depending on model size)
- Per-function, per-check analysis (2 LLM calls when issue detected):
- Detection: ~2-5 seconds
- Solution proposal: ~3-8 seconds
- Cached retrieval: <10ms (instant!)
- Running all 8 checks: ~8x time compared to single check (but only on first run - subsequent runs use cache)
- The tool processes functions sequentially to manage memory
- Larger models (24B) provide more detailed and accurate analysis but require more RAM
- Cache dramatically improves repeated runs: Second analysis on same codebase is ~100x faster
- Tip: Use
--checksto run only the checks you need for faster first-time analysis
Troubleshooting
Large Functions
Symptoms: "Function too large" warnings for very large functions (>500 lines)
Solution: Increase context size to accommodate larger functions
loopsleuth --context-size 8192 -m ~/.loopsleuth/models/qwen*.gguf ./code
Or skip analyzing extremely large functions:
loopsleuth --skip-large 300 -m ~/.loopsleuth/models/qwen*.gguf ./code
Slow Analysis
Symptoms: Takes a while to analyze many functions
This is normal:
- Each function requires 2 LLM calls per check (detection + solution) if issue found
- With all 8 checks: expect ~40-80 seconds per function on first run (depending on issues found)
- With single check: expect ~5-10 seconds per function with 3B model
- Progress bar shows real-time status with check name and function name
- Second run is instant if code hasn't changed (cache hit)
To speed up:
- Use
--checksto run only needed checks (e.g.,--checks quadratic,linear-in-loop) - Use
--excludeto skip ML-specific checks if not relevant - Use smaller models (Qwen2.5-0.5B) for faster analysis at cost of accuracy
- Use
--skip-largeto skip very large functions - Let the cache work - subsequent runs are ~100x faster
Out of Memory
Symptoms: System runs out of RAM (rare with default settings)
Solutions:
- Use smaller model (Qwen2.5-0.5B instead of 3B)
- Close other memory-intensive applications
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file loopsleuth-0.1.2.tar.gz.
File metadata
- Download URL: loopsleuth-0.1.2.tar.gz
- Upload date:
- Size: 73.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c951c3a146334fbbade9cb1b09d9ef05c5e9abccdaba4db74ad9eeda497c7443
|
|
| MD5 |
c27600ee1621a8e53480129dc96a60fd
|
|
| BLAKE2b-256 |
41aa2f84fb290f7a5c082b7d351daf10f0d633a32ccd17ee5a8cb4012162f426
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2.tar.gz:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2.tar.gz -
Subject digest:
c951c3a146334fbbade9cb1b09d9ef05c5e9abccdaba4db74ad9eeda497c7443 - Sigstore transparency entry: 923977563
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp314-cp314-win_amd64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp314-cp314-win_amd64.whl
- Upload date:
- Size: 4.5 MB
- Tags: CPython 3.14, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
311e57df1aca8c30f2ae1962b0307835579339202a0fe966c6ad34f7eba7eb82
|
|
| MD5 |
fe9adddf4ebee5c0e46b3f84fc5db72b
|
|
| BLAKE2b-256 |
d8669751eaa478719ab3ed5ca8fc2cbafa9a1fc37bf625867906de0ad03e7507
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp314-cp314-win_amd64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp314-cp314-win_amd64.whl -
Subject digest:
311e57df1aca8c30f2ae1962b0307835579339202a0fe966c6ad34f7eba7eb82 - Sigstore transparency entry: 923977571
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp314-cp314-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp314-cp314-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 4.9 MB
- Tags: CPython 3.14, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c898e0cc6aa653c1f1551f19afe18c0b6c7ce6ac229462e807de6750cba40e82
|
|
| MD5 |
2e0eab615e6ff5e8c4ee8203cadc06ac
|
|
| BLAKE2b-256 |
e64b9778617f55b1b0b2a12815002359189513ce2c71079f5c0ed996138678da
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp314-cp314-manylinux_2_28_x86_64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp314-cp314-manylinux_2_28_x86_64.whl -
Subject digest:
c898e0cc6aa653c1f1551f19afe18c0b6c7ce6ac229462e807de6750cba40e82 - Sigstore transparency entry: 923977576
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp314-cp314-macosx_11_0_arm64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp314-cp314-macosx_11_0_arm64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.14, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0d6445557fb92c3cfce0e2f725c4c46760bb340accd89065d82c50407686c58
|
|
| MD5 |
75f5ec6f11f8af69c388c4dcc714de9f
|
|
| BLAKE2b-256 |
28c2af51510deb6f367d1c78a461ba1f2602969f85c961e02e8be74c5e28b8ad
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp314-cp314-macosx_11_0_arm64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp314-cp314-macosx_11_0_arm64.whl -
Subject digest:
e0d6445557fb92c3cfce0e2f725c4c46760bb340accd89065d82c50407686c58 - Sigstore transparency entry: 923977568
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d742d4527116f5fcd65a1d97e5a90c16b90df3098b3b6c3cb349c5fbd6449dbf
|
|
| MD5 |
535529620fd790eccf629520d12da0a3
|
|
| BLAKE2b-256 |
79380eaf1a4b91e7ef1a2ed803ea3281666c86f322e96eff4910b327da494655
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp313-cp313-win_amd64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp313-cp313-win_amd64.whl -
Subject digest:
d742d4527116f5fcd65a1d97e5a90c16b90df3098b3b6c3cb349c5fbd6449dbf - Sigstore transparency entry: 923977592
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp313-cp313-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp313-cp313-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 4.9 MB
- Tags: CPython 3.13, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
77ebf469ad9406bcc7a8c69bc0b3c4847f7169f1d375a66a6a14f37f26acacd1
|
|
| MD5 |
91c845433998ac21487686a11af95b9f
|
|
| BLAKE2b-256 |
49a18d471125994ab6d2c0aa80bc380b59f3f5340ff783a8b67e2411c177e871
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp313-cp313-manylinux_2_28_x86_64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp313-cp313-manylinux_2_28_x86_64.whl -
Subject digest:
77ebf469ad9406bcc7a8c69bc0b3c4847f7169f1d375a66a6a14f37f26acacd1 - Sigstore transparency entry: 923977586
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp313-cp313-macosx_11_0_arm64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp313-cp313-macosx_11_0_arm64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.13, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d6cf42385c08a03e4948344e9d90d1142e8ba086bbecc8faddb1d68578f6fa5
|
|
| MD5 |
33974d5320ec9b5ed8f50ef8885ff40c
|
|
| BLAKE2b-256 |
708e2bba6aa52f1c61890ced5c1662ba5b2012def178f8e55601672b907d33e0
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp313-cp313-macosx_11_0_arm64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp313-cp313-macosx_11_0_arm64.whl -
Subject digest:
2d6cf42385c08a03e4948344e9d90d1142e8ba086bbecc8faddb1d68578f6fa5 - Sigstore transparency entry: 923977590
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
139c780ef8ae8e7daf33eb4c696ad7547d9aa7ad0638f47bf227a67edbdb0b2f
|
|
| MD5 |
2424f6e44ce33fc80909626417608188
|
|
| BLAKE2b-256 |
7c903ec83937fb292e6ebf8f3c5da57b04f926b7a932a1f6b875332e69b6339b
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp312-cp312-win_amd64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp312-cp312-win_amd64.whl -
Subject digest:
139c780ef8ae8e7daf33eb4c696ad7547d9aa7ad0638f47bf227a67edbdb0b2f - Sigstore transparency entry: 923977564
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp312-cp312-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp312-cp312-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 4.9 MB
- Tags: CPython 3.12, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dcb6e901e7128f12f63798102cede13d797bf3163e2112deb19491e23d29cddc
|
|
| MD5 |
eb92cf5c3bf5d7cfd2287d474d670ced
|
|
| BLAKE2b-256 |
9ea662b0d101ab2d0a0c4d499d1f511d38ae846d33cbdfca113e8cedd76aa742
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp312-cp312-manylinux_2_28_x86_64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp312-cp312-manylinux_2_28_x86_64.whl -
Subject digest:
dcb6e901e7128f12f63798102cede13d797bf3163e2112deb19491e23d29cddc - Sigstore transparency entry: 923977595
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp312-cp312-macosx_11_0_arm64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp312-cp312-macosx_11_0_arm64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.12, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2867b141a9687fb75d43cab35e4aef9c0806d0df4929f42259ee2d7c63713f3e
|
|
| MD5 |
cc9029d11be64b4b5857f4bc8941b672
|
|
| BLAKE2b-256 |
274e031c39b70007f40c3847dfd7f35c476b628c46811956cb1a42c7f3c0a996
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp312-cp312-macosx_11_0_arm64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp312-cp312-macosx_11_0_arm64.whl -
Subject digest:
2867b141a9687fb75d43cab35e4aef9c0806d0df4929f42259ee2d7c63713f3e - Sigstore transparency entry: 923977583
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a97e75b5b35ef7afd8f8bccd645fe4060d9cdfb4a3f228dddd2f391d6f7cfac2
|
|
| MD5 |
97087d15655a76f89e712e0bc97a5535
|
|
| BLAKE2b-256 |
aa8ae12f7879bd8e86239b7621859c0e799bfe9e061de8981d7b789d7b18f18a
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp311-cp311-win_amd64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp311-cp311-win_amd64.whl -
Subject digest:
a97e75b5b35ef7afd8f8bccd645fe4060d9cdfb4a3f228dddd2f391d6f7cfac2 - Sigstore transparency entry: 923977584
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp311-cp311-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp311-cp311-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 4.9 MB
- Tags: CPython 3.11, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a522cf60dd8a6ff353493295d20bfc38dc4719f197545132237d19d2767fe95d
|
|
| MD5 |
3d72ebfaf2243e02e588f1e2a5e16d1f
|
|
| BLAKE2b-256 |
904e00f46e9c87ae3f11c983e01e9a45abea4b7ad192934a4bbe076380cb055c
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp311-cp311-manylinux_2_28_x86_64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp311-cp311-manylinux_2_28_x86_64.whl -
Subject digest:
a522cf60dd8a6ff353493295d20bfc38dc4719f197545132237d19d2767fe95d - Sigstore transparency entry: 923977574
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp311-cp311-macosx_11_0_arm64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp311-cp311-macosx_11_0_arm64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.11, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fdf54e937174827f9722bdd841cea502615265de1c7cbd7d014b246530d45b3f
|
|
| MD5 |
3291c20a80f0270f11e8abfa2dcb0eca
|
|
| BLAKE2b-256 |
d64c90d8c9e6019cc80642c9b42cba91fe5bb27f3a641981b3800a7f1c0013de
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp311-cp311-macosx_11_0_arm64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp311-cp311-macosx_11_0_arm64.whl -
Subject digest:
fdf54e937174827f9722bdd841cea502615265de1c7cbd7d014b246530d45b3f - Sigstore transparency entry: 923977603
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp310-cp310-win_amd64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp310-cp310-win_amd64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
94671faef689fabb90a25742bd6bee7bdf1a42ffec79f96eae95364c424ccada
|
|
| MD5 |
e5b609f8a07b8cb285514c75387a0f7d
|
|
| BLAKE2b-256 |
0f0b19b276e435c2e89f821f5374f48ae9c2cb9d024586c9bdd7a72181a92748
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp310-cp310-win_amd64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp310-cp310-win_amd64.whl -
Subject digest:
94671faef689fabb90a25742bd6bee7bdf1a42ffec79f96eae95364c424ccada - Sigstore transparency entry: 923977600
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp310-cp310-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp310-cp310-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 4.9 MB
- Tags: CPython 3.10, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e91bcfc5354f21f09635b4179d51319db30b894ab4ca7e22801961333170fe7
|
|
| MD5 |
1060b28b979966d662f582d8cf6555eb
|
|
| BLAKE2b-256 |
99e4c0462b61a2a7924ceb3aabd47cae4e533189582757c9483280a1c80eabee
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp310-cp310-manylinux_2_28_x86_64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp310-cp310-manylinux_2_28_x86_64.whl -
Subject digest:
0e91bcfc5354f21f09635b4179d51319db30b894ab4ca7e22801961333170fe7 - Sigstore transparency entry: 923977580
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file loopsleuth-0.1.2-cp310-cp310-macosx_11_0_arm64.whl.
File metadata
- Download URL: loopsleuth-0.1.2-cp310-cp310-macosx_11_0_arm64.whl
- Upload date:
- Size: 4.3 MB
- Tags: CPython 3.10, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
37fdd6ee93139e8a8c98d62960845f008a95ee69fe64f285c8125f19d3facb51
|
|
| MD5 |
302b4b6796a345e0e79d3cfcc4f95665
|
|
| BLAKE2b-256 |
5809e1d685f8ddac8e8e5ec4544748dd6baa8fe8e68e5171bfc1c9b4c2d71ea9
|
Provenance
The following attestation bundles were made for loopsleuth-0.1.2-cp310-cp310-macosx_11_0_arm64.whl:
Publisher:
publish.yml on tarekziade/loopsleuth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
loopsleuth-0.1.2-cp310-cp310-macosx_11_0_arm64.whl -
Subject digest:
37fdd6ee93139e8a8c98d62960845f008a95ee69fe64f285c8125f19d3facb51 - Sigstore transparency entry: 923977565
- Sigstore integration time:
-
Permalink:
tarekziade/loopsleuth@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Branch / Tag:
refs/tags/v0.1.2 - Owner: https://github.com/tarekziade
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@797ec6d3eb2429bc4d98dbdb666a9786f0b71d6a -
Trigger Event:
release
-
Statement type: