The problem
Update-time reports a vulnerability suppression that holds nothing back. A reference marked
# update-time: ignore[vulnerable] is still looked up, and when the version has no vulnerability at all the marker
is reported as redundant:
WARNING Redundant update-time directive ignore[vulnerable] for django in docs/requirements.txt:12: version 4.2.0 has no vulnerability
The README gives the reason: the check is what can tell you the marker went stale, because a suppression outlives
the thing it was written for.
The same is true of ignore[yanked], ignore[stale], and ignore[archived], and Update-time says nothing about
any of them. A reference marked ignore[yanked] whose pin has moved off the yanked release, one marked
ignore[stale] whose project publishes again, and one marked ignore[archived] whose project was never archived
each carry a directive that silences nothing. Nobody is told, so the marker stays in the file for as long as the
file lives.
Where the gap is
Logger._report is the one place all three of these checks report through:
def _report(self, check, marker, resolved, fields) -> None:
if fields is None:
return
if marker.ignores(check.scope):
... # log the hold-back at DEBUG
else:
... # log the warning
fields is None means the check found nothing: the version stands, the project is fresh, the project is active.
The marker is not consulted on that path, so a directive silencing a finding that is not there is passed over. The
vulnerability check reports its three redundant forms from a path of its own, which is why it is the exception.
Because the three checks share that branch, one change reaches all three.
What to report
A warning in the shape the vulnerability suppressions use, naming what the check found instead:
| Directive |
Reason reported |
an ignore[yanked] on a version that stands |
version 4.15.0 was not yanked |
an ignore[stale] on a project that published recently |
newest release 4.15.0 is not older than 365 days |
an ignore[archived] on a project that is active |
the project is not archived |
The words above are a starting point. The archival warning names what its source archived — a project on PyPI, a
repository on GitHub — so its redundancy warning should name the same subject.
Each reaches the references whose source answers that check. A reference whose source cannot answer it at all
already gets a redundancy warning of its own, saying so, and this one must not double up on it.
Only the bare scopes
ignore[stale<90] and the other comparison items are out of scope. They set a threshold rather than silence a
finding, and ignore[stale<90] warns earlier than the run's setting rather than later. A reader who wants a
policy rather than a suppression writes one of those, which is also the answer to a bare scope reported as
redundant: replace it with the threshold you meant.
Out of scope
- The three vulnerability suppressions, which already report.
- The comparison items, for the reason above.
ignore[update], which holds a version back whether or not a newer one exists, so it silences no finding.
Documentation
The per-scope sections that describe the suppression — Stale dependencies, Yanked dependencies, and Archived
dependencies — and the list under Redundant markers.
The problem
Update-time reports a vulnerability suppression that holds nothing back. A reference marked
# update-time: ignore[vulnerable]is still looked up, and when the version has no vulnerability at all the markeris reported as redundant:
WARNING Redundant update-time directive ignore[vulnerable] for django in docs/requirements.txt:12: version 4.2.0 has no vulnerabilityThe README gives the reason: the check is what can tell you the marker went stale, because a suppression outlives
the thing it was written for.
The same is true of
ignore[yanked],ignore[stale], andignore[archived], and Update-time says nothing aboutany of them. A reference marked
ignore[yanked]whose pin has moved off the yanked release, one markedignore[stale]whose project publishes again, and one markedignore[archived]whose project was never archivedeach carry a directive that silences nothing. Nobody is told, so the marker stays in the file for as long as the
file lives.
Where the gap is
Logger._reportis the one place all three of these checks report through:fields is Nonemeans the check found nothing: the version stands, the project is fresh, the project is active.The marker is not consulted on that path, so a directive silencing a finding that is not there is passed over. The
vulnerability check reports its three redundant forms from a path of its own, which is why it is the exception.
Because the three checks share that branch, one change reaches all three.
What to report
A warning in the shape the vulnerability suppressions use, naming what the check found instead:
ignore[yanked]on a version that standsignore[stale]on a project that published recentlyignore[archived]on a project that is activeThe words above are a starting point. The archival warning names what its source archived — a project on PyPI, a
repository on GitHub — so its redundancy warning should name the same subject.
Each reaches the references whose source answers that check. A reference whose source cannot answer it at all
already gets a redundancy warning of its own, saying so, and this one must not double up on it.
Only the bare scopes
ignore[stale<90]and the other comparison items are out of scope. They set a threshold rather than silence afinding, and
ignore[stale<90]warns earlier than the run's setting rather than later. A reader who wants apolicy rather than a suppression writes one of those, which is also the answer to a bare scope reported as
redundant: replace it with the threshold you meant.
Out of scope
ignore[update], which holds a version back whether or not a newer one exists, so it silences no finding.Documentation
The per-scope sections that describe the suppression — Stale dependencies, Yanked dependencies, and Archived
dependencies — and the list under Redundant markers.