Using semver¶
The semver module can store a version in different types:
- as a string.
- as
semver.VersionInfo, a dedicated class for a version type. - as a dictionary.
Each type can be converted into the other, if the minimum requirements are met.
Knowing the Implemented semver.org Version¶
The semver.org is the authorative specification of how semantical versioning is definied. To know which version of semver.org is implemented in the semver libary, use the following constant:
>>> semver.SEMVER_SPEC_VERSION
'2.0.0'
Creating a Version¶
A version can be created in different ways:
as a complete version string:
>>> semver.parse_version_info("3.4.5-pre.2+build.4") VersionInfo(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4') >>> semver.VersionInfo.parse("3.4.5-pre.2+build.4") VersionInfo(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')
with individual parts:
>>> semver.format_version(3, 4, 5, 'pre.2', 'build.4') '3.4.5-pre.2+build.4' >>> semver.VersionInfo(3, 5) VersionInfo(major=3, minor=5, patch=0, prerelease=None, build=None)
You can pass either an integer or a string for
major,minor, orpatch:>>> semver.VersionInfo("3", "5") VersionInfo(major=3, minor=5, patch=0, prerelease=None, build=None)
In the simplest form,
prereleaseandbuildcan also be integers:>>> semver.VersionInfo(1, 2, 3, 4, 5) VersionInfo(major=1, minor=2, patch=3, prerelease=4, build=5)
Parsing a Version String¶
“Parsing” in this context means to identify the different parts in a string.
With
semver.parse_version_info():>>> semver.parse_version_info("3.4.5-pre.2+build.4") VersionInfo(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')
With
semver.VersionInfo.parse()(basically the same assemver.parse_version_info()):>>> semver.VersionInfo.parse("3.4.5-pre.2+build.4") VersionInfo(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')
With
semver.parse():>>> semver.parse("3.4.5-pre.2+build.4") {'major': 3, 'minor': 4, 'patch': 5, 'prerelease': 'pre.2', 'build': 'build.4'}
Accessing Parts of a Version¶
The semver.VersionInfo contains attributes to access the different
parts of a version:
>>> v = VersionInfo.parse("3.4.5-pre.2+build.4")
>>> v.major
3
>>> v.minor
4
>>> v.patch
5
>>> v.prerelease
'pre.2'
>>> v.build
'build.4'
However, the attributes are read-only. You cannot change an attribute.
If you do, you get an AttributeError:
>>> v.minor = 5
Traceback (most recent call last)
...
AttributeError: attribute 'minor' is readonly
In case you need the different parts of a version stepwise, iterate over the semver.VersionInfo instance:
>>> for item in VersionInfo.parse("3.4.5-pre.2+build.4"):
... print(item)
3
4
5
pre.2
build.4
>>> list(VersionInfo.parse("3.4.5-pre.2+build.4"))
[3, 4, 5, 'pre.2', 'build.4']
Replacing Parts of a Version¶
If you want to replace different parts of a version, but leave other parts
unmodified, use one of the functions semver.replace() or
semver.VersionInfo.replace():
From a version string:
>>> semver.replace("1.4.5-pre.1+build.6", major=2) '2.4.5-pre.1+build.6'
From a
semver.VersionInfoinstance:>>> version = semver.VersionInfo.parse("1.4.5-pre.1+build.6") >>> version.replace(major=2, minor=2) VersionInfo(major=2, minor=2, patch=5, prerelease='pre.1', build='build.6')
If you pass invalid keys you get an exception:
>>> semver.replace("1.2.3", invalidkey=2)
Traceback (most recent call last)
...
TypeError: replace() got 1 unexpected keyword argument(s): invalidkey
>>> version = semver.VersionInfo.parse("1.4.5-pre.1+build.6")
>>> version.replace(invalidkey=2)
Traceback (most recent call last)
...
TypeError: replace() got 1 unexpected keyword argument(s): invalidkey
Converting Different Version Types¶
Depending which function you call, you get different types (as explained in the beginning of this chapter).
From a string into
semver.VersionInfo:>>> semver.VersionInfo.parse("3.4.5-pre.2+build.4") VersionInfo(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')
From
semver.VersionInfointo a string:>>> str(semver.VersionInfo.parse("3.4.5-pre.2+build.4")) '3.4.5-pre.2+build.4'
From a dictionary into
semver.VersionInfo:>>> d = {'major': 3, 'minor': 4, 'patch': 5, 'prerelease': 'pre.2', 'build': 'build.4'} >>> semver.VersionInfo(**d) VersionInfo(major=3, minor=4, patch=5, prerelease='pre.2', build='build.4')
As a minimum requirement, your dictionary needs at least the
majorkey, others can be omitted. You get aTypeErrorif your dictionary contains invalid keys. Onlymajor,minor,patch,prerelease, andbuildare allowed.From a tuple into
semver.VersionInfo:>>> t = (3, 5, 6) >>> semver.VersionInfo(*t) VersionInfo(major=3, minor=5, patch=6, prerelease=None, build=None)
From a
semver.VersionInfointo a dictionary:>>> v = semver.VersionInfo(major=3, minor=4, patch=5) >>> semver.parse(str(v)) {'major': 3, 'minor': 4, 'patch': 5, 'prerelease': None, 'build': None}
Increasing Parts of a Version¶
The semver module contains the following functions to raise parts of
a version:
semver.bump_major(): raises the major part and set all other parts to zero. SetprereleaseandbuildtoNone.semver.bump_minor(): raises the minor part and setspatchto zero. SetprereleaseandbuildtoNone.semver.bump_patch(): raises the patch part. SetprereleaseandbuildtoNone.semver.bump_prerelease(): raises the prerelease part and setbuildtoNone.semver.bump_build(): raises the build part.
>>> semver.bump_major("3.4.5-pre.2+build.4")
'4.0.0'
>>> semver.bump_minor("3.4.5-pre.2+build.4")
'3.5.0'
>>> semver.bump_patch("3.4.5-pre.2+build.4")
'3.4.6'
>>> semver.bump_prerelease("3.4.5-pre.2+build.4")
'3.4.5-pre.3'
>>> semver.bump_build("3.4.5-pre.2+build.4")
'3.4.5-pre.2+build.5'
Comparing Versions¶
To compare two versions depends on your type:
Two strings
Use
semver.compare():>>> semver.compare("1.0.0", "2.0.0") -1 >>> semver.compare("2.0.0", "1.0.0") 1 >>> semver.compare("2.0.0", "2.0.0") 0
The return value is negative if
version1 < version2, zero ifversion1 == version2and strictly positive ifversion1 > version2.Two
semver.VersionInfotypesUse the specific operator. Currently, the operators
<,<=,>,>=,==, and!=are supported:>>> v1 = VersionInfo.parse("3.4.5") >>> v2 = VersionInfo.parse("3.5.1") >>> v1 < v2 True >>> v1 > v2 False
A
semver.VersionInfotype and atupleUse the operator as with two
semver.VersionInfotypes:>>> v = VersionInfo.parse("3.4.5") >>> v > (1, 0) True >>> v < (3, 5) True
The opposite does also work:
>>> (1, 0) < v True >>> (3, 5) > v True
Other types cannot be compared (like dictionaries, lists etc).
If you need to convert some types into other, refer to Converting Different Version Types.
Comparing Versions through an Expression¶
If you need a more fine-grained approach of comparing two versions,
use the semver.match() function. It expects two arguments:
- a version string
- a match expression
Currently, the match expression supports the following operators:
<smaller than>greater than>=greater or equal than<=smaller or equal than==equal!=not equal
That gives you the following possibilities to express your condition:
>>> semver.match("2.0.0", ">=1.0.0")
True
>>> semver.match("1.0.0", ">1.0.0")
False
Getting Minimum and Maximum of two Versions¶
>>> semver.max_ver("1.0.0", "2.0.0")
'2.0.0'
>>> semver.min_ver("1.0.0", "2.0.0")
'1.0.0'