Nexus Repo Manager does not honor PEP440 version epochs correctly

This is the relevant pep documentation

According to this, if we have a python package with a “number!semver” then the way version order should be handled is different than how it is currently handled by the nexus pypi hosted repo.

We need to figure out why nexus is not doing this correctly or if their implementation of PEP440 needs to be fixed via a bug.

Where is this causing an issue?

Hi Matthew,

We face this situation because we want to change the way we are versioning our pypi package in our internal repo and we want to use the epoch value to differentiate this change. So we want to start using 1! so that the previous versioning scheme is always older than versions published using this new scheme.

Sorry but this doesn’t describe where the problem occurs either.

Is this in Search? Browse? pip client?

Symptoms of issues:

Old Pkg versions


2023.11.1
2023.12.1

New Pkg versions


1!1.0.1
1!1.0.2

According to the PEP440 doc, when installing the package using pip install , the newer version 1! should be considered more recent than the prev version. But we still see the old version 2023.12.1 take precedence over 1!1.0.1 etc.

Again, I understand what you’re saying in respect to PEP but you’ve yet to provide specifics on where this problem occurs in Nexus.

Hmm, is it possible to get on a support call for me to be able to show you the symptom? I’m not sure how else I can explain this to you.

Old Pkg versions


2023.11.1
2023.12.1

New Pkg versions


1!1.0.1
1!1.0.2

Given the “Old” and “New (with epoch 1!)” version packages in my nexus pypi repo. As a user, when I try to do pip install , it does not install what should be considered latest version with the epoch. The expectation above is to install version 1!1.0.2 whereas the version being installed is 2023.12.1

[UPDATING This msg on April 24, 2024, since I’m only allowed 3 comments]
Hello, can we get some help on this? As I said, the issue is, when trying to do a pip install from a client machine pointing to a hosted pypi repo on nexus, the expectation is that versions with higher epoch tags should be picked as more recent (1!1.0.1 > 2023.11.1) but we are seeing that nexus still returns 2023.11.1 as the most recent package.

Hi @mpiggott , in nexus we have package with version as 1!6.2a2311. But when we try to install that package, getting the following error.

pip install --upgrade --index-url=https://uname:pswd@url/repository/bamboo-sandbox-zpy/simple tafsdk-simple==‘1!6.2a2311’
Looking in indexes: https://uname:pswd@url/repository/bamboo-sandbox-zpy/simple
ERROR: Could not find a version that satisfies the requirement tafsdk-simple==1!6.2a2311 (from versions: 1-6.1b240505, 1-6.2a2311, 1-6.2.post2402, 1-6.3a2311, 1-6.3.post20240515, 1-6.3.2311, 6.2a2311, 6.3a2311, 6.3b231110, 6.3rc2311, 6.3, 6.3.post2311, 6.3.post231109, 6.3.2311, 6.3.2311.post0, 6.3.231109, 22.5.27, 22.5.27.1, 22.5.28.1, 22.5.28.3, 22.5.28.4, 22.5.28.6, 22.5.28.8, 22.5.30, 23.11.10, 23.11.17, 23.11.20, 23.11.24, 23.12.1, 23.12.8, 23.12.15, 24.1.30, 24.1.31, 24.2.1, 24.2.6, 2311.6.2a0, 2311.6.2a15, 2311.6.2, 2311.6.2.post0)
ERROR: No matching distribution found for tafsdk-simple==1!6.2a2311

And if we use the package version as tafsdk-simple==1-6.2a2311 we get this following error

ERROR: Exception:
Traceback (most recent call last):
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_internal/cli/base_command.py”, line 173, in _main
status = self.run(options, args)
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_internal/cli/req_command.py”, line 203, in wrapper
return func(self, options, args)
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_internal/commands/install.py”, line 315, in run
requirement_set = resolver.resolve(
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/resolver.py”, line 94, in resolve
result = self._result = resolver.resolve(
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py”, line 472, in resolve
state = resolution.resolve(requirements, max_rounds=max_rounds)
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py”, line 341, in resolve
self._add_to_criteria(self.state.criteria, r, parent=None)
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py”, line 172, in _add_to_criteria
if not criterion.candidates:
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_vendor/resolvelib/structs.py”, line 151, in bool
return bool(self._sequence)
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py”, line 140, in bool
return any(self)
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py”, line 128, in
return (c for c in iterator if id(c) not in self._incompatible_ids)
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py”, line 32, in _iter_built
candidate = func()
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/factory.py”, line 204, in _make_candidate_from_link
self._link_candidate_cache[link] = LinkCandidate(
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py”, line 283, in init
wheel_version = Version(wheel.version)
File “/root/virtualenv/py3_env/lib/python3.10/site-packages/pip/_vendor/packaging/version.py”, line 266, in init
raise InvalidVersion(f"Invalid version: ‘{version}’")
pip._vendor.packaging.version.InvalidVersion: Invalid version: ‘1-6.2a2311’

Nexus is not handling version epochs properly.