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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions