真实来源改编 SymPy issue + SWE-bench / PatchDiff 中的 AI 错误补丁案例。Review 001
001ReviewMidPython / SymPy

这个 AI 修复能合并吗?

你正在审核一个 AI agent 生成的补丁。补丁声称修复 SymPy 中 `Point2D` 在 `evaluate(False)` 下误报 `Imaginary coordinates are not permitted` 的问题。

你的任务

阅读下面的 AI PR diff,判断它是否可以 merge。如果不能,需要指出具体问题、影响和修复建议。你不需要了解整个 SymPy 项目,只需要围绕本页给出的行为规则和 diff 做判断。

是否可以合并:可以 / 不可以 / 需要更多信息

问题 1:
- 严重程度:
- 问题描述:
- 影响说明:
- 修复建议:

问题 2:
...

题目上下文

Python

`Point` / `Point2D` 是 SymPy 里的几何点对象。坐标必须是合法的 SymPy 表达式,并且不能是明确的虚数坐标。

`evaluate(False)` 表示临时关闭部分自动化简。真实 issue 的问题是:关闭自动化简后,普通坐标也可能被旧逻辑误判, 从而抛出 `Imaginary coordinates are not permitted`。

这道题要练的是 code review 判断力:一个补丁修好 happy path 之后,是否仍然保留了原有输入约束和边界语义。

术语速查

不用先学完整 SymPy
PR / diff

PR 是一次代码变更提议,diff 展示这次变更具体改了哪些行。

merge / request changes

merge 表示接受变更;request changes 表示发现必须修复的问题,暂时不能进主分支。

回归

修一个问题时,把原本正确的行为弄坏。Review Mode 很多题都在考这个。

边界条件 / 负例测试

边界条件是容易暴露错误的输入;负例测试用来确认非法输入仍然会被拒绝。

Point / Point2D

SymPy 里的几何点对象。这里你只需要知道:点坐标有一组原有合法性约束。

evaluate(False)

临时关闭部分自动化简。它可能让表达式保持未化简状态,所以要留意分支判断是否被影响。

im(a)

读取表达式 a 的虚部。你不需要掌握 SymPy 内部,只要知道它参与坐标合法性判断。

a.is_number

判断 a 是否是具体数值。审核时要看它被放进条件判断后,是否改变了输入分类。

推荐审核流程

review path
  1. 先看改动点先确认 PR 声称修复什么用户问题,再看 diff 改了哪条校验逻辑。
  2. 再看新增测试新增测试通常能证明一个正向场景,也要检查是否覆盖了反向场景和边界输入。
  3. 对照原有约束判断补丁是精确修复,还是只让某个 case 通过并顺手放宽了旧规则。
  4. 主动找反例想一类补丁作者没有写进测试、但原有约束必须继续成立的输入。
  5. 给出 merge 结论如果有回归风险,就写出 blocking finding、影响和可执行修复方向。

审查清单

不要只看 happy path
输入类型原有约束你要验证的问题
普通数值坐标不应因为关闭自动化简被误拒新增测试是否只证明了这个正向场景
明显非法的坐标原有非法输入校验仍应清楚可解释PR 是否改变了合法 / 非法输入的分类边界
无法静态确定的符号坐标不应被粗暴当成非法输入条件判断是否把 unknown 和 invalid 混成一种

AI PR 变更

ai-pr.diff
diff --git a/sympy/geometry/point.py b/sympy/geometry/point.py
index 73c20334d09e..ai0000000000 100644
--- a/sympy/geometry/point.py
+++ b/sympy/geometry/point.py
@@ -149,7 +149,7 @@ def __new__(cls, *args, **kwargs):
         if any(coords[dim:]):
             raise ValueError('Nonzero coordinates cannot be removed.')
-        if any(a.is_number and im(a) for a in coords):
+        if evaluate and any(a.is_number and im(a) for a in coords):
             raise ValueError('Imaginary coordinates are not permitted.')
         if not all(isinstance(a, Expr) for a in coords):
             raise TypeError('Coordinates must be valid SymPy expressions.')
diff --git a/sympy/geometry/tests/test_point.py b/sympy/geometry/tests/test_point.py
index 930d707735e2..ai1111111111 100644
--- a/sympy/geometry/tests/test_point.py
+++ b/sympy/geometry/tests/test_point.py
@@ -1,5 +1,6 @@
 from sympy.core.basic import Basic
 from sympy.core.numbers import (I, Rational, pi)
+from sympy.core.parameters import evaluate
 from sympy.core.singleton import S
 from sympy.core.symbol import Symbol
 from sympy.core.sympify import sympify
@@ -452,6 +453,12 @@ def test__normalize_dimension():
         Point(1, 2, 0), Point(3, 4, 0)]
 
 
+def test_issue_22684():
+    # Used to give an error
+    with evaluate(False):
+        Point(1, 2)
+
+
 def test_direction_cosine():
     p1 = Point3D(0, 0, 0)
     p2 = Point3D(1, 1, 1)

提交你的审核

本地 Review 反馈
1. 这个 PR 能不能合并?