Python 语义版本控制对参数名称更改意味着什么?

Python 语义版本控制对参数名称更改意味着什么?,python,semantic-versioning,Python,Semantic Versioning,试图向朋友解释语义版本控制的重要性,我面临以下困境 假设我们有一个库libfoo,版本1.2.3,它公开了以下函数: def foo(x, y): """ Compute the sum of the operands. :param x: The first argument. :param y: The second argument. :returns: The sum of `x` and `y`. """ return x + y

试图向朋友解释语义版本控制的重要性,我面临以下困境

假设我们有一个库
libfoo
,版本
1.2.3
,它公开了以下函数:

def foo(x, y):
    """
    Compute the sum of the operands.
    :param x: The first argument.
    :param y: The second argument.
    :returns: The sum of `x` and `y`.
    """
    return x + y
现在假设此函数及其文档更改为:

def foo(a, b):
    """
    Compute the sum of the operands.
    :param a: The first argument.
    :param b: The second argument.
    :returns: The sum of `a` and `b`.
    """
    return a + b
我的第一印象是,下一个版本将是
1.2.4
,因为公共界面没有改变。例如,像这样调用函数的人根本不会注意到更改:

foo(3, 4)
但再进一步考虑,这很可能是一个API中断,因为Python允许通过名称指定参数。如果有人调用我的函数,比如:

foo(y=4, x=3)
这将不再适用于版本
1.2.4
,从而破坏了语义版本控制契约

另一方面,这样的更改似乎太小了,如果将版本增加到
2.0.0
,我会感到很遗憾


总而言之,这是否构成API中断?在这种情况下,下一个版本号应该是什么?

这种类型的更改可能会在发布规模上分为许多不同的领域

重大变化(从1.x增加到2.x) 这打破了API合同,将被视为一个重大变更。不过,要注意的是,这是否是唯一的变化。如果是的话,我不会把它作为一个重大的版本更改。另一方面,如果这是破坏API契约的众多更改之一,我相信一个主要的版本增量是合理的

微小变化(从1.2增加到1.3) 借用Python:

次要版本号[增加]以减少惊天动地的变化

对我来说,这只是一个小小的改变。正如您所说,如果用户没有命名他们的参数,他们甚至不会注意到已经发生了更改

微小变化(从1.2.3增加到1.2.4) 这是您的bug修复级别的更改。如果因为它是一个bug而将
foo(x,y)
更改为
foo(a,b)
,那么此修复程序证明了微点增量的合理性



我对这种变化的看法是把它变成一个小的变化。这当然不是一个“惊天动地”的变化,但它确实有可能迫使最终用户更改代码。我不会将其归类为重大更改,因为它只是在函数调用上更改参数名称,否则,函数调用的行为方式完全相同,返回完全相同的数据,并将完全相同的数据作为参数,但仅将其应用于函数中的不同名称。

简短回答:是,我认为将构成API中断,从而可能增加主要版本号。不过,请注意下面的注意事项


当您公开公共/外部API时,您需要承担额外的“注意义务”,仔细考虑接口的更改。例如,这包括推迟潜在的改进以避免破坏向后兼容性*。在维护API时,应该非常仔细地考虑任何可能影响使用接口的代码的更改

问题是明确的:

如果对公共API引入任何向后不兼容的更改,则必须增加主版本X(X.y.z | X>0)

正如您在问题中所指出的,更改参数的名称会导致按关键字传递参数的代码向后不兼容

然而,与其说这一更改应该增加主要版本,不如说不应该进行更改,或者至少不应该单独进行更改-这一更改太小,无法证明可能会破坏现有有效代码的主要增加是合理的。但以下情况除外:

  • 这是一些更大的重要变化的一部分;或
  • 对于您的示例中没有显示的更改,有一个非常好的理由(一些显示停止bug,或者其他依赖它的特性) 我会把零钱全部推迟。最好放慢速度,并确保继续满足语义版本控制契约,只有在有充分理由这样做的情况下才进行此类更改


    从中,您可以指定仅用于位置的参数,并调用此类问题 作为理由的一部分(我的重点):

    如果API的调用方开始使用关键字参数,则库 作者无法重命名该参数,因为该参数将被破坏 更改

    在这种情况下,如果原始定义是:

    定义foo(x,y,/): 然后重命名参数将而不是是一个突破性的改变


    *当我们在Python标记中时,考虑整数除法,尽管,在2天时,它仍然存在。


    **我说“合法”是为了排除官方文档中没有使用它的代码,例如通过访问约定的私有属性——他们应该期望偶尔会遇到不便!因此,如果您预测了此更改,并且明确指定只使用位置参数,则此更改是可以的,但这将是一个奇怪的选择。

    从另一个角度考虑—考虑到您正在尝试维护版本控制契约,您是否会自行更改(可能会破坏)接口?或者你会推迟更改直到你有足够的更改(或者其他很好的理由)来证明新的整数版本的合理性吗?@jornsharpe:当然。但问题更多的是关于“一个人是否可以在代码库中安全地这样做,或者他/她是否必须假设这是API中断?”并且正如您正确地指出的,“他/她是否应该将此类更改推迟到下一版本?”这对您来说很小。我经常使用关键字参数,即使它们不是必需的(为了更明确,尤其是当有3个以上的参数时),所以这样的机会可能会破坏代码