Multi-language AI Slop Detector - Intelligent detection of AI-generated code anti-patterns
Project description
๐ง DeepLint
Detect AI-generated code anti-patterns in your multi-language codebase.
Catches AI-specific anti-patterns that traditional linters miss
โก Quick Start
pip install deeplint
deeplint .
# Output:
# CRITICAL (2 issues)
# ============================================================
# src/api.py:23 mutable_default_arg
# Mutable default argument - use None instead
# > def process(items=[]):
#
# src/db.py:15 bare_except
# Bare except catches everything including SystemExit
# > except:
#
# DEEPLINT INDEX
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# Information Utility (Noise) : 24 pts
# Information Quality (Lies) : 105 pts
# Style / Taste (Soul) : 31 pts
# Structural Issues : 45 pts
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# TOTAL SLOP SCORE : 205 pts
#
# Verdict: SLOPPY
๐ Multi-Language Support
DeepLint automatically detects and scans multiple programming languages in your codebase:
| Language | File Extensions | Status |
|---|---|---|
| Python | .py, .pyw |
โ Full support (AST + patterns) |
| JavaScript | .js, .jsx, .mjs, .cjs |
โ Pattern detection |
| TypeScript | .ts, .tsx |
โ Pattern detection |
| Go | .go |
โ Pattern detection |
Automatic Detection
By default, DeepLint automatically detects which languages are present in your project:
# Scans all supported languages found in the directory
deeplint .
# Output shows detected languages:
# Scanned languages: javascript, python, typescript
Manual Language Override
Advanced users can override automatic detection with the --language flag:
# Scan only Python files
deeplint src/ --language python
# Scan multiple specific languages
deeplint src/ --language javascript,typescript
# Case-insensitive language names
deeplint src/ --language Python,JavaScript
This is useful when:
- You want to focus on specific languages in a polyglot codebase
- You need faster scans by limiting scope
- You're debugging language-specific issues
๐ค Why DeepLint Exists
Traditional linters catch style and syntax issues. But AI-generated code introduces new failure patterns they weren't designed to detect:
- Hallucinated imports - packages and functions that don't exist
- Cross-language leakage -
.push(),.equals(),.lengthin Python - Placeholder code -
pass,TODO, functions that do nothing - Confident wrongness - code that looks right but fails at runtime
DeepLint targets these AI-specific patterns that escape Pylint, Flake8, ESLint, and code review.
Frontend-Focused Detection
Building on insights from KarpeSlop, DeepLint includes 30 TypeScript/JavaScript patterns specifically designed for modern frontend frameworks:
- React Hooks Anti-patterns -
useEffectwith derived state, empty deps, stale closures - TypeScript Type Safety -
anytype abuse, unsafe assertions, missing generics - Hallucinated Imports - React APIs from wrong packages (e.g.,
useRouterfrom 'react') - Frontend-Specific Issues - IIFE wrappers, nested ternaries, magic CSS values
๐ฏ What It Catches
The Three Axes of AI Slop
| Axis | What It Detects | Examples |
|---|---|---|
| ๐ข Noise | Debug artifacts, redundant comments | print(), # increment x above x += 1 |
| ๐คฅ Lies | Hallucinations, placeholders | def process(): pass, mutable defaults |
| ๐ Soul | Over-engineering, bad style | God functions, deep nesting, hedging comments |
| ๐๏ธ Structure | Anti-patterns | Bare except, star imports, single-method classes |
๐ฅ What You Put In
# Automatic language detection - scans all supported languages
deeplint .
# Scan a specific directory
deeplint src/
# Scan specific files
deeplint app.py utils.py
# Language-specific scanning
deeplint src/ --language python # Python only
deeplint src/ --language javascript,typescript # JS/TS only
# Only high severity issues
deeplint --severity high
# CI mode - exit 1 if issues found
deeplint --ci --max-score 50
# Export JSON report
deeplint --output report.json
๐ค What You Get Out
| Output | Description |
|---|---|
| ๐ฏ Issues by Severity | Critical, High, Medium, Low |
| ๐ Slop Score | Points breakdown by axis |
| ๐ Verdict | CLEAN / ACCEPTABLE / SLOPPY / DISASTER |
| ๐ JSON Report | Machine-readable for CI/CD |
๐ Pattern Examples
Critical Severity
# ๐จ mutable_default_arg - AI's favorite mistake
def process_items(items=[]): # Bug: shared state between calls
items.append(1)
return items
# โ
Fix: Use None and initialize inside
def process_items(items=None):
if items is None:
items = []
items.append(1)
return items
# ๐จ bare_except - Catches SystemExit, KeyboardInterrupt
try:
risky_operation()
except: # Bug: swallows Ctrl+C!
pass
# โ
Fix: Catch specific exceptions
try:
risky_operation()
except ValueError as e:
logger.error(f"Invalid value: {e}")
High Severity
# ๐จ pass_placeholder - AI gave up
def validate_email(email):
pass # TODO: implement
# ๐จ hedging_comment - AI uncertainty
x = calculate() # should work hopefully
TypeScript/React Patterns (KarpeSlop-Inspired)
// ๐จ hallucinated_react_import - AI hallucinating package locations
import { useRouter, Link } from 'react'; // Bug: These are from 'next/router' and 'next/link'
// โ
Fix: Import from correct packages
import { useRouter } from 'next/router';
import Link from 'next/link';
// ๐จ ts_any_type_usage - TypeScript type safety bypass
function processData(data: any): any { // Bug: Loses all type safety
return data.someProp;
}
// โ
Fix: Use proper types or unknown
function processData<T>(data: T): T {
return data;
}
// ๐จ js_useEffect_derived_state - React anti-pattern
useEffect(() => {
setDerived(name.toUpperCase()); // Bug: Unnecessary re-render
}, [name]);
// โ
Fix: Use useMemo for derived state
const derived = useMemo(() => name.toUpperCase(), [name]);
// ๐จ js_setState_in_loop - Multiple re-renders
for (let i = 0; i < items.length; i++) {
setTotal(total + items[i]); // Bug: Re-renders on each iteration
}
// โ
Fix: Batch the update
const newTotal = items.reduce((sum, item) => sum + item, 0);
setTotal(newTotal);
๐ฐ The Value
๐ Catch AI mistakes before they hit production
Why This Matters
| Problem | Impact | DeepLint Catches |
|---|---|---|
| Mutable defaults | Shared state bugs | โ Critical alert |
| Bare except | Swallows Ctrl+C | โ Critical alert |
| Placeholder functions | Runtime failures | โ High alert |
| Hallucinated imports | ImportError in prod | โ High alert |
| Wrong language patterns | JS/Java/Ruby/Go/C#/PHP in Python | โ High alert |
| Unused imports | Code bloat | โ Medium alert |
| Dead code | Maintenance burden | โ Medium alert |
| Copy-paste code | Maintenance nightmare | โ Medium alert |
Research Says
- 20% of AI package imports reference non-existent libraries โ DeepLint catches these
- LLMs leak patterns from other languages they were trained on โ DeepLint catches 100+ of these
- 66% of developers say AI code is "almost right" (the dangerous kind)
๐ ๏ธ CLI Commands
deeplint . # ๐ Scan current directory (auto-detect languages)
deeplint src/ tests/ # ๐ Scan multiple directories
# Language selection
deeplint --language python # ๐ Scan Python only
deeplint --language js,ts # ๐ Scan JavaScript & TypeScript
deeplint -l go # ๐ Scan Go only
# Severity & reporting
deeplint --severity high # โก Only critical/high issues
deeplint --lenient # ๐ฏ Same as --severity high
deeplint --strict # ๐ฌ Report everything
deeplint --ci # ๐ฆ Exit 1 if any issues
deeplint --max-score 50 # ๐ Exit 1 if score > 50
deeplint --output report.json # ๐ Export JSON report
# Filtering
deeplint --ignore "tests/*" # ๐ซ Exclude patterns
deeplint --disable magic_number # โญ๏ธ Skip specific checks
deeplint --version # ๐ Show version
โ Features
| Feature | Description | Status |
|---|---|---|
| ๐ Multi-Language Support | Python, JavaScript, TypeScript, Go | โ Auto-detection |
| ๐ Smart Detection | Automatic language identification | โ Done |
| ๐ฏ Manual Override | --language flag for specific languages |
โ Done |
| ๐คฅ Hallucinated Imports | Detect non-existent packages | โ Done |
| ๐ฆ Unused Imports | AST-based detection (Python) | โ Done |
| ๐ Dead Code | Unused functions/classes | โ Done |
| ๐ Duplicate Detection | Cross-file copy-paste | โ Done |
| ๐จ Rich Output | Colors and tables (optional) | โ Done |
| โ๏ธ Config Support | pyproject.toml configuration | โ Done |
Cross-Language Pattern Detection
LLMs are trained on code from many languages. When generating code, they sometimes produce patterns from other languages:
| Language | Example Mistakes | Correct Alternative |
|---|---|---|
| JavaScript | .push(), .length, .forEach() |
.append(), len(), for loop |
| Java | .equals(), .toString(), .isEmpty() |
==, str(), not obj |
| Ruby | .each, .nil?, .first, .last |
for loop, is None, [0], [-1] |
| Go | fmt.Println(), nil |
print(), None |
| C# | .Length, .Count, .ToLower() |
len(), len(), .lower() |
| PHP | strlen(), array_push(), explode() |
len(), .append(), .split() |
๐ซ What DeepLint Is Not
DeepLint does not replace:
- Human code review
- Traditional linters (Pylint, Flake8, Ruff)
- Type checkers (mypy, pyright)
- Security scanners (Bandit, Semgrep)
It complements them by catching patterns these tools missโpatterns uniquely common in AI-generated code.
๐ฆ Installation
# Install from PyPI
pip install deeplint
# With colored output (recommended)
pip install deeplint[rich]
# With all optional features
pip install deeplint[all]
# Or install from source for development
git clone https://github.com/del-zhenwu/deeplint.git
cd deeplint
pip install -e ".[dev]"
โ๏ธ Configuration
Configure via pyproject.toml:
[tool.deeplint]
ignore = ["tests/*", "migrations/*"]
disable = ["magic_number", "debug_print"]
severity = "medium"
max-score = 100
ci = false
format = "detailed" # or "compact" or "json"
๐งช Development & Testing
Quick Start for Contributors
# Clone the repository
git clone https://github.com/del-zhenwu/deeplint.git
cd deeplint
# Install in development mode with all dependencies
pip install -e ".[dev]"
# Run all tests (114+ tests should pass)
pytest tests/ -v
# Run tests with coverage report
pytest tests/ --cov=src/deeplint --cov-report=term-missing
# Run tests for a specific language
pytest tests/test_python_patterns.py -v
pytest tests/test_go_patterns.py -v
pytest tests/test_js_patterns.py -v
pytest tests/test_karpeslop_patterns.py -v
Test Structure
DeepLint has comprehensive test coverage for all supported languages:
| Test File | Description | Coverage |
|---|---|---|
test_python_patterns.py |
Python-specific patterns (noise, hallucinations, style, structure) | 15 tests |
test_go_patterns.py |
Go language support and patterns | 7 tests |
test_js_patterns.py |
JavaScript/TypeScript basic patterns | 11 tests |
test_karpeslop_patterns.py |
Advanced JS/TS/React patterns | 22 tests |
test_language_detector.py |
Multi-language detection | 12 tests |
test_cli_multi_language.py |
CLI with language filtering | 12 tests |
test_patterns/ |
Core pattern detection (hallucinations, structure) | 20 tests |
corpus/ |
Integration tests with real-world code samples | 6 tests |
Running Linters and Type Checkers
# Format check with Ruff
ruff check src/ tests/
ruff format --check src/ tests/
# Format check with Black and isort
black --check src/ tests/
isort --check-only src/ tests/
# Type checking with mypy
mypy src/deeplint
# Security audit
pip-audit
CI/CD Workflows
DeepLint uses GitHub Actions for continuous integration and deployment:
Test Workflow (.github/workflows/ci.yml)
Runs automatically on every push and pull request to main:
- Test Matrix: Python 3.9, 3.10, 3.11, 3.12
- Linting: Ruff, Black, isort format checks
- Type Checking: mypy strict mode
- Security: pip-audit dependency scanning
- Self-Check: Runs DeepLint on itself
- Coverage: Uploads to Codecov (82%+ coverage)
Publish Workflow (.github/workflows/publish.yml)
Deploys to PyPI automatically on GitHub releases:
- Build: Creates source distribution and wheel
- Publish: Uses trusted publishing (OIDC) to PyPI
- Trigger: GitHub release creation or manual workflow dispatch
Adding New Tests
When adding new patterns or features, follow these guidelines:
- Create focused test files for each language (see
test_python_patterns.py) - Test both positive and negative cases (detection and non-detection)
- Use descriptive test names that explain what's being tested
- Add fixtures in
tests/fixtures/for complex test cases - Update test counts in README when adding new tests
Test Fixtures
tests/
โโโ fixtures/
โ โโโ go/ # Go test files with known issues
โ โโโ js/ # JavaScript/TypeScript test files
โ โโโ .gitkeep
โโโ corpus/
โโโ true_positives/ # Code that should trigger warnings
โโโ false_positives/ # Valid code that shouldn't trigger warnings
Development Resources
- Pattern Implementation Guide: See AGENTS.md for coding conventions
- AI Assistant Integration: Check Skills for tool descriptions
- Pattern Categories: Noise (Axis 1), Quality/Hallucinations (Axis 2), Style (Axis 3), Structure
Making a Contribution
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Add tests for your changes
- Ensure all tests pass:
pytest tests/ -v - Run linters:
ruff check src/ tests/ - Submit a pull request
๐ License
MIT
๐ Acknowledgments
Inspiration
- KarpeSlop - The original AI Slop Linter for TypeScript
- Andrej Karpathy's commentary on AI-generated code quality
Research
- Counterfeit Code - MIT research on "looks right but doesn't work" patterns
- Package Hallucinations - USENIX study on hallucinated dependencies
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 deeplint-0.0.2.tar.gz.
File metadata
- Download URL: deeplint-0.0.2.tar.gz
- Upload date:
- Size: 62.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b21a8cae2da4ee45f9c127bc7edf000c2c5f81300a3c7193e39bf1891ad6aee
|
|
| MD5 |
077af1b7b2ce6eb38c1b7210d8d9e38f
|
|
| BLAKE2b-256 |
f4ac058f67ec72d26eee31aef6900bfd7e8fdaffb3fd561be6a301af8f0f7155
|
File details
Details for the file deeplint-0.0.2-py3-none-any.whl.
File metadata
- Download URL: deeplint-0.0.2-py3-none-any.whl
- Upload date:
- Size: 43.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.25
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b626121e22ef8f833616a7c5e56fbffd0b2d0ce732ab3038c619267da4db30e1
|
|
| MD5 |
afd0b5a502270e5cc689e87beccdee85
|
|
| BLAKE2b-256 |
d3d5cd2dcf5d15dd49a6572d76ce380002ec456b5abaeea12aedf3b6307ffcdc
|