slopcop
A fast, opinionated Python linter written in Rust that catches anti-patterns commonly produced by language models.
Built on tree-sitter for AST-correct analysis — no false positives on strings or comments.
Install
pip install slopcop
# or
uv tool install slopcop
Or from source:
cargo install --git https://github.com/cm2435/slopcop
Usage
# Lint directories (walks recursively for .py files)
slopcop src/ tests/
# Lint specific files
slopcop path/to/file.py
# Quiet mode (exit code only, for CI)
slopcop --quiet src/
# JSON output
slopcop --format json src/
# Only fail on errors, treat warnings as non-blocking
slopcop --warn-only src/
Exit codes: 0 = clean, 1 = violations found, 2 = fatal error.
Rules
All rules are enabled by default. Disable per-project via pyproject.toml.
| Rule | What it catches |
|---|---|
no-hasattr-getattr |
hasattr() and getattr() calls — use explicit attribute checks or protocols |
guarded-function-import |
Function-scope import without a comment on the line above explaining why |
no-future-annotations |
from __future__ import annotations — unnecessary on 3.13+ and breaks runtime inspection |
no-dataclass |
@dataclass usage and dataclasses imports — use Pydantic or project-standard models |
no-bare-except |
except: without a type — catches everything including KeyboardInterrupt |
no-broad-except |
except Exception: / except BaseException: — too broad, catch specific types |
no-pass-except |
except blocks containing only pass — silently swallows exceptions |
no-nested-try |
Nested try blocks — extract the inner try into a separate function |
no-async-from-sync |
asyncio.run() / get_event_loop() / run_until_complete() / ensure_future() / create_task() inside a sync function — make the caller async def or move the sync/async boundary to an entrypoint |
no-print |
print() calls — use structured logging |
no-todo-comment |
TODO, FIXME, HACK, XXX comments — resolve or track in an issue |
no-assert |
assert in production code — use if not ...: raise ValueError(...) instead |
no-typing-any |
Any in type annotations — use specific types or protocols |
no-str-empty-default |
str = "" defaults on params and model fields — use str | None = None or make required |
no-boolean-positional |
Bare True/False as positional arguments — use keyword arguments for clarity |
no-redundant-none-check |
x is None when x is typed as non-optional |
no-or-empty-coalesce |
obj.attr or {} / or [] / or "" etc. — check is None explicitly or remove dead fallback |
max-function-params |
Functions with more than 8 parameters (configurable) — group into a model |
Configuration
Add [tool.slopcop] to your pyproject.toml:
[tool.slopcop]
exclude = [
"no-dataclass", # this project uses dataclasses
"no-print", # CLI app, print is fine
]
Per-file ignores
Disable rules for specific file patterns:
[tool.slopcop.per-file-ignores]
"tests/**" = ["no-print"]
"**/cli/**" = ["no-print"]
Rule-specific config
[tool.slopcop.rules.max-function-params]
max = 10
slopcop walks upward from the target path to find the nearest pyproject.toml.
Inline suppression
x = getattr(obj, name) # slopcop: ignore
x = getattr(obj, name) # slopcop: ignore[no-hasattr-getattr]
x = getattr(obj, name) # slopcop: ignore[no-hasattr-getattr, no-print]
Adding to CI
# GitHub Actions
- run: pip install slopcop
- run: slopcop src/ tests/
Development
cargo test # run the test suite
cargo run -- src/ # run locally
License
MIT
Metadata
Release files for slopcop 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| slopcop-0.1.1.tar.gz | 40.5 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| slopcop-0.1.1-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| slopcop-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| slopcop-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| slopcop-0.1.1-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| slopcop-0.1.1-py3-none-macosx_10_12_x86_64.whl | Python 3 | none | macOS 10.12+ x86-64 | Details |
Total release size: 8.3 MB
Release files / slopcop-0.1.1.tar.gz
| Download URL | slopcop-0.1.1.tar.gz |
|---|---|
| Size | 40.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8698297781af5d46e94557a17c0bb61f70f5186ec99b9478b3f07e3fffd5a9ee
|
|
BLAKE2b-256 checksum How to use checksums |
cbb253cd4ba6b13ff42214d82ff47d4464c1fae63ed496d7d1352e1b8aa74f86
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.13.1
|
Release files / slopcop-0.1.1-py3-none-win_amd64.whl
| Download URL | slopcop-0.1.1-py3-none-win_amd64.whl |
|---|---|
| Size | 1.4 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
b069a522d583ea082a4c6b05341483557dc8d276fce1068e681b81fe97f8f669
|
|
BLAKE2b-256 checksum How to use checksums |
e417434f028f789a86a7c807c5131ec286b98c001b39159fcbe5979a36568ee4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.13.1
|
Release files / slopcop-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | slopcop-0.1.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
b91c0ecfde8e87d6247bdd0eabacbae0b92cad6b996725f1023378623cffae53
|
|
BLAKE2b-256 checksum How to use checksums |
18bf6408ceeafdc9759ac353c9ebf177ff68754f28f93ea6d42172b6a5935e83
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.13.1
|
Release files / slopcop-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | slopcop-0.1.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 1.7 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
ee9e512ff1b6008741472481a183ed56e7993c55ab73b72beaa7eccb4576e1bd
|
|
BLAKE2b-256 checksum How to use checksums |
4af529837ba662834c38954de467bfc54cd3c99b38667ff8424850a536e5f8e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.13.1
|
Release files / slopcop-0.1.1-py3-none-macosx_11_0_arm64.whl
| Download URL | slopcop-0.1.1-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 1.6 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
7f047907bc98a87c9c85bda5ba39bdda2b0f4013f82765a1a73357134bbe1086
|
|
BLAKE2b-256 checksum How to use checksums |
0b9e4d17525f48a487a60dfb5f028bdff8103a0c98d711c7dc17cf1b980660f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.13.1
|
Release files / slopcop-0.1.1-py3-none-macosx_10_12_x86_64.whl
| Download URL | slopcop-0.1.1-py3-none-macosx_10_12_x86_64.whl |
|---|---|
| Size | 1.7 MB |
| Tags | Python 3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
25d8bdf1ac5f52f32123cf32db298e9f95e68d1dc637cdf2ccb9f0aec2fd3a57
|
|
BLAKE2b-256 checksum How to use checksums |
e47b2933a6205f72ccbdf94c93c878122b6a0e91eb0751d2157658a66224d290
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
maturin/1.13.1
|