Usage#

parver provides the Version class. It is immutable, so methods which you might expect to mutate instead return a new instance with the requested modifications:

>>> v = Version.parse('1.3')
>>> v
<Version '1.3'>
>>> v.bump_release(index=0)
<Version '2.0'>
>>> v.bump_release(index=1)
<Version '1.4'>
>>> assert v == Version(release=(1, 3))

Note here that we used an index to tell parver which number to bump. You may typically refer to indices 0, 1, and 2 as major, minor, and patch releases, but this depends on which versioning convention your project uses.

Development, pre-release, and post releases are also supported:

>>> Version.parse('1.3').bump_dev()
<Version '1.3.dev0'>
>>> Version.parse('1.3').bump_pre('b')
<Version '1.3b0'>
>>> Version.parse('1.3').bump_post()
<Version '1.3.post0'>

Parsing#

parver can parse any PEP 440-compatible version string. Here is one in canonical form:

>>> v = Version.parse('1!2.3a4.post5.dev6+local', strict=True)
>>> v
<Version '1!2.3a4.post5.dev6+local'>
>>> assert v.epoch == 1
>>> assert v.release == (2, 3)
>>> assert v.pre_tag == 'a'
>>> assert v.pre == 4
>>> assert v.post == 5
>>> assert v.dev == 6
>>> assert v.local == 'local'

With strict=True, parse() will raise ParseError if the version is not in canonical form.

Any version in canonical form will have the same normalized string output:

>>> assert str(v.normalize()) == str(v)

For version numbers that aren’t in canonical form, parver has no problem parsing them. In this example, there are a couple of non-standard elements:

  • Non-standard separators in the pre-release segment.

  • alpha rather than a for the pre-release identifier.

  • An implicit post release number.

>>> v = Version.parse('1.2.alpha-3.post')
>>> v
<Version '1.2.alpha-3.post'>
>>> assert v.pre == 3
>>> assert v.pre_tag == 'alpha'
>>> assert v.is_alpha
>>> assert v.post == 0
>>> assert v.post_implicit
>>> v.normalize()
<Version '1.2a3.post0'>
>>> assert v == v.normalize()
>>> assert str(v) != str(v.normalize())

Note that normalization does not affect equality (or ordering).

Also note that parver can round-trip [1] your version strings; non-standard parameters are kept as-is, even when you mutate:

>>> v = Version.parse('v1.2.alpha-3.post')
>>> v.replace(post=None).bump_pre()
<Version 'v1.2.alpha-4'>