tenequm/claude-plugins/python-dev
Claude Code and agent skill by tenequm/claude-plugins
- community
- ext:[{"type":"hook","description":"Pre/post lifecycle hooks"}]
Checking that the SKILL.md file is still in the repository.
Opinionated Python development setup with uv, ty, ruff, pytest, lefthook, and just. Use when creating a new Python project, writing or fixing pyproject.toml, or configuring linting, formatting, type checking, testing, git hooks, or CI.
Install
npx vskill@latest install tenequm/claude-plugins/python-devSemi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard
SKILL.md
Python Development Setup
Opinionated, production-ready Python development stack. No choices to make - just use this.
When to Use
- Starting a new Python project
- Modernizing an existing project (migrating from pip/poetry/mypy/black/flake8)
- Setting up linting, formatting, type checking, or testing
- Creating a Justfile for project commands
- Configuring pyproject.toml as the single source of truth
The Stack
| Tool | Role | Replaces | |
|---|---|---|---|
| uv 0.12+ | Package manager, Python versions, runner | pip, poetry, pyenv, virtualenv | |
| ty (beta) | Type checker (Astral, Rust) | mypy, pyright | |
| ruff | Linter + formatter | flake8, black, isort, pyupgrade | |
| pytest | Testing | unittest | |
| just | Command runner | make | |
| lefthook 2.1+ | Git hooks (single binary, parallel) | pre-commit |
Note on ty: ty is in beta (0.0.x) - no stable API, and inference can change between anytwo versions, so pin it. Pydantic is no longer a fair complaint: ty has shipped a dedicatedlibrary-support track for it since 0.0.57 (constructors,model_config,BaseSettings,RootModel, strict vs lax). Django and SQLAlchemy still have no such support and remain thelikely source of false positives. Before swapping the whole checker, reach for[tool.ty.analysis] replace-imports-with-any = ["sqlalchemy.**"], which silences one baddependency instead of all of them. If you do need rock-solid checking today, swaptyforpyrightand keep the rest of the stack unchanged.
Quick Start: New Project
pyproject.toml Template
This is the single config file. Copy this and adjust [project] fields.
asyncio_default_fixture_loop_scope is intentionally unset above; pytest-asyncio warns about that on every run. Set it to "function" to silence the warning and lock the behavior in.
Justfile Template
Lefthook Config
Lefthook replaces pre-commit here for the same reason go-dev uses it: one binary, hooks in parallel, and - the reason that matters most in Python - the hook runs your ruff from uv.lock instead of a second copy pinned separately in a hook config. It installs from PyPI as a platform wheel, so uv add --dev lefthook is the whole install; no Go toolchain.
`--force-exclude` is mandatory, not decoration. Ruff ignores its own exclude config for paths passed explicitly on the command line, and {staged_files} passes paths explicitly. Without the flag a staged file under [tool.ruff] exclude gets linted anyway - verified: with the flag ruff check --force-exclude src/generated/gen.py reports All checks passed, without it the same call finds errors. pre-commit users never met this because ruff-pre-commit bakes the flag into its hook entry; on lefthook it is yours to remember.
`stage_fixed: true` is the ergonomic win over pre-commit. pre-commit fails the commit when a hook rewrites a file and makes you re-stage and re-run. lefthook re-runs git add on the fixed files and the commit proceeds. Since 2.1.12 a failing git add fails the hook, so a fix can never slip through unstaged.
Ordering is why `piped: true` is set. Ruff's own guidance is lint-with-fix before format, because --fix emits code that then needs reformatting. Piped also means the guards run first and a leaked key stops the commit before any tool burns time.
Notes worth knowing before editing this config:
- A `glob` silently skips the whole job when nothing matches - and that is a gate hole, not
a convenience. A job with a glob but no {staged_files} in its run is still filtered by that glob, so ty with glob: "*.{py,pyi}" is skipped on a commit that changes only pyproject.toml - exactly where [tool.ty] and your dependency pins live. Verified: such a commit prints ty (skip) no matching staged files and records with no type check at all. Any job that checks the project rather than the staged files must carry no glob. The ruff jobs above keep theirs because they act on {staged_files} and nothing else.
- `
matches one or more directories, not zero or more.**glob: "src/**/.py"` does not*
match src/main.py. Use glob_matcher: doublestar for the behavior every other tool has.
- Config location is load-bearing. lefthook auto-discovers only the repo root or
.config/
(the latter since v1.11.12). Anywhere else and commits silently stop running hooks, because git invokes the hook directly and no task-runner recipe can intercept that.
- Never put a mutating job in `pre-push`. A job that rewrites files there fails the push and
leaves you with uncommitted edits. --fix belongs in pre-commit, where stage_fixed handles it; pre-push stays read-only, like the pytest job above.
- `file_types` is available when a glob is too blunt -
text,binary,executable,
symlink, and MIME types including text/x-python.
- Deleted files drop out of `{staged_files}` and the job is skipped with
no files for inspection, so a deletion-only commit does not error.
- Unstaged changes are hidden for the hook's duration and restored after, so the gate judges
what you are actually committing, not your dirty worktree. Verified on 2.1.12: staging a clean file while leaving a broken copy unstaged passes, commits the clean version, and gives the unstaged edit back.
- lefthook is dormant until installed.
assert_lefthook_installed: trueturns a missing
binary into a failure instead of hooks silently not firing. Make lefthook install part of onboarding.
lefthook validatecatches a malformed config in CI;lefthook dumpprints the merged
effective config. A gitignored lefthook-local.yml lets one developer add or skip jobs without imposing it on teammates.
What you give up by leaving pre-commit. The pre-commit-hooks library has no lefthook equivalent. Three of its hooks were worth keeping and are hand-rolled in the guards group above: detect-private-key, check-merge-conflict and check-added-large-files. Four are not replicated - check-yaml, check-toml, end-of-file-fixer, trailing-whitespace and mixed-line-ending: ruff's formatter already handles whitespace and final newlines for Python files, and the rest only ever covered non-Python files. Add them back as shell jobs if your repo carries a lot of hand-edited YAML. You also lose pre-commit autoupdate and hosted pre-commit.ci - in exchange, uv lock --upgrade is now the one place tool versions move.
Project Structure
Always use src layout:
Daily Workflow
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/python-dev/SKILL.md
Popularity
- Repository stars
- 18
- 7-day trend score
- 15
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 17 Mar 2026, 7 months ago.
Extension points
hookPre/post lifecycle hooks
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/tenequm/claude-plugins/python-dev)