Summary

  • PyPI describes yanking as a non-destructive alternative to deletion. Its current release-management action applies to an entire release, while repository views expose the yanked state on files.
  • PEP 592 makes the marker reversible and leaves important selection behavior to installers. A marker is not an installation transcript or an account of a package’s safety.
  • A consequential conclusion needs separate records for the repository state, the requested constraint or lock, the resolver’s choice, the retrieved artifact, and any security or deployment assessment.

“Yanked” is easy to overread because it sounds final. PyPI’s own documentation makes the narrower point. A maintainer may yank a release as a non-destructive alternative to deletion; the guidance gives broken or uninstallable releases, violated compatibility promises, and a security vulnerability as reasons to consider it. Those are possible reasons, not a classification that the marker itself proves. The optional reason can help a downstream user respond, but it is neither a forensic finding nor a universal instruction.

The repository surface has a specific scope. PyPI currently supports yanking an entire release rather than an individual file in its management interface. PEP 592 defines a data-yanked attribute on Simple API links, which means a client can encounter the state at file level. That is a useful distinction: a release-management action and a file-level index representation are connected, but neither establishes a deletion receipt, a publisher-authorization decision, or a statement about a consumer’s environment.

Selection remains a separate event. PEP 592 says an installer must ignore yanked releases when a non-yanked choice satisfies the constraints, and may refuse a yanked release even where refusal leaves no satisfying choice. PyPI documents an exact-version exception in its own service behavior. A resolver therefore needs the constraint, available index view, client policy, clock, and lock or prior state before one can say what it chose. A current yanked flag cannot recreate an earlier resolution; an exact pin or a different client can make the practical result different from a broad request.

Deletion is a separate state again. PyPI says yanking does not free storage, while deletion is permanent without administrator intervention and can disrupt pinned downstream use. Neither contrast permits a shortcut from “still present” to “endorsed,” or from “yanked” to “withdrawn everywhere.” The JSON API’s yanked and yanked_reason fields are valuable observations of repository presentation. They do not say whether an artifact was downloaded, installed, executed, blocked by a policy, or accepted by a release owner.

Daniel Kade recommends a five-part yank receipt for a claim that matters. Preserve the project and release identifier, repository endpoint, observed yanked value/reason, observer, and time. Preserve the exact requested requirement or lock and the source indexes available to the resolver. Preserve the resolver and installer version, policy, decision, warnings, and artifact hashes. Preserve any separate deletion, publisher-authority, vulnerability, or incident evidence under its own authority. Finally, preserve deployment or inventory evidence separately. Sensitive project names can be protected; the join should not be invented.

Sources

  1. PyPI Docs — Yanking
  2. PEP 592 — Adding “Yank” Support to the Simple API
  3. PyPI Docs — Storage Limits
  4. PyPI Docs — JSON API