引言 (Introduction)
收到了关于 CI 中持续失败用例的详细分析报告。这份报告质量很高,其列出的四个阻塞性缺陷(B1-B4)与我之前从架构层面指出的脆弱性完全吻合。这再次证明,当前合并器的核心逻辑已经不可靠,必须进行根本性修复,而非表面修补。
我将整合这份详细的分析,发布一份权威的、指导性的 Issue,作为后续所有相关修复工作的唯一参考。
Canonical Issue #40 (重构版): 核心合并逻辑存在架构性缺陷,导致四个可复现的阻塞级 Bug
- 标签 (Labels):
bug, priority:critical, architecture, refactor, merger-logic
- 状态 (Status):
Open
1. 背景与现象 (Background & Phenomena)
在 PR「增强变量绑定与作用域隔离」合并后,ASTAuditor 的健壮性得到提升,但这反而更加暴露了合并器 advanced_merge.py 自身的严重缺陷。当前 CI 中持续的测试失败,均由合并器逻辑引起。
具体现象与我分析的根因对应如下:
| 现象 ID |
具体表现 (Symptom) |
根因分析 (Root Cause Analysis) |
| F-1 |
本应抛出 CircularDependencyError 的用例,执行时畅通无阻。 |
依赖图构建不完整。ContextAwareVisitor 这个“上帝对象”未能捕捉到所有依赖边,导致提供给拓扑排序算法的是一张错误的、没有环路的图。 |
| F-2 |
super().__init__() 等属性调用链,在合并后被错误截断为裸的 __init__。 |
错误的属性访问转换。AdvancedNodeTransformer.visit_Attribute 在替换属性链的根节点时,逻辑存在缺陷,直接丢弃了后续的属性访问 (.attr)。 |
| F-3 |
合并后的代码运行时出现 NameError 或 TypeError。 |
失败的符号冲突策略。当用户定义的函数名与导入的模块别名冲突时,generate_name_mappings 的决策失误,可能错误地重命名了用户代码,或产生了覆盖。 |
| F-4 |
外部模块别名(Alias)的重命名策略混乱且不一致。 |
缺乏单一入口和状态管理。重命名逻辑分散在 _process_imports 和 AdvancedNodeTransformer 中,导致对同一个别名进行多次、不同规则的重命名。 |
2. 修复标准 (Acceptance Criteria / Expected Behavior)
- 循环依赖 (F-1): 任何存在于代码逻辑中的循环依赖,必须被检测到,并抛出
CircularDependencyError,报告中应包含清晰的循环路径。
- 属性链 (F-2): 任何属性调用链(如
a.b.c, super().__init__)在合并后必须保持其完整结构,不允许任何形式的截断。
- 命名冲突 (F-3): 当用户代码(函数/类)与导入别名冲突时,必须优先重命名导入别名,绝不允许修改用户定义的符号名称。
- 别名后缀 (F-4): 必须采用统一且无歧义的别名重命名策略,并在整个合并流程中只执行一次。我在此规定:
- 静态外部导入:
xxx → xxx__mod
- 运行时导入 (
try/except):xxx → xxx__rt
3. 建议的修复路线与任务清单 (Suggested Fix Route & Task List)
请严格按照以下路线图执行修复,不要偏离。
-
[ ] 修复 F-2 (属性链截断)
- 方法: 这是最直接的修复。修改
AdvancedNodeTransformer.visit_Attribute,确保在递归访问 node.value 后,用返回的新节点重新构建 ast.Attribute。
# In AdvancedNodeTransformer
def visit_Attribute(self, node: ast.Attribute) -> ast.AST:
# 1. 递归访问并替换属性链的根 (base)
new_base = self.visit(node.value)
# 2. 用新的 base 和旧的 attr 重建节点,保证属性链不丢失
return ast.Attribute(value=new_base, attr=node.attr, ctx=node.ctx)
-
[ ] 修复 F-4 (别名命名混乱)
- 方法: 统一改名入口,避免重复执行。
- 移除
_process_imports 中的所有重命名逻辑,让它只负责去重。
- 所有重命名逻辑集中到
AdvancedNodeTransformer 的 visit_Import 和 visit_ImportFrom 方法中。
- 在
ast.alias 节点上设置一个临时标记(如 alias._renamed = True)来防止同一个节点被重复处理。
-
[ ] 修复 F-3 (命名冲突策略)
- 方法: 在
generate_name_mappings 或 _write_symbol 中明确决策逻辑。
- 当检测到名称冲突时,检查每个冲突符号的类型 (
symbol.type)。
- 如果符号类型是
import_alias,则对其应用重命名。
- 如果符号类型是
function 或 class,则保持其原名(除非存在多个同名函数/类)。
- 增加往返测试 (Round-trip Test):创建一个新的测试,先调用
advanced_merge.py 生成合并文件,然后 import 并执行该文件,断言其运行结果正确,没有抛出 NameError 或 TypeError。
-
[ ] 修复 F-1 (循环依赖检测)
- 方法: 这个问题根源最深,在前三者修复之后处理。
- 深入调试
ContextAwareVisitor,特别是 analyze_dependencies 方法。
- 针对失败的用例,手动画出正确的依赖图,然后对比程序生成的
symbol.dependencies,找出缺失的依赖边。
- 在
topological_sort 的末尾增加断言:检查图中是否还存在入度大于 0 的节点。如果存在,说明环路依然存在,此时应打印出这些节点的详细信息以辅助调试。
-
[ ] CI 与兼容性:
- 移除对 Python 3.8 的支持,或为
ast.unparse 等不兼容的 API 引入兼容层,以保证 CI 的稳定。
重申:Issue #41 依然有效
最后,我必须重申,我之前提交的 Issue #41: ASTAuditor 的属性验证存在致命盲区 依然是开放且关键的。它与此处的合并器问题是独立的。在修复完合并器的这些缺陷后,必须立即着手解决审计器的“虚假安全感”问题。
将这份整合后的 Issue 分配下去。我要求看到的是针对这些根本问题的架构性修复,而不是更多的临时补丁。
引言 (Introduction)
收到了关于 CI 中持续失败用例的详细分析报告。这份报告质量很高,其列出的四个阻塞性缺陷(B1-B4)与我之前从架构层面指出的脆弱性完全吻合。这再次证明,当前合并器的核心逻辑已经不可靠,必须进行根本性修复,而非表面修补。
我将整合这份详细的分析,发布一份权威的、指导性的 Issue,作为后续所有相关修复工作的唯一参考。
Canonical Issue #40 (重构版): 核心合并逻辑存在架构性缺陷,导致四个可复现的阻塞级 Bug
bug,priority:critical,architecture,refactor,merger-logicOpen1. 背景与现象 (Background & Phenomena)
在 PR「增强变量绑定与作用域隔离」合并后,
ASTAuditor的健壮性得到提升,但这反而更加暴露了合并器advanced_merge.py自身的严重缺陷。当前 CI 中持续的测试失败,均由合并器逻辑引起。具体现象与我分析的根因对应如下:
CircularDependencyError的用例,执行时畅通无阻。ContextAwareVisitor这个“上帝对象”未能捕捉到所有依赖边,导致提供给拓扑排序算法的是一张错误的、没有环路的图。super().__init__()等属性调用链,在合并后被错误截断为裸的__init__。AdvancedNodeTransformer.visit_Attribute在替换属性链的根节点时,逻辑存在缺陷,直接丢弃了后续的属性访问 (.attr)。NameError或TypeError。generate_name_mappings的决策失误,可能错误地重命名了用户代码,或产生了覆盖。_process_imports和AdvancedNodeTransformer中,导致对同一个别名进行多次、不同规则的重命名。2. 修复标准 (Acceptance Criteria / Expected Behavior)
CircularDependencyError,报告中应包含清晰的循环路径。a.b.c,super().__init__)在合并后必须保持其完整结构,不允许任何形式的截断。xxx→xxx__modtry/except):xxx→xxx__rt3. 建议的修复路线与任务清单 (Suggested Fix Route & Task List)
请严格按照以下路线图执行修复,不要偏离。
[ ]修复 F-2 (属性链截断)AdvancedNodeTransformer.visit_Attribute,确保在递归访问node.value后,用返回的新节点重新构建ast.Attribute。[ ]修复 F-4 (别名命名混乱)_process_imports中的所有重命名逻辑,让它只负责去重。AdvancedNodeTransformer的visit_Import和visit_ImportFrom方法中。ast.alias节点上设置一个临时标记(如alias._renamed = True)来防止同一个节点被重复处理。[ ]修复 F-3 (命名冲突策略)generate_name_mappings或_write_symbol中明确决策逻辑。symbol.type)。import_alias,则对其应用重命名。function或class,则保持其原名(除非存在多个同名函数/类)。advanced_merge.py生成合并文件,然后import并执行该文件,断言其运行结果正确,没有抛出NameError或TypeError。[ ]修复 F-1 (循环依赖检测)ContextAwareVisitor,特别是analyze_dependencies方法。symbol.dependencies,找出缺失的依赖边。topological_sort的末尾增加断言:检查图中是否还存在入度大于 0 的节点。如果存在,说明环路依然存在,此时应打印出这些节点的详细信息以辅助调试。[ ]CI 与兼容性:ast.unparse等不兼容的 API 引入兼容层,以保证 CI 的稳定。重申:Issue #41 依然有效
最后,我必须重申,我之前提交的 Issue #41: ASTAuditor 的属性验证存在致命盲区 依然是开放且关键的。它与此处的合并器问题是独立的。在修复完合并器的这些缺陷后,必须立即着手解决审计器的“虚假安全感”问题。
将这份整合后的 Issue 分配下去。我要求看到的是针对这些根本问题的架构性修复,而不是更多的临时补丁。