Skip to main content

High-performance version string parsing and comparison across all major package ecosystems

Project description

anyver

CI PyPI Python License: MIT

A high-performance Python library (written in Rust via PyO3) for parsing and comparing software version strings across all major package ecosystems.

Handles: SemVer, PEP 440, npm, Go modules, Debian/dpkg, RPM, Ruby Gems, Maven, NuGet, Composer, Crates.io, Hex, Swift PM, CalVer, Alpine, Docker — with a single generic parser and ecosystem-specific modes.

Installation

pip install anyver

Build from source (requires Rust toolchain):

pip install maturin
maturin develop --release

Quick Start

from anyver import Version
import anyver

# Parse and compare versions
Version("1.2.3") < Version("2.0.0")          # True
Version("1.0.0-alpha") < Version("1.0.0")    # True
Version("1.0") == Version("1.0.0")           # True (trailing zero equivalence)
Version("v1.0") == Version("1.0")            # True (v-prefix stripped)
Version("1.0+build") == Version("1.0+other") # True (build metadata ignored)

# Module-level compare
anyver.compare("1.0", "2.0")                 # -1
anyver.compare("2.0", "1.0")                 #  1
anyver.compare("1.0", "1.0.0")               #  0

Version Object

v = Version("1.2.3-rc.1+build.42")

# Properties
v.raw              # "1.2.3-rc.1+build.42"
v.ecosystem        # "generic" (detected ecosystem name)
v.epoch            # 0
v.build            # "build.42"
v.major            # 1
v.minor            # 2
v.patch            # 3
v.is_prerelease    # True
v.is_postrelease   # False
v.is_stable        # False (opposite of is_prerelease)

# Segments
v.segments()       # (1, 2, 3, "rc", 1)
v.release()        # (1, 2, 3)
len(v)             # 5
v[0]               # 1
v[3]               # "rc"
v[-1]              # 1

# String representations
str(v)             # "1.2.3-rc.1+build.42"
repr(v)            # "Version('1.2.3-rc.1+build.42')"

# Compare using the Version's own detected ecosystem
v.compare("1.2.3")      # 0
v.compare("2.0.0")      # -1
v.compare("0.1.0")      # 1

Sorting and Batch Operations

anyver.sort_versions(["2.0", "1.0-alpha", "1.0", "0.1"])
# ["0.1", "1.0-alpha", "1.0", "2.0"]

anyver.batch_compare([("1.0", "2.0"), ("2.0", "1.0"), ("1.0", "1.0")])
# [-1, 1, 0]

anyver.max_version(["1.0", "3.0", "2.0"])  # "3.0"
anyver.min_version(["1.0", "3.0", "2.0"])  # "1.0"

Boolean Helpers

anyver.gt("2.0", "1.0")    # True
anyver.ge("1.0", "1.0.0")  # True
anyver.lt("1.0", "2.0")    # True
anyver.le("1.0", "1.0.0")  # True
anyver.eq("1.0", "1.0.0")  # True
anyver.ne("1.0", "2.0")    # True

Version Constraints

Check whether a version satisfies a constraint expression. Supports >=, <=, >, <, ==, != operators, combined with commas for AND logic:

anyver.satisfies("1.5.0", ">=1.0.0,<2.0.0")   # True
anyver.satisfies("2.0.0", ">=1.0.0,<2.0.0")   # False
anyver.satisfies("1.0.0", ">=1.0.0")           # True
anyver.satisfies("1.0.0", "!=1.0.0")           # False
anyver.satisfies("1.0.0-alpha", ">1.0.0")      # False

# Works with any ecosystem
anyver.satisfies("5.14.0-503.19.1.el9_5", ">=5.14.0-427.0.0.el9_4", ecosystem="rpm")

Stable Version Filtering

Filter out pre-release versions or find the latest stable:

anyver.stable_versions(["2.0.0-rc1", "1.0.0", "2.0.0", "1.5.0-beta"])
# ["1.0.0", "2.0.0"]

anyver.latest_stable(["2.0.0-rc1", "1.0.0", "2.0.0", "1.5.0-beta"])
# "2.0.0"

Version Bumping

anyver.bump_major("1.2.3")          # "2.0.0"
anyver.bump_minor("1.2.3")          # "1.3.0"
anyver.bump_patch("1.2.3")          # "1.2.4"

# Pre-release tags are stripped
anyver.bump_major("1.2.3-alpha")    # "2.0.0"
anyver.bump_patch("1.0.0-rc1")     # "1.0.1"

Hashable (Sets and Dicts)

s = {Version("1.0"), Version("1.0.0"), Version("2.0")}
len(s)  # 2 — "1.0" and "1.0.0" are equal, so deduplicated

d = {Version("1.0"): "stable"}
d[Version("1.0.0")]  # "stable"

Ecosystem Auto-Detection

By default, Version() and anyver.version() use ecosystem="auto" — the library inspects the version string and picks the best ecosystem automatically:

# Auto-detected as PEP 440 (contains "!")
Version("1!2.0.0")                           # ecosystem=pep440

# Auto-detected as Debian (contains "~")
Version("1.0~rc1")                           # ecosystem=debian

# Auto-detected as RPM (contains ".fc" / ".el")
Version("5.14.0-362.24.1.el9_4")             # ecosystem=rpm

# Auto-detected as Go (ends with "+incompatible")
Version("v2.0.0+incompatible")               # ecosystem=go

# Auto-detected as Alpine (contains "_alpha", "_rc", "-rN")
Version("3.1.4-r5")                          # ecosystem=alpine

# Auto-detected as Maven (ends with "-SNAPSHOT")
Version("1.0-SNAPSHOT")                      # ecosystem=maven

# Auto-detected as CalVer (starts with year-like number)
Version("2024.1.15")                         # ecosystem=calver

# Falls back to generic when ambiguous
Version("1.2.3")                             # ecosystem=generic

Detection rules (in priority order):

  1. ! in string → PEP 440
  2. ~ → Debian, ^ → RPM
  3. .post, .dev → PEP 440
  4. +incompatible → Go, -SNAPSHOT → Maven
  5. _alpha, _beta, _rc, _p, -rN → Alpine
  6. +deb, +ubuntu → Debian; .el, .fc, .amzn → RPM
  7. Digit-letter patterns like 1a1, 1b2, 1rc1 → PEP 440
  8. Dot-separated .pre, .rc, .beta, .alpha (no hyphens) → Ruby
  9. Year-like first segment (1990-2100) → CalVer
  10. Otherwise → Generic

Ecosystem-Specific Comparison

You can also set the ecosystem explicitly:

# Strict SemVer (numeric < alpha in pre-release)
anyver.compare_semver_strict("1.0.0-alpha", "1.0.0")  # -1

# Debian/dpkg (tilde sorts before everything)
anyver.compare("1.0~rc1", "1.0", ecosystem="debian")   # -1

# RPM (caret for post-release snapshots)
anyver.compare("1.0", "1.0^git1", ecosystem="rpm")     # -1

# PEP 440 (epoch with !)
anyver.compare("1!0.1", "2.0", ecosystem="pep440")     # 1

# All supported ecosystems:
# auto (default for Version), generic (default for compare),
# semver, npm, pep440, debian, rpm, go, ruby/gem/rubygems,
# maven/mvn, nuget/dotnet, composer/php/packagist,
# crates/cargo, hex/elixir/erlang, swift/swiftpm,
# calver, alpine/apk, docker/oci

Database Integration

to_dict() — Structured Export

Version("1.2.3-rc.1+build.42").to_dict()
# {
#   "raw": "1.2.3-rc.1+build.42",
#   "epoch": 0,
#   "major": 1,
#   "minor": 2,
#   "patch": 3,
#   "build": "build.42",
#   "is_prerelease": True,
#   "is_postrelease": False
# }

sort_key() — Database-Friendly Sort Key

Version("1.2.3-rc.1").sort_key()
# Tuple of tuples that preserves comparison order when sorted lexically.
# Guarantees perfect isomorphism with anyver.compare().

Cross-Ecosystem Examples

# PEP 440 (Python)
Version("1.0.dev1") < Version("1.0a1") < Version("1.0b1") < Version("1.0rc1") < Version("1.0") < Version("1.0.post1")

# Debian
Version("1.0~alpha") < Version("1.0~beta") < Version("1.0")

# RPM
Version("1.0~rc1") < Version("1.0") < Version("1.0^git1")

# Maven
Version("1.0-alpha-1") < Version("1.0-SNAPSHOT") < Version("1.0") < Version("1.0-sp-1")

# Go modules
Version("v2.0.0+incompatible") == Version("v2.0.0")

# Ruby Gems — numeric, not lexical
Version("3.2") < Version("3.10")

# Epoch overrides everything
Version("1:0.1") > Version("999.0")

Performance

Built in Rust for speed. Typical benchmarks (Apple M-series):

Operation Time
Version("1.2.3") construction ~330 ns
anyver.compare("1.2.3", "1.2.4") ~300 ns
Version < Version (pre-parsed) ~66 ns
sort_versions(1000) ~460 us
vs Python packaging.version ~14x faster
vs Python semver ~23x faster

Stability & Versioning

anyver follows Semantic Versioning. The public API surface covered by SemVer guarantees:

Stable (breaking changes require a major version bump):

  • The Version class constructor, operators, properties, and methods (raw, ecosystem, epoch, build, major/minor/patch, is_prerelease, is_postrelease, is_stable, count, segments(), release(), compare(), to_dict(), from_dict(), sort_key(), parse(), try_parse()).
  • Module-level functions: version, compare, compare_semver_strict, sort_versions, batch_compare, gt/ge/gte/lt/le/lte/eq/ne, max_version, min_version, stable_versions, latest_stable, satisfies, bump_major/bump_minor/bump_patch/bump_prerelease, next_stable.
  • The set of accepted ecosystem names (aliases may grow, but existing names keep their meaning).
  • The comparison result (-1/0/1) for any pair of versions within a given ecosystem, within a major version.
  • Type stubs (.pyi) and the py.typed marker.
  • Pickle format and __reduce__ output (stable across patch versions).

Experimental (may change within minor versions until documented stable):

  • Version.sort_key() tuple shape (the encoding scheme can evolve if new ecosystems require additional distinguishing fields).
  • The ecosystem="auto" detection heuristic. The rules may be refined to reduce false positives; the existing correct detections will not flip.
  • Error messages and exception attribute text.

Not covered by SemVer:

  • Rust internals (src/), benchmarks, CI configuration.
  • Performance numbers (we aim to improve them monotonically, but there are no guarantees tied to the public version).

See CHANGELOG.md for release history.

Author

Aleksandr Pavlov ckidoz@gmail.com

License

MIT — see LICENSE for details.

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

anyver-1.0.0.tar.gz (54.8 kB view details)

Uploaded Source

Built Distributions

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

anyver-1.0.0-cp311-abi3-win_amd64.whl (199.2 kB view details)

Uploaded CPython 3.11+Windows x86-64

anyver-1.0.0-cp311-abi3-musllinux_1_2_x86_64.whl (554.4 kB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ x86-64

anyver-1.0.0-cp311-abi3-musllinux_1_2_aarch64.whl (522.7 kB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ ARM64

anyver-1.0.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (349.6 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ x86-64

anyver-1.0.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (345.2 kB view details)

Uploaded CPython 3.11+manylinux: glibc 2.17+ ARM64

anyver-1.0.0-cp311-abi3-macosx_11_0_arm64.whl (310.2 kB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

anyver-1.0.0-cp311-abi3-macosx_10_12_x86_64.whl (319.1 kB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

Details for the file anyver-1.0.0.tar.gz.

File metadata

  • Download URL: anyver-1.0.0.tar.gz
  • Upload date:
  • Size: 54.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for anyver-1.0.0.tar.gz
Algorithm Hash digest
SHA256 acf7243c193d800495219aeff86c36349e35e1b414682e14c33b45e610050720
MD5 7814001a9c4f93e8cd279c48433ab1bc
BLAKE2b-256 510e6853935803afa5071e5c269307c7260c2a7c32f6a200a9b3ee233e7c1fb6

See more details on using hashes here.

Provenance

The following attestation bundles were made for anyver-1.0.0.tar.gz:

Publisher: publish.yml on kidoz/anyver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file anyver-1.0.0-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: anyver-1.0.0-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 199.2 kB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for anyver-1.0.0-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 17f608d51f20c3cb3589bb3a7f2307c494024b484dafc79becb2ac3fae059638
MD5 751f57384c01aa67849b9141717e5d92
BLAKE2b-256 eecfaf74d64f44e06360866333d804f286e59134b3b6bfbcb83a142b214189a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for anyver-1.0.0-cp311-abi3-win_amd64.whl:

Publisher: publish.yml on kidoz/anyver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file anyver-1.0.0-cp311-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for anyver-1.0.0-cp311-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f76faa7c4cd57c05e854f830318b62b001b1e02b32912c99360da7ab7b2e69c5
MD5 eac7122adeb9d244428053a723329532
BLAKE2b-256 22a24160f76d577cca860ea7094b888ba69a399f4e9e707f830c895186312c9f

See more details on using hashes here.

Provenance

The following attestation bundles were made for anyver-1.0.0-cp311-abi3-musllinux_1_2_x86_64.whl:

Publisher: publish.yml on kidoz/anyver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file anyver-1.0.0-cp311-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for anyver-1.0.0-cp311-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 520d77af58344dabef22f55dfff0a3fc7569f6ea61c2d3d20ae3f9c2fba32290
MD5 d78e50800062b109f6822c182c215564
BLAKE2b-256 b78c7a72b2160b0f14542ff9ecf67956ee0e3c38d2d678225038278ccfa0af07

See more details on using hashes here.

Provenance

The following attestation bundles were made for anyver-1.0.0-cp311-abi3-musllinux_1_2_aarch64.whl:

Publisher: publish.yml on kidoz/anyver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file anyver-1.0.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for anyver-1.0.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9d6dcb691d1850e01179b96732de65eebfe2f304501fbe666b5afec72441d76d
MD5 a247c5d0ff07b8670d4504b7ea2cc966
BLAKE2b-256 d023beb23101bfd16efa10b98796854ad8945cc3c16bc814169d6db3718e5e92

See more details on using hashes here.

Provenance

The following attestation bundles were made for anyver-1.0.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: publish.yml on kidoz/anyver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file anyver-1.0.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for anyver-1.0.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3d44fc9a9de8ab6ad669551d846157fef9bf77838c71429afb7e6e400cde822a
MD5 c0583f82e62f654a5b3d5cae02fe378c
BLAKE2b-256 14bf72357fd6a0411d17a5c26b36c2201932207e8e0c9535b3a95f5845d01780

See more details on using hashes here.

Provenance

The following attestation bundles were made for anyver-1.0.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: publish.yml on kidoz/anyver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file anyver-1.0.0-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for anyver-1.0.0-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 028603d53543c899b519a927fe14fffa614b8e7a7304f964a8cf5c01437c1762
MD5 96a554a3c80770e74b0f84068b5846c1
BLAKE2b-256 6e9e03154f93cb0a67406398a672f637b69206e2048a4e679adfe391405abf98

See more details on using hashes here.

Provenance

The following attestation bundles were made for anyver-1.0.0-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: publish.yml on kidoz/anyver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file anyver-1.0.0-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for anyver-1.0.0-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 2ed905221222366af7e45cace721eafd736dc66baade6a5b479f4e6ab369822e
MD5 43b6c70b9425d7496ad9352729420c78
BLAKE2b-256 482ee31ceff5d15d7e092806daec5b45b0ddebbfab112d9ec025403b306e4062

See more details on using hashes here.

Provenance

The following attestation bundles were made for anyver-1.0.0-cp311-abi3-macosx_10_12_x86_64.whl:

Publisher: publish.yml on kidoz/anyver

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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