一键导入
python-project-conventions
Direct, typed and compact Python design, implementation, packaging and validation rules.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Direct, typed and compact Python design, implementation, packaging and validation rules.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | Python project conventions |
| description | Direct, typed and compact Python design, implementation, packaging and validation rules. |
| distribution | repository |
Use this skill for all Python changes.
Write correct, secure and compact Python. Prefer modules, functions, explicit data and straightforward control flow. Add an abstraction only when current code needs it.
Apply these priorities in order:
Before editing:
AGENTS.md and relevant local skills;git status, the active branch and worktrees;Do not design from memory when the repository can answer the question.
Start with a focused module, typed functions and explicit values.
Add an abstraction only when it:
Do not add:
Prefer a module function to a forwarding method. Prefer a data-driven mapping to repeated subclasses. Prefer deletion to deprecation when the code has no external consumer.
A function must perform one coherent operation.
Treat 200 lines as a soft maximum. Use a lower limit when a function:
A 120-line function can be too large in a 200-line module. A cohesive 160-line transaction can be acceptable in a large domain module.
Split long functions into typed helpers around real stages such as:
Do not create wrapper classes or one-line helpers to satisfy a line count. The split must improve names, testing or control flow.
Use early validation and ordinary branches. Avoid modifying caller-owned mutable values. Use keyword-only arguments when adjacent parameters share a type.
Keep policy and transformations pure when practical. Keep MCP/framework calls, model calls, Git, SQLite, clocks, environment variables, subprocesses and filesystem access at explicit boundaries.
The composition root may:
It should not contain the domain operation itself.
deploy/ contains deployment artefacts. Reusable application logic and CLI code belong under src/memento/. Repository tests live under tests/. Developer utilities and experiments belong under tools/.
Do not perform I/O in module imports, validators, properties or hidden constructors.
Use the lightest type that enforces the real boundary.
@dataclass(frozen=True, slots=True) for trusted internal values.TypedDict for trusted structured mappings when runtime validation adds no value.StrEnum, Enum or Literal for closed values.Protocol only for current interchangeable implementations.from dataclasses import dataclass
@dataclass(frozen=True, slots=True)
class BlobVersion:
etag: str
version_id: str
from pydantic import BaseModel, ConfigDict
class SkillManifest(BaseModel):
model_config = ConfigDict(extra="forbid", frozen=True)
name: str
revision: int
content_sha256: str
Do not use Pydantic for a trusted intermediate projection merely because nearby code uses it. Do not create a model for every private value.
Type every changed function, method, callback and data field.
Prefer:
X | None;list[str];collections.abc for accepted interfaces;Do not use Any to avoid design work. Keep casts narrow. A # type: ignore must include an error code and a reason.
Fail explicitly and preserve causes with raise ... from exc.
Catch an error only to:
Do not catch Exception and return None, False or an empty collection. Distinguish validation, authorisation, missing data, conflict, retryable failure and permanent failure when callers respond differently.
Keep exception hierarchies small. Error text must not expose secrets or sensitive content.
Read environment variables at the composition root and pass typed settings inward. Validate configuration before side effects.
Consume authenticated principals from trusted uMCP request context. Never place credentials in code, fixtures, logs, examples or shell commands.
Log once at the boundary that records the outcome. Persist immutable audit records for security-sensitive or durable mutations. Library code must not print; CLI and operator commands may print deliberate results.
Extract shared code only after finding multiple current callers with the same contract.
Good shared candidates include:
Keep domain rules in their domain functions. Similar syntax does not prove a shared contract.
When renaming or moving code:
git mv;Do not add a compatibility namespace unless a known external consumer requires it.
Use the layout that exists in this repository:
src/
memento/
cli.py # service CLI entry points
repository/ # canonical bundle and Git transactions
control/ # operation and proposal state
derived/ # rebuildable search and graph state
deploy/ # deployment artefacts
tools/ # developer utilities and experiments
tests/
Create milestone packages only when implementation starts. Do not add empty optional-tier module trees as architectural placeholders.
Preserve logical package boundaries with import tests. Do not create repeated source roots to simulate package isolation in one distribution.
Prefer the standard library when it is clear and maintained. Add a dependency only for a current requirement and pin it under repository policy.
Use established parsers for structured formats. In this repository:
markdownify converts HTML to Markdown;markdown-it-py parses Markdown structure;python-frontmatter handles frontmatter;ruamel.yaml handles round-trip YAML.Do not edit Markdown structure with regular expressions.
The repository must install through standard Python tooling.
pyproject.toml.Use the Makefile as the stable interface:
make install
make install-dev
make format
make check
make typecheck
make coverage
For Rust work, prefer make rust-check from the repository root or make check inside rust/. Raw cargo commands are secondary and should not replace the documented Make workflow.
Update Make targets when source paths or tools change. CI should call Make targets instead of duplicating raw Ruff, pytest or Mypy commands.
Test behaviour and invariants through public interfaces.
Include:
Prefer parameterised tests, small fakes and in-memory protocol implementations. Avoid deep mocks and tests that only reproduce private call order.
A Python change is complete when:
make format produces no further changes;make check passes;make typecheck passes;git diff --check passes.Static analysis must stay clean on Python 3.12, the lowest supported version. Runtime compatibility evidence covers Python 3.12 through 3.14.
If you need model or corpus fixtures, install and fetch Git LFS objects first:
git lfs install
git lfs pull