diff --git a/pep-0592.rst b/pep-0592.rst index e3646ecc8..f7851afca 100644 --- a/pep-0592.rst +++ b/pep-0592.rst @@ -41,13 +41,33 @@ mitigate the worst of the breakage while still keeping things working for projects who have otherwise worked around or didn't hit the underlying issues. +One of the main scenarios where this may happen, is when dropping +support for a particular version of Python. The ``python-requires`` +metadata allows for dropping support for a version of Python in +a way that is not disruptive to users who are still using that +Python. However, a common mistake is to either omit or forget to +update that bit of metadata. When that mistake has been made, a +project really only has three options: + +- Prevent that version from being installed through some mechanism + (currently, the only mechanism is by deleting the release entirely). +- Re-release the version that worked as a higher version number, and + then re-release the version that dropped support as an even higher + version number with the correct metadata. +- Do nothing, and document that people using that older Python have + to manually exclude that release. + +With this PEP, projects can choose the first option, but with a +mechanism that is less likely to break the world for people who +are *currently* successfully using said project. + Specification ============= Links in the simple repository **MAY** have a ``data-yanked`` attribute -which may have a no value, or may have an arbitrary string as a value. -The presence of a ``data-yanked`` attribute **SHOULD** be interpreted as +which may have no value, or may have an arbitrary string as a value. The +presence of a ``data-yanked`` attribute **SHOULD** be interpreted as indicating that the file pointed to by this particular link has been "Yanked", and should not generally be selected by an installer, except under specific scenarios. @@ -57,19 +77,75 @@ string that represents the reason for why the file has been yanked. Tools that process the simple repository API **MAY** surface this string to end users. -When an installer encounters a link that has a ``data-yanked`` attribute, -they **SHOULD** treat that file link as if it does not exist *UNLESS* the -user is requesting the version of that file using an exact ``==`` or -``===`` match without any modifiers that make it a range (i.e. ``.*``). -Matching this version specifier is otherwise done as per PEP 440 for things -like local versions, zero padding, etc. +The yanked attribute is not immutable once set, and may be rescinded in +the future (and once rescinded, may be reset as well). Thus API users +**MUST** be able to cope with a yanked file being "unyanked" (and even +yanked again). -In other words, ``foo==1.0`` should install a yanked 1.0 or 1.0.0, but -``foo>0``, ``foo``, ``foo==1.*``, etc should not. +Whenever a file has been yanked or unyanked, an entry will be recorded +in the journal using one of the following string patterns: -In addition, an installer **SHOULD** only use a yanked file as a last -resort if there are no files available that match the requested -version that are not yanked. +* Yanking a single file: ``yank file {filename}``. +* Unkyanking a single file: ``unyank file {filename}``. + +If an entire release has been yanked, this will be recorded in the +journal as a seperate event for yanking each individual file that +is part of that release. + + +Installers +---------- + +The desireable experience for users is that once a file is yanked, when +a human being is currently trying to directly install a yanked file, that +it fails as if that file had been deleted. However, when a human did that +awhile ago, and now a computer is just continuing to mechanically follow +the original order to install the now yanked file, then it acts as if it +had not been yaned. + +An installer **MUST** ignore yanked releases, if the selection constraints +can be satisified with a non-yanked version, and **MAY** refuse to use a +yanked release even if it means that the request cannot be satisfied at all. +An implementation **SHOULD** choose a policy that follows the spirit of the +intention above, and that prevents "new" dependnecies on yanked +releases/files. + +What this means is left up to the specific installer, to decide how to best +fit into the overall usage of their installer. However, there are two +suggested approaches to take: + +1. Yanked files are always ignored, unless they are the only file that + matches a version specifier that "pins" to an exact version using + either ``==`` (without any modifiers that make it a range, such as + ``.*``) or ``===``. Matching this version specifier should otherwise + be done as per PEP 440 for things like local versions, zero padding, + etc. +2. Yanked files are always ignored, unless they are the only file that + matches what a lock file (such as ``Pipfile.lock`` or ``poetry.lock`` + specifies to be installed. In this case, a yanked file **SHOULD** not + be used when creating or updating a lock file from some input file or + command. + +Regardless of the specific strategy that an installer chooses for deciding +when to install yanked files, an installer **SHOULD** emit a warning when +it does decide to install a yanked file. That warning **MAY** utilize the +value of the ``data-yanked`` attribute (if it has a value) to provide more +specific feedback to the user about why that file had been yanked. + + +Mirrors +------- + +Mirrors can generally treat yanked files one of two ways: + +1. They may choose to omit them from their simple repository API completely, + providing a view over the repository that shows only "active", unyanked + files. +2. They may choose to include yanked files, and additionally mirror the + ``data-yanked`` attribute as well. + +Mirrors **SHOULD NOT** mirror a yanked file without also mirroring the +``data-yanked`` attribute for it. Rejected Ideas @@ -89,6 +165,12 @@ string both simplified the implementation, and provided additional generalized functionality to allow projects to provide a mechanism to indicate *why* they were yanking a release. +Another suggestion was to reserve some syntax in the arbitrary string +to allow us to evolve the standard in the future if we ever need to. +However, given we can add additional attributes in the future, this +idea has been rejected, favoring instead to use additional attributes +if the need ever arose. + .. _`Simple Repository API`: