Skip to main content

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, Conda, Arch/pacman, Gentoo/Portage, R/CRAN, Spack, Dart pub, Julia Pkg, Terraform/OpenTofu, Helm, CPAN, Nix, Homebrew, FreeBSD pkg — with a single generic parser, ecosystem-specific modes, range helpers, and security-interoperability utilities.

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")

Range helpers also support OR with ||, npm/Cargo-style caret and tilde ranges, x-ranges, Maven/NuGet interval notation, and Terraform-style ~>:

anyver.range_contains("1.5.0", ">=1.0.0,<2.0.0")    # True
anyver.range_contains("1.2.7", "1.2.x")              # True
anyver.range_contains("1.5.0", "[1.0.0,2.0.0)")      # True
anyver.ranges_intersect(">=1.0,<2.0", ">=1.5,<3.0")  # True

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,
# conda/mamba, arch/pacman, gentoo/portage, cran/r,
# spack, dart/pub/flutter, julia, terraform/opentofu, helm,
# cpan/perl, nix/nixpkgs, homebrew/brew, freebsd/freebsd-pkg

The mature exact-native comparators are Debian/dpkg, RPM, Maven (ComparableVersion), strict SemVer-family modes, and PEP 440 local-version handling. Newer ecosystem modes start with validation plus generic or SemVer-compatible ordering where their native algorithm is not yet fully specialized.

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.
# Isomorphic with comparing two versions of the same ecosystem, including
# PEP 440 local labels (e.g. `1.0+abc` sorts above `1.0`).

Scope: the key reproduces the generic/SemVer and PEP 440 orderings exactly. Debian, RPM and Maven compare with their native dpkg/rpm/ComparableVersion algorithms, which the key approximates via the generic ordering — the same documented approximation the parser makes for those ecosystems. For Debian/RPM/Maven, sort with anyver.sort_versions(..., ecosystem=...) rather than by sort_key() when exact native ordering matters.

hash(Version(...)) follows the same encoding, with Maven versions hashed through their canonical form so that equal Maven versions always hash equal. Hash equality is guaranteed within one ecosystem; mixing ecosystems in a set or dict is best-effort, since cross-ecosystem == falls back to generic comparison.

Security Interop

Helpers are provided for package-url (PURL), VERS-style version ranges, and OSV-shaped affected records:

anyver.parse_purl("pkg:npm/%40scope/name@1.2.3")
# {"type": "npm", "namespace": "%40scope", "name": "name",
#  "version": "1.2.3", "ecosystem": "npm", ...}

anyver.build_purl("npm", "name", "1.2.3", "%40scope")
# "pkg:npm/%40scope/name@1.2.3"

vers = anyver.build_vers("npm", ">=1.0.0,<2.0.0")
anyver.vers_contains(vers, "1.5.0")  # True

affected = {
    "package": {"ecosystem": "npm", "name": "demo"},
    "ranges": [{"events": [{"introduced": "1.0.0"}, {"fixed": "1.2.0"}]}],
}
anyver.osv_affected("1.1.0", affected)  # True

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 — ecosystem="maven" implements Apache Maven's ComparableVersion
Version("1.0-alpha-1") < Version("1.0-SNAPSHOT") < Version("1.0") < Version("1.0-sp-1")
anyver.compare("1.0-jre", "1.0", ecosystem="maven")   #  1 — unknown qualifiers rank above the release
anyver.compare("1.0-1", "1.0.1", ecosystem="maven")   # -1 — `-` nests, `.` does not

# 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.

Release files for anyver 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for anyver 1.2.0
File Size Uploaded
anyver-1.2.0.tar.gz 78.3 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for anyver 1.2.0
File
anyver-1.2.0-cp311-abi3-win_amd64.whl CPython 3.11 abi3 Windows x86-64 Details
anyver-1.2.0-cp311-abi3-musllinux_1_2_x86_64.whl CPython 3.11 abi3 Linux musl 1.2+ x86-64 Details
anyver-1.2.0-cp311-abi3-musllinux_1_2_aarch64.whl CPython 3.11 abi3 Linux musl 1.2+ ARM64 Details
anyver-1.2.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.11 abi3 Linux glibc 2.17+ x86-64 Details
anyver-1.2.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.11 abi3 Linux glibc 2.17+ ARM64 Details
anyver-1.2.0-cp311-abi3-macosx_11_0_arm64.whl CPython 3.11 abi3 macOS 11.0+ ARM64 Details
anyver-1.2.0-cp311-abi3-macosx_10_12_x86_64.whl CPython 3.11 abi3 macOS 10.12+ x86-64 Details

Total release size:3.0 MB

Release files / anyver-1.2.0.tar.gz

Download URL anyver-1.2.0.tar.gz
Size 78.3 kB
Tags Source
SHA-256 checksum
How to use checksums
464b3db131ac1a4002c7f77263629bd7988f9084c771859676487273a673d9de
BLAKE2b-256 checksum
How to use checksums
24f9f80cfd0388d17003ea3d5a34ebfb4f6eb386cc80b78f92361f5ec5043d11
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 26, 2026.

Transparency log

Release files / anyver-1.2.0-cp311-abi3-win_amd64.whl

Download URL anyver-1.2.0-cp311-abi3-win_amd64.whl
Size 247.4 kB
Tags CPython 3.11 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
87fd8004e17fd95e5769670893aaaeb79751a8c30f2ca709a78cda098c23f9ae
BLAKE2b-256 checksum
How to use checksums
595b34433e88b96236f536fd3973958a0afe4530bdde55628d5c49b13bdc68d3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 26, 2026.

Transparency log

Release files / anyver-1.2.0-cp311-abi3-musllinux_1_2_x86_64.whl

Download URL anyver-1.2.0-cp311-abi3-musllinux_1_2_x86_64.whl
Size 605.2 kB
Tags CPython 3.11 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
e735909e8cbbe1379a296a00a046ff6cce58f13ea73efcc258bafb95771a3683
BLAKE2b-256 checksum
How to use checksums
7b97521d838f68b9cd11ce3beacfc25653be2d626b69fd5a44e64861dd199ccb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 26, 2026.

Transparency log

Release files / anyver-1.2.0-cp311-abi3-musllinux_1_2_aarch64.whl

Download URL anyver-1.2.0-cp311-abi3-musllinux_1_2_aarch64.whl
Size 570.0 kB
Tags CPython 3.11 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
b3901b217272c235e5937ac1b7d788bb415ed4c41377c61236828b441d80e444
BLAKE2b-256 checksum
How to use checksums
2eedc86be02b6bc9fd96e61bd37a23848d605e534db336558c00158c50744fb3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 26, 2026.

Transparency log

Release files / anyver-1.2.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL anyver-1.2.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 396.7 kB
Tags CPython 3.11 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
4b19dcd01b9ff4b7e6f1864ed0477d7b62fdf50120e06976ad90e982334d8682
BLAKE2b-256 checksum
How to use checksums
8ecb29f7b811ca6749fad1894d5df1004c3c45207d53df2978056d306b18c111
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 26, 2026.

Transparency log

Release files / anyver-1.2.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL anyver-1.2.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 394.5 kB
Tags CPython 3.11 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
9e49f643329df1fd18c4418c8994974c35d99d98f4166dfe71129d19f0b5c020
BLAKE2b-256 checksum
How to use checksums
e4620246045e3776dea4e69ea35663d60b62d41facd37d948120219b056dd88c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 26, 2026.

Transparency log

Release files / anyver-1.2.0-cp311-abi3-macosx_11_0_arm64.whl

Download URL anyver-1.2.0-cp311-abi3-macosx_11_0_arm64.whl
Size 358.1 kB
Tags CPython 3.11 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
ea701088247d3b1dcbd65f5bf2dffbd8d0c06e76ae2e4e2a53f6edeb97a46fc1
BLAKE2b-256 checksum
How to use checksums
3ae6454f5531c9ef03d001057750ad33b7aabc534873ccd76f8a0efa995accb9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 26, 2026.

Transparency log

Release files / anyver-1.2.0-cp311-abi3-macosx_10_12_x86_64.whl

Download URL anyver-1.2.0-cp311-abi3-macosx_10_12_x86_64.whl
Size 355.5 kB
Tags CPython 3.11 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
d6cc7fc79db0c1a8b366a81474c087e03ebfdebebedf01c807678eaf06c9f84d
BLAKE2b-256 checksum
How to use checksums
87f1b0bc22f154947de0149f3b1ad973bccdfdb1d0dfcd22fa7ccfda47a8a9f1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 26, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.2.0 This release

8 release files

1.1.0

8 release files

1.0.0

8 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page