fix: treat bare version constraints as exact match
When resolving dependencies like certifi@2025.10.5, the bare version string "2025.10.5" was being rejected as an invalid SpecifierSet and falling back to wildcard, which fetched the latest version instead. Now bare versions starting with a digit are automatically prefixed with "==" to create an exact match constraint.
This commit is contained in:
@@ -269,8 +269,18 @@ class PyPIRegistryClient(RegistryClient):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
# Parse constraint
|
# Parse constraint
|
||||||
|
# If constraint looks like a bare version (no operator), treat as exact match
|
||||||
|
# e.g., "2025.10.5" -> "==2025.10.5"
|
||||||
|
effective_constraint = constraint
|
||||||
|
if constraint and constraint[0].isdigit():
|
||||||
|
effective_constraint = f"=={constraint}"
|
||||||
|
logger.debug(
|
||||||
|
f"Bare version '{constraint}' for {normalized}, "
|
||||||
|
f"treating as exact match '{effective_constraint}'"
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
specifier = SpecifierSet(constraint)
|
specifier = SpecifierSet(effective_constraint)
|
||||||
except InvalidSpecifier:
|
except InvalidSpecifier:
|
||||||
# Invalid constraint - treat as wildcard
|
# Invalid constraint - treat as wildcard
|
||||||
logger.warning(
|
logger.warning(
|
||||||
|
|||||||
@@ -176,6 +176,42 @@ class TestPyPIRegistryClient:
|
|||||||
|
|
||||||
assert result is None
|
assert result is None
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_resolve_constraint_bare_version(self, client, mock_http_client):
|
||||||
|
"""Test resolving bare version string as exact match."""
|
||||||
|
mock_response = MagicMock()
|
||||||
|
mock_response.status_code = 200
|
||||||
|
mock_response.json.return_value = {
|
||||||
|
"info": {"version": "2.0.0"},
|
||||||
|
"releases": {
|
||||||
|
"1.0.0": [
|
||||||
|
{
|
||||||
|
"packagetype": "bdist_wheel",
|
||||||
|
"url": "https://files.pythonhosted.org/test-1.0.0.whl",
|
||||||
|
"filename": "test-1.0.0.whl",
|
||||||
|
"digests": {"sha256": "abc123"},
|
||||||
|
"size": 1000,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2.0.0": [
|
||||||
|
{
|
||||||
|
"packagetype": "bdist_wheel",
|
||||||
|
"url": "https://files.pythonhosted.org/test-2.0.0.whl",
|
||||||
|
"filename": "test-2.0.0.whl",
|
||||||
|
"digests": {"sha256": "def456"},
|
||||||
|
"size": 2000,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
mock_http_client.get.return_value = mock_response
|
||||||
|
|
||||||
|
# Bare version "1.0.0" should resolve to exactly 1.0.0, not latest
|
||||||
|
result = await client.resolve_constraint("test-package", "1.0.0")
|
||||||
|
|
||||||
|
assert result is not None
|
||||||
|
assert result.version == "1.0.0"
|
||||||
|
|
||||||
|
|
||||||
class TestVersionInfo:
|
class TestVersionInfo:
|
||||||
"""Tests for VersionInfo dataclass."""
|
"""Tests for VersionInfo dataclass."""
|
||||||
|
|||||||
Reference in New Issue
Block a user