@@ -245,7 +245,8 @@ present in that wheel's filename.
245245
246246It has 3 levels. The first level keys are variant labels, the second
247247level keys are namespaces, the third level are feature names, and the
248- third level values are lists of feature values.
248+ third level values are sets of feature values, converted to lists,
249+ sorted lexically.
249250
250251
251252Example
@@ -281,11 +282,11 @@ Example
281282
282283 "variants": {
283284 // REQUIRED: in variant.json, always a single entry, with the key
284- // matching the variant label ("x8664v3_openblas ") and the value
285+ // matching the variant label ("x86_64_v3_openblas ") and the value
285286 // specifying its properties (the system must be compatible with both):
286287 // - blas_lapack :: library :: openblas
287288 // - x86_64 :: level :: v3
288- "x8664v3_openblas ": {
289+ "x86_64_v3_openblas ": {
289290 "blas_lapack": {
290291 "library": ["openblas"]
291292 },
@@ -318,8 +319,8 @@ the variant metadata across multiple variant wheels of the same package
318319version and the index-level metadata file is consistent. They MAY
319320require that keys other than ``variants `` have exactly the same values,
320321or they may carefully merge their values, provided that no conflicting
321- information is introduced, and the resolution results within a subset of
322- variants do not change .
322+ information is introduced, and the result is the same irrespective of
323+ the order in which the wheels are processed .
323324
324325This file SHOULD NOT be considered immutable and MAY be updated in a
325326backward compatible way at any point (e.g. when adding a new variant).
@@ -346,10 +347,10 @@ like:
346347 // if a null variant is present
347348 "null": {},
348349
349- // "x8664v3_openblas " label corresponds to:
350+ // "x86_64_v3_openblas " label corresponds to:
350351 // - blas_lapack :: library :: openblas
351352 // - x86_64 :: level :: v3
352- "x8664v3_openblas ": {
353+ "x86_64_v3_openblas ": {
353354 "blas_lapack": {
354355 "library": ["openblas"]
355356 },
@@ -358,10 +359,10 @@ like:
358359 }
359360 },
360361
361- // "x8664v4_mkl " label corresponds to:
362+ // "x86_64_v4_mkl " label corresponds to:
362363 // - blas_lapack :: library :: mkl
363364 // - x86_64 :: level :: v4
364- "x8664v4_mkl ": {
365+ "x86_64_v4_mkl ": {
365366 "blas_lapack": {
366367 "library": ["mkl"]
367368 },
@@ -680,7 +681,7 @@ Example
680681 index = "https://pypi.anaconda.org/mgorny/simple"
681682 wheels = [
682683 { url = "https://pypi.anaconda.org/mgorny/simple/numpy/2.3.4/numpy-2.3.4-cp314-cp314-linux_x86_64-openblas.whl", hashes = {} },
683- { url = "https://pypi.anaconda.org/mgorny/simple/numpy/2.3.4/numpy-2.3.4-cp314-cp314-linux_x86_64-x8664v4_mkl .whl", hashes = {} },
684+ { url = "https://pypi.anaconda.org/mgorny/simple/numpy/2.3.4/numpy-2.3.4-cp314-cp314-linux_x86_64-x86_64_v4_mkl .whl", hashes = {} },
684685 { url = "https://pypi.anaconda.org/mgorny/simple/numpy/2.3.4/numpy-2.3.4-cp314-cp314-macosx_13_0_x86_64-accelerate.whl", hashes = {} },
685686 { url = "https://pypi.anaconda.org/mgorny/simple/numpy/2.3.4/numpy-2.3.4-cp314-cp314-macosx_13_0_x86_64-openblas.whl", hashes = {} },
686687 ]
@@ -693,8 +694,8 @@ Example
693694
694695 [packages.variant_json.variants]
695696 null = { }
696- x8664v3_openblas = { "blas_lapack" = { "library" = ["openblas"]}, "x86_64" = { "level" = ["v3"]} }
697- x8664v4_mkl = { "blas_lapack" = { "library" = ["mkl"]}, "x86_64" = { "level" = ["v4"]} }
697+ x86_64_v3_openblas = { "blas_lapack" = { "library" = ["openblas"]}, "x86_64" = { "level" = ["v3"]} }
698+ x86_64_v4_mkl = { "blas_lapack" = { "library" = ["mkl"]}, "x86_64" = { "level" = ["v4"]} }
698699
699700
700701 Suggested implementation logic for tools (non-normative)
@@ -802,6 +803,10 @@ the variant metadata is mirrored in a JSON file published on the index.
802803This enables installers to obtain variant property mapping without
803804having to fetch individual wheels.
804805
806+ Since JSON format does not feature a set type, sets are represented as
807+ sorted lists. Sorting ensures that tools can safely use equality
808+ comparison over dictionaries.
809+
805810The variant ordering algorithm has been proposed with the assumption
806811that variant properties take precedence over Platform compatibility
807812tags, as they are primarily used to express user preferences. This
@@ -955,7 +960,7 @@ interpreter) incompatibility, while other tools could still use it.
955960However, the authors decided it safer to break the backwards
956961compatibility. Additionally, reusing tags posed a potential risk of
957962wheel labels being incorrectly combined with compressed tag sets. For
958- example, a ``manylinux_2_27_x86_64.manylinux_2_28_x86_64+x8664v3 `` tag
963+ example, a ``manylinux_2_27_x86_64.manylinux_2_28_x86_64+x86_64_v3 `` tag
959964would be incorrectly deemed compatible because of the
960965``manylinux_2_27_x86_64 `` part.
961966
@@ -988,6 +993,14 @@ and Zanie Blue.
988993Change History
989994==============
990995
996+ - 09-Mar-2026
997+
998+ - Clarified that feature values in ``variants `` dictionary are sets,
999+ and that they ought to be sorted when serializing.
1000+ - Changed the rule for merging variant metadata to state that the
1001+ result must be the same irrespective of wheel order. This conveys
1002+ the goal of avoiding ambiguous results clearer.
1003+
9911004- 17-Feb-2026
9921005
9931006 - Initial version, split from :pep: `817 ` draft.
0 commit comments