What
# update-time: ignore[yanked] holds back the yank warning for a reference. For most reference kinds there is no yank warning to hold back, and there never can be: only PyPI reports yanks (PEP 592) and only npm reports the per-version deprecation Update-time treats as its counterpart. A Docker image, a GitHub Action, and a pre-commit hook have no yank concept at all, so their resolved version's yank state is always "not yanked", whatever the registry answers.
A user who writes ignore[yanked] on one of those references gets no yank warning, no update held back, and no diagnostic. The marker is recognised, echoed at DEBUG as Applying update-time marker ignore[yanked] ..., and then does nothing — this run and every future run.
Why
Update-time already warns about a marker that cannot have an effect: warn_if_redundant_bound reports a version bound that never has an effect or blocks every update, on the grounds that removing it would change nothing. An ignore[yanked] on a reference kind that is never yank-checked meets exactly that test, and more strongly: a redundant bound stops being redundant once the pin moves, while this marker can never do anything for as long as the reference points where it points.
The silence is what makes it a trap. The user has expressed an intent — "I have acknowledged this yank, stop telling me" — and Update-time neither honours it nor contradicts it. The marker reads as accepted, so the mistaken belief survives every run.
Current behaviour
A Dockerfile base image with the marker, run with --log-level DEBUG:
# update-time: ignore[yanked]
FROM python:3.12-bookworm-slim
DEBUG Applying update-time marker ignore[yanked] to python in Dockerfile:2
Nothing further is logged about the marker, now or ever, because a Docker image's version carries no yank state to suppress.
Expected behaviour
A marker that can never have an effect for the reference it is attached to is reported at WARNING, like a redundant version bound, so the user can remove it or discover that the acknowledgement belongs elsewhere.
Proposed behaviour
- Warn at
WARNING when a reference carries ignore[yanked] and its version can never carry a yank state.
- Keep the warning per reference and informational only, like the redundant-bound and staleness warnings: no file content changes and no effect on the exit status.
- Say what the user can act on, without naming internals: something in the spirit of
Redundant update-time marker ignore[yanked] on python in Dockerfile:2: Docker images have no yank concept, so the marker holds nothing back. The README already words this as "Docker images and GitHub Actions have no yank concept".
Which references are affected
Of the reference kinds that accept a marker at all, exactly one is yank-checked:
| Reference kind |
Where its versions come from |
Yank state possible? |
requirements.txt dependencies |
PyPI |
yes (PEP 592) |
| Docker images (Dockerfile, Compose, Helm, CircleCI, GitLab CI, devcontainer) |
OCI registries, Docker Hub |
no |
| GitHub Actions |
GitHub |
no |
| Pre-commit hooks |
GitHub |
no |
.python-version entries |
Docker Hub, or the project's Dockerfile |
no |
So ignore[yanked] is meaningful in requirements.txt and nowhere else a marker can be written. jsDelivr URLs are yank-checked through the npm registry, but they accept no marker at all, which is a separate gap.
Where the knowledge lives
Only sources/pypi.py and sources/jsdelivr.py (through sources/npmjs.py) ever set a non-default Yank; sources/oci.py, sources/docker_hub.py, and sources/github.py leave it at its default. The fact to expose is therefore a property of the source a reference resolves through, not of the file it lives in.
resolve.latest_version is the natural place to report from: it already has the marker, the location, the logger, and the resolver, and it is where the sibling redundant-bound warning is raised. Marking the resolver itself — an attribute on the NewVersionGetter, set once per source — keeps the fact in one place per source instead of at every updater's call site, but the shape is the maintainer's call.
Notes
- A bare
# update-time: ignore must not warn. It holds back the update, the staleness warning, and the yank warning together, and it is a deliberate freeze rather than a claim about yanks. It never reaches latest_version anyway: apply_marker returns the line without querying the source when all three scopes are held back, so the correct behaviour falls out for free.
- An
ignore[yanked] alongside a live ignore[update] should still warn. The yank scope is just as pointless there.
- This is deliberately narrower than "warn about a marker that suppressed nothing on this run". A dormant marker is not a mistaken one: yank state and staleness both change over time, and a dependency hovering near the staleness threshold would flip such a warning on and off between runs. That situational case is answered at DEBUG by #169; this issue is only about markers that can never fire.
- A candidate for the same treatment, worth deciding separately:
ignore[stale] on an image hosted outside Docker Hub. Staleness relies on a tag's push date, which other registries (ghcr.io, mcr.microsoft.com, …) do not expose, so that marker is permanently inert too. It is a weaker case than the yank one, because the fact follows from the registry named in the reference rather than from the kind of reference it is.
- The README's marker table presents
ignore[yanked] as generally available. If this warning lands, that section should say where the scope can actually have an effect.
What
# update-time: ignore[yanked]holds back the yank warning for a reference. For most reference kinds there is no yank warning to hold back, and there never can be: only PyPI reports yanks (PEP 592) and only npm reports the per-version deprecation Update-time treats as its counterpart. A Docker image, a GitHub Action, and a pre-commit hook have no yank concept at all, so their resolved version's yank state is always "not yanked", whatever the registry answers.A user who writes
ignore[yanked]on one of those references gets no yank warning, no update held back, and no diagnostic. The marker is recognised, echoed at DEBUG asApplying update-time marker ignore[yanked] ..., and then does nothing — this run and every future run.Why
Update-time already warns about a marker that cannot have an effect:
warn_if_redundant_boundreports a version bound that never has an effect or blocks every update, on the grounds that removing it would change nothing. Anignore[yanked]on a reference kind that is never yank-checked meets exactly that test, and more strongly: a redundant bound stops being redundant once the pin moves, while this marker can never do anything for as long as the reference points where it points.The silence is what makes it a trap. The user has expressed an intent — "I have acknowledged this yank, stop telling me" — and Update-time neither honours it nor contradicts it. The marker reads as accepted, so the mistaken belief survives every run.
Current behaviour
A Dockerfile base image with the marker, run with
--log-level DEBUG:DEBUG Applying update-time marker ignore[yanked] to python in Dockerfile:2Nothing further is logged about the marker, now or ever, because a Docker image's version carries no yank state to suppress.
Expected behaviour
A marker that can never have an effect for the reference it is attached to is reported at
WARNING, like a redundant version bound, so the user can remove it or discover that the acknowledgement belongs elsewhere.Proposed behaviour
WARNINGwhen a reference carriesignore[yanked]and its version can never carry a yank state.Redundant update-time marker ignore[yanked] on python in Dockerfile:2: Docker images have no yank concept, so the marker holds nothing back. The README already words this as "Docker images and GitHub Actions have no yank concept".Which references are affected
Of the reference kinds that accept a marker at all, exactly one is yank-checked:
requirements.txtdependencies.python-versionentriesSo
ignore[yanked]is meaningful inrequirements.txtand nowhere else a marker can be written. jsDelivr URLs are yank-checked through the npm registry, but they accept no marker at all, which is a separate gap.Where the knowledge lives
Only
sources/pypi.pyandsources/jsdelivr.py(throughsources/npmjs.py) ever set a non-defaultYank;sources/oci.py,sources/docker_hub.py, andsources/github.pyleave it at its default. The fact to expose is therefore a property of the source a reference resolves through, not of the file it lives in.resolve.latest_versionis the natural place to report from: it already has the marker, the location, the logger, and the resolver, and it is where the sibling redundant-bound warning is raised. Marking the resolver itself — an attribute on theNewVersionGetter, set once per source — keeps the fact in one place per source instead of at every updater's call site, but the shape is the maintainer's call.Notes
# update-time: ignoremust not warn. It holds back the update, the staleness warning, and the yank warning together, and it is a deliberate freeze rather than a claim about yanks. It never reacheslatest_versionanyway:apply_markerreturns the line without querying the source when all three scopes are held back, so the correct behaviour falls out for free.ignore[yanked]alongside a liveignore[update]should still warn. The yank scope is just as pointless there.ignore[stale]on an image hosted outside Docker Hub. Staleness relies on a tag's push date, which other registries (ghcr.io,mcr.microsoft.com, …) do not expose, so that marker is permanently inert too. It is a weaker case than the yank one, because the fact follows from the registry named in the reference rather than from the kind of reference it is.ignore[yanked]as generally available. If this warning lands, that section should say where the scope can actually have an effect.