python-conventions-skills
CLAUDE.md2 starsChanged 6 months agoMITView on GitHub
Python conventions for modern (3.11+) projects. Apply to every .py, pyproject.toml, and requirements*.txt. Tradeoff: bias toward strict-but-modern defaults. For one-off scripts or legacy codebases (3.8-, untyped, old Django), use judgment. A new Python project starts with: License: MIT.
In this repository2 other files it gives its agents.
- .cursor/rules/python-conventions.mdcCursor rule
- python-conventionsSkill
The file
We split this CLAUDE.md into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 27
Never time.sleep() in async code — await asyncio.sleep() only
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md 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
CLAUDE.md
Python conventions for modern (3.11+) projects. Apply to every .py, pyproject.toml, and requirements*.txt.
Tradeoff: bias toward strict-but-modern defaults. For one-off scripts or legacy codebases (3.8-, untyped, old Django), use judgment.
Type discipline
- Type hints required on every function signature, public attribute, and return value
from __future__ import annotationsat top of files — gives forward-reference types and PEP 604 union (A | B) on older runtimes- Pydantic v2 for any external/IO model — never plain
dict[str, Any]at API boundaries TypedDictfor internal dict shapes that don't need validationLiteral["a", "b"]for string-literal enums (lighter thanenum.Enum)
Stdlib preferences
pathlib.Pathoveros.path— composable, type-safedataclasses(or Pydantic) over manually-written__init__for data containerssubprocess.run()overos.system— actual return-code handlingf-stringsover%or.format()— except for logging, where lazy formatting mattersmatchstatements (3.10+) for tagged-union dispatch — cleaner than chainedisinstance
Async
async defend-to-end — don't mix syncrequestsinto an async stack; usehttpxasyncio.gatherfor parallel;asyncio.TaskGroup(3.11+) for structured concurrency with proper cancellation- Never
time.sleep()in async code —await asyncio.sleep()only
Logging
structlogif available in the project; else stdlibloggingwith structured extras- Never
print()in library code — only allowed in CLIs / scripts where stdout is the deliverable - Lazy formatting:
logger.info("user %s logged in", user_id)notlogger.info(f"user {user_id}...")— avoids string interpolation when log level is filtered
Tooling defaults
rufffor lint + format (replacesblack+flake8+isort)mypy --strictfor type checking when the codebase tolerates itpytestwith fixtures over class-based setup/teardownuvoverpipfor new projects (faster, lockfile by default)
Anti-patterns
- Bare
except:clauses (catchesKeyboardInterrupt,SystemExit— almost never what you want) - Mutable default arguments (
def f(x=[]):— useNoneand assign inside) - Catching exception just to re-raise (
except Exception: raise— pointless) - Stringly-typed return contracts (return enum/Literal/dataclass, not arbitrary strings)
eval()/exec()on user inputfrom foo import *
Project setup
A new Python project starts with:
# pyproject.toml
[project]
name = "your-project"
version = "0.1.0"
requires-python = ">=3.11"
[tool.ruff]
target-version = "py311"
line-length = 100
[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP", "B", "C4", "SIM", "RET"]
ignore = ["E501"] # line length — ruff format handles it
[tool.mypy]
strict = true
python_version = "3.11"
[tool.pytest.ini_options]
testpaths = ["tests"]# Initialize
uv init
uv add ruff mypy pytest
uv add --dev pytest-covLicense: MIT.
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.

