{"id":35312345,"url":"https://github.com/willynilly/verple","last_synced_at":"2026-05-21T02:01:50.593Z","repository":{"id":298752137,"uuid":"1000955270","full_name":"willynilly/verple","owner":"willynilly","description":"Verple is a ridiculously strict and ultra-conservative universal version format, comparator, serializer, and protocol.","archived":false,"fork":false,"pushed_at":"2025-06-12T23:06:38.000Z","size":29,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-27T13:35:39.355Z","etag":null,"topics":["pep440","semver","version-parser","versioning","versioning-semantics"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willynilly.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-06-12T15:22:19.000Z","updated_at":"2025-09-18T00:35:00.000Z","dependencies_parsed_at":"2025-09-05T12:01:23.554Z","dependency_job_id":"50db37d6-89a7-4115-8833-4d0bab827ebf","html_url":"https://github.com/willynilly/verple","commit_stats":null,"previous_names":["willynilly/universion","willynilly/verple"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/willynilly/verple","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willynilly%2Fverple","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willynilly%2Fverple/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willynilly%2Fverple/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willynilly%2Fverple/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willynilly","download_url":"https://codeload.github.com/willynilly/verple/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willynilly%2Fverple/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33284879,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-20T15:12:43.734Z","status":"online","status_checked_at":"2026-05-21T02:00:07.181Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pep440","semver","version-parser","versioning","versioning-semantics"],"created_at":"2025-12-30T17:48:37.517Z","updated_at":"2026-05-21T02:01:50.587Z","avatar_url":"https://github.com/willynilly.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Verple\n\n**Verple** is a ridiculously strict and ultra-conservative universal version format, comparator, serializer, and protocol.\n\n## Design Goals\n\n- 🔒 **Ultra-conservative equality**: versions are considered different if any field differs (`release`, `prerelease`, `postrelease`, `devrelease`, `local`).\n- ⚖ **Strict conservative ordering**: ordering is only permitted when local metadata matches exactly; otherwise ordering raises `ValueError` to avoid ambiguity.\n- 🔎 **Multi-standard input support**: parses version strings from PEP 440, SemVer, Canonical, and Calendar Versioning (CalVer).\n- 🔁 **Canonical serialization**: provides fully reversible serialization via `to_canonical_string()` and parsing via `from_canonical_string()`.\n- 🧮 **Hashable and set-safe**: fully hashable and safe for use in sets and dictionaries, with hashes consistent with strict equality.\n- 📦 **JSON-LD serialization**: supports semantic serialization with provenance (`sourceFormat` and `sourceInput` fields).\n- 🔐 **Versioned deserialization protocol**: fully versioned serialization model allowing future-safe protocol evolution.\n- 📚 **Use Case Domains**: reproducible builds, registries, deployment pipelines, archival systems, provenance tracking, scientific reproducibility.\n\n## Supported Python Versions\n\n- Python \u003e= 3.10\n\n## Installation\n\n```bash\npip install verple\n```\n\n## Example Usage\n\n```python\nfrom verple import Verple\n\n# Parse version string\nv1 = Verple.parse(\"1.2.3a1.post2.dev3+build99\")\nprint(v1.to_canonical_string())  # 1.2.3-a1.post2.dev3+build99\n\n# Strict equality\nv2 = Verple.parse(\"1.2.3a1.post2.dev3+build99\")\nassert v1 == v2\n\n# Hashable and set-safe\nversions = {v1, v2}\nassert len(versions) == 1\n\n# Conservative ordering (only if local metadata matches)\nv3 = Verple.parse(\"1.2.4+build99\")\nassert v1 \u003c v3\n\n# JSON-LD serialization\njsonld = v1.to_jsonld()\nv1_roundtrip = Verple.from_jsonld(jsonld)\nassert v1 == v1_roundtrip\n```\n\n## Canonical Serialization Format\n\nVerple canonical strings follow this grammar:\n\n```\n\u003crelease\u003e[-\u003cprerelease\u003e][.post\u003cN\u003e][.dev\u003cN\u003e][+\u003clocal\u003e]\n```\n\nExample:\n\n- `1.2.3-a1.post2.dev3+build99`\n\n## JSON-LD Serialization Format\n\nVerple also supports semantic serialization:\n\n```json\n{\n  \"@context\": \"https://gitlab.com/willynilly/verple/-/raw/main/src/verple/context/v1.0.0.jsonld\",\n  \"@type\": \"Verple\",\n  \"verple\": \"1.0.0\",\n  \"sourceFormat\": \"pep440\",\n  \"sourceInput\": \"1.2.3a1.post2.dev3+build99\",\n  \"release\": [1, 2, 3],\n  \"prerelease\": [\"a\", 1],\n  \"postrelease\": 2,\n  \"devrelease\": 3,\n  \"local\": \"build99\"\n}\n```\n\nThis allows full provenance and schema evolution.\n\n## Tests\n\nThis project uses `pytest`:\n\n```bash\npytest tests/\n```\n\n## Protocol Semantics\n\n### Normalization\n\nVerple normalizes versions into a fully structured model with the following fields:\n\n- `release`: tuple of integers (major, minor, patch, or calendar parts)\n- `prerelease`: tuple of `(label: str, num: int)` or `None`\n- `postrelease`: integer or `None`\n- `devrelease`: integer or `None`\n- `local`: string or `None`\n- `sourceInput`: original version string\n- `sourceFormat`: the parsed format (`pep440`, `semver`, `canonical`, `calver`)\n\nAll formats (PEP 440, SemVer, Canonical, CalVer) are converted into this internal structure.\n\n### Equality Algorithm\n\nTwo versions are equal if and only if all of the following fields are equal:\n\n- `release`\n- `prerelease`\n- `postrelease`\n- `devrelease`\n- `local`\n\nFields are compared strictly; any difference implies inequality.\n\n### Ordering Algorithm\n\nOrdering is permitted only if both versions have identical `local` metadata. If `local` differs, ordering is refused.\n\nIf allowed, versions are compared using the tuple:\n\n```\n(\n  release,\n  prerelease_key(prerelease),\n  postrelease or -1,\n  devrelease or infinity\n)\n```\n\nWhere:\n\n- `prerelease_key(None)` → `(infinity,)` (normal releases sort after prereleases)\n- `prerelease_key((label, num))` → `(label, num)` (string then numeric comparison)\n\nThe algorithm aligns with PEP 440 precedence where applicable.\n\n### Canonical Form Algorithm\n\nSerialization via `to_canonical_string()` reconstructs the version string as:\n\n```\n\u003crelease\u003e[-\u003cprerelease\u003e][.post\u003cN\u003e][.dev\u003cN\u003e][+\u003clocal\u003e]\n```\n\nFields that are `None` are omitted.\n\n### JSON-LD Serialization\n\nThe full semantic model is serialized as JSON-LD, including provenance fields `sourceFormat` and `sourceInput` for full reproducibility.\n\n## Field Definitions\n\nThe following fields are used throughout Verple's internal model, canonical serialization, and JSON-LD serialization:\n\n| Field        | Type             | Meaning |\n|--------------|------------------|-------------------------------------------------------------|\n| `release`    | tuple of int     | Core version numbers: major.minor.patch or calendar parts |\n| `prerelease` | tuple (str, int) or None | Pre-release stage (alpha, beta, rc, etc.) and stage number |\n| `postrelease` | int or None     | Post-release revision applied after final release |\n| `devrelease` | int or None      | Development release version for pre-release internal builds |\n| `local`      | str or None      | Local build metadata identifier (build info, git hash, etc.) |\n| `sourceInput` | str            | The original version string provided as input |\n| `sourceFormat` | str          | The detected format: `pep440`, `semver`, `canonical`, or `calver` |\n| `verple`     | str              | Serialization format version (e.g. `\"1.0.0\"`) |\n| `@context`   | URL              | JSON-LD context URL defining linked data vocabulary |\n| `@type`      | str              | Always `\"Verple\"` |\n\n### Conceptual Definitions\n\n- **release**: The main numeric version (e.g. `1.2.3`), structured as Major.Minor.Patch (SemVer, PEP 440) or Year.Month.[Day] (CalVer).\n\n- **prerelease**: A pre-final release marker such as `alpha`, `beta`, or `rc`, optionally followed by a stage number (e.g. `rc1`).\n\n- **postrelease**: Identifies patches or hotfixes applied after a final release (`.postN`).\n\n- **devrelease**: Development snapshots issued before formal releases (`.devN`), typically for internal or unstable builds.\n\n- **local**: Build metadata or local identifiers following `+build` semantics, capturing build environment or other internal state.\n\n- **sourceInput**: The raw version string provided by the caller.\n\n- **sourceFormat**: Indicates which parser was used to interpret the input (`pep440`, `semver`, `canonical`, `calver`).\n\n- **verple**: The version of the Verple serialization protocol used to encode the JSON-LD document.\n\n- **@context / @type**: JSON-LD linked data metadata used to enable semantic parsing of Verple objects.\n\n## License\n\nApache 2.0\n\n## Author\n\n- Will Riley\n- Co-developed with ChatGPT-4o during protocol design.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillynilly%2Fverple","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillynilly%2Fverple","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillynilly%2Fverple/lists"}