关于 adversarial-python
adversarial-python 是一项针对 Python 代码结构和现代语言惯用法的通过或失败审查技能。它通过盲审员和基于证据的规则评估代码是否应简化或重构,但不会自行修改代码。
主要功能
- 01现代 Python 惯用法与结构规则
- 02基于证据判定通过、失败或不适用
- 03结合 Python 版本检查规则
- 04单个盲审员审查流程
- 05失败即不通过,并给出具体修复项
适用场景
- 01合并前审查 Python 代码变更
- 02Python 版本下限提高后的代码检查
- 03评估重构是否真正简化代码
- 04发现新功能沿用的旧式模式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill adversarial-python安装后在 Claude Code 中输入/adversarial-python确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
gotchas.mdmetadata.jsonassets/templates/verdict.mdreferences/_sections.mdalt-collapse-passthrough-layers.mdalt-compose-over-concrete-inheritance.mdalt-function-over-single-method-class.mdalt-no-single-impl-interfaces.mddisp-match-over-isinstance-ladders.mddisp-registry-over-branch-ladders.mddisp-split-boolean-switch-params.mddisp-strenum-over-string-states.mdflow-no-silent-broad-except.mdflow-taskgroup-over-orphan-tasks.mdmodel-dataclass-over-boilerplate.mdmodel-shape-the-data-clump.mdmodel-typed-boundary-payloads.mdreviewer-prompt.mdstd-aware-utc-datetimes.mdstd-no-hand-rolled-batteries.mdstd-pathlib-over-ospath.mdstd-zip-strict-independent-sources.mdtyping-builtin-generics-and-unions.mdtyping-pep695-generics.mdtyping-self-over-typevar-fluent.md详细介绍
对抗式 Python 审查门禁
针对 Python 现代惯用写法和代码结构的审查门禁——结果为通过/不通过:由一个盲审子 Agent 根据本门禁的规则,以对抗式审查的方式评判代码;只有每条规则都为 PASS 或 N/A 时,代码才算通过。本技能只给出判定,绝不修复代码。
这些规则针对两种失败模式,而它们的根源相同——作者只是复刻了某种形式,而没有进行设计。训练数据惯性会产出可被现代 Python 特性直接替代的代码:可由 match 或注册表取代的 if/elif 分支链,可由 @dataclass(slots=True) 生成的 __init__/__repr__/__eq__ 三件套,PEP 695 已淘汰的 TypeVar 仪式,以及标准库已提供的分块辅助函数 itertools.batched。旧式模式传播会让新代码照搬并延续周围代码库中的糟糕结构——在事件分支链上再加一个分支,在只做转发的服务中再加一个方法——而不是从头到尾追踪功能并为其建模。每条规则都附有一段违规证据,让审查者仅凭工件证据即可判定 PASS/FAIL/N/A;如果修复依赖特定语言版本,还会标明 Requires Python ≥ 3.X。
适用场景
- 一个 Python 功能、端点或模块(由 Agent 或人工编写)即将合并,需要客观判定现代 Python 和重新审视架构是否会删掉或重构它。
- Agent 扩展了旧代码库,而你怀疑它只是照搬现有模式——事件/版本分支链、只做转发的服务层、字符串类型状态——而没有重新设计该功能。
- 代码库提高了 Python 版本下限(至 3.12、3.13、3.14+),应要求修改后的代码采用新版本支持的惯用写法。
- 某项重构声称实现了现代化或简化,而你希望通过判定来核验这一说法,而不是仅仅扫一眼差异。
不要将其用于没有 Python 源码的目标(审查提示词的前置条件会中止并显示 “GATE NOT APPLICABLE”),也不要用于用户想要解释和重构而非判定的情况。本门禁有意排除的主观判断——命名偏好、函数长度、文档字符串和测试覆盖率、性能调优——应由建议类技能处理,而不是本门禁。
Review Protocol
请严格按以下步骤执行——门禁的价值在于确保每次审查都以相同方式进行。
- 确定目标。 明确要审查的内容(差异、一组文件或 PR),并记录引用和路径,确保审查针对明确且固定的目标。包含仓库根目录——若干
alt-和disp-规则必须在差异之外搜索实现者、替代位置、测试替身和调用点(审查者提示词会列出这些内容)。 - 探查 Python 版本。 从目标的
pyproject.toml(requires-python)、.python-version、setup.cfg或 CI 矩阵中读取 Python 最低版本,并引用来源;如果未声明,则按最新稳定版 Python 进行判断并说明这一点。然后将最低版本与 metadata.json 中的verified_python比较:- 最低版本 ≤ 已验证版本:继续;高于最低版本的版本门控规则均为 N/A。
- 最低版本 > 已验证版本:为版本差距中的每个版本获取
https://docs.python.org/3/whatsnew/3.{N}.html,并编写差异简报——包括新的标准库电池(扩展std-no-hand-rolled-batteries表格)、新的语法和类型标注形式(扩展disp-/typing-规则的适用范围),每一项都需附上引用。将简报填入审查者提示词的{{VERSION_DELTA_BRIEFING}}占位符。审查结束后,将差异记录到 gotchas.md,以便重新验证规则并提升verified_python。
- 加载规则。 阅读 references/_sections.md 以及
references/中的每个规则文件(所有disp-*.md、model-*.md、alt-*.md、typing-*.md、std-*.md、flow-*.md文件)。 - 编写审查者提示词。 将规则、目标、Python 最低版本以及差异简报(如有)填入 references/reviewer-prompt.md。编写完成的提示词必须完全自包含——审查者看不到任何对话历史,因此不得引用提示词之外的上下文。
- 派发一名盲审审查者。 启动单个 Task 子 Agent,其全部输入仅为编写完成的提示词——不得附带对话上下文或评论。
- 按失败即关闭原则给出结果。 审查者的结构化输出就是判定结果——不设合并步骤。仅当每条规则均为 PASS 或 N/A 时,总体判定才为 PASS;任何一条 FAIL 都会导致门禁失败。绝不取平均、衡量严重程度或豁免规则——“轻微”的 FAIL 也是 FAIL。如果审查者返回“GATE NOT APPLICABLE”(目标中没有 Python 源代码),则停止并报告此结果,不要给出判定。
- 呈现判定结果。 填写 assets/templates/verdict.md。若为 FAIL,将审查者提出的“通过所需的改动”建议汇总到修复清单中,每项注明位置,并按类别重要性排序。每条结果为 FAIL 的规则都必须出现在修复清单中,且改动必须具体到可直接照此实施——如果审查者的建议只是在重述违规内容,则根据规则中的正确示例推导修复方案后再呈现。
如果同一规则在对未变更目标的重复审查中判定结果反复变化,或人工查看证据后推翻判定结果,则说明该规则存在可判定性缺陷——请将其记录到 gotchas.md 并完善规则;不要推翻门禁结果。
Verdict Format
审查者需对每条规则返回:PASS | FAIL | N/A、证据(file:line 或引文——PASS 和 FAIL 均必须提供),以及每条 FAIL 对应的修复方案;应用该方案后,该规则应转为 PASS。修复方案必须写明改动及其位置,不能只是重述违规内容。最终报告遵循 assets/templates/verdict.md。
规则类别
| # | 类别 | 前缀 | 所要约束的错误默认做法 |
|---|---|---|---|
| 1 | 分发与控制流 | disp- | 设计中已有分发结构,却仍使用分支链——在注册表/match 上使用事件/版本 if/elif 链、对模式使用 isinstance 分支链、重复使用状态字面量而非 StrEnum,以及用布尔参数分叉整个函数体 |
| 2 | 数据建模 | model- | 数据始终没有明确结构——手写 __init__/__repr__/__eq__ 而非使用 @dataclass(slots=True)、将一堆参数穿过多个签名传递,以及越过边界后仍用字符串键访问外部载荷 |
| 3 | 抽象层级 | alt- | 只增加间接层而不做决策的层——单方法类、1:1 透传包装器、只有一个实现的 ABC(消费者一侧的 Protocol 才是抽象边界),以及为复用而使用具体类继承 |
| 4 | 现代类型标注 | typing- | 因习惯沿用 Python 3.10 之前的写法——使用 typing.List/Optional/Union 而非内置类型和 X | None,使用 TypeVar/Generic 而非 PEP 695,使用类名作为返回类型而非 Self |
| 5 | 标准库更新 | std- | 手动造轮子——用 os.path 操作路径而非 pathlib、重新实现 batched/pairwise/cache/tomllib、使用已弃用的 utcnow(),以及对独立数据源使用未经检查的 zip;版本差异说明还会补充此类别 |
| 6 | 异步与错误流 | flow- | 消失的失败路径——使用即发即弃的 create_task 而非 TaskGroup,以及使用宽泛的 except 处理代码块,却不记录日志或留存信息而直接吞掉异常 |
注意事项
分派审核者之前,请先阅读 gotchas.md——其中预先记录了范围限制(版本探测的边缘情况、关注形态而非品牌、搜索差异与搜索整个代码库的要求,以及“绿地判断”的许可范围),避免审核者超出规则进行判断。
相关技能
adversarial-ts-patterns— 针对同一问题(过度抽象和建模不足)的 TypeScript/React 配套规则;协议相同,语言不同。radical-simplification— 提供建议的配套技能:当你想要修复未通过的评审结果,而非对其进行判断时,可借助其中简化复杂性的思路。
参考文件
| 文件 | 描述 |
|---|---|
| references/reviewer-prompt.md | 适用于每位盲审者的独立提示词模板 |
| assets/templates/verdict.md | 评审报告模板 |
| references/_sections.md | 类别定义与顺序 |
| metadata.json | 版本、verified_python 和来源参考 |