Skip to content
87 changes: 47 additions & 40 deletions peps/pep-9999.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Status: Draft
Type: Standards Track
Topic: Packaging
Requires: 825
Created: 21-Sep-2026
Created: 22-Sep-2026
Post-History: Pending

Abstract
Expand Down Expand Up @@ -151,6 +151,10 @@ namespace:
and feature values. For providers that were not trusted, it MUST
assume that the list of compatible features is empty.

For every unique provider, the tool MUST obtain the list of compatible
features and their values only once throughout the install session and
use it across all the packages being installed.


Variant metadata
----------------
Expand Down Expand Up @@ -340,6 +344,10 @@ These can be implemented either as module-level functions, class methods
or static methods. The specifics are provided in the subsequent
sections.

Any errors occurring while installing or executing the plugin API,
including the plugin code terminating the calling process, MUST result
in tools aborting the install process.


API endpoint
''''''''''''
Expand Down Expand Up @@ -521,24 +529,31 @@ Example implementation
# no runtime found, system not supported at all
return []

return [
configs = [
VariantFeatureConfig(
name="min_version",
# [current, current - 1, ..., 1]
values=[str(x) for x in range(current_version, 0, -1)],
multi_value=False,
),
VariantFeatureConfig(
name="gpu",
# this may be empty if no GPUs are supported --
# 'example :: gpu feature' is not supported then;
# but wheels with no GPU-specific code and only
# 'example :: min_version' could still be installed
values=[x for x in _ALL_GPUS if _is_gpu_available(x)],
multi_value=True,
),
]

# this may be empty if no GPUs are supported --
# 'example :: gpu feature' is not supported then;
# but wheels with no GPU-specific code and only
# 'example :: min_version' could still be installed
supported_gpus = [x for x in _ALL_GPUS if _is_gpu_available(x)]
if supported_gpus:
configs.append(
VariantFeatureConfig(
name="gpu",
values=supported_gpus,
multi_value=True,
)
)

return configs


Future extensions
'''''''''''''''''
Expand Down Expand Up @@ -573,16 +588,20 @@ with the same system.

Within this namespace, zero or more properties can be used to express
compatible dependency versions. For each property, the feature name MUST
be the :ref:`normalized name <packaging:name-normalization>` of the
dependency, whereas the value MUST be a valid release segment of a
public version identifier, as defined by the
:doc:`packaging:specifications/version-specifiers` specification. It
MUST contain up to three version components, that are matched against
the installed version same as the ``=={value}.*`` specifier. Notably,
trailing zeroes match versions with fewer components (e.g. ``2.0``
matches release ``2`` but not ``2.1``). This also implies that the
property values have different semantics than PEP 440 versions, in
particular ``2``, ``2.0`` and ``2.0.0`` represent different ranges.
be the name of the dependency and the value MUST be a valid release
segment of a public version identifier, as defined by the
:doc:`packaging:specifications/version-specifiers` specification. Both
the dependency name and version MUST be normalized according to the same
rules as wheel files, as found in the
:ref:`packaging:wheel-file-name-spec` of the Binary Distribution Format
specification.

The feature version MUST contain up to three version components, that
are matched against the installed version same as the ``=={value}.*``
specifier. Notably, trailing zeroes match versions with fewer components
(e.g. ``2.0`` matches release ``2`` but not ``2.1``). This also implies
that the property values have different semantics than PEP 440 versions,
in particular ``2``, ``2.0`` and ``2.0.0`` represent different ranges.

Versions with nonzero epoch are not supported.

Expand Down Expand Up @@ -765,24 +784,6 @@ The `variantlib <https://github.com/wheelnext/variantlib>`__ project
contains a reference implementation of this PEP.


Rejected Ideas
==============

An approach without provider plugins
------------------------------------

Rather than introducing provider plugins, the rules governing every
variant namespace could be defined via PEPs. However, such an approach
would be less scalable and impose additional effort on stakeholders, PEP
editors and tool maintainers.

Every new namespace would have to go through standardization process,
followed by explicit implementation process. Deployment of new variant
properties would be entirely dependent on tool updates. The added
maintenance cost could lead to support for less popular variant axes not
being accepted, or lack of feature parity between different tools.


Acknowledgements
================

Expand All @@ -801,7 +802,7 @@ and Zanie Blue.
Change History
==============

- 21-Sep-2026
- 22-Sep-2026

- Initial version, split from :pep:`817` draft.
- Namespaces have been removed from the `provider plugin API`_.
Expand All @@ -819,6 +820,12 @@ Change History
required to be non-empty.
- The entry point name is now used to provide the recommended
namespace for a provider.
- The feature names and values in the `ABI Dependency Variant Provider
(Optional)`_ are now normalized according to the wheel normalization
rules, to match the restrictions in :pep:`825`.
- A provision has been added that a consistent list of compatible
feature names and values from a single provider must be used
throughout the install session.


Appendices
Expand Down
20 changes: 15 additions & 5 deletions peps/pep-9999/variant-schema-0.2.0.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,30 @@
},
"minItems": 0,
"uniqueItems": true
},
"additionalProperties": false
}
}
},
"additionalProperties": false
}
},
"additionalProperties": false,
"oneOf": [
{
"required": ["requires"],
"not": {"required": ["feature-order"]}
"not": {
"anyOf": [
{ "required": ["feature-order"] },
{ "required": ["static-properties"] }
]
}
},
{
"required": ["static-properties"],
"not": {"required": ["plugin-api"]}
"not": {
"anyOf": [
{ "required": ["requires"] },
{ "required": ["plugin-api"] }
]
}
}
]
}
Expand Down
Loading