Multi-language CLI tool for detecting concurrency and thread safety issues
Project description
Thread Safety Analyzer
A multi-language static analysis tool for detecting concurrency and thread safety issues. Use it locally as a linter, in CI pipelines, or to generate context for LLM-assisted PR reviews.
Installation
pip install thread-safety
Or install from source:
git clone https://github.com/steph-dove/thread-safe-check.git
cd thread-safe-check
pip install -e .
Use Cases
Local Development (Linter)
Run as a linter during development to catch concurrency issues early:
# Analyze your project
thread-safety analyze ./src
# Check only files you've changed
thread-safety analyze . --git-diff
# Focus on critical issues
thread-safety analyze ./src --min-severity high
CI/CD Integration
Add to your CI pipeline to catch thread safety issues before merge.
GitHub Actions:
- name: Thread Safety Check
run: |
pip install thread-safety
thread-safety analyze ./src --output json -f thread-safety-report.json
- name: Upload Report
uses: actions/upload-artifact@v3
with:
name: thread-safety-report
path: thread-safety-report.json
GitLab CI:
thread-safety:
script:
- pip install thread-safety
- thread-safety analyze ./src --min-severity medium
allow_failure: true # Start as warning-only
Pre-commit Hook:
# .pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: thread-safety
name: Thread Safety Check
entry: thread-safety analyze
language: system
files: \.(py|js|ts|go|rs)$
pass_filenames: false
LLM PR Review Context
Generate rich context for AI-assisted code review:
# Generate LLM-optimized output
thread-safety analyze ./src --output llm
# Analyze only changed files for PR review
thread-safety analyze . --git-diff --output llm
The LLM output format includes:
- Code snippets with context
- Detailed explanations of why each issue matters
- Suggested fixes with before/after examples
- Severity and category information
Quick Start
# Analyze a directory
thread-safety analyze ./src
# Output formats
thread-safety analyze ./src --output text # Human-readable (default)
thread-safety analyze ./src --output json # For CI/tooling
thread-safety analyze ./src --output markdown # For documentation
thread-safety analyze ./src --output llm # For AI review
# Filter by severity (info, low, medium, high, critical)
thread-safety analyze ./src --min-severity high
# Run specific rules only
thread-safety analyze ./src --rule TS001 --rule TS010
# Analyze only git-changed files
thread-safety analyze . --git-diff
# Save report to file
thread-safety analyze ./src --output json -f report.json
# List all available rules
thread-safety rules
# Generate config file
thread-safety init
Detection Rules
Shared Mutable State
- TS001: Global variable mutation in threaded context
- TS002: Class attribute mutation across threads
- TS003: Closure capturing mutable variable
- TS004: Module-level mutable default argument
Race Conditions
- TS010: Unprotected shared variable access
- TS011: Check-then-act (TOCTOU)
- TS012: Compound operation without lock
- TS013: Collection modification during iteration
Lock Issues
- TS020: Potential deadlock (inconsistent lock ordering)
- TS021: Lock acquired but never released
- TS022: Double lock acquisition (non-reentrant)
- TS023: Lock held during blocking I/O
Async Patterns
- TS030: Blocking call in async function
- TS031: Missing await on coroutine
- TS032: Using threading.Lock in async code
- TS033: Shared mutable state in coroutine
- TS034: Sync primitive in async context
Supported Languages
| Language | Status | Rules | Notes |
|---|---|---|---|
| Python | ✅ Stable | 17 | Full coverage |
| JavaScript/TypeScript | ✅ Stable | 8 | Async/Promise patterns |
| Go | ✅ Stable | 5 | Goroutines, sync.Mutex |
| Rust | ✅ Stable | 8 | Async, std::sync |
| Java | Planned | - | - |
Language Support Matrix
| Rule | Python | JS/TS | Go | Rust |
|---|---|---|---|---|
| TS001 Global Mutation | ✅ | - | - | - |
| TS002 Class Attribute | ✅ | - | - | - |
| TS003 Closure Capture | ✅ | ✅ | ✅ | ✅ |
| TS004 Mutable Default | ✅ | - | - | - |
| TS010 Unprotected Access | ✅ | - | - | - |
| TS011 Check-Then-Act | ✅ | ✅ | ✅ | ✅ |
| TS012 Compound Operation | ✅ | - | - | - |
| TS013 Collection Iteration | ✅ | ✅ | ✅ | ✅ |
| TS020 Deadlock | ✅ | - | ✅ | ✅ |
| TS021 Lock Not Released | ✅ | - | - | - |
| TS022 Double Lock | ✅ | - | - | - |
| TS023 Lock Blocking I/O | ✅ | - | ✅ | ✅ |
| TS030 Blocking in Async | ✅ | ✅ | - | ✅ |
| TS031 Missing Await | ✅ | ✅ | - | ✅ |
| TS032 Threading Lock in Async | ✅ | - | - | - |
| TS033 Shared State in Coroutine | ✅ | ✅ | - | ✅ |
| TS034 Sync Primitive in Async | ✅ | - | - | - |
Configuration
Create a thread-safety.toml file in your project root:
[thread-safety]
include = ["src", "lib"]
exclude = ["**/node_modules/**", "**/.venv/**", "**/test/**"]
min_severity = "medium"
[thread-safety.rules]
# Enable only specific rules
enable = ["TS001", "TS010", "TS020"]
# Or disable specific rules
disable = ["TS004"]
Output Formats
Text (default)
Human-readable output for terminal with colors and code snippets.
JSON
Structured output for CI/CD integration and tooling:
thread-safety analyze ./src --output json -f report.json
Markdown
Documentation-friendly format for reports:
thread-safety analyze ./src --output markdown -f report.md
LLM
Optimized for AI-assisted code review with rich context:
thread-safety analyze ./src --output llm
Example Output
Found 2 issue(s):
■ TS030 src/api/handler.py:45:4
Blocking call 'requests.get' in async function 'fetch_data'
43 | async def fetch_data(url: str):
44 | # This blocks the event loop!
> 45 | response = requests.get(url)
46 | return response.json()
Suggestion: Replace with async alternative: aiohttp or httpx
■ TS013 src/cache.py:23:8
Collection 'items' modified with 'pop' during iteration
21 | for key in cache.items:
22 | if is_expired(key):
> 23 | cache.items.pop(key)
24 |
Suggestion: Collect keys to remove first, then remove outside the loop
Development
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run linting
ruff check src tests
# Type checking
mypy src
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 Distribution
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 thread_safety-0.4.0.tar.gz.
File metadata
- Download URL: thread_safety-0.4.0.tar.gz
- Upload date:
- Size: 60.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
778244f825472f7e16f87782f9301a6185691d2f59399700118c2eed6a135bbd
|
|
| MD5 |
e970df66cc60bc804e727baddd5a768d
|
|
| BLAKE2b-256 |
a79e9a28e140b244a43a50c5fc5e6c0db53f766d2a144398bde221d707084de8
|
File details
Details for the file thread_safety-0.4.0-py3-none-any.whl.
File metadata
- Download URL: thread_safety-0.4.0-py3-none-any.whl
- Upload date:
- Size: 89.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
40a9556641227c1c5895eb121aab65d224f0938e42a8363121171050be08142d
|
|
| MD5 |
4a9bb877d23c2f7cd72069b2bb88417b
|
|
| BLAKE2b-256 |
e66b2d8a2a9dcf92fa62db019aac7c4e7bf0d94c25b365b0136d61fc6355af6a
|