ac-python
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePython Bible (Python 3.14)
Python 宝典 (Python 3.14)
Targets: Python 3.14 · Previous line: Python 3.13 (trailing section) · Tooling: uv · ruff · mypy/ty · prek · pytest
适用版本: Python 3.14 · 上一版本线: Python 3.13(见末尾章节) · 工具链: uv · ruff · mypy/ty · prek · pytest
Version Policy
版本策略
This skill documents one Python line: the current one. Keep it that way when
you update it.
- Main path = the current feature release. Today that is Python 3.14. When 3.15 ships, the main path moves to it in the same edit.
- Unmarked prose means the current line, and there is no marker form. Python
ships features only in a feature release, and the main path always is the
current feature release — so nothing in it can post-date the line, and a version
suffix would have nothing to qualify. (This is where the sibling policy differs: Django adds features within a line, so it needs version markers; Python does not.) Do not write "On Python 3.X+, ..." or "if you are on 3.13" in the main path — a conditional in the main path is the defect this rule exists to stop.
ac-django - Older lines get one trailing section each, at the end of , and nothing anywhere else — the reference files carry the current line only and get no trailing section of their own. Today that is
SKILL.md. It carries the diff a reader on that version needs: what is missing, what to use instead, and what to change on upgrade.## Previous line: Python 3.13 - Research order when refreshing. and the library reference first. Then the sources already cited under Canonical Sources. Blogs and newsletters last, briefly, for what the docs do not cover.
https://docs.python.org/3/whatsnew/ - Rotation. Each October a new line ships: re-base unmarked prose on it, replace the trailing section with the line being retired, drop stale markers.
本Skill文档仅覆盖一个Python版本线:当前最新版本。更新时请保持这一原则。
- 主路径 = 当前特性版本。 目前主路径为Python 3.14。当3.15发布后,主路径将在同一次编辑中切换至该版本。
- 未标注版本的内容均适用于当前版本线,无需额外版本标记。 Python仅在特性版本中发布新功能,而主路径始终对应当前特性版本——因此主路径中的内容不可能晚于当前版本,无需添加版本后缀。(这与同系列的规范不同:Django会在同一版本线内新增功能,因此需要版本标记;Python则不需要。)请勿在主路径中编写“在Python 3.X+版本中...”或“如果你使用3.13版本”这类表述——主路径中的条件判断是本规则要避免的问题。
ac-django - 旧版本线仅在末尾保留一个章节,其他位置不涉及旧版本内容——参考文件仅覆盖当前版本线,也不单独设置旧版本章节。目前旧版本章节为
SKILL.md,其中包含该版本用户需要了解的差异:缺失的功能、替代方案以及升级时的修改点。## 上一版本线:Python 3.13 - 更新文档时的资料查阅顺序。 和标准库参考文档优先,其次是“权威来源”章节中列出的资料。最后可简要查阅博客和技术通讯,补充文档未覆盖的内容。
https://docs.python.org/3/whatsnew/ - 版本更迭。 每年10月会发布新的Python版本线:将未标注版本的内容适配到新版本,将刚退役的版本线内容替换到末尾的旧版本章节,移除过时的标记。
Canonical Sources
权威来源
- Python docs: https://docs.python.org/3/
- Ruff docs: https://docs.astral.sh/ruff/
- uv docs: https://docs.astral.sh/uv/
- mypy docs: https://mypy.readthedocs.io/
- pytest docs: https://docs.pytest.org/
- Typer (CLI): https://typer.tiangolo.com/
- Python官方文档:https://docs.python.org/3/
- Ruff官方文档:https://docs.astral.sh/ruff/
- uv官方文档:https://docs.astral.sh/uv/
- mypy官方文档:https://mypy.readthedocs.io/
- pytest官方文档:https://docs.pytest.org/
- Typer(CLI工具):https://typer.tiangolo.com/
Reference Files (load as needed)
参考文件(按需加载)
| File | Covers | When to load |
|---|---|---|
| Style, Pythonic idioms, type annotations, readability rules | Writing or reviewing any Python code |
| OOP patterns, data models, factories, properties, design principles | Designing classes, data models, module structure |
| Testing patterns, pytest setup, tooling (uv/ruff/mypy/prek), quality gates | Writing tests, setting up a project, CI |
| 文件 | 覆盖内容 | 加载时机 |
|---|---|---|
| 代码风格、Pythonic惯用写法、类型注解、可读性规则 | 编写或评审任何Python代码时 |
| OOP模式、数据模型、工厂模式、属性、设计原则 | 设计类、数据模型、模块结构时 |
| 测试模式、pytest配置、工具链(uv/ruff/mypy/prek)、质量门禁 | 编写测试、搭建项目、配置CI时 |
Dependencies
依赖
Standalone. No dependencies on other skills.
When used alongside ac-django, provides generic Python guidelines that complement Django-specific patterns.
本Skill独立运行,不依赖其他Skill。
与ac-django搭配使用时,可提供通用Python规范,作为Django专属模式的补充。
Trigger QA (Release Gate)
触发QA(发布门禁)
Before shipping skill changes, validate activation behavior with sample prompts:
- Should trigger:
- "Write a CLI script that processes CSV files."
- "Review this Python class for design issues."
- "Set up testing for this Python microservice."
- Should NOT trigger:
- "Add a Django model field and migration."
- "Set up git worktrees for a ticket."
- "Implement project delivery workflow."
If behavior under-triggers or over-triggers, tighten cues before release.
description发布Skill变更前,请使用以下示例提示词验证触发行为是否正确:
- 应当触发:
- “编写一个处理CSV文件的CLI脚本。”
- “评审这个Python类的设计问题。”
- “为这个Python微服务搭建测试体系。”
- 不应触发:
- “添加一个Django模型字段和迁移。”
- “为一个工单配置git worktree。”
- “实现项目交付工作流。”
如果出现触发不足或过度触发的情况,请在发布前优化中的提示信息。
descriptionExample: Adding a new data model
示例:新增数据模型
User says: "Add a data model with validation"
LoanApplication- Load for data model patterns
references/oop-and-design.md - Load for typing conventions
references/style-and-typing.md - Use a dataclass or attrs/pydantic if the project already uses them
- Add full type annotations, use for derived attributes
@cached_property - Name the factory if needed in tests
build_loan_application(...) - Mirror the module path in for the test file
tests/
用户说:“添加一个带校验的数据模型”
LoanApplication- 加载参考数据模型模式
references/oop-and-design.md - 加载参考类型注解规范
references/style-and-typing.md - 如果项目已使用dataclass、attrs或pydantic,则优先使用
- 添加完整的类型注解,派生属性使用
@cached_property - 如测试需要,工厂函数命名为
build_loan_application(...) - 测试文件的路径需与目录下的模块路径保持一致
tests/
Prime Directives
核心准则
Pythonic first
Pythonic优先
- Prefer the idiomatic Python solution over a generic one.
- Use list comprehensions, walrus operator (),
:=,itertoolswhere they clarify intent.operator - Avoid intermediate variables that are only used once.
- Prefer t-strings (, PEP 750) over f-strings when building SQL, HTML, shell commands, or templates from interpolated values. A t-string evaluates to a
t"...", not astring.templatelib.Template: the static text and eachstrstay separable, so a processing function can escape every interpolated value for its target grammar. The safety is in that function — the stdlib ships none, so use a library's or write one. AInterpolationpassed where aTemplateis expected is an error, not an escape.str - Use the stdlib for zstd rather than the third-party
compression.zstdpackage.zstandard,compression.lzma,compression.bz2andcompression.gzipare the preferred import names for those modules too; the originals still work and are not deprecated.compression.zlib,tarfileandzipfileread and write zstd archives.shutil - Omit the brackets in a multi-type when there is no
exceptclause (PEP 758):as. Withexcept TimeoutError, ConnectionRefusedError:, the brackets are still required.as - Never ,
return, orbreakout of acontinueblock — it swallows the in-flight exception, and the compiler emits afinallyfor it (PEP 765).SyntaxWarning
- 优先采用符合Python惯用风格的解决方案,而非通用方案。
- 在能清晰表达意图的场景下,使用列表推导式、海象运算符()、
:=、itertools模块。operator - 避免仅使用一次的中间变量。
- 在构建SQL、HTML、Shell命令或模板时,优先使用t-strings(,PEP 750)而非f-strings。t-string的求值结果是
t"..."而非string.templatelib.Template:静态文本与每个str(插值项)保持分离,因此处理函数可以针对目标语法对每个插值进行转义。安全性取决于处理函数——标准库未提供该函数,因此需要使用第三方库或自行实现。将Interpolation传入期望Template的场景会报错,而非自动转义。str - zstd压缩请使用标准库,而非第三方
compression.zstd包。zstandard、compression.lzma、compression.bz2和compression.gzip也是对应模块的推荐导入名称;原导入方式仍然可用,并未被弃用。compression.zlib、tarfile和zipfile支持读写zstd归档文件。shutil - 当多类型没有
except子句时,可省略括号(PEP 758):as。如果带有except TimeoutError, ConnectionRefusedError:子句,仍需使用括号。as - 绝对不要在块中使用
finally、return或break——这会吞掉正在抛出的异常,编译器会为此发出continue(PEP 765)。SyntaxWarning
Types are documentation
类型即文档
- Full, modern annotations everywhere: ,
list[str],str | None.dict[str, int] - Use the statement for recurring complex types.
type - No duck-typing: if you are checking for attribute existence before acting, the type hint is too broad — narrow it.
- 所有位置都使用完整的现代类型注解:、
list[str]、str | None。dict[str, int] - 重复出现的复杂类型使用语句定义别名。
type - 禁止鸭子类型:如果你需要先检查属性是否存在再执行操作,说明类型注解过于宽泛——请收窄类型范围。
No docstrings — names are the docs
无需docstring——名称即文档
- Use short, expressive function and variable names.
- Comment ONLY the non-obvious WHY. Never restate the code; never write a signature-echo docstring.
- A long comment is a code smell — refactor or rename instead of explaining. Multi-line comments are legit only for a genuine non-obvious why, never to narrate the code.
- Use vertical whitespace to group related lines.
- 使用简短、表意清晰的函数名和变量名。
- 仅对非显而易见的“为什么”添加注释。绝不复述代码内容;绝不编写只是重复函数签名的docstring。
- 长注释是代码坏味道——请通过重构或重命名来替代解释。多行注释仅适用于真正难以理解的原因说明,绝不能用来逐行讲解代码。
- 使用空行对相关代码行进行分组。
Clean imports
整洁导入
- All statements at the top of the file.
import - No function-level imports, no guards. (Repo-specific conventions may relax this for established circular-import patterns.)
try...except ImportError - Assume all dependencies are installed.
- 所有语句放在文件顶部。
import - 禁止函数级导入,禁止防护。(针对已存在的循环导入模式,仓库特定规范可适当放宽此要求。)
try...except ImportError - 默认所有依赖均已安装。
No dirty hacks
禁止肮脏Hack
- Pick the straightforward solution. If it doesn't exist, reconsider the design.
- Do not fight third-party frameworks — follow their intended patterns.
- 选择直接明了的解决方案。如果不存在这样的方案,请重新考虑设计是否合理。
- 不要与第三方框架对抗——遵循其设计的使用模式。
Review Checklist
评审清单
Style
代码风格
- no single-use intermediate variables
- list comprehensions / stdlib idioms used where appropriate
- vertical whitespace groups related logic
- 无仅使用一次的中间变量
- 在合适的场景下使用列表推导式/标准库惯用写法
- 使用空行对相关逻辑分组
Typing
类型注解
- full modern annotations on all public functions and methods
- statement used for complex/recurring types
type - no duck-typing (no guards in place of proper types)
hasattr
- 所有公共函数和方法都有完整的现代类型注解
- 复杂/重复出现的类型使用语句定义别名
type - 无鸭子类型(不使用检查替代正确的类型定义)
hasattr
Imports
导入
- all imports at top of file
- no blocks
try...except ImportError - no function-level imports
- 所有导入都在文件顶部
- 无块
try...except ImportError - 无函数级导入
OOP / Design
面向对象/设计
- data models are first-class (not plain dicts passed around)
- factories named
build_... - application logic in methods, not module-scope functions
- /
@propertyfor derived attributes@cached_property
- 数据模型为一等公民(不使用普通字典传递数据)
- 工厂函数以命名
build_... - 应用逻辑放在方法中,而非模块级函数
- 派生属性使用/
@property@cached_property
Best Practices
最佳实践
- UTC timezone-aware datetimes throughout
- boolean params preceded by
, *, - blocks and context managers are minimal (ideally one line each)
try
- 所有datetime都使用带UTC时区的感知型对象
- 布尔参数前添加(强制关键字参数)
, *, - 块和上下文管理器尽可能小(理想情况下各占一行)
try
Architectural Health (Module-Level)
架构健康度(模块级)
Apply to full files touched by the diff, not just changed lines:
- no module with >500 LOC (split by concern)
- no module with >10 module-level functions (use classes)
- module-level functions are justified — default is methods on a class
- no god-module (single file mixing unrelated concerns — CLI wiring + business logic + subprocess management = split)
- no complexity rule suppressions (,
C901) inPLR09xxbeyond thepyproject.tomlbaselinepython-boilerplate - tests assert behavior through public interfaces, not by patching private functions or asserting subprocess command lists
适用于本次变更涉及的完整文件,而非仅修改的行:
- 无超过500行的模块(按职责拆分)
- 无超过10个模块级函数的模块(使用类封装)
- 模块级函数都有合理理由——默认应使用类的方法
- 无上帝模块(单个文件混合不相关的职责——CLI接线+业务逻辑+子进程管理=需要拆分)
- 中没有超出
pyproject.toml基线的复杂度规则抑制(python-boilerplate、C901)PLR09xx - 测试通过公共接口断言行为,而非通过patch私有函数或断言子进程命令列表
Testing
测试
Integration-First Testing (Non-Negotiable)
集成测试优先(不可妥协)
Write integration tests for happy paths, unit tests for edge cases. This maximizes confidence per line of test code.
- Integration tests exercise multiple modules together with real (or near-real) I/O. They catch the bugs that matter most: broken contracts between modules, wrong assumptions about state, ordering issues. Mock only what you cannot control (network, external processes, databases).
- Unit tests target specific functions in isolation — but only when the function has edge cases worth covering (error handling, boundary values, complex branching). Don't unit-test trivial glue code.
- Don't duplicate coverage. If a happy path is already covered by an integration test, don't write a unit test for the same path. Unit tests should cover what integration tests cannot reach efficiently (rare error branches, corner cases).
- E2E tests (browser, full-stack) are separate — they belong in frontend/application test suites, not in library or infrastructure code. Write them when testing user-visible behavior end-to-end.
主流程用集成测试覆盖,边界情况用单元测试覆盖。 这样能最大化每行测试代码带来的信心。
- 集成测试 会同时运行多个模块,使用真实(或接近真实)的I/O。它们能捕获最重要的bug:模块间契约破坏、状态假设错误、时序问题。仅mock你无法控制的部分(网络、外部进程、数据库)。
- 单元测试 针对单个函数进行隔离测试——但仅当函数有值得覆盖的边界情况时才使用(错误处理、边界值、复杂分支)。不要为简单的粘合代码编写单元测试。
- 不要重复覆盖。 如果主流程已经被集成测试覆盖,就不要为同一条路径编写单元测试。单元测试应该覆盖集成测试无法高效触达的场景(罕见错误分支、极端情况)。
- E2E测试(浏览器、全栈)属于独立范畴——它们属于前端/应用测试套件,而非库或基础设施代码的一部分。仅在需要端到端测试用户可见行为时才编写。
Test Conciseness (Non-Negotiable)
测试简洁性(不可妥协)
Tests must be easy to read and maintain. Verbose tests get skimmed, misunderstood, and copy-pasted without thought.
- One assertion per concept. A test method should test one behavior. Multiple assertions are fine when they verify different facets of the same behavior.
- Use fixtures for setup, not copy-paste. Repeated setup code across test methods means a missing fixture or parametrize.
- Parametrize over copy-paste. When multiple tests differ only in input/output values, use . Five test methods that differ by one string are one parametrized test.
@pytest.mark.parametrize - Name tests after the behavior, not the method. beats
test_returns_error_when_db_missing.test_db_import_3 - No unnecessary mocks. Only mock what you cannot control (network, clock, external processes). Over-mocking makes tests tautological — they test the mocks, not the code.
- Flat over nested. Prefer module-level test functions or flat test classes. Deeply nested class hierarchies in tests add complexity without value.
- Prefer context managers () over
with patch(...). Context managers clearly isolate the scope that needs the mock. Usemonkeypatchonly when it genuinely simplifies the test (e.g., env vars,monkeypatch, patching attributes on fixtures that outlive the test body).chdir
测试必须易于阅读和维护。冗长的测试会被跳过、误解,甚至被不假思索地复制粘贴。
- 每个概念对应一个断言。 一个测试方法应该只测试一种行为。如果多个断言验证的是同一行为的不同方面,则完全可以接受。
- 使用fixture做初始化,不要复制粘贴。 不同测试方法中存在重复的初始化代码,说明缺少对应的fixture或参数化测试。
- 优先参数化,而非复制粘贴。 当多个测试仅输入/输出值不同时,使用。五个仅差一个字符串的测试方法可以合并为一个参数化测试。
@pytest.mark.parametrize - 测试按行为命名,而非按方法命名。 比
test_returns_error_when_db_missing好得多。test_db_import_3 - 不要不必要的mock。 仅mock你无法控制的部分(网络、时钟、外部进程)。过度mock会让测试变得毫无意义——它们测试的是mock,而不是代码本身。
- 扁平优于嵌套。 优先使用模块级测试函数或扁平的测试类。测试中深层嵌套的类层次只会增加复杂度,没有任何价值。
- 优先使用上下文管理器()而非
with patch(...)。 上下文管理器能清晰隔离需要mock的作用域。仅当monkeypatch确实能简化测试时才使用(例如环境变量、monkeypatch、patch生命周期长于测试体的fixture属性)。chdir
Checklist
清单
- test file mirrors module path
src - test class and method names describe the behavior under test
- happy path covered by integration test; unit tests cover edge cases
- no duplicated coverage between integration and unit tests
- used where 3+ tests differ only by input/output
@pytest.mark.parametrize - fixtures used for repeated setup — no copy-pasted boilerplate
- mocks only for external boundaries (subprocess, network, clock)
- 测试文件路径与模块路径一致
src - 测试类和方法名描述了被测行为
- 主流程由集成测试覆盖;单元测试覆盖边界情况
- 集成测试和单元测试之间无重复覆盖
- 当3个以上测试仅输入/输出不同时,使用
@pytest.mark.parametrize - 重复初始化使用fixture——无复制粘贴的样板代码
- 仅在外部边界使用mock(子进程、网络、时钟)
Previous line: Python 3.13
上一版本线:Python 3.13
Everything above targets Python 3.14. On 3.13:
- No t-strings. Build SQL/HTML with the target library's own parameterisation
or escaping (,
cursor.execute(sql, params)), never f-string interpolation.markupsafe - No . The third-party
compression.zstdpackage is the option;zstandard/tarfile/zipfiledo not read or write zstd.shutil - Annotations are evaluated eagerly. is still needed for forward references, and there is no
from __future__ import annotations— useannotationlib. The main path's ruff config bans that import (typing.get_type_hints()inlint.flake8-tidy-imports.banned-api."__future__.annotations"); drop that one entry while the project targets 3.13, and restore it on 3.14.references/testing-and-tooling.md - needs brackets for multiple types:
except.except (TimeoutError, ConnectionRefusedError): - Free-threading is experimental, not officially supported, and carries a much larger single-threaded penalty than 3.14's ~5–10%.
- Pin /
python_versiontopython-versionin the mypy/ty config while the project targets it."3.13"
以上所有内容均适用于Python 3.14。在3.13版本中:
- 不支持t-strings。 构建SQL/HTML时使用目标库自带的参数化或转义功能(、
cursor.execute(sql, params)),绝对不要用f-string插值。markupsafe - 无模块。 可使用第三方
compression.zstd包;zstandard/tarfile/zipfile不支持读写zstd。shutil - 类型注解为立即求值。 前向引用仍需要,且没有
from __future__ import annotations模块——请使用annotationlib。主路径的ruff配置禁止了该导入(见typing.get_type_hints()中的references/testing-and-tooling.md);当项目目标版本为3.13时移除该规则,升级到3.14后再恢复。lint.flake8-tidy-imports.banned-api."__future__.annotations" - 多类型需要括号:
except。except (TimeoutError, ConnectionRefusedError): - 自由线程(free-threading)仍处于实验阶段,未被官方支持,且单线程性能损耗远大于3.14的约5–10%。
- 当项目目标版本为3.13时,在mypy/ty配置中将/
python_version固定为python-version。"3.13"