Python AI Slop Detector - Find over-engineering, hallucinations, and dead code
Project description
๐ท Sloppylint
Detect AI-generated code anti-patterns in your Python codebase.
Catches AI-specific anti-patterns that traditional linters miss
โก Quick Start
pip install sloppylint
sloppylint .
# 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:
#
# SLOPPY 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
๐ค Why Sloppylint 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
Sloppylint targets these AI-specific patterns that escape Pylint, Flake8, and code review.
๐ฏ 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
# Scan a directory
sloppylint src/
# Scan specific files
sloppylint app.py utils.py
# Only high severity issues
sloppylint --severity high
# CI mode - exit 1 if issues found
sloppylint --ci --max-score 50
# Export JSON report
sloppylint --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
๐ฐ The Value
๐ Catch AI mistakes before they hit production
Why This Matters
| Problem | Impact | Sloppylint 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 โ sloppylint catches these
- LLMs leak patterns from other languages they were trained on โ sloppylint catches 100+ of these
- 66% of developers say AI code is "almost right" (the dangerous kind)
๐ ๏ธ CLI Commands
sloppylint . # ๐ Scan current directory
sloppylint src/ tests/ # ๐ Scan multiple directories
sloppylint --severity high # โก Only critical/high issues
sloppylint --lenient # ๐ฏ Same as --severity high
sloppylint --strict # ๐ฌ Report everything
sloppylint --ci # ๐ฆ Exit 1 if any issues
sloppylint --max-score 50 # ๐ Exit 1 if score > 50
sloppylint --output report.json # ๐ Export JSON report
sloppylint --ignore "tests/*" # ๐ซ Exclude patterns
sloppylint --disable magic_number # โญ๏ธ Skip specific checks
sloppylint --version # ๐ Show version
โ Features
| Feature | Description | Status |
|---|---|---|
| ๐ Multi-Language Detection | Catches patterns from JS, Java, Ruby, Go, C#, PHP | โ 100+ patterns |
| ๐ Hallucinated Imports | Detect non-existent packages | โ Done |
| ๐ฆ Unused Imports | AST-based detection | โ 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 |
Language Patterns Detected
LLMs are trained on code from many languages. When generating Python, they sometimes produce patterns from other languages:
| Language | Example Mistakes | Python Fix |
|---|---|---|
| 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 Sloppylint Is Not
Sloppylint 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 sloppylint
# With colored output (recommended)
pip install sloppylint[rich]
# With all optional features
pip install sloppylint[all]
# Or install from source for development
git clone https://github.com/rsionnach/sloppylint.git
cd sloppylint
pip install -e ".[dev]"
โ๏ธ Configuration
Configure via pyproject.toml:
[tool.sloppy]
ignore = ["tests/*", "migrations/*"]
disable = ["magic_number", "debug_print"]
severity = "medium"
max-score = 100
ci = false
format = "detailed" # or "compact" or "json"
๐ค Contributing
git clone https://github.com/rsionnach/sloppylint.git
cd sloppylint
pip install -e ".[dev]"
pytest tests/ -v # 62 tests should pass
See AGENTS.md for coding conventions and pattern implementation guide.
๐ 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 sloppylint-0.1.5.tar.gz.
File metadata
- Download URL: sloppylint-0.1.5.tar.gz
- Upload date:
- Size: 41.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e4785434d11b1579169500fe8cd66487f8b0137c389f7e88d31a05610916ea8
|
|
| MD5 |
cb647c0ef135386a7a600897befa75f8
|
|
| BLAKE2b-256 |
76fa027bd56880418fcc933ecd2ddb98c98a511cd1d2d7b53196b21f6190790d
|
Provenance
The following attestation bundles were made for sloppylint-0.1.5.tar.gz:
Publisher:
publish.yml on rsionnach/sloppylint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sloppylint-0.1.5.tar.gz -
Subject digest:
8e4785434d11b1579169500fe8cd66487f8b0137c389f7e88d31a05610916ea8 - Sigstore transparency entry: 746654902
- Sigstore integration time:
-
Permalink:
rsionnach/sloppylint@278a1c9de06e7879f58d17ae9e4f83fbd8f46f83 -
Branch / Tag:
refs/tags/v0.1.5 - Owner: https://github.com/rsionnach
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@278a1c9de06e7879f58d17ae9e4f83fbd8f46f83 -
Trigger Event:
release
-
Statement type:
File details
Details for the file sloppylint-0.1.5-py3-none-any.whl.
File metadata
- Download URL: sloppylint-0.1.5-py3-none-any.whl
- Upload date:
- Size: 38.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4222f79038391c636f99a5559b5f95c53d1fa783ff256b3f3a1919b32ab1f889
|
|
| MD5 |
0d549420e2644a2df10526e248d25c7d
|
|
| BLAKE2b-256 |
e43a657ee60cc0c570ff48c665f45b3cfddeccddf15ac10ff3bcfc1c0a39f739
|
Provenance
The following attestation bundles were made for sloppylint-0.1.5-py3-none-any.whl:
Publisher:
publish.yml on rsionnach/sloppylint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sloppylint-0.1.5-py3-none-any.whl -
Subject digest:
4222f79038391c636f99a5559b5f95c53d1fa783ff256b3f3a1919b32ab1f889 - Sigstore transparency entry: 746654921
- Sigstore integration time:
-
Permalink:
rsionnach/sloppylint@278a1c9de06e7879f58d17ae9e4f83fbd8f46f83 -
Branch / Tag:
refs/tags/v0.1.5 - Owner: https://github.com/rsionnach
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@278a1c9de06e7879f58d17ae9e4f83fbd8f46f83 -
Trigger Event:
release
-
Statement type: