1

I'm looking for a foolproof way to sort a list of semantic version strings in python3 without use of the third-party semver module.

For instance, if I have a list like this:

versions_list = ["1.0.0", "1.0.0-alpha", "11.3.3", "1.0.12", "1.0.0-0", "1.0.0+rc1", ]

I'd like it to sort to the rules of semantic versioning

# Oldest to "Newest"
versions_list = ['0.0.1', '1.0.0-0', '1.0.0-alpha', '1.0.0+rc1', '1.0.0', '1.0.12', '11.3.3']

This is the best I could come up with, utilizing the semver regex from https://semver.org/

# From semver.org 
>>> semver = re.compile(r'^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P<buildmetadata>[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$')

# Unsorted
>>> l = ["0.0.1", "1.0.0", "1.0.0-alpha", "11.3.3", "1.0.12", "1.0.0-0", "1.0.0+rc1"]

# Sort via sorted() and lambda creating list from regex match groups
>>> sorted_l = sorted(l, key=lambda w: [[int(x.group('major')), int(x.group('minor')), int(x.group('patch')), str(x.group('prerelease') or 'zzzzzz'), str(x.group('buildmetadata') or 'zzzzzzz')] for x in [semver.match(w)]])

>>> print(sorted_l)
['0.0.1', '1.0.0-0', '1.0.0-alpha', '1.0.0+rc1', '1.0.0', '1.0.12', '11.3.3']

But I was wondering if there is a way without the hack I had using the 'zzzzzzz' on the None/no match groups.

tgh4492382
  • 27
  • 2
  • 1
    Related: [Sort Versions in Python](https://stackoverflow.com/q/12255554/11082165), and [Sorting a list of dot-separated numbers, like software versions](https://stackoverflow.com/q/2574080/11082165). However, those questions _are not_ duplicates, since they do not deal with the complications of correctly sorting prereleases and builds in a semver compatible way. – Brian61354270 Feb 07 '23 at 15:56
  • 1
    I started writing an answer, but I'm pretty sure I would just be reimplementing that other module from scratch. – Karl Knechtel Feb 07 '23 at 16:01
  • 1
    Actually, distutils will soon be deprecated. It will be time to update the answer to the related question :) – Stef Feb 07 '23 at 16:23
  • Exactly, I saw the distutils solution, but then also saw that was being removed in 3.11 – tgh4492382 Feb 08 '23 at 01:31

0 Answers0