Page 44 - 《软件学报》2025年第4期
P. 44
1450 软件学报 2025 年第 36 卷第 4 期
被传入的关键字集合. 第 11、12 行的 TravelExceptionAboutKwargs 表示遍历与关键字参数有关的异常流信息, 若
P.kwargs 没有关键字 key 时 API 会抛出异常, 则将 key 存入 KY; 若 P.kwargs 有关键字 key 时, API 会抛出异常,
则将 key 存入 KN. 若 v1 版本和 v2 版本的 KY 或 KN 存在差异, 则该 API 存在关键字参数的键增删 (CI2).
第 18–21 行检测参数的范围改变 (CI5). 其中, 第 19 行的 Raise(condition, E) 表示通过分析 API 的异常流信息
E, 判断条件 condition 成立时 API 是否会抛出异常. 如果会抛出异常, Raise(condition, E) 返回相应的异常类型; 否
则返回 False. 如果某异常仅在 v2 版本抛出而不在 v1 版本抛出 (第 19 行), 并且该异常的触发条件与某参数的输
入有关 (第 20、21 行), 则该 API 存在参数的范围改变 (CI5).
例 7: 示例代码 2 中, 算法 1 第 2 行 P D 、P A 和 P M 分别初始化为{‘fname’, ‘encoding’}、{‘path’}和{‘self’,
‘convert_dates’, ‘write_index’, ‘byteorder’}. 由 M.change∪M.unchange={<s 3 , s 3 >, <s 4 , s 5 >, <s 6 , s 6 >}, S 1 .FP[‘fname’]
={s 4 , s 6 }, S 2 .FP[‘path’]={s 5 , s 6 }, 可知参数 fname 和参数 path 前向切片中的保留语句之间存在对应关系. 因此, 第 3、
4 行认为参数 fname 被重命名为 path, 并更新 P D 为{‘encoding’}, P A 为{}, CI 为{CI3}. 由于 Len(P D )>0, 第 5 行更
新 CI 为{CI1, CI3}.
例 8: 示例代码 6 中, E 1 .R={}, E 2 .R={s 4 : <TypeError, ‘labels’ in kwargs>}, 所以算法 1 第 11、12 行中 KN2=
{‘labels’}, KY1=KY2=KN1={}. 由于 KN1 与 KN2 不相等, 更新 CI 为{CI2}.
例 9: 示例代码 3 中, S 2 .FP[‘self’]={s 3 , s 4 }, E 1 .R={s 4 : <ValueError, not self.index.is_monotonic>}, E 2 .R={s 4 :
<ValueError, not self.index.is_monotonic_increasing>}. 当第 18 行中 s 为 s 4 时, Raise(not self.index.is_
monotonic_increasing, E 1 ) 为 False, 而 s 4 ∈S 2 .FP[‘self’], 所以参数 self 的范围发生改变, 更新 CI 为{CI5}.
3.3.2 检测与异常有关的兼容性问题 (CI6)
检测与异常有关兼容性问题如算法 2 所示, 其输入为异常流信息 E, 输出为兼容性问题产生原因集合 CI, 包括
抛出不同的异常 (CI6).
算法 2. 检测与异常有关的兼容性问题.
输入: E;
输出: CI.
Function DetectException AttributeError, 这导致算法
1. for each s in E 2 .R then:
2. exception 1 = Raise(E 2 .R[s].condition, E 1 )
3. CI ← {CI6} if exception 1 != False and exception 1 != E 2 .R[s].exception
4. return CI
Function End
算法 2 展示了检测抛出不同的异常 (CI6) 的具体流程. 如果相同条件 E 2 .R[s].condition 下, v1 版本和 v2 版本
均抛出异常, 但抛出的异常类型不同, 则认为该 API 存在抛出不同的异常 (CI6).
例 10: 示例代码 5 中, E 1 .R={s 5 : <AttributeError, AttributeNotFound(ctx, app) OR AttributeNotFound(ctx.app,
update_template_context)>}, E 2 .R={s 4 : <RuntimeError, ctx is None>}. 当 ctx is None 条件在 v1 版本成立时, 会在 s 5
抛出异常 AttributeError, 即 exception 1 为 2 第 3 行的条件成立, 更新 CI 为{CI6}.
3.3.3 检测与返回值有关的兼容性问题 (CI7)
检测与返回值有关的兼容性问题如算法 3 所示, 其输入为语句匹配信息 M、返回值信息 R、异常流信息 E、
切片信息 S、全局语句信息 G 以及条件分支信息 B, 输出为兼容性问题产生原因集合 CI, 包括输出不同的返回值 (CI7).
首先, 第 1–23 行计算 API 从 v1 版本更新至 v2 版本中的良性变化语句集合 BSC 1 和 BSC 2 . 根据文献 [12], 当
第三方库进行更新时, 由于修复缺陷、提升性能、重构方法等原因, 可能会发生良性的语义变化 (benign semantic
change), 这些变化通常不被视为兼容性问题. 对于缺陷修复而言, 它不符合兼容性问题定义中的第 1 个条件, 即在