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

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


                    可变参数和关键字参数: 可变参数可以接受任意数量的值, 包括不传递任何值, 而关键字参数可以接受任意数
                 量的键值对, 包括不传递任何键值对. 因此, 当第三方库               API 新增可变参数和关键字参数时, 不会对上层应用造成
                 破坏性影响.
                    (2) 参数的删除: 如表    6  所示, 无论何种类别的参数, 一旦发生删除操作, 都会导致兼容性问题. 这是因为删除
                 参数会导致上层调用中原本用于赋值给被删除参数的值冗余, 从而影响代码正常执行.

                                   表 6 由于参数删除原因导致的          Python  第三方库  API 兼容性问题

                                 删除该类参数是否                                示例代码
                     参数类别
                                 会造成兼容性问题               第三方库API代码              受兼容性问题影响的上层应用代码
                                                    -  def foo(a, b):
                     位置参数            一定是            +  def foo(a):                   foo(‘  a’, ‘b’)
                                                          pass                       foo(a=‘a’, b=‘b’)
                                                    -  def foo(a=0, b=1):            foo(‘a  ’, ‘b’)
                     默认参数            一定是            +  def foo(a=0):                 foo(a=‘a’, b=‘b’)
                                                          pass                       foo(b=‘  b’)
                                                    -  def foo(*arg):
                     可变参数            一定是            +  def foo():                      foo(0, 1, 2)
                                                          pass
                                                    -  def foo(*, key1=1, key2):
                  命名关键字参数            一定是            +  def foo(*):                 foo(key1=‘1’, key2=‘2’)
                                                                                   foo(key2=‘  2’)
                                                          pass
                                                    -  def foo(**kwargs):
                    关键字参数            一定是            +  def foo():                     foo(key=‘key’)
                                                          pass

                    1  个  API 的兼容性问题由关键字参数的键增删           (CI2) 导致. 关键字参数的键增删指关键字参数所需传入键的
                 增加或删除, 此种原因导致的兼容性问题表现为非法输入参数值                     (S2). 当  API 有关键字参数时, API 内部会对关键
                 字参数的各个键值对进行读写. 当          API 内部需要对键     key  进行读取, 但  API 调用者未对键    key  传值时, API 会抛出
                 异常  KeyError. 若  API 内部不允许传入键   key, 但 (CI3) 导致. 由于在调用
                                                       API 调用者对键
                                                                       传值时, API 也会抛出异常.
                                                                   key
                    例  4: 示例代码  6 中, 在  v2 版本  pandas1.0.0 中, 新增的第  3、4 行不再允许关键字参数    kwargs 被传入键   labels.
                 示例代码   6. 关键字参数的键增删       (CI2).
                 # 版本变更: pandas0.25.3 → pandas1.0.0
                 1       def copy(self, names=None, dtype=None, levels=None, codes=None, deep=False, _set_identity=False,
                          **kwargs):
                 2       name = kwargs.get(‘name’)
                 3    +   if ‘labels’ in kwargs:
                 4    +    raise TypeError(“ ‘labels’ argument has been removed; use ‘codes’ instead”)
                 5        ...

                    3  个  API 的兼容性问题由参数的重命名                            API 时可以使用键值对的形式传递参数, 若
                 第三方库   API 发生参数的重命名, 则会导致上层应用无法运行. 此种原因导致的兼容性问题表现为输入参数格式
                 错误  (S1).
                    11  个  API 的兼容性问题由参数默认值的改变          (CI4) 导致. 参数默认值的改变是默认参数和命名关键字参数特
                 有的兼容性问题. 若它们的参数默认值发生改变, 则                API 内部与这些参数相关的行为也会随之改变, 进而可能导
                 致  API 的输出内容发生变化, 从而影响上层应用的正常运行. 此种原因导致的兼容性问题表现为输出变量值错误                             (S4).
                    45  个  API 的兼容性问题由参数的范围改变          (CI5) 导致. 参数的范围改变指第三方库         API 更新后对输入参数
   34   35   36   37   38   39   40   41   42   43   44