From 6e5fbde14ec786d08d3ab8f6ba475bae41d0327b Mon Sep 17 00:00:00 2001 From: mvdbeek Date: Mon, 18 May 2026 20:00:14 +0200 Subject: [PATCH] use galaxy.tool_util.version.parse_version everywhere MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Galaxy vendors a ``parse_version`` (lib/galaxy/tool_util/version.py:45) that falls back to ``LegacyVersion`` when ``packaging``'s ``Version`` raises ``InvalidVersion`` — the eager toolbox uses it (lib/galaxy/tools/__init__.py:128). The new lazy paths (LazyTool's ``version_object`` / ``_ver_key``, ``ToolIndex.add_entry``'s multi-version tiebreaker) were importing ``packaging.version.parse`` directly, bypassing the LegacyVersion fallback. Swap to the vendored function in three places: - ``lib/galaxy/tools/lazy_toolbox.py`` module-level import. - ``ToolIndex.add_entry``'s inline import. - The matching comment in ``_ver_key``. No behaviour change for versions that parse as PEP-440; the difference shows up on Galaxy-specific version strings that need ``LegacyVersion`` semantics. --- lib/galaxy/tool_source_store/index.py | 12 ++++++------ lib/galaxy/tools/lazy_toolbox.py | 9 +++++---- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/galaxy/tool_source_store/index.py b/lib/galaxy/tool_source_store/index.py index 9226c8dcd48..47690e601c7 100644 --- a/lib/galaxy/tool_source_store/index.py +++ b/lib/galaxy/tool_source_store/index.py @@ -252,11 +252,11 @@ class ToolIndex: """Add an entry, populating both the default and per-version maps. The "default" entry per id (used by ``ToolIndex.get(tool_id)`` and - the ``/api/tools`` listing) is the highest version per - :func:`packaging.version.parse`. Pure string comparison fails on - e.g. ``"0.1+galaxy6"`` vs ``"0.2"`` (which compares as ``"0.1+..." - < "0.2"`` lexically only by accident — a different prefix would - flip the sign). + the ``/api/tools`` listing) is the highest version per Galaxy's + vendored :func:`galaxy.tool_util.version.parse_version`. Pure + string comparison fails on e.g. ``"0.1+galaxy6"`` vs ``"0.2"`` + (which compares as ``"0.1+..." < "0.2"`` lexically only by + accident — a different prefix would flip the sign). """ self.entries_by_version.setdefault(entry.id, {})[entry.version or ""] = entry existing = self.entries.get(entry.id) @@ -264,7 +264,7 @@ class ToolIndex: self.entries[entry.id] = entry return try: - from packaging.version import parse as _parse_version + from galaxy.tool_util.version import parse_version as _parse_version new_v = _parse_version(entry.version or "0") old_v = _parse_version(existing.version or "0") diff --git a/lib/galaxy/tools/lazy_toolbox.py b/lib/galaxy/tools/lazy_toolbox.py index f9d52f184ef..f8ec4fac0f9 100644 --- a/lib/galaxy/tools/lazy_toolbox.py +++ b/lib/galaxy/tools/lazy_toolbox.py @@ -20,7 +20,7 @@ from typing import ( from uuid import UUID from cachetools import LRUCache -from packaging.version import parse as parse_version +from galaxy.tool_util.version import parse_version from galaxy.tool_source_store import ( StoredToolSource, @@ -540,9 +540,10 @@ class LazyToolBox(ToolBox): # determine the latest; returning only the requested version # makes upgrades silently no-op. def _ver_key(v: str): - # ``packaging.version.parse`` matches what the - # eager ToolLineage uses to order versions and - # tolerates non-numeric segments (e.g. ``"1.0.0+galaxy0"``). + # ``galaxy.tool_util.version.parse_version`` matches what + # the eager ToolLineage uses to order versions and + # tolerates non-numeric segments (e.g. ``"1.0.0+galaxy0"``) + # via ``LegacyVersion`` fallback. try: return (0, parse_version(v)) except Exception: