关于 ub-python
ub-python 是用于 Python 开发与维护的技能,指导采用现代类型标注、边界验证和兼顾迁移的改动,并依据仓库实际配置进行工具检查。
主要功能
- 01现代 Python 模式与严格类型标注
- 02边界验证和结构化错误
- 03渐进式迁移旧代码
- 04检测仓库实际工具链
- 05Ruff 配置脚手架与验证指导
适用场景
- 01实现或重构 Python 代码
- 02检查项目 Python 版本和工具配置
- 03为数据边界添加验证
- 04建立 Ruff 基础配置
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ robert-hoffmann/ uncle-bob --skill ub-python安装后在 Claude Code 中输入/ub-python确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/ruff-template/ruff.tomlassets/task-bundle/ub-python.Taskfile.ymlreferences/python-standards.mdrepository-python-workflows.mdruff-config-resolution.mdtask-bundle.mdscripts/scaffold_ruff.py详细介绍
UB Python
概述
使用此技能来强制采用最新稳定版 Python 的现代默认做法、严格类型检查、边界验证,以及了解迁移情况的旧代码处理方式。
为新代码生成现代模式,并在修改现有代码时逐步重构旧模式。
面向项目当前支持的 Python 版本编写代码,但应合理组织代码,使其能够顺利迁移到更新的稳定版本,而不是不断累积兼容层。
不适用场景
- 不要将此技能用于工作流受理、冲刺规划或可恢复的计划编排;请改用
ub-workflow。 - 如果主要问题由非 Python 工作流、文档或框架技能负责,不要将此技能作为主要入口。
- 如果主要任务是 Markdown 结构或文档质量,而非 Python 实现,不要将此技能作为通用的文档规范化层。
随附资源
此技能在 assets/ 下提供可复用的 Ruff 脚手架,并在 scripts/ 下提供一个确定性辅助脚本。
当代码库希望采用相同的 Ruff 基线,但尚无自己的 Python lint 配置时,请使用它们。
按需加载参考资料
- 调整共享路由指南、输出结构或跨技能编写规范时,阅读
../ub-authoring/references/authoring-conventions.md。 - 加载并应用
references/python-standards.md,以了解规范的 Python 规则和工具链策略。 - 加载并应用
references/repository-python-workflows.md,以确定目标代码库实际使用的 Python 验证与打包工具基线。 - 当 Ruff 配置发现、适配点或脚手架行为很重要时,加载
references/ruff-config-resolution.md。 - 仅当目标代码库希望为此技能的入门配置添加可选的 Task 自动化层时,阅读
references/task-bundle.md。 - 当目标代码库需要确定性的 Ruff 入门配置,而非临时改写配置时,使用
scripts/scaffold_ruff.py和assets/ruff-template/。
向前兼容约定
- 根据项目实际支持的 Python 版本、运行时和库版本下限进行实现。
- 设计时优先考虑下一步稳定升级路径,而非默认保留旧版本行为。
- 如果
typing_extensions、collections.abc和abc等向前兼容工具能够让代码兼容当前代码库的版本下限,同时与较新的稳定版 Python 发展方向保持一致,则优先使用。 - 只有在明确的支持约定或分阶段迁移计划要求时,才添加向后兼容的垫片、回退方案或桥接代码。
- 不要将向前兼容工具视为许可,使用当前代码库所支持的最低 Python 版本无法解析或运行的语法。
核心工作流
- 根据项目文件(
pyproject.toml、锁定文件、CI、现有配置)确定运行时和工具链的实际情况。 - 提出实现方案前,确认 Python 的适用范围和版本要求。
- 对于非平凡或与版本相关的建议,比较官方指南、仓库实际情况和观察到的代码现状。
- 当权威来源、仓库实际情况或当前代码现状在非平凡建议上存在重大分歧时,指出
OFFICIAL_CONFLICT。 - 针对无法通过定向研究在官方来源中确认的非平凡说法,指出
UNVERIFIED。 - 对于非平凡的 Python 工作,至少提出两种可行的实现方案,并简要说明各自的优缺点。
- 选择满足正确性、可维护性和项目约束的最简单方案。
- 对行为变更,先编写或调整测试。
- 实现最小改动以通过测试,然后在保持行为和边界不变的前提下进行重构。
- 修改 Python 代码后,运行仓库配置的验证,从最小的相关范围开始。
- 报告结果、有限的例外、任何冲突或不确定性说明,以及会显著降低置信度的工具缺口。
- 如果仓库希望采用此 Ruff 基线,但尚无生效的 Ruff 配置,则搭建随附的起始配置,并说明所需的仓库本地调整,而不是在说明文字中嵌入策略。
版本与研究政策
- 指南以最新稳定版 Python 为目标,但实现须遵循项目实际支持的版本要求。
- 根据
pyproject.toml、.python-version、锁定文件和 CI 配置,确定项目实际使用的 Python 版本。 - 使用网络搜索,依据 Python 官方文档核实当前最佳实践、API 可用性和迁移指南。
- 判断实际可交付且不会破坏当前项目的内容时,将仓库实际情况视为实现的黄金标准。
- 对面向未来的设计和便于迁移的模式,优先以 Python 官方文档作为指南基准。
- 如果官方指南与仓库实际情况在非平凡建议上存在重大分歧,则指出
OFFICIAL_CONFLICT,采用对仓库安全的方案,并说明后续迁移路径。 - 如果无法通过定向研究在官方来源中确认某项非平凡说法,则将其标记为
UNVERIFIED,或避免将其作为确定的指南。 - 仅针对非平凡、与版本相关或存在争议的指南说明冲突和不确定性,不要对琐碎改动作此说明。
- 除非用户明确要求,否则不要生成仅在尚未发布的 Python 版本中可用的语法或标准库行为。
- 如果项目安装的版本落后于最新稳定版,应指出版本差距、建议升级路径,并优先采用能平稳适应升级的模式。
- 如果宿主仓库中存在
AGENTS.md或同类说明,应检查其中针对项目的版本政策和工具要求;不要假定其中包含本目录的默认设置。 - 不要在生成的指南中硬编码版本号;建议应保持长期适用。
时效性审查
- 变化性:高
- 审查建议:修改相关内容时审查,并在定期维护期间审查;条件允许时按季度进行。
- 触发信号:Python 版本发布、工具成熟度变化、打包指南更新,或会改变实际强制基线的仓库验证规则变更。
- 执行方式:仅供参考;时效性审查应指出需要审查的目标,不应将缺少 mypy 或 pytest 配置一概视为采用该指南的仓库的阻碍。
- 稳定核心:强类型、边界验证、结构化错误以及依据仓库实际情况进行验证,始终是可靠的基线,即使工具偏好会随时间变化。
实现规则
运行时与环境
- 使用项目本地虚拟环境,并在命令中明确指定解释器。
- 优先使用
python -m ...和/或uv run ...,确保命令由预期的解释器执行。 - 文件系统操作优先使用
pathlib.Path,并确保路径处理兼容 Windows。
类型标注与 API 设计
- 为非简单函数和所有公共接口添加类型标注。
- 优先使用现代语法:
list[str]、dict[str, int]、X | Y、type Alias = ...。 - 优先使用
collections.abc中的接口类型(Iterable、Sequence、Mapping、Callable);不需要具体的可变行为时,使用abc或Protocol中的抽象契约。 - 当项目支持的最低版本不提供较新的类型功能时,或回移版本能提供更清晰的跨版本语义并更利于未来升级时,优先使用
typing_extensions。 - 使用
Protocol、Self、override、TypeGuard、TypeIs、Required、NotRequired、ReadOnly、TypeAliasType和assert_never,以提升正确性并降低重构风险。 - 如果
typing_extensions已提供迁移路径,就不要自行编写类型兼容垫片。 - 将
Any限制在边界处;无法避免时,说明原因。 - 在严格的公共代码或面向 SDK 的代码中,避免使用
dict(mapping)这类含义不明确的构造函数重载,尤其是源类型为递归别名或宽泛的Mapping[str, JsonValue]时。优先使用带类型的复制辅助函数、{**mapping}或显式负载构造器,以便 Pyright/Pylance 能推断出精确的返回类型。
数据建模与验证
- 使用 Pydantic v2 或显式手动验证边界数据(HTTP、文件、环境变量、队列负载)。
- 内部领域容器优先使用数据类。
- 数据类默认设置:使用
@dataclass(slots=True, kw_only=True),并为可变字段使用field(default_factory=...)。 - Pydantic v2 默认设置:使用
ConfigDict、@field_validator、@model_validator和model_dump()。
并发与结构化错误
- 并发异步任务优先使用
asyncio.TaskGroup。 - 在适用时,使用
ExceptionGroup和except*处理分组错误。 - 明确处理网络或外部 I/O 的取消和超时行为。
打包与工具链规范
- 将项目元数据保存在
pyproject.toml中,并包含[build-system],以明确构建后端。 - 优先使用现代构建/安装命令(
python -m pip、python -m build),而不是已弃用的python setup.py ...命令。 - 优先使用标准库;只有在能显著提升正确性、可维护性或开发体验时才添加依赖。
编辑后验证约定
- 生成或修改 Python 代码后,运行与改动范围相关且由仓库配置的检查。
- 最低要求:配置了 Ruff 时运行 Ruff;配置了 mypy/pyright/basedpyright 时运行类型检查器;存在测试或行为发生变化时运行针对性的 pytest 测试。
- 从小范围开始(对改动文件运行
ruff check、运行针对性测试和限定范围的类型检查);只有在失败表明影响范围更广时才扩大检查范围。 - 最终确定前,修复任务范围内新引入的 lint、类型或测试失败。
- 如果无法运行某项已配置的检查,请准确说明跳过或受阻的原因。
仓库实际情况说明:
- 在将某条命令或检查门槛说成既定事实前,先确认宿主仓库实际配置的 lint、类型检查和测试基线。
- 对 Python 占比较高的仓库,
mypy和pytest通常是强烈建议,但只有在宿主仓库确实已将其纳入检查流程时,才应将它们作为强制检查门槛。 - 如果 lint、类型检查或测试要求较弱或缺失,请明确指出这一差距,不要假称这些检查已得到强制执行。
工具链缺失警告策略
- 如果仓库缺少用于 lint、类型检查或测试的 Python 工具,配置较弱,或明显未纳入常规工作流,请明确警告用户。
- 适用时建议具体的补充方案:使用 Ruff 进行 lint,使用 mypy/pyright 进行类型检查,使用 pytest 进行测试,并通过 pre-commit 或 CI 接入自动强制检查。
- 将缺失的质量门禁视为已报告的风险,而不是默许跳过验证。
错误处理、日志记录与边界
- 使用具体的异常来报错,并保留因果链(
raise ... from err)。 - 记录决策和失败时,提供可采取行动的上下文,避免无意义的日志。
- 保持分层边界:表示层 -> 服务层 -> 仓储层 -> 数据层。
工具链策略(主要方案 + 后备方案)
- 将仓库配置的工具视为事实依据。如果已配置 Ruff、mypy、pytest、pre-commit 或其他检查工具,应生成符合其生效规则的代码,而不是依赖通用默认值。
- 如果已配置 Ruff、mypy、pytest、pre-commit 或同类检查,编辑后应运行相关检查,而不是止步于生成代码。
- 主要工具栈:
uv、ruff、mypy、pytest、pre-commit。 - 约束要求使用后备方案时:
- 依赖管理:
pip-tools - 类型检查器:
pyright或basedpyright - 编辑器反馈:当团队/编辑器策略偏好标准模式诊断时,使用 Pylance(Pyright 引擎)并设置
python.analysis.typeCheckingMode = "standard"
- 依赖管理:
- 条件允许时,应在项目文档/自动化流程中提供易于查找的一键检查工作流。
配置解析与脚手架
将实际工具配置视为事实依据:
- 如果存在配置,先检查
ruff.toml、.ruff.toml或pyproject.toml中的[tool.ruff] - 在假设命令格式之前,先检查任务运行器、CI 和包元数据入口
- 仅当配置缺失且采用该风格的仓库需要此约定时,才使用随附的 Ruff 脚手架
- 将脚手架视为起步方案;仍需针对目标版本、包含/排除路径和第一方包布局进行本地适配
- 不要在搭建脚手架时擅自安装依赖或修改 CI
权衡处理
- 对重要的设计或工具选择,使用共享的
ub-quality决策分析基线。 - 涉及 Python 特定权衡时,应在各选项的优缺点中明确指出兼容性、策略、交付和现代化成本。
- 默认选择最安全的现代方案,除非兼容性、策略或交付约束足以支持替代方案。
- 记录为保持兼容性而有意推迟的清理工作或保留的技术债务。
避免旧式用法的防护规则
- 除非兼容性约束有此要求,否则不要在新代码中生成旧式类型别名(
Optional、Union、List、Dict)。 - 不要在新代码中使用 Pydantic v1 的验证器/风格 API。
- 不要新增
python setup.py ...命令用法。 - 如果使用类型化模型切实可行,就不要添加大量依赖无类型字典的接口约定。
- 如果项目已不再支持较旧的 Python 行为,不要以“以防万一”为由保留相关支持。
- 如果
typing_extensions或标准库已涵盖预期的迁移路径,不要为类型功能添加自定义向后兼容层。
迁移期间的例外政策:
- 仅当现有代码存在明确的兼容性约束时,才允许暂时保留旧式用法。
- 明确记录具体保留了什么、保留原因,以及下一步现代化工作。
输出要求
对于此目录中的重要 Python 工作,请将本节视为稳定的输出要求。
生成或审查 Python 代码时,请包含:
- 环境说明:检测到的运行时、解释器策略及相关工具上下文。
- 事实依据说明:仓库的版本和工具实际情况,以及与最新稳定指导之间的重大差异。
- 决策说明:所选方案及至少一种替代方案。
- 权衡说明:简要说明所选方案和被否决方案的优缺点。
- 遗留说明:已移除的遗留模式或有明确范围的例外,并说明理由。
- 验证说明:已运行的检查(lint/类型检查/测试/构建)及结果。
- 工具缺口说明:缺失或较弱的 lint/类型检查/测试措施,以及用户应考虑添加或接入的内容。
- 冲突说明(相关时):
OFFICIAL_CONFLICT或UNVERIFIED,并简要说明及指出对实现的影响。
使用此技能为其他仓库配置 Ruff 时,还请包含:
- 已创建或跳过的文件
- 仍需调整的仓库本地 Ruff 设置
- 目标仓库接下来应运行的确切 lint 命令
参考资料
- 核心规则和基于来源的策略:
references/python-standards.md - 特定于仓库的工作流和验证基线:
references/repository-python-workflows.md
完成检查清单
- 有意执行最新稳定版 Python 基线。
- 在相关情况下应用现代类型标注和边界验证。
- 明确说明数据模型选择(dataclass 或 Pydantic v2)。
- 并发和错误处理模式具备结构性且可观测。
- 编辑后已运行仓库配置的 lint/类型检查/测试,或明确说明未运行的原因。
- 未引入新的遗留输出。
- 在相关情况下说明缺失的 lint/类型检查/测试措施。
- 记录任何保留的遗留行为及其迁移路径。
- 在相关情况下,明确披露任何重大的官方来源冲突或未经验证的重要指导。
- 将任何配置的 Ruff 入门模板明确说明为入门配置,而非默认作为仓库策略。
评论
支持 Markdown