From f83c6feeaa50a51b17161d592a71b88f0253f7ce Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Fri, 28 Aug 2026 13:37:12 +0200 Subject: [PATCH] Accept exact pins with more than three version components `types-requests==2.33.0.20260712` was reported as "not exact-pinned" against its own value: the regex capped the release segment at three components, and PyPI stub packages date-stamp a fourth. PEP 440 places no such limit. Found by running the gate over crdt-sync's newly pinned requirements.txt, which is the only manifest in the fleet with a four-part pin. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01CRykabMwPgDzFHcARoqpaK --- dep_freshness/tests/test_versions.py | 5 ++++- dep_freshness/versions.py | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/dep_freshness/tests/test_versions.py b/dep_freshness/tests/test_versions.py index 969e3a8..70f5204 100644 --- a/dep_freshness/tests/test_versions.py +++ b/dep_freshness/tests/test_versions.py @@ -34,7 +34,10 @@ def test_newest_stable_ignores_unparseable_entries(): @pytest.mark.parametrize("raw,expected", [ ("1.6.0", "1.6.0"), ("==1.6.0", "1.6.0"), ("v2.0.0", "2.0.0"), - (" 1.0.0 ", "1.0.0"), + (" 1.0.0 ", "1.0.0"), ("1.9", "1.9"), ("3", "3"), + # PyPI stub packages date-stamp a fourth component. Capping the regex at + # three reported this exact pin as unpinned *against its own value*. + ("==2.33.0.20260712", "2.33.0.20260712"), ]) def test_exact_pins_are_recognised(raw, expected): assert exact_pin(raw) == expected diff --git a/dep_freshness/versions.py b/dep_freshness/versions.py index 0a63e2e..1929424 100644 --- a/dep_freshness/versions.py +++ b/dep_freshness/versions.py @@ -74,7 +74,10 @@ def behind(pinned: str, latest: str) -> bool: return left < right -EXACT = re.compile(r"^\s*(?:==\s*)?v?\d+(?:\.\d+){0,2}(?:[-+][0-9A-Za-z.-]+)?\s*$") +# Any number of numeric release components, not three: PyPI stub packages +# date-stamp a fourth (`types-requests==2.33.0.20260712`), and capping at +# three reported an exact pin as unpinned against itself. +EXACT = re.compile(r"^\s*(?:==\s*)?v?\d+(?:\.\d+)*(?:[-+][0-9A-Za-z.-]+)?\s*$") def exact_pin(constraint: str) -> str | None: