Skip to main content

Parse, compare, and format version numbers across PEP 440, SemVer, NuGet, CalVer, and loose formats

Project description

Overview

PyPI Python License

PS Version is a Python library for parsing, comparing, and formatting version numbers across multiple versioning standards. It provides a unified Version dataclass that automatically detects the version format, parses version strings into a consistent internal representation, and supports standard comparison operators and cross-format output.

The library supports PEP 440, SemVer, NuGet, CalVer, and loose version formats without requiring the caller to specify the format explicitly.

For working project examples, see the ps-poetry-examples repository.

Installation

pip install ps-version

Or with Poetry:

poetry add ps-version

Quick Start

from ps.version import Version, VersionStandard

version = Version.parse("1.2.3-alpha.1+build.42")
print(version.major)    # 1
print(version.minor)    # 2
print(version.patch)    # 3

v1 = Version.parse("1.2.3")
v2 = Version.parse("1.2.4")
print(v1 < v2)   # True

print(version.format(VersionStandard.PEP440))  # 1.2.3a1+build.42  (canonical PEP 440 form; 'alpha' is also accepted but 'a' is canonical)

View full example

Parsing Version Strings

Use Version.parse() to convert a version string into a Version object. The method returns None if no parser can match the string, so callers should handle that case.

from ps.version import Version

version = Version.parse("1.2.3-rc.1+build.123")
if version is None:
    print("Could not parse version")

The parser tries formats in this order: PEP 440, SemVer, NuGet, CalVer, Loose. The first successful match is returned. Because several versioning standards overlap syntactically, the parser order determines which format interpretation is selected.

Version Components

Version is a dataclass with the following fields. Only major is required; all others are optional.

from ps.version import Version

version = Version.parse("1.2.3.4.post4.dev1+git.abc")
print(version.major)    # 1
print(version.minor)    # 2
print(version.patch)    # 3
print(version.rev)      # 4  (fourth numeric component)
print(version.post)     # 4  (PEP 440 post-release)
print(version.dev)      # 1  (PEP 440 dev release)
print(version.core)     # "1.2.3.4"  (numeric components as string)

The core property represents the numeric portion of the version and omits a trailing revision of zero as a convenience representation. This is a library-specific behavior, not a rule from any versioning specification.

Pre-release

Pre-release information is represented by a VersionPreRelease object with a name (str) and optional number (int):

version = Version.parse("1.2.3-alpha.1")
print(version.pre.name)    # alpha
print(version.pre.number)  # 1

Build Metadata

Build metadata is represented by a VersionMetadata object. Access the full string via str() or individual dot-separated parts via .parts:

version = Version.parse("1.2.3+g1234567.dirty")
print(str(version.metadata))       # g1234567.dirty
print(version.metadata.parts[0])   # g1234567
print(version.metadata.parts[1])   # dirty

Comparing Versions

Version supports all standard comparison operators (<, <=, ==, !=, >=, >). Version comparison uses PEP 440 precedence rules as the canonical ordering model across all supported version formats: dev releases come before the base release, pre-releases come before the final release, and post releases come after.

from ps.version import Version

v1 = Version.parse("1.2.3a1")
v2 = Version.parse("1.2.3")
v3 = Version.parse("1.2.3.post1")

print(v1 < v2 < v3)  # True

Formatting Versions

Use Version.format(standard) to produce a version string in a specific format. str(version) formats the version using the first compatible standard from the version's detected compatibility list.

from ps.version import Version, VersionStandard

version = Version.parse("1.2.3-alpha.1")
print(version.format(VersionStandard.PEP440))  # 1.2.3a1
print(version.format(VersionStandard.SEMVER))  # 1.2.3-alpha.1
print(version.format(VersionStandard.NUGET))   # 1.2.3-alpha.1

To determine which standards a version is compatible with, use the standards property:

version = Version.parse("1.2.3")
print(version.standards)  # [SEMVER, NUGET, LOOSE, PEP440]

version = Version.parse("1.2.3.post4")
print(version.standards)  # [PEP440]

Version Constraints

Use Version.get_constraint(constraint) to generate a dependency constraint string from a version and a VersionConstraint mode.

from ps.version import Version, VersionConstraint

version = Version.parse("1.2.3")
print(version.get_constraint(VersionConstraint.EXACT))            # ==1.2.3
print(version.get_constraint(VersionConstraint.MINIMUM_ONLY))     # >=1.2.3
print(version.get_constraint(VersionConstraint.RANGE_NEXT_MAJOR)) # >=1.2.3,<2.0.0
print(version.get_constraint(VersionConstraint.RANGE_NEXT_MINOR)) # >=1.2.3,<1.3.0
print(version.get_constraint(VersionConstraint.RANGE_NEXT_PATCH)) # >=1.2.3,<1.2.4
print(version.get_constraint(VersionConstraint.COMPATIBLE))       # >=1.2.3,<2.0.0

View full example

The COMPATIBLE mode pins to the next breaking boundary: next major when major > 0, next minor when minor > 0, otherwise next patch.

Using Parsers Directly

Each format has a dedicated parser class that can be used independently when the format is known in advance:

from ps.version import PEP440Parser, SemVerParser, NuGetParser, CalVerParser, LooseParser

pep_parser = PEP440Parser()
version = pep_parser.parse("1.2.3a1+build")

semver_parser = SemVerParser()
version = semver_parser.parse("1.2.3-alpha.1+build.123")

Each parser returns None if the input does not match its format, making them safe to call without try/except.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ps_version-0.2.10.tar.gz (8.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ps_version-0.2.10-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

Details for the file ps_version-0.2.10.tar.gz.

File metadata

  • Download URL: ps_version-0.2.10.tar.gz
  • Upload date:
  • Size: 8.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.13.12 Linux/6.17.0-1010-azure

File hashes

Hashes for ps_version-0.2.10.tar.gz
Algorithm Hash digest
SHA256 757f902498447f97ab9c84717028e22a025caa47c86ed5cb510f87a2b500d68b
MD5 91b8903335c95f69b9a9a2740011dbcc
BLAKE2b-256 3b42bda74964cf87d4d2f2a4f41ec8c6a14dca222951cc991bf38fb538b0920e

See more details on using hashes here.

File details

Details for the file ps_version-0.2.10-py3-none-any.whl.

File metadata

  • Download URL: ps_version-0.2.10-py3-none-any.whl
  • Upload date:
  • Size: 11.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.3.2 CPython/3.13.12 Linux/6.17.0-1010-azure

File hashes

Hashes for ps_version-0.2.10-py3-none-any.whl
Algorithm Hash digest
SHA256 66487542e80d22c34c59cb3c02dad4e50d2dfa5ba6695fe9643f4e2a1eb2fc67
MD5 23b7a9ff1875eff34809637a04466c59
BLAKE2b-256 1167ae479620afc41dbc9af0ff3b557036db4e5aab228bd875955c33e9910779

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page