Page 43 - 《软件学报》2025年第4期
P. 43

沈阚 等: 基于静态分析的      Python  第三方库  API 兼容性问题检测方法                                  1449



                 算法  1. 检测与参数有关的兼容性问题.

                 输入: M, P, E, S;
                 输出: CI.

                 Function DetectParam:
                 1.  CI = {}
                 2.  P D  = Name(P 1 )–Name(P 2 ), P A  = Name(P 2 )–Name(P 1 ), P M  = Name(P 1 )∩Name(P 2 )
                 3.  P D , P A , P M , IsRename = MATCH(P D , P A , P M , S 1 .FP, S 2 .FP, M.change, M.unchange)
                 4.  CI ← {CI3} if IsRename is True
                 5.  CI ← {CI1} if Len(P D )>0 or Len(P A ∩Name(P 2 .pst))>0
                 6.  max_index =MAX(P 2 .dft[param 2 ].idx for each param 2  in P M ∩Name(P 2 .dft))
                 7.  for each param 2  in P A ∩Name(P 2 .dft) then:
                                     版本中的前向切片保留语句和新增参数
                 8.    CI ← {CI1} if P 2 .dft[param 2 ].idx < max_index
                 9.  for each param 2  in P A ∩Name(P 2 .key) then:
                 10.  CI ← {CI1} if P 2 .key[param 2 ].value is NA
                 11. KY1, KN1 = TravelExceptionAboutKwargs(P 1 .kwargs, S 1 .FP, E 1 )
                 12. KY2, KN2 = TravelExceptionAboutKwargs(P 2 .kwargs, S 2 .FP, E 2 )
                 13. CI ← {CI2} if KY1 != KY2 or KN1 != KN2
                 14. for each param in Name(P 1 .dft)∩Name(P 2 .dft) then:
                 15.  CI ← {CI4} if P 1 .dft[param].value != P 2 .dft[param].value
                 16. for each param in Name(P 1 .key)∩Name(P 2 .key) then:
                 17.  CI ← {CI4} if P 1 .key[param].value != P 2 .key[param].value
                 18. for each s in E 2 .R then:
                 19.  if Raise(E 2 .R[s].condition, E 1 ) is False then:
                 20.   for each param 2  in P M  then:
                 21.    CI ← {CI5} if s in S 2 .FP[param 2 ]
                 22. return CI
                 Function End
                    算法  1  中, 第  2  行通过比较参数名列表     Name(P 1 ) 和  Name(P 2 ), 获得参数增删的初步结果  P D 、P A  和  P M , 它们
                 分别表示增加、删除和保留的参数集合. 第              3、4  行检测参数的重命名      (CI3). 具体来说, 第  4  行的  MATCH  逐个对
                 比  v1  版本  P D  中的删除参数和  v2  版本  P A  中的增加参数, 通过分析它们的前向切片信息         S.FP  和语句匹配信息    M,
                 判断  API 是否发生重命名并更新         P D 、P A  和  P M . 若对某被删参数  param 1 和某新增参数  param 2 , 集合  S 1 .FP
                 [param 1 ]∩(M 1 .change∪M 1 .unchange) 中的任意语句  s a 在二元组<s a , s b > 中对应的语句  s b , 均满足  s b ∈S 2 .FP[param 2 ],
                 即被删参数    param 1 在  v1                             param 2 在  v2  版本中的前向切片保留语句之间
                 均存在对应关系, 则认为       v1  版本中的参数    param 1 在  v2  版本中被重命名为   param 2 , 并返回  IsRename 为  True. 同
                 时, 更新  P D =P D –{param 1 }, P A =P A –{param 2 }, P M =P M ∪{param 1 , param 2 }.
                    第  5–10  行检测参数的增删     (CI1). 其中, 第  5  行的  Len(Set) 表示集合  Set 中的元素个数. 如果仍存在被删除的
                 参数  (第  5  行), 则认为该  API 存在参数删除导致的兼容性问题. 如果增加位置参数              (第  5  行), 或者增加的默认参数
                 后有保留的默认参数        (第  6–8  行), 或者增加无默认值的命名关键字参数          (第  9、10  行), 则认为该  API 存在参数增
                 加导致的兼容性问题.
                    第  11–13  行检测关键字参数的键增删        (CI2). KY  和  KN  分别表示关键字参数必须传入的关键字集合和不允许
   38   39   40   41   42   43   44   45   46   47   48