What does semantic versioning about parameter name changes mean?

Trying to explain the importance of the semantic version to a friend, I was faced with the following dilemma.

Say we have a libfoo library, version 1.2.3 , which provides the following function:

 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 

Now suppose this function and its documentation change to:

 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 

My first impression was that the next version would be 1.2.4 , since the public interface has not changed. For example, someone calling such a function does not notice the change at all:

 foo(3, 4) 

But, thinking a little further, it can really be a break API , given that Python allows you to specify parameters by their names. If someone had to call my function, for example:

 foo(y=4, x=3) 

this will not work with version 1.2.4 , violating the semantic version contract.

On the other hand, such a change seems so small that I will feel bad about increasing the version to 2.0.0 .

To summarize, does this mean a violation of the API? What should be the next version number?

+5
source share
2 answers

Short answer: yes, I think it will make up the API gap and thus potentially increase the major version number. Please see the warnings below.


When you open the public / external API, you take the additional “responsibility to take care” to think carefully about the changes to the interface. This includes, for example, removing potential improvements to avoid backward compatibility *. Any changes that may affect any code legally ** using your interface should be considered very carefully when you support the API.

The specification for semantic versioning is unambiguous:

The major version of X (Xyz | X> 0) MUST be incremented if any backward incompatible changes are introduced into the open API.

Changing parameter names, as you determined in the question, introduces backward incompatibility for passing code by keywords.

However, instead of saying that this change should increase the main version, I will instead conclude that the change should not be made , or at least not in isolation - this is too small a change to justify the main gain, potentially violating the existing one valid code. Except when:

  • This is part of a larger package of important changes; or
  • There is a really good reason for changes that are not shown in your example (some show stop errors or other functions that rely on it);

I would completely abandon this change. It is better to move slower and make sure that you continue to fulfill your semantic version contract, making such changes only with convincing reasons for this.

* Since we are in the Python tag, consider integer division, which, despite being recognized by the BDFL error , remains at 2.x to this day.

** I say “legal” to exclude the use of code that does not use it as officially documented, for example, by accessing the private-by-convention attributes — they should count on inconvenience on occasion! Therefore, if you predicted this change, and it was clearly stated that only positional arguments should be used, this change would be OK, but it would be a strange choice.

+3
source

This type of change can fall into many different areas of the release scale.

Major change (increase from 1.x to 2.x)

This will violate your API contract and will qualify as a major change. A massive caveat to this, however, is whether this is the only change. If so, I would not change this version. If, on the other hand, this is one of many changes that also violate your API contract, I believe that increasing the main version is justified.

Minor change (increase from 1.2 to 1.3)

Borrowing from the Python documentation:

minor version number [is] increases for less damaging earthquakes.

For me, this is a minor change. As you say, if users don’t name their parameters, they don’t even notice that a change has occurred.

Micro Change (Increment from 1.2.3 to 1.2.4)

This is your level of error correction. If you change foo(x, y) to foo(a, b) because it is a mistake, then this correction justifies the growth of the microdot.


My opinion on such changes should be to make it a Minor Change. This, of course, is not a “terrific” change, but it could potentially lead to code changes for your end users. I would not classify this as a major change, because it changes the parameter names only to a function call, which otherwise behaves exactly the same, returns exact data and takes the same data as the parameters, but just applies them to different names inside the function.

0
source

Source: https://habr.com/ru/post/1212056/


All Articles