setting-up-python-libraries
Skill111 starsChanged 18 days agoMITView on GitHub
Sets up professional Python library projects with modern tooling (pyproject.toml, uv, ruff, pytest, pre-commit, GitHub Actions). Use when creating new Python libraries, modernizing existing projects to pyproject.toml, configuring linting/testing/CI, or setting up Makefiles and pre-commit hooks.
In this repository41 other files it gives its agents.
- building-accessible-interfacesSkill
- wiring-application-configSkill
- shipping-build-artifactsSkill
- permissioning-ci-workflowsSkill
- concurrent-branchesSkill
- shipping-across-surfacesSkill
- writing-defect-reportsSkill
- reporting-derived-metricsSkill
- guarding-destructive-operationsSkill
- running-github-actions-efficientlySkill
- keeping-git-repos-cleanSkill
- designing-interaction-statesSkill
- designing-marketing-pagesSkill
- rendering-untrusted-contentSkill
- reproducing-ci-locallySkill
- running-resumable-sync-jobsSkill
- normalizing-text-for-measurementSkill
- calibrating-thresholds-and-baselinesSkill
- designing-interfacesSkill
- verifying-external-behaviorSkill
- building-go-projectsSkill
- building-browser-extensionsSkill
- designing-python-apisSkill
- building-python-clisSkill
- improving-python-code-qualitySkill
- building-python-communitiesSkill
- documenting-python-librariesSkill
- deferring-heavy-dependenciesSkill
- reviewing-python-librariesSkill
- building-llm-backed-featuresSkill
- building-python-mcp-serversSkill
- packaging-python-librariesSkill
- optimizing-python-performanceSkill
- managing-python-releasesSkill
- auditing-python-securitySkill
- testing-python-librariesSkill
- building-python-web-appsSkill
- building-rust-cratesSkill
- building-scala-projectsSkill
- building-swift-appsSkill
- shipping-swift-appsSkill
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 10
Create a new library with this structure:
- Very specific: line 24
Use src/ layout to prevent accidental imports of development code.
- Very specific: line 80
Put --fix only in format and the pre-commit hook.
- Distinctive: line 130
Create a new project structure:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Python Library Project Setup
Quick Start
Create a new library with this structure:
my-library/
├── src/my_library/
│ ├── __init__.py
│ └── py.typed
├── tests/
├── pyproject.toml
├── Makefile
├── .pre-commit-config.yaml
└── .github/workflows/ci.ymlUse src/ layout to prevent accidental imports of development code.
Core Configuration
For complete templates, see:
- PYPROJECT.md - Full pyproject.toml with all tool configs
- CI.md - GitHub Actions and pre-commit setup
- MAKEFILE.md - Makefile automation patterns
Minimal pyproject.toml
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "my-library"
version = "0.1.0"
description = "What it does"
readme = "README.md"
requires-python = ">=3.10"
license = "MIT" # SPDX expression
dependencies = []
[project.optional-dependencies]
dev = ["pytest>=7.0", "ruff>=0.1", "mypy>=1.0"]
[tool.setuptools.packages.find]
where = ["src"]Essential Commands
# Setup
uv sync --extra dev
pre-commit install
# Daily workflow
ruff check src tests # Lint
ruff format src tests # Format
pytest # Test
mypy src # Type checkKeep local checks identical to CI
The most common CI failure is not a bug — it's a check that passes locally but fails in CI (or vice versa) because the two run different commands. Two rules prevent an entire class of "green locally, red in CI" (and chronically-red base branch) problems:
1. make lint must be read-only — never --fix. A lint target that runs
ruff check --fix mutates your files and almost always exits 0, so pre-existing
violations silently sit on the branch while CI's read-only ruff check goes red.
Put --fix only in format and the pre-commit hook. make lint should run the
exact commands CI runs.
2. CI (and make lint) must check formatting too. ruff check and
ruff format are different tools: the linter passing says nothing about
formatting. Gate on both, or formatting drift ships / turns a branch red
unexpectedly:
ruff check src tests # lint rules
ruff format --check src tests # formatting — REQUIRED, not implied by ruff checkLint the same paths in the Makefile and CI (add examples/, docs/, etc. if
they contain Python) — a narrower local scope lets violations accumulate in dirs
CI checks. Configure ruff under [tool.ruff.lint] (not the deprecated top-level
select/ignore), and keep requires-python and [tool.ruff] target-version
in sync so ruff doesn't apply upgrade rules for a version you don't support.
For coverage, prefer running pytest --cov with a terminal report
(--cov-report=term-missing) in the CI log over uploading to a third-party
service — no external account, token, or network dependency in the gate.
Key Decisions
| Choice | Recommendation | Why |
| Layout | src/ | Catches packaging bugs early |
| Build backend | setuptools | Mature, broad compatibility |
| Linter | ruff | Fast, replaces flake8+isort+black |
| Python range | >=3.10 | Don't pin exact versions |
| Dependencies | Minimal | Move optional deps to extras |
Checklist
Project Setup:
- [ ] src/ layout with py.typed marker
- [ ] pyproject.toml (not setup.py)
- [ ] Makefile with dev/test/lint/format (lint read-only, no --fix)
- [ ] `make lint` runs the exact `ruff check` + `ruff format --check` CI runs
- [ ] Build-gating tools pinned (linter, formatter, toolchain, test runner) so upstream releases don't flip green/red on unrelated PRs
- [ ] .pre-commit-config.yaml
- [ ] .github/workflows/ci.yml
- [ ] README.md, LICENSE, CHANGELOG.md
- [ ] .gitignoreHelper Script
Create a new project structure:
python scripts/create_project.py my-library --author "Name" --license MIT--license takes an SPDX identifier (default MIT); a LICENSE file is generated for MIT and BSD-3-Clause.
Learn More
This skill is based on the Guide to Developing High-Quality Python Libraries by Will McGinnis. See these posts for deeper coverage:
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

