What are your favourite pre-commit hooks and why?
Add `ty` to `.pre-commit-config.yaml`
Ultra-Strict Python Template v3 — now with pre-commit automation
What are your pre-commit hooks?
How do I run mypy or ty as a pre-commit hook?
How do I run pre-commit hooks in CI?
How do I configure Ruff as a pre-commit hook?
Just getting started with pre-commit and I think it's awesome. Looking to find out what other code automation tools people are using. Let me know what works for you and why. Thanks!
I rebuilt my strict Python scaffold to be cleaner, stricter, and easier to drop into projects.
pystrict-strict-python
A TypeScript-style --strict experience for Python using:
uvruffbasedpyrightpre-commit
What’s in v3?
Single
pyproject.tomlas the source of truthStricter typing defaults (no implicit Any, explicit None, unused symbols = errors)
Aggressive lint/format rules via ruff
pytest + coverage (80% required)
Skylos for dead-code detection (better than Vulture)
Optional Pandera rules
Anti-LLM code smell checks
NEW: pre-commit automation
On commit:
ruff format+ auto-fix lint
On push:
full lint validation + strict basedpyright check
Setup:
uv run pre-commit install uv run pre-commit install --hook-type pre-push uv run pre-commit autoupdate
Why?
To get fast feedback locally and block bad pushes before CI.
Repo
👉 GitHub link here
PyStrict Development Log: Journey to Maximum Strictness
Week 1 (6 weeks ago) - Foundation
Day 1: Initial Commit
7d01a2b - first commit
Started with the core concept: Python strictness equivalent to TypeScript's --strict mode.
Day 1-2: Type Checking Evolution
2393d49 - feat: migrate from pyright to basedpyright with stricter error-level checking
Migrated from
pyrighttobasedpyrightfor enhanced strictnessEnabled error-level checking instead of warnings
Target: eliminate all implicit
Anytypes
Day 2: Documentation & Standards
84eb424 - docs: add comprehensive README with template usage instructions accd12e - fix: rename pyproyect.toml to pyproject.toml
Established project philosophy: production-grade quality from day one
Fixed typo in config filename (early iteration pain 😅)
Documented the "ultra-strict" approach
Day 3: Tooling Refinement
1ab6a8a - style: normalize indentation in dev dependencies ba7448b - feat: add BLE rule and optional Pandera configuration
Added
BLE(flake8-blind-except) rule - no more bareexcept:blocksIntroduced Pandera for DataFrame schema validation (optional)
Normalized tooling configuration for consistency
Day 4: Dead Code Detection
fe34b82 - chore: add .gitignore and uv.lock for dependency management e7bd14b - refactor: replace vulture with skylos for dead code detection
Swapped
vultureforskylos- better accuracy, fewer false positivesLocked dependencies with uv.lock for reproducible builds
Week 2 (6 weeks ago) - Anti-Slop Measures
62ff0bd - feat: add comprehensive anti-LLM-slop rules and documentation
Major milestone: Implemented systematic defenses against AI-generated code bloat:
Max cyclomatic complexity: 10
Max nested blocks: 3
Mandatory Pydantic models for all I/O
Boolean trap detection (FBT rules)
Comprehensive documentation on avoiding over-engineering
This became PyStrict's signature feature - actively fighting verbose, over-commented LLM output.
Week 3 (6 weeks ago) - Workflow Optimization
8190f81 - feat: reorder quality checks to run radon before skylos 1d34ce4 - feat: treat pytest warnings as errors to catch deprecations early
Optimized quality check order: complexity analysis → dead code detection
Made pytest warnings fatal - catch deprecations before they break production
Philosophy: fail fast, fail early, fix immediately
Week 6 (3 weeks ago) - Automation Phase
d4195e8 - feat: add pre-commit to dev dependencies f872295 - feat: update ruff pre-commit hook to v0.14.8 and add setup instructions
Integrated pre-commit hooks for automated quality gates
Updated to latest Ruff version (v0.14.8)
Added comprehensive setup documentation for new contributors
Week 7 (1 week ago) - Runtime Validation
ca73a67 - feat: add ty for runtime type checking to quality workflow
Added
tyfor runtime type validationBridge the gap: static type checking (basedpyright) + runtime validation (ty)
Catch type errors in production, not just in IDE
27/12/25 - Performance Revolution
[current] - feat: migrate from pre-commit to prek for 3x faster execution
The Problem: Running 7+ quality tools (ruff, basedpyright, skylos, radon, ty, pytest) on every commit was getting slow.
The Solution: Migrated to prek - Rust-based pre-commit alternative.
Technical Changes:
pyproject.toml: Replaced
pre-commitdependency withprek==0.2.25.pre-commit-config.yaml: Updated autoupdate command reference
README.md: Updated all installation and usage commands
Performance Gains:
3x faster hook execution via parallel processing
50% less disk space with shared toolchain management
Native
uvintegration (we were already usinguv)Zero config changes - 100% backward compatible
Why It Matters: With PyStrict's aggressive quality checks, every commit triggers:
Ruff format
Ruff lint (commit)
Ruff lint (push)
basedpyright type check
Radon complexity analysis
Skylos dead code detection
ty runtime validation
pytest with 80% coverage requirement
Prek's priority-based parallel execution turns sequential pain into concurrent speed.
Architecture Evolution
Week 1: Foundation (Type safety + Linting) Week 2: Anti-Slop (Complexity limits + Best practices) Week 3: Workflow (Automation + CI/CD readiness) Week 7: Runtime (Bridge static/dynamic checking) Today: Performance (Parallel execution + Native tooling)
Key Metrics
Strictness level: TypeScript
--strictequivalentQuality tools: 7 integrated tools
Coverage requirement: 80% minimum
Hook execution: 3x faster with prek
Configuration: Single pyproject.toml source of truth
Philosophy
Every change follows one principle: Make bad code impossible to write, not just discouraged.
The prek migration maintains this - faster feedback loops mean developers catch issues sooner, making the strict workflow actually pleasant to use.
Hi folks!
I'm curious to know what pre-commit hooks you're using.
I start with linters and formatters.
Two weeks ago I shared copier-astral here and the response was incredible — thank you! The feedback helped me find and fix real bugs.
What's new since last post:
-
Fixed
github_usernamenot being set during installation -
Fixed
uv tool injectbug -
Fixed missing
tydependency in generated projects -
Replaced
pre-commitwithprek— a faster Rust-based alternative -
Added
pysentry-rsandsemgrepto scan for potential vulnerabilities -
Now at 100+ stars
Quick reminder — what it does:
Scaffolds a complete Python project with modern tooling pre-configured:
-
ruff for linting + formatting (replaces black, isort, flake8)
-
ty for type checking (Astral's new Rust-based type checker)
-
pytest + hatch for testing (including multi-version matrix)
-
MkDocs with Material theme + mkdocstrings
-
pre-commit hooks with prek
-
GitHub Actions CI/CD
-
Docker support
-
Typer CLI scaffold (optional)
-
git-cliff for auto-generated changelogs
Looking for contributors:
3 open issues if anyone wants to help out: https://github.com/ritwiktiwari/copier-astral/issues
Thanks again — happy to answer any questions!
Links:
-
GitHub: https://github.com/ritwiktiwari/copier-astral
-
Docs: https://ritwiktiwari.github.io/copier-astral/
-
Reddit: Previous Post