From a0e70bfae6a7b3b1896eaf38aca95fc5d6de5c36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Thu, 29 Jan 2026 17:46:15 +0100 Subject: [PATCH 01/29] Rewrite the security bits per feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Key takeaways: 1. Vendoring is no longer presented as the primary recommendation. Rather, it is given as something installers are allowed to do, much like reimplementing. 2. UI recommendations were removed, and even more emphasis has been put on leaving the exact trust mechanism "implementation-specific". 3. I've volunteered that we start a dedicated team to maintain the allowlist of providers, but kept it in the "rationale" section, so we don't get into governance area too deeply. I think it's an acceptable compromise that satisfies maintainer's concerns that they don't want to be responsible for maintaining their own list. 4. Put even more emphasis that opt-in is likely to cause security issues (it was already there). Signed-off-by: Michał Górny --- peps/pep-0817.rst | 49 +++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index b49509bd3bf..409a52a0a9b 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -752,7 +752,7 @@ wheel maintainer or queried at wheel build time from an AoT plugin. Both kinds of plugins are usually implemented as Python packages which implement the `provider plugin API`_, but they may also be vendored or -reimplemented by installers to improve security, as outlined in +reimplemented by installers to improve user experience, as outlined in `Providers`_. Plugin packages may be installed in isolated or non-isolated environments. In particular, all plugins may be returned by the ``get_requires_for_build_wheel()`` hook of a :pep:`517` backend, and @@ -1207,14 +1207,22 @@ without explicit user consent. The `Providers`_ section of the specification provides further suggestions that aim to improve both security and the user experience. -It is expected that a limited subset of popular provider plugins will -be either vendored by the installer, eliminating the use of packages -external to the tool altogether, or pinned to specific versions, -providing the same level of code auditing as the tools themselves. +Particularly, it is expected that the most popular provider plugins will +be available out of the box, and a dedicated team of maintainers +(initially including a subset of the PEP authors) will be responsible +for inspecting them for security risks and vetting the plugins as safe +to use. Installers will be able to either use a published allowlist, +vendor specific provider plugin versions or reimplement them at their +leisure. + This will lead to the majority of packages focusing on these specific -plugins. External plugins requiring explicit opt-in should be rare, -minimizing the workflow disruption and reducing the risk that users -blanket-allow all plugins. +plugins, rather than implementing competing solutions. Plugins requiring +explicit opt-in should be rare, and primarily affect expert users. This +is important, as many users are not expected to have sufficient +expertise to judge plugins' trustworthiness. Furthermore, the frequent +disruption of workflows would inevitably lead to a number of users +learning to blanket-allow all plugins, making supply chain attacks +trivial. Furthermore, the specification permits using static configuration as input to skip running plugins altogether. @@ -1342,10 +1350,10 @@ compatible with the system and to select the best variant through verification and install a specified variant explicitly. Providers can be marked as install-time or ahead-of-time. For -install-time providers, installers MUST use the provider package or an -equivalent reimplementation to query variant property compatibility. For -ahead-of-time providers, they MUST use the static metadata embedded in -the wheel instead. +install-time providers, installers MUST query the provider for variant +property compatibility. Installers MAY vendor or reimplement specific +providers. For ahead-of-time providers, they MUST use the static +metadata embedded in the wheel instead. Providers can be marked as optional. If a provider is marked optional, then the installer MUST NOT query said provider by default, and instead @@ -1360,20 +1368,15 @@ markers do not match, and instead assume that their properties are incompatible. All the tools that need to query variant providers and are run in a -security-sensitive context, MUST NOT install or run code from any -untrusted package for variant resolution without explicit user opt-in. +security-sensitive context, MUST NOT install or run provider packages, +unless they can determine the particular provider package version to be +trusted. The exact mechanism used to do that is implementation-specific. +However, installers SHOULD ensure that the most commonly used providers +can be securely used without an explicit user opt-in. + Install-time provider packages SHOULD take measures to guard against supply chain attacks, for example by vendoring all dependencies. -It is RECOMMENDED that said tools vendor, reimplement or lock the most -commonly used plugins to specific wheels. For plugins and their -dependencies that are neither reimplemented, vendored nor otherwise -vetted, a trust-on-first-use mechanism for every version is RECOMMENDED. -In interactive sessions, the tool can explicitly ask the user for -approval. In non-interactive sessions, the approval can be given using -command-line interface options. It is important that the user is -informed of the risk before giving such an approval. - For a consistent experience between tools, variant wheels SHOULD be supported by default. Tools MAY provide an option to only use non-variant wheels. From fcf92f662f4d58afc696827aa076de610ce89c27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Thu, 29 Jan 2026 18:21:07 +0100 Subject: [PATCH 02/29] Add "opt-in" to rejected ideas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 409a52a0a9b..048355a038b 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -2509,6 +2509,39 @@ uses. Rejected ideas ============== +Variants being entirely or transitionally opt-in +------------------------------------------------ + +In discussing the security concerns, proposals were made to make variant +provider usage entirely opt-in, either permanently, or at least +initially to facilitate further testing. While such approaches may +naively avoid the immediate security risks by avoiding the new +functionality by default, they are not suitable as long-term solutions. + +Most importantly, the opt-in mechanism would lead to far worse user +experience out-of-the-box. For variant-enabled packages, the default +experience would be installing a suboptimal variant. It should be noted +that variant-enabled packages may not only be installed directly, but +also as dependencies of other packages. Therefore, for optimal user +experience, all packages that are variant-enabled or that feature +dependencies that are variant-enabled, would have to document +appropriate installer-specific mechanisms for enabling the respective +provider plugins. + +The proliferation of this experience would eventually lead to users +naively configuring their installers to enable all variant providers +unconditionally. This in turn would effectively render the provider +usage opt-out for a large number of users, enabling all kinds of supply +chain attacks described in the `security implications`_ section. + +The authors would like to emphasize that security cannot be achieved at +the cost of severely impaired user experience. Instead, the PEP attempts +to strike a balance by introducing a pool of trusted providers that are +subject to review. The list of such providers will be maintained +centrally, both ensuring a more consistent user experience and +increasing the level of scrutiny given to them. + + An approach without provider plugins ------------------------------------ From 6dd38d3f513447aa0e7b3d6924ded61db247fb28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 30 Jan 2026 12:02:08 +0100 Subject: [PATCH 03/29] Update peps/pep-0817.rst Co-authored-by: konsti --- peps/pep-0817.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 048355a038b..b96b906cf56 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1220,7 +1220,7 @@ plugins, rather than implementing competing solutions. Plugins requiring explicit opt-in should be rare, and primarily affect expert users. This is important, as many users are not expected to have sufficient expertise to judge plugins' trustworthiness. Furthermore, the frequent -disruption of workflows would inevitably lead to a number of users +disruption of workflows incentivises users to blanket-allow all plugins (security fatigue) learning to blanket-allow all plugins, making supply chain attacks trivial. From 46428fd0b0fbf82ec21346377ea30c348f2a9459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 30 Jan 2026 12:02:15 +0100 Subject: [PATCH 04/29] Update peps/pep-0817.rst Co-authored-by: konsti --- peps/pep-0817.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index b96b906cf56..2a17cd7827b 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -2515,7 +2515,7 @@ Variants being entirely or transitionally opt-in In discussing the security concerns, proposals were made to make variant provider usage entirely opt-in, either permanently, or at least initially to facilitate further testing. While such approaches may -naively avoid the immediate security risks by avoiding the new +avoid the immediate security risks by avoiding the new functionality by default, they are not suitable as long-term solutions. Most importantly, the opt-in mechanism would lead to far worse user From 440f68243f464000857fb44f3058066ea7108517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 30 Jan 2026 12:13:48 +0100 Subject: [PATCH 05/29] Address @konstin's comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 2a17cd7827b..677db29c9d7 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1212,17 +1212,15 @@ be available out of the box, and a dedicated team of maintainers (initially including a subset of the PEP authors) will be responsible for inspecting them for security risks and vetting the plugins as safe to use. Installers will be able to either use a published allowlist, -vendor specific provider plugin versions or reimplement them at their -leisure. +vendor specific provider plugin versions, reimplement them or use them +as a Python library at their leisure. This will lead to the majority of packages focusing on these specific plugins, rather than implementing competing solutions. Plugins requiring explicit opt-in should be rare, and primarily affect expert users. This -is important, as many users are not expected to have sufficient -expertise to judge plugins' trustworthiness. Furthermore, the frequent -disruption of workflows incentivises users to blanket-allow all plugins (security fatigue) -learning to blanket-allow all plugins, making supply chain attacks -trivial. +is important to make variant usage secure-by-default. Furthermore, the +frequent disruption of workflows incentivises users to blanket-allow all +plugins (security fatigue). Furthermore, the specification permits using static configuration as input to skip running plugins altogether. @@ -2520,26 +2518,28 @@ functionality by default, they are not suitable as long-term solutions. Most importantly, the opt-in mechanism would lead to far worse user experience out-of-the-box. For variant-enabled packages, the default -experience would be installing a suboptimal variant. It should be noted -that variant-enabled packages may not only be installed directly, but -also as dependencies of other packages. Therefore, for optimal user -experience, all packages that are variant-enabled or that feature -dependencies that are variant-enabled, would have to document -appropriate installer-specific mechanisms for enabling the respective -provider plugins. - -The proliferation of this experience would eventually lead to users -naively configuring their installers to enable all variant providers -unconditionally. This in turn would effectively render the provider -usage opt-out for a large number of users, enabling all kinds of supply -chain attacks described in the `security implications`_ section. +experience would be installing a suboptimal or outright broken variant. +It should be noted that variant-enabled packages may not only be +installed directly, but also as dependencies of other packages. +Therefore, for optimal user experience, all packages that are +variant-enabled or that feature dependencies that are variant-enabled, +would have to document appropriate installer-specific mechanisms for +enabling the respective provider plugins. + +The proliferation of this experience could have two significant +outcomes. The inability to make variants work out of the box for users +could lead to package maintainers refraining from using them, and +instead sticking to the earlier workarounds. What's even worse, it could +also lead to users eventually naively configuring their installers +to enable all variant providers unconditionally, effectively rendering +the provider usage opt-out for a large number of users, enabling all +kinds of supply chain attacks described in the `security implications`_ +section. The authors would like to emphasize that security cannot be achieved at the cost of severely impaired user experience. Instead, the PEP attempts -to strike a balance by introducing a pool of trusted providers that are -subject to review. The list of such providers will be maintained -centrally, both ensuring a more consistent user experience and -increasing the level of scrutiny given to them. +to strike a balance by introducing a centrally maintained and vetted +pool of trusted providers. An approach without provider plugins From a622affba9bee8ecb243aa189fc27accf0239189 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 30 Jan 2026 19:58:21 +0100 Subject: [PATCH 06/29] Rename "rationale" into "overview and rationale" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Given that people have been complaining that it's both... Signed-off-by: Michał Górny --- peps/pep-0817.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 677db29c9d7..f235b15363e 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -675,8 +675,8 @@ are used in conjunction with USE flags. For example, build against. -Rationale -========= +Overview and rationale +====================== Wheel variant glossary ---------------------- From 086f43fe10d1195eba2250ea722cc74a53c8fa0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 30 Jan 2026 20:11:22 +0100 Subject: [PATCH 07/29] Try to initially explain the install steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index f235b15363e..8ce3be5d758 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1055,6 +1055,48 @@ optional. This implies that any packages using it need to provide non-variant wheels as well. +Outline of tool behavior +------------------------ + +Installing a package from remote index +'''''''''''''''''''''''''''''''''''''' + +When asked to install a package from a remote index, the proposed +behavior would be to: + +1. Query the remote index for the package in question. +2. Initially select a potentially suitable package version, as usual. +3. Filter available wheels based on Platform Compatibility Tags. +4. Determine if among remaining wheels any feature variant labels. + If not, proceed as with non-variant wheels. +5. If any wheels feature variant labels, download the index-level + variant metadata file, ``{name}-{version}-variants.json``. If this + file is missing, assume all variant wheels are incompatible and + proceed as with non-variant wheels. +6. Map the variant labels into sets of variant properties using the + index-level variant metadata file. +7. Obtain the ordered lists of supported variant properties using + providers specified in the index-level variant metadata file: + + - for enabled AoT providers, obtain them from static property data in + the index-level variant metadata file. + - for enabled install-time providers that are vendored or + reimplemented in the installer, query them in + implementation-speciifc manner. + - for enabled install-time providers that were vetted for + installation, install them in an isolated environment and query + them via the plugin API. + - for disabled providers (e.g. opt-in providers that were not enabled + by the user, providers excluded via environment markers, providers + not considered secure, etc.), assume that all variant properties + are incompatible. +8. Filter and order variants based on the lists of supported properties. + Select the most preferred variant. +9. If multiple wheels for a given version share the same variant label, + order them by Platform compatibility tags and build number, and + select the best wheel. + + Example use cases ----------------- From e17665589ad7e744eb3a0775dbeb2a9563ff4170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 30 Jan 2026 20:20:10 +0100 Subject: [PATCH 08/29] Mention caching for `get_supported_variants()` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 8ce3be5d758..e6646528fa3 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -2207,6 +2207,9 @@ The value returned by ``get_supported_configs()`` MUST be a subset of the feature names and values returned by ``get_all_configs()`` (modulo ordering). +The value returned by ``get_supported_configs()`` MAY be cached +throughout multiple packages in a single install session. + Example implementation '''''''''''''''''''''' From e33811518e02830a57044c9952da46ea7fbc1eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 30 Jan 2026 20:26:41 +0100 Subject: [PATCH 09/29] Propose some index restrictions wrt JSON files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index e6646528fa3..934c21b68f9 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1764,6 +1764,12 @@ in the file, though careful merging is possible, as long as no conflicting information is introduced, and the resolution results within a subset of variants do not change. +The index MAY generate the index level variant metadata file +automatically from uploaded wheel metadata. However, if it does not +generate it automatically, it MUST permit package maintainers to upload +it. Once the variant level metadata file is uploaded, the package +maintainers SHOULD NOT upload new variants for the version in question. + The ``foo-1.2.3-variants.json`` corresponding to the package with two wheel variants, one of them listed in the previous example, would look like: From 4049fc4d1ff3b33cbe5fea18d824b191defeddf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Mon, 2 Feb 2026 16:14:10 +0100 Subject: [PATCH 10/29] Clarify that user information can be used instead of IT providers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 934c21b68f9..a5593a25054 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1384,16 +1384,19 @@ Providers --------- When installing or resolving variant wheels, installers SHOULD query the -variant provider to verify whether a given wheel's properties are +variant providers to verify whether a given wheel's properties are compatible with the system and to select the best variant through `variant ordering`_. However, they MAY provide an option to omit the verification and install a specified variant explicitly. Providers can be marked as install-time or ahead-of-time. For -install-time providers, installers MUST query the provider for variant -property compatibility. Installers MAY vendor or reimplement specific -providers. For ahead-of-time providers, they MUST use the static -metadata embedded in the wheel instead. +install-time providers, installers MUST either query the provider for +variant property compatibility, or use user-provided compatibility +information. Installers MAY vendor or reimplement specific providers. +The format of user-provided information is left implementation-defined. + +For ahead-of-time providers, they MUST use the static metadata embedded +in the wheel instead. Providers can be marked as optional. If a provider is marked optional, then the installer MUST NOT query said provider by default, and instead From 8d81b07eeb465a71a837fe2e2643d7dbe938d00e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Mon, 2 Feb 2026 16:31:12 +0100 Subject: [PATCH 11/29] Clarify installer outline further MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index a5593a25054..244b506bdb5 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1065,26 +1065,31 @@ When asked to install a package from a remote index, the proposed behavior would be to: 1. Query the remote index for the package in question. -2. Initially select a potentially suitable package version, as usual. +2. Initially select a package version meeting the version constraints, + as usual. 3. Filter available wheels based on Platform Compatibility Tags. -4. Determine if among remaining wheels any feature variant labels. +4. Determine if among the remaining wheels any feature variant labels. If not, proceed as with non-variant wheels. 5. If any wheels feature variant labels, download the index-level variant metadata file, ``{name}-{version}-variants.json``. If this file is missing, assume all variant wheels are incompatible and proceed as with non-variant wheels. 6. Map the variant labels into sets of variant properties using the - index-level variant metadata file. + index-level variant metadata file. If any of the labels present in + wheel filenames are missing in the file, assume that the respective + wheels are incompatible. 7. Obtain the ordered lists of supported variant properties using providers specified in the index-level variant metadata file: - for enabled AoT providers, obtain them from static property data in the index-level variant metadata file. - - for enabled install-time providers that are vendored or + - for enabled install-time providers, use user-provided property + compatibility information if provided + - otherwise, for enabled install-time providers that are vendored or reimplemented in the installer, query them in implementation-speciifc manner. - - for enabled install-time providers that were vetted for - installation, install them in an isolated environment and query + - for the remaining enabled install-time providers that were vetted + for installation, install them in an isolated environment and query them via the plugin API. - for disabled providers (e.g. opt-in providers that were not enabled by the user, providers excluded via environment markers, providers From 748c6b2e525966740095ee83bed53c00d87a9872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Mon, 2 Feb 2026 16:38:16 +0100 Subject: [PATCH 12/29] Add an outline for installing a local wheel as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 244b506bdb5..730de905ff3 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1102,6 +1102,22 @@ behavior would be to: select the best wheel. +Installing a local wheel +'''''''''''''''''''''''' + +When asked to install a local wheel file, the proposed behavior would be +to: + +1. If no variant label is present in the filename, proceed as with + non-variant wheels. +2. Verify the wheel compatibility via Platform compatibility tags. +3. Read variant metadata from ``*.dist-info/variant.json`` inside the + wheel file. +4. Obtain the ordered lists of supported variant properties, as when + `installing a package from remote index`_. +5. Verify the wheel compatibility via supported properties. + + Example use cases ----------------- From e74d68fd9eac4b0e859243be91e6049b6dbf5418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Mon, 2 Feb 2026 16:54:38 +0100 Subject: [PATCH 13/29] Add clarifications for isolated environment usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 730de905ff3..b044e208563 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1438,6 +1438,9 @@ trusted. The exact mechanism used to do that is implementation-specific. However, installers SHOULD ensure that the most commonly used providers can be securely used without an explicit user opt-in. +When installing provider packages, tools SHOULD use an isolated virtual +environment. + Install-time provider packages SHOULD take measures to guard against supply chain attacks, for example by vendoring all dependencies. @@ -2062,6 +2065,9 @@ packages MUST be provided for plugins. However, as noted in the needing them. In the latter case, the resulting reimplementation does not need to follow the API defined in this section. +Plugin packages may be run in an isolated environment. They MUST NOT +make decisions based on installed packages. + A plugin implemented as Python package exposes two kinds of objects at a specified API endpoint: From 3b155d33a45323cf7a848f2d63198a3001575d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Mon, 2 Feb 2026 18:32:39 +0100 Subject: [PATCH 14/29] Include outline for building a variant wheel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index b044e208563..9a048f6b49b 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1118,6 +1118,32 @@ to: 5. Verify the wheel compatibility via supported properties. +Building a variant wheel +'''''''''''''''''''''''' + +In order to build a variant wheel, the build backend needs to receive a +list of variant properties and a variant label. The recommended way to +do that is to use backend-defined keys in the ``config_settings`` +dictionary passed to the build backend hooks. + +When building a variant wheel, the proposed behavior for the build +backend would be to: + +1. Read variant provider metadata from ``pyproject.toml``. +2. Verify that all namespaces specified in the user-defined variant + properties have a corresponding provider in the metadata. +3. In the ``get_requires_for_build_wheel()`` hook, return variant + provider plugin packages along with other build dependencies. +4. In the ``build_wheel()`` hook, query the provider plugins + ``get_all_configs()`` function to obtain all valid property keys and + values. Use it to verify that the specified properties are correct. +5. Convert the variant metadata from ``pyproject.toml`` to JSON, append + the mapping from variant label to variant properties and write the + result into the wheel's ``*.dist-info/variant.json`` file. +6. Build the wheel as usual, except for including the + ``*.dist-info/variant.json`` and the variant label in the filename. + + Example use cases ----------------- From 18d55e3ca479ba89415854123bcbd802fc64221d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Mon, 2 Feb 2026 18:55:09 +0100 Subject: [PATCH 15/29] Add an outline for index behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 9a048f6b49b..297bed7ca55 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1144,6 +1144,33 @@ backend would be to: ``*.dist-info/variant.json`` and the variant label in the filename. +Publishing variant wheels on an index +''''''''''''''''''''''''''''''''''''' + +An index with full support for variant wheels should ideally generate +the index-level ``{name}-{version}-variants.json`` file for every +package version itself: + +1. Upon uploading the first variant wheel for a given package version, + copy the data from its ``*.dist-info/variant.json`` file. +2. Upon uploading subsequent wheels, merge the data from their + ``*.dist-info/variant.json`` files into the existing data: + + - disjoint keys of ``providers``, ``static-properties`` and + ``variants`` dictionaries are merge together + - common keys of these dictionaries must have exactly the same value + - ``default-priorities.namespace`` list can be replaced if the new + value starts with the old value + - ``default-priorities.feature`` and ``default-priorities.value`` + keys can be added if they were not present in the previous + ``default-priorities.namespace`` value + - other keys must have exactly the same value + +If the index does not wish to generate +``{name}-{version}-variants.json`` file itself, it should permit +uploading one. + + Example use cases ----------------- From 0281843748e76d295f574879ed02dc85bbc63291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Tue, 3 Feb 2026 15:39:18 +0100 Subject: [PATCH 16/29] Add a missing Copyright section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 297bed7ca55..13f322b15b8 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -2775,3 +2775,10 @@ Emma Smith, Geoffrey Thomas, Henry Schreiner, Jeff Daily, Jeremy Tanner, Jithun Nair, Keith Kraus, Leo Fang, Mike McCarty, Nikita Shulga, Paul Ganssle, Philip Hyunsu Cho, Robert Maynard, Vyas Ramasubramani, and Zanie Blue. + + +Copyright +========= + +This document is placed in the public domain or under the +CC0-1.0-Universal license, whichever is more permissive. From 2185a4d9745fca750ded8b948595581482034c8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Tue, 3 Feb 2026 15:54:25 +0100 Subject: [PATCH 17/29] Add a change history MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 13f322b15b8..32629ea5ecf 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -2777,6 +2777,33 @@ Paul Ganssle, Philip Hyunsu Cho, Robert Maynard, Vyas Ramasubramani, and Zanie Blue. +Change history +============== + +- TBD + + - Added outlines for suggested tool behavior. + - Deemphasized vendoring providers in installers. While it is still + permitted as an implementation choice, it is not presented as the + recommended solution to improve security anymore. + - Made a centrally maintained allowlist the primary solution for + enabling providers by default. Such an allowlist would be maintained + by a dedicated team, starting with a subset of the PEP authors. + - Clarified the specification to permit using user-provided + compatibility information in place of provider queries. + - Removed unnecessary UX suggestions regarding the opt-in mechanism. + - Clarified that the index level variant metadata file can be + generated by the index itself, or uploaded by the package maintainer + if index does not support that. + - Added a recommendation that no new variants are introduced once the + index level variant metadata file is published. + - Added an explicit recommendation that variant provider packages are + run in an isolated environment. + - Clarified that the value returned by ``get_supported_configs()`` may + be cached. + - Emphasized the risks of a full scale opt-in approach. + + Copyright ========= From e5318cad86eafb2ed2cc557da329b426ee1e0f3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Tue, 3 Feb 2026 18:33:20 +0100 Subject: [PATCH 18/29] Update the GROMACS plot to respect dark theme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 1 + peps/pep-0817/avx512_gromacs_benchmark.svg | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 32629ea5ecf..7431da138c5 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -2802,6 +2802,7 @@ Change history - Clarified that the value returned by ``get_supported_configs()`` may be cached. - Emphasized the risks of a full scale opt-in approach. + - Updated the GROMACS plot to respect dark theme. Copyright diff --git a/peps/pep-0817/avx512_gromacs_benchmark.svg b/peps/pep-0817/avx512_gromacs_benchmark.svg index d6691364839..14540af9fde 100644 --- a/peps/pep-0817/avx512_gromacs_benchmark.svg +++ b/peps/pep-0817/avx512_gromacs_benchmark.svg @@ -1,2 +1,2 @@ -0.00.51.01.52.0yum (2018.8)generic (SSE2)ivybridgehaswellbroadwellskylake_avx512cascadelakeperformance (ns/day)SSE2AVXAVX2AVX512 +0.00.51.01.52.0yum (2018.8)generic (SSE2)ivybridgehaswellbroadwellskylake_avx512cascadelakeperformance (ns/day)SSE2AVXAVX2AVX512 From e7b0cbfe5624191f2634cf4bc48b91be2662936c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Thu, 5 Feb 2026 16:14:33 +0100 Subject: [PATCH 19/29] Update peps/pep-0817.rst Co-authored-by: konsti --- peps/pep-0817.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 7431da138c5..95855bc8786 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1087,7 +1087,7 @@ behavior would be to: compatibility information if provided - otherwise, for enabled install-time providers that are vendored or reimplemented in the installer, query them in - implementation-speciifc manner. + implementation-specific manner. - for the remaining enabled install-time providers that were vetted for installation, install them in an isolated environment and query them via the plugin API. From 8252da9ee128f5598651545da66094f51540b126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Thu, 5 Feb 2026 16:22:33 +0100 Subject: [PATCH 20/29] Update peps/pep-0817.rst Co-authored-by: Ralf Gommers --- peps/pep-0817.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 95855bc8786..fb19b9f4f12 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1068,7 +1068,7 @@ behavior would be to: 2. Initially select a package version meeting the version constraints, as usual. 3. Filter available wheels based on Platform Compatibility Tags. -4. Determine if among the remaining wheels any feature variant labels. +4. Determine if any of the remaining wheels are variant wheels. If not, proceed as with non-variant wheels. 5. If any wheels feature variant labels, download the index-level variant metadata file, ``{name}-{version}-variants.json``. If this From ed443f202ab9aba6a51977d3cdeffe886c1cd991 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Thu, 5 Feb 2026 16:37:38 +0100 Subject: [PATCH 21/29] Address review comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 57 +++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index fb19b9f4f12..76fd12cd5c9 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1058,15 +1058,15 @@ non-variant wheels as well. Outline of tool behavior ------------------------ -Installing a package from remote index -'''''''''''''''''''''''''''''''''''''' +Installing a package from an index +'''''''''''''''''''''''''''''''''' -When asked to install a package from a remote index, the proposed +When asked to install a version of a package from an index, the proposed behavior would be to: 1. Query the remote index for the package in question. 2. Initially select a package version meeting the version constraints, - as usual. + as usual (this does not take variant metadata into account). 3. Filter available wheels based on Platform Compatibility Tags. 4. Determine if any of the remaining wheels are variant wheels. If not, proceed as with non-variant wheels. @@ -1081,22 +1081,28 @@ behavior would be to: 7. Obtain the ordered lists of supported variant properties using providers specified in the index-level variant metadata file: - - for enabled AoT providers, obtain them from static property data in - the index-level variant metadata file. - - for enabled install-time providers, use user-provided property - compatibility information if provided - - otherwise, for enabled install-time providers that are vendored or - reimplemented in the installer, query them in - implementation-specific manner. - - for the remaining enabled install-time providers that were vetted - for installation, install them in an isolated environment and query - them via the plugin API. - - for disabled providers (e.g. opt-in providers that were not enabled - by the user, providers excluded via environment markers, providers - not considered secure, etc.), assume that all variant properties - are incompatible. -8. Filter and order variants based on the lists of supported properties. - Select the most preferred variant. + - for the enabled AoT providers, obtain them from static property + data in the index-level variant metadata file. + - for the enabled install-time providers: + + - if the user provided static compatibility information, use that. + - otherwise, if the provider is vendored or reimplemented, query it + in implementation-specific manner. + - otherwise, if the Python provider package is considered secure + (either by the installer or via explicit user opt-in), install it + in an isolated environment, and query it via the plugin API. + - if none of the above applies, do not run the provider and either + consider the variant properties incompatible, or fail the + installation. + + - for the disabled providers (e.g. opt-in providers that were not + enabled by the user, providers excluded via environment markers), + assume that all variant properties in the namespace are + incompatible. + +8. Filter and order variants based on the lists of supported properties, + and select the most preferred variant. If no variant wheel matched, + use the non-variant wheels by their rules. 9. If multiple wheels for a given version share the same variant label, order them by Platform compatibility tags and build number, and select the best wheel. @@ -1114,7 +1120,7 @@ to: 3. Read variant metadata from ``*.dist-info/variant.json`` inside the wheel file. 4. Obtain the ordered lists of supported variant properties, as when - `installing a package from remote index`_. + `installing a package from an index`_. 5. Verify the wheel compatibility via supported properties. @@ -1151,9 +1157,9 @@ An index with full support for variant wheels should ideally generate the index-level ``{name}-{version}-variants.json`` file for every package version itself: -1. Upon uploading the first variant wheel for a given package version, - copy the data from its ``*.dist-info/variant.json`` file. -2. Upon uploading subsequent wheels, merge the data from their +1. For the first variant wheel for a given package version, copy the + data from its ``*.dist-info/variant.json`` file. +2. For subsequent wheels, merge the data from their ``*.dist-info/variant.json`` files into the existing data: - disjoint keys of ``providers``, ``static-properties`` and @@ -1166,6 +1172,9 @@ package version itself: ``default-priorities.namespace`` value - other keys must have exactly the same value +If possible, the index should defer publishing the file until the upload +session is finished, to avoid clients fetching partial data. + If the index does not wish to generate ``{name}-{version}-variants.json`` file itself, it should permit uploading one. From 782a0886e61277cdb8a2fbde988bcf15380d4c9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Thu, 5 Feb 2026 17:00:12 +0100 Subject: [PATCH 22/29] Add the conceptual install diagram MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 5 +++++ peps/pep-0817/conceptual_diagram_installers.svg | 2 ++ 2 files changed, 7 insertions(+) create mode 100644 peps/pep-0817/conceptual_diagram_installers.svg diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 76fd12cd5c9..bb5d94f3537 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1061,6 +1061,11 @@ Outline of tool behavior Installing a package from an index '''''''''''''''''''''''''''''''''' + .. figure:: pep-0817/conceptual_diagram_installers.svg + :alt: TODO. + + A conceptual diagram of installing a wheel. + When asked to install a version of a package from an index, the proposed behavior would be to: diff --git a/peps/pep-0817/conceptual_diagram_installers.svg b/peps/pep-0817/conceptual_diagram_installers.svg new file mode 100644 index 00000000000..4de670b6b92 --- /dev/null +++ b/peps/pep-0817/conceptual_diagram_installers.svg @@ -0,0 +1,2 @@ + + From 6af46cfccc0a62221e78eca38506c7821e89d82b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Thu, 5 Feb 2026 17:09:21 +0100 Subject: [PATCH 23/29] Start working on dark mode for the conceptual diagram MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817/conceptual_diagram_installers.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0817/conceptual_diagram_installers.svg b/peps/pep-0817/conceptual_diagram_installers.svg index 4de670b6b92..fab776d26fa 100644 --- a/peps/pep-0817/conceptual_diagram_installers.svg +++ b/peps/pep-0817/conceptual_diagram_installers.svg @@ -1,2 +1,2 @@ - + From 1da3fb236cd5b22bea5be2e698072bf6361e1be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Thu, 5 Feb 2026 17:17:06 +0100 Subject: [PATCH 24/29] Link the diagram MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index bb5d94f3537..7c271341ed3 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1062,6 +1062,7 @@ Installing a package from an index '''''''''''''''''''''''''''''''''' .. figure:: pep-0817/conceptual_diagram_installers.svg + :target: _images/conceptual_diagram_installers.svg :alt: TODO. A conceptual diagram of installing a wheel. From 6c7d2c59f1673ad316627b51ce0701955fc38988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Thu, 5 Feb 2026 18:07:30 +0100 Subject: [PATCH 25/29] Adjust the diagram for dark mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817/conceptual_diagram_installers.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0817/conceptual_diagram_installers.svg b/peps/pep-0817/conceptual_diagram_installers.svg index fab776d26fa..f70023264ce 100644 --- a/peps/pep-0817/conceptual_diagram_installers.svg +++ b/peps/pep-0817/conceptual_diagram_installers.svg @@ -1,2 +1,2 @@ - + From 70ecf2263091e7c2814311f77a37740fafc48159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 6 Feb 2026 18:37:37 +0100 Subject: [PATCH 26/29] Update peps/pep-0817.rst Co-authored-by: Ralf Gommers --- peps/pep-0817.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index 7c271341ed3..c8fd2d374a8 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -2662,8 +2662,9 @@ Variants being entirely or transitionally opt-in In discussing the security concerns, proposals were made to make variant provider usage entirely opt-in, either permanently, or at least initially to facilitate further testing. While such approaches may -avoid the immediate security risks by avoiding the new -functionality by default, they are not suitable as long-term solutions. +alter who takes responsibility of vetting the provider code, and hence the maintenance +effort or number of packages/maintainers that need to be trusted, +they are not suitable as long-term solutions. Most importantly, the opt-in mechanism would lead to far worse user experience out-of-the-box. For variant-enabled packages, the default From 04bb5d39f95b8068338fdfeb302d705f659b699b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 6 Feb 2026 18:38:22 +0100 Subject: [PATCH 27/29] Update peps/pep-0817.rst Co-authored-by: Ralf Gommers --- peps/pep-0817.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index c8fd2d374a8..b775adb7062 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1055,8 +1055,8 @@ optional. This implies that any packages using it need to provide non-variant wheels as well. -Outline of tool behavior ------------------------- +Suggested implementation logic per type of packaging tool +--------------------------------------------------------- Installing a package from an index '''''''''''''''''''''''''''''''''' From 8e857a66f979a00bce84308ac308a67d746a0457 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 6 Feb 2026 18:38:34 +0100 Subject: [PATCH 28/29] Update peps/pep-0817.rst Co-authored-by: Ralf Gommers --- peps/pep-0817.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index b775adb7062..f8d850b4c19 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -2798,7 +2798,7 @@ Change history - TBD - - Added outlines for suggested tool behavior. + - Added high-level outlines of suggested implementation logic per type of packaging tool, and a diagram for installer behavior. - Deemphasized vendoring providers in installers. While it is still permitted as an implementation choice, it is not presented as the recommended solution to improve security anymore. From 64b31b748fd8094808b4597a48e6a1b6700f0301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20G=C3=B3rny?= Date: Fri, 6 Feb 2026 18:39:11 +0100 Subject: [PATCH 29/29] Address other review comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Górny --- peps/pep-0817.rst | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/peps/pep-0817.rst b/peps/pep-0817.rst index f8d850b4c19..9a9e8c0be38 100644 --- a/peps/pep-0817.rst +++ b/peps/pep-0817.rst @@ -1072,7 +1072,7 @@ behavior would be to: 1. Query the remote index for the package in question. 2. Initially select a package version meeting the version constraints, - as usual (this does not take variant metadata into account). + as usual (this does not need to take variant metadata into account). 3. Filter available wheels based on Platform Compatibility Tags. 4. Determine if any of the remaining wheels are variant wheels. If not, proceed as with non-variant wheels. @@ -1159,9 +1159,19 @@ backend would be to: Publishing variant wheels on an index ''''''''''''''''''''''''''''''''''''' -An index with full support for variant wheels should ideally generate -the index-level ``{name}-{version}-variants.json`` file for every -package version itself: +Variant wheels are uploaded to an index just like regular wheels. +There are two possible approaches to publishing the index-level +``{name}-{version}-variants.json`` file for every package version: +it can either be prepared and uploaded by the user, or it can be +generated automatically by the index. + +The file should not be changed once it is published, as clients may have +already cached it or locked to the existing hash. For this reason, if +the index is responsible for generating the file, it should use some +mechanism to defer publishing it until the release is fully uploaded +(for example, :pep:`694`). + +To generate the ``{name}-{version}-variants.json`` file: 1. For the first variant wheel for a given package version, copy the data from its ``*.dist-info/variant.json`` file. @@ -1178,13 +1188,6 @@ package version itself: ``default-priorities.namespace`` value - other keys must have exactly the same value -If possible, the index should defer publishing the file until the upload -session is finished, to avoid clients fetching partial data. - -If the index does not wish to generate -``{name}-{version}-variants.json`` file itself, it should permit -uploading one. - Example use cases ----------------- @@ -1860,10 +1863,14 @@ conflicting information is introduced, and the resolution results within a subset of variants do not change. The index MAY generate the index level variant metadata file -automatically from uploaded wheel metadata. However, if it does not -generate it automatically, it MUST permit package maintainers to upload -it. Once the variant level metadata file is uploaded, the package -maintainers SHOULD NOT upload new variants for the version in question. +automatically from uploaded wheel metadata. If that is the case, the +file SHOULD NOT be published until it is final, and once published, it +SHOULD NOT change, as clients MAY cache it. + +If the file is not generated automatically, the index MUST permit +package maintainers to upload it. Once the variant level metadata file +is uploaded, the package maintainers SHOULD NOT upload new variants for +the version in question. The ``foo-1.2.3-variants.json`` corresponding to the package with two wheel variants, one of them listed in the previous example, would look