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.15.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.15-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: ps_version-0.2.15.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.15.tar.gz
Algorithm Hash digest
SHA256 931b6c4e2bb87e911ba8aa8b8420423ce1d710cb82951f5e0cf7345d8a1043e2
MD5 9f15146bb1bdd46f554cc435b445edc1
BLAKE2b-256 ed41f490080560b7ecf2a7b06d5aec7606dee01caa8879d2b6d7aa7007c339fd

See more details on using hashes here.

File details

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

File metadata

  • Download URL: ps_version-0.2.15-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.15-py3-none-any.whl
Algorithm Hash digest
SHA256 50ebe11dbf2e4723f21fb87d5c36f2ef566a22ee058dc9cc70727066c7286afd
MD5 4838b1adc41b4a80105dd24f3112945e
BLAKE2b-256 6dda30f069510f297f3d39458aa9105d9725df436cd22e2baf87577633a32e03

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