Version Handling

A core requirement of dealing with packages is the ability to work with versions.

See Version Specifiers Specification for more details on the exact format implemented in this module, for use in Python Packaging tooling.

Usage

>>> from packaging.version import Version, parse
>>> v1 = parse("1.0a5")
>>> v2 = Version("1.0")
>>> v1
<Version('1.0a5')>
>>> v2
<Version('1.0')>
>>> v1 < v2
True
>>> v1.epoch
0
>>> v1.release
(1, 0)
>>> v1.pre
('a', 5)
>>> v1.is_prerelease
True
>>> v2.is_prerelease
False
>>> Version("french toast")
Traceback (most recent call last):
    ...
InvalidVersion: Invalid version: 'french toast'
>>> Version("1.0").post
>>> Version("1.0").is_postrelease
False
>>> Version("1.0.post0").post
0
>>> Version("1.0.post0").is_postrelease
True

Reference

packaging.version.VERSION_PATTERN

A string containing the regular expression used to match a valid version.

The pattern is not anchored at either end, and is intended for embedding in larger expressions (for example, matching a version number as part of a file name). The regular expression should be compiled with the re.VERBOSE and re.IGNORECASE flags set.

Changed in version 26.0: The regex now uses possessive qualifiers on Python 3.11 if they are supported (CPython 3.11.5+, PyPy 3.11.13+).

exception packaging.version.InvalidVersion

Raised when a version string is not a valid version.

>>> Version("invalid")
Traceback (most recent call last):
    ...
packaging.version.InvalidVersion: Invalid version: 'invalid'
class packaging.version.Version

This class abstracts handling of a project’s versions.

A Version instance is comparison aware and can be compared and sorted using the standard Python interfaces.

>>> v1 = Version("1.0a5")
>>> v2 = Version("1.0")
>>> v1
<Version('1.0a5')>
>>> v2
<Version('1.0')>
>>> v1 < v2
True
>>> v1 == v2
False
>>> v1 > v2
False
>>> v1 >= v2
False
>>> v1 <= v2
True

Version is immutable; use __replace__() to change part of a version.

__match_args__

Pattern matching is supported on Python 3.10+.

Added in version 26.0.

__init__(version)

Initialize a Version object.

Parameters:

version (str) – The string representation of a version which will be parsed and normalized before use.

Raises:

InvalidVersion – If the version does not conform to PEP 440 in any way then this exception will be raised.

Return type:

None

classmethod from_parts(*, epoch=0, release, pre=None, post=None, dev=None, local=None)

Return a new version composed of the various parts.

This allows you to build a version without going though a string and running a regular expression. It normalizes pre-release strings. The release= keyword argument is required.

>>> Version.from_parts(release=(1,2,3))
<Version('1.2.3')>
>>> Version.from_parts(release=(0,1,0), pre=("b", 1))
<Version('0.1.0b1')>
Parameters:
  • epoch (int)

  • release (tuple[int, ...]) – This version tuple is required

  • pre (tuple[str, int] | None)

  • post (int | None)

  • dev (int | None)

  • local (str | None)

Return type:

Self

Added in version 26.0.

__replace__(*, epoch=..., release=..., pre=..., post=..., dev=..., local=...)

Return a new version with parts replaced.

This returns a new version (unless no parts were changed). The pre-release is normalized. Setting a value to None clears it.

>>> v = Version("1.2.3")
>>> v.__replace__(pre=("a", 1))
<Version('1.2.3a1')>
Parameters:
  • epoch (int | None)

  • release (tuple[int, ...] | None)

  • pre (tuple[str, int] | None)

  • post (int | None)

  • dev (int | None)

  • local (str | None)

  • kwargs (Unpack[_VersionReplace])

Return type:

Self

Added in version 26.0.

Changed in version 26.1: The pre-release portion is now normalized.

__repr__()

A representation of the Version that shows all internal state.

>>> Version('1.0.0')
<Version('1.0.0')>
Return type:

str

__str__()

A string representation of the version that can be round-tripped.

>>> str(Version("1.0a5"))
'1.0a5'
Return type:

str

property epoch: int

The epoch of the version.

>>> Version("2.0.0").epoch
0
>>> Version("1!2.0.0").epoch
1
property release: tuple[int, ...]

The components of the “release” segment of the version.

>>> Version("1.2.3").release
(1, 2, 3)
>>> Version("2.0.0").release
(2, 0, 0)
>>> Version("1!2.0.0.post0").release
(2, 0, 0)

Includes trailing zeroes but not the epoch or any pre-release / development / post-release suffixes.

property pre: tuple[Literal['a', 'b', 'rc'], int] | None

The pre-release segment of the version.

>>> print(Version("1.2.3").pre)
None
>>> Version("1.2.3a1").pre
('a', 1)
>>> Version("1.2.3b1").pre
('b', 1)
>>> Version("1.2.3rc1").pre
('rc', 1)
property post: int | None

The post-release number of the version.

>>> print(Version("1.2.3").post)
None
>>> Version("1.2.3.post1").post
1
property dev: int | None

The development number of the version.

>>> print(Version("1.2.3").dev)
None
>>> Version("1.2.3.dev1").dev
1
property local: str | None

The local version segment of the version.

>>> print(Version("1.2.3").local)
None
>>> Version("1.2.3+abc").local
'abc'
property public: str

The public portion of the version.

This returns a string. If you want a Version again and care about performance, use v.__replace__(local=None) instead.

>>> Version("1.2.3").public
'1.2.3'
>>> Version("1.2.3+abc").public
'1.2.3'
>>> Version("1!1.2.3dev1+abc").public
'1!1.2.3.dev1'
property base_version: str

The “base version” of the version.

This returns a string. If you want a Version again and care about performance, use v.__replace__(pre=None, post=None, dev=None, local=None) instead.

>>> Version("1.2.3").base_version
'1.2.3'
>>> Version("1.2.3+abc").base_version
'1.2.3'
>>> Version("1!1.2.3dev1+abc").base_version
'1!1.2.3'

The “base version” is the public version of the project without any pre or post release markers.

property is_prerelease: bool

Whether this version is a pre-release.

>>> Version("1.2.3").is_prerelease
False
>>> Version("1.2.3a1").is_prerelease
True
>>> Version("1.2.3b1").is_prerelease
True
>>> Version("1.2.3rc1").is_prerelease
True
>>> Version("1.2.3dev1").is_prerelease
True
property is_postrelease: bool

Whether this version is a post-release.

>>> Version("1.2.3").is_postrelease
False
>>> Version("1.2.3.post1").is_postrelease
True
property is_devrelease: bool

Whether this version is a development release.

>>> Version("1.2.3").is_devrelease
False
>>> Version("1.2.3.dev1").is_devrelease
True
property major: int

The first item of release or 0 if unavailable.

>>> Version("1.2.3").major
1
property minor: int

The second item of release or 0 if unavailable.

>>> Version("1.2.3").minor
2
>>> Version("1").minor
0
property micro: int

The third item of release or 0 if unavailable.

>>> Version("1.2.3").micro
3
>>> Version("1").micro
0
packaging.version.normalize_pre(letter, /)

Normalize the pre-release segment of a version string.

Returns a lowercase version of the string if not a known pre-release identifier.

>>> normalize_pre('alpha')
'a'
>>> normalize_pre('BETA')
'b'
>>> normalize_pre('rc')
'rc'
Parameters:

letter (str)

Return type:

str

Added in version 26.1.

packaging.version.parse(version)

Parse the given version string.

This is identical to the Version constructor.

>>> parse('1.0.dev1')
<Version('1.0.dev1')>
Parameters:

version (str) – The version string to parse.

Raises:

InvalidVersion – When the version string is not a valid version.

Return type:

Version

CLI

A CLI utility is provided:

usage: python -m packaging.version [-h] {compare} ...

Version utilities

positional arguments:
  {compare}
    compare             Compare two semantic versions.

options:
  -h, --help            show this help message and exit

You can compare two versions:

usage: python -m packaging.version compare [-h]
                                           version1
                                           {lt,le,eq,ne,ge,gt,<,<=,==,!=,>=,>}
                                           version2

Compare two semantic versions. Return code is 0 or 1.

positional arguments:
  version1              First version to compare
  {lt,le,eq,ne,ge,gt,<,<=,==,!=,>=,>}
                        Comparison operator
  version2              Second version to compare

options:
  -h, --help            show this help message and exit

Added in version 26.1.