Description
Situation
The min_ver
and max_ver
functions have currently this signature:
def max_ver(ver1, ver2):
# ...
def min_ver(ver1, ver2):
# ...
In other words, these functions allow to compare exactly two versions. However, there may be situations, where you have a list of versions. This use case could not be done with the current implementation and needs a cumbersome for-loop.
As we have comparison operators, there is no need for this functions anymore. Of course, this works only for VersionInfo types, not strings. If someone still wants to compare strings, we could document a replacement.
Action Items:
- add deprecation warning for both functions
- document replacement; maybe something like:
max(map(semver.VersionInfo.parse, ['1.1.0', '1.2.0', '2.1.0', '0.5.10', '0.4.99']))
Old issue:
Suggested Solution
To allow to compare more than two versions, it would be useful to change the above signature like this:
def max_ver(ver1, ver2, *others):
# ...
def min_ver(ver1, ver2, *others):
# ...
This would resemble the builtin functions min
and max
. The above functions could be used like this:
from semver import max_ver
m = max_ver("3.0.0", "2.0.0", "1.0.0", "4.0.0")
print(m)
# => "1.0.0"
Benefits:
- No incompatible changes to API; it's still possible to use two arguments
- Only minimal changes in the implementation
Alternative Solution
The proposed solution may has some drawbacks:
- it doesn't allow to pass an iterable (like the builtin functions
min
andmax
). - could hit a performance bottleneck
If you don't like the proposed solution, we could:
- leave the current implementation of
min_ver
andmax_ver
untouched, or, - allow iterables in
min_ver
andmax_ver
(would introduce incompatible API changes), - introduce additional functions with the suffix
_iter
which allows to optimize for iterables. The signature could be:
def max_ver_iter(iterable, *, default=None, key=None):
"""Returns the biggest version from an iterable
:param iterable: an iterable with version strings
:param default: specifies an object to return if the provided iterable is empty.
:param key: specifies a one-argument ordering function like that used for list.sort()
:raises: ValueError (If the iterable is empty and default is not provided)
"""
Questions
- Does it make sense?
- Should we raise something if the
*others
tuple contains an invalid version? - Should we ignore invalid versions? Or provide a flag (something like
raise_if_invalid
) which can be set? - Anything else?