Skip to content

bug: lexicographic version sort returns wrong "latest" version for semver-style version IDs #70

Description

@Prakhar54-byte
# Bug Report                                                                                                              
                                                                                                                          
**Describe the bug**                                                                                                      
When downloading an artifact without specifying a version, the client fetches all                                         
available versions and picks the "latest" one using:                                                                      
                                                                                                                          
```python                                                                                                                 
version_urls.sort(reverse=True)                                                                                           
return version_urls[0]                                                                                                    

This is a lexicographic (string) sort, not a semantic/numeric sort. For
semver-style version IDs this produces the wrong result:

Version list │ Lexicographic "latest" │ Correct "latest"
─────────────────────────────────────────┼─────────────────────────────────────────┼────────────────────────────────────────
["2.10.0", "2.9.0", "2.1.0"] │ "2.9.0" ❌ │ "2.10.0" ✅
["1.12", "1.9", "1.2"] │ "1.9" ❌ │ "1.12" ✅

Date-style versions ( 2022.12.01 ) happen to sort correctly lexicographically, so
the bug is currently hidden for DBpedia's own datasets — but will surface for any
artifact using numeric versioning.

To Reproduce

  1. Publish an artifact with versions 1.9 and 1.10 to any Databus instance.

  2. Run:
    databusclient download https://///

  3. Observe that version 1.9 is downloaded instead of 1.10 .

Expected behavior
The latest version should be determined by numeric comparison of version segments,
not by lexicographic string sort.

Root Cause
File: databusclient/api/download.py , function _get_databus_versions_of_artifact() , line 878.

# current (broken for semver)                                                                                             
version_urls.sort(reverse=True)                                                                                           
                                                                                                                          
# suggested fix: parse trailing version segment numerically                                                               
from packaging.version import Version, InvalidVersion                                                                     
                                                                                                                          
def _version_key(url):                                                                                                    
    segment = url.rstrip("/").split("/")[-1]                                                                              
    try:                                                                                                                  
        return Version(segment)                                                                                           
    except InvalidVersion:                                                                                                
        return Version("0")  # fallback for non-standard formats                                                          
                                                                                                                          
version_urls.sort(key=_version_key, reverse=True)                                                                         

Additional context

• Affected function: _get_databus_versions_of_artifact() in download.py
• packaging is not currently a dependency but is a very lightweight stdlib-adjacent
package; alternatively a pure-Python numeric segment comparator can be used with
no new dependencies.
• This also affects the --all-versions flag ordering (cosmetic, but confusing).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions