From afee09a2fd0fb4e9b376b8ba599e03521de87369 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Thu, 28 Aug 2025 11:17:48 +0200 Subject: [PATCH 01/11] Describe `specifier_syntax` --- peps/pep-9999.rst | 115 +++++++++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 42 deletions(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index a42e0a6c081..1b244c74f06 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -259,8 +259,9 @@ take a list of dictionaries, with each of them reporting the following fields: - ``name`` (string), unique identifier for this package manager. Usually, the executable name. - ``commands`` (list of dictionaries), the commands to run to install the mapped package(s) and check whether they are already installed. -- ``version_operators``: a mapping of PEP 440 operator names to the relevant - syntax for this package manager. +- ``specifier_syntax``: instructions on how to map a subset of PEP 440 specifiers to + the target package manager. Three levels of support are offered: name-only, exact-version-only, + and full version-ranges compatibility (with per-operator translations). Each mapping MUST have a canonical URL for online retrieval. These mappings MAY also be packaged for offline distribution in each platform. The authors @@ -345,9 +346,10 @@ For example, a hypothetical conda-forge mapping (``conda-forge.mapping.json``) w "command": [ "conda", "install", - "--yes", "{}" - ] + ], + "multiple_specifiers": "always", + "requires_elevation": false, }, "query": { "command": [ @@ -355,20 +357,30 @@ For example, a hypothetical conda-forge mapping (``conda-forge.mapping.json``) w "list", "-f", "{}" - ] + ], + "multiple_specifiers": "never", + "requires_elevation": false, } }, - "version_operators": { - "and": ",", - "arbitrary": "==", - "compatible": "~=", - "equal": "=", - "greater_than": ">", - "greater_than_equal": ">=", - "less_than": "<", - "less_than_equal": "<=", - "not_equal": "!=", - "separator": "" + "specifier_syntax": { + "exact_version": [ + "{name}=={version}" + ], + "name_only": [ + "{name}" + ], + "version_ranges": { + "and": ",", + "equal": "={version}", + "greater_than": ">{version}", + "greater_than_equal": ">={version}", + "less_than": "<{version}", + "less_than_equal": "<={version}", + "not_equal": "!={version}", + "syntax": [ + "{name}{ranges}" + ] + } } } ] @@ -670,35 +682,54 @@ Each entry in this list is defined as a dictionary with these fields: - Short identifier for this package manager (usually the command name) - True * - ``commands`` - - ``dict[Literal['install', 'query'], dict[Literal['command', 'requires_elevation'], list[str] | bool]]`` + - ``dict[Literal['install', 'query'], dict[Literal['command', 'requires_elevation', 'multiple_specifiers'], list[str] | bool | Literal['always', 'name-only', 'never']]]`` - Commands used to install or query the given package(s). - Only two keys are allowed: ``install`` and ``query``. Their value - is a dictionary with a required key ``command`` that takes a list of - strings (as expected by ``subprocess.run``), and an optional - ``requires_elevation`` boolean (``False`` by default) to indicate whether - the command must run with elevated permissions. - Exactly one of the ``command`` items MUST include a ``{}`` placeholder, which will be - replaced by the mapped package identifier(s). The ``install`` command MUST support - the placeholder being replaced by multiple identifiers, ``query`` will only receive a single - identifier per command. + Only two keys are allowed: ``install`` and ``query``. Their value is a + dictionary with a required key ``command`` that takes a list of strings + (as expected by ``subprocess.run``), an optional ``requires_elevation`` + boolean (``False`` by default) to indicate whether the command must run + with elevated permissions, and an enum ``multiple_specifiers`` that + determines whether the command accepts multiple package specifiers at + the same time, accepting ``always`` (default in ``install``), + ``name-only`` (the command only accepts multiple specifiers if they do + not contain version constraints) or ``never`` (default in ``query``). + Exactly one of the ``command`` items MUST include a ``{}`` placeholder, + which will be replaced by the mapped package identifier(s). The + ``install`` command MUST support the placeholder being replaced by + multiple identifiers, ``query`` will only receive a single identifier + per command. + - True + * - ``specifier_syntax`` + - ``dict[Literal['name_only', 'exact_version', 'version_ranges'], None | list[str] | dict[Literal['and', 'equal', 'greater_than', 'greater_than_equal', 'less_than', 'less_than_equal', 'not_equal', 'syntax'], None | str | list[str]] + - Mapping of allowed PEP440 version comparison operators to the syntax + used in this package manager. ``name_only`` takes a list of strings as + the syntax used for specifiers that do not contain any version + information; it MUST include the placeholder ``{name}``. + ``exact_version`` takes a list of strings as the syntax used for + specifiers that only express an exact version constraints; it must + include the placeholders ``{name}`` and ``{version}``. + ``version_ranges`` is a dictionary where: the key ``syntax`` takes a + list of strings that MUST include the ``{ranges}`` placeholder (to be + replaced by the maybe-joined version constraints, to be determined by + the value of ``and``) and also accept the ``{name}`` one; the keys + ``equal``, ``greater_than``, ``greater_than_equal``, ``less_than``, + ``less_than_equal``, and ``not_equal`` take a string that MUST include + the ``{name}`` and ``{version}`` placeholders, or ``None`` to indicate + that that operator is not supported; and the key ``{and}`` takes a + string or ``None`` (if a string is used, the different version + constraints will be ``join``-ed using that string; if ``None`` the + different constraints will be "exploded" into several constraints using + the ``syntax`` template). ``exact_version`` and ``version_ranges`` MAY + be set to ``None`` to indicate that this type of specifiers are not + supported by the package manager. - True - * - ``version_operators`` - - ``dict[Literal['and', 'arbitrary', 'compatible', 'equal', 'greater_than_equal', 'greater_than', 'less_than_equal', 'less_than', 'not_equal', 'separator'], string]`` - - Mapping of PEP440 version comparison operators to the syntax used in this - package manager. If omitted, PEP 440 operators are used. If set to an empty - dictionary, it means that the package manager (or ecosystem) doesn't support - the notion of requesting particular package versions. The keys are ``and``, - ``arbitrary``, ``compatible``, ``equal``, ``greater_than_equal``, - ``greater_than``, ``less_than_equal``, ``less_than``, ``not_equal``, and - ``separator``. Empty strings can be used as a value if that particular operator - is not supported. - - False Examples -------- -The following repository provides examples of how these schemas would look like in real cases: +The following repository provides examples of how these schemas *could* look like in real cases. +They are not meant to be prescriptive, but just illustrative of how to apply these schemas: - `Central registry `__. - `Known ecosystems `__. @@ -886,11 +917,11 @@ The ``pyproject-external`` Python API also allows users to do these operations p # {"command": ["pixi", "add", "{}"]} ['pixi', 'add', 'c-compiler', 'cxx-compiler', 'python'] >>> external.query_commands(ecosystem, package_manager=package_manager) - # {"command": ["pixi", "list", "^{}$"]} + # {"command": ["pixi", "list", "{}"]} [ - ['pixi', 'list', '^c-compiler$'], - ['pixi', 'list', '^cxx-compiler$'], - ['pixi', 'list', '^python$'], + ['pixi', 'list', 'c-compiler'], + ['pixi', 'list', 'cxx-compiler'], + ['pixi', 'list', 'python'], ] Grayskull From 9cdfd8aac7959927a85233277145c15b73db149e Mon Sep 17 00:00:00 2001 From: jaimergp Date: Thu, 28 Aug 2025 11:23:22 +0200 Subject: [PATCH 02/11] close backticks --- peps/pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index 1b244c74f06..13d06e6ca7f 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -700,7 +700,7 @@ Each entry in this list is defined as a dictionary with these fields: per command. - True * - ``specifier_syntax`` - - ``dict[Literal['name_only', 'exact_version', 'version_ranges'], None | list[str] | dict[Literal['and', 'equal', 'greater_than', 'greater_than_equal', 'less_than', 'less_than_equal', 'not_equal', 'syntax'], None | str | list[str]] + - ``dict[Literal['name_only', 'exact_version', 'version_ranges'], None | list[str] | dict[Literal['and', 'equal', 'greater_than', 'greater_than_equal', 'less_than', 'less_than_equal', 'not_equal', 'syntax'], None | str | list[str]]`` - Mapping of allowed PEP440 version comparison operators to the syntax used in this package manager. ``name_only`` takes a list of strings as the syntax used for specifiers that do not contain any version From 87e58372ff275a66e1ce9587e7d6b1e8b60df398 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Thu, 28 Aug 2025 16:14:11 +0200 Subject: [PATCH 03/11] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michał Górny --- peps/pep-9999.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index 13d06e6ca7f..8898f1f16f0 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -261,7 +261,7 @@ take a list of dictionaries, with each of them reporting the following fields: check whether they are already installed. - ``specifier_syntax``: instructions on how to map a subset of PEP 440 specifiers to the target package manager. Three levels of support are offered: name-only, exact-version-only, - and full version-ranges compatibility (with per-operator translations). + and version-range compatibility (with per-operator translations). Each mapping MUST have a canonical URL for online retrieval. These mappings MAY also be packaged for offline distribution in each platform. The authors @@ -711,16 +711,16 @@ Each entry in this list is defined as a dictionary with these fields: ``version_ranges`` is a dictionary where: the key ``syntax`` takes a list of strings that MUST include the ``{ranges}`` placeholder (to be replaced by the maybe-joined version constraints, to be determined by - the value of ``and``) and also accept the ``{name}`` one; the keys + the value of ``and``) and MAY include the ``{name}`` placeholder; the keys ``equal``, ``greater_than``, ``greater_than_equal``, ``less_than``, ``less_than_equal``, and ``not_equal`` take a string that MUST include - the ``{name}`` and ``{version}`` placeholders, or ``None`` to indicate - that that operator is not supported; and the key ``{and}`` takes a - string or ``None`` (if a string is used, the different version - constraints will be ``join``-ed using that string; if ``None`` the - different constraints will be "exploded" into several constraints using + the ``{version}`` placeholder, and MAY include ``{name}``, or ``None`` to indicate + that the respective operator is not supported; and the key ``{and}`` takes a + string used to join multiple version constraints in a single token, or ``None`` + if only a single constraint can be used per token. In the latter case, the + different constraints will be "exploded" into several tokens using the ``syntax`` template). ``exact_version`` and ``version_ranges`` MAY - be set to ``None`` to indicate that this type of specifiers are not + be set to ``None`` to indicate that the respective types of specifiers are not supported by the package manager. - True From cf4cd037bf061836408ea339b4e83a511c0a9a7b Mon Sep 17 00:00:00 2001 From: jaimergp Date: Thu, 28 Aug 2025 16:23:21 +0200 Subject: [PATCH 04/11] clean up --- peps/pep-9999.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index f6fb4f804ef..07d3ff41007 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -530,8 +530,6 @@ Each entry in this list is defined as: .. list-table:: :widths: 25 75 - * - Title - - Package Managers * - Type - ``array`` * - Description @@ -741,10 +739,6 @@ for brevity, could look like: ] } - -Examples --------- - The following repository provides examples of how these schemas *could* look like in real cases. They are not meant to be prescriptive, but just illustrative of how to apply these schemas: From 811d86c9994b13746e4359fc294e61c40b400bfa Mon Sep 17 00:00:00 2001 From: jaimergp Date: Thu, 28 Aug 2025 16:31:21 +0200 Subject: [PATCH 05/11] use sublists in table --- peps/pep-9999.rst | 84 +++++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index 07d3ff41007..cabc4f1d721 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -554,45 +554,65 @@ Each entry in this list is defined as a dictionary with these fields: - True * - ``commands`` - ``dict[Literal['install', 'query'], dict[Literal['command', 'requires_elevation', 'multiple_specifiers'], list[str] | bool | Literal['always', 'name-only', 'never']]]`` - - Commands used to install or query the given package(s). - Only two keys are allowed: ``install`` and ``query``. Their value is a - dictionary with a required key ``command`` that takes a list of strings - (as expected by ``subprocess.run``), an optional ``requires_elevation`` - boolean (``False`` by default) to indicate whether the command must run - with elevated permissions, and an enum ``multiple_specifiers`` that - determines whether the command accepts multiple package specifiers at - the same time, accepting ``always`` (default in ``install``), - ``name-only`` (the command only accepts multiple specifiers if they do - not contain version constraints) or ``never`` (default in ``query``). + - Commands used to install or query the given package(s). Only two keys + are allowed: ``install`` and ``query``. Their value is a dictionary + with: + + - a required key ``command`` that takes a list of strings + (as expected by ``subprocess.run``), + + - an optional ``requires_elevation`` + boolean (``False`` by default) to indicate whether the command must run + with elevated permissions, + + - and an enum ``multiple_specifiers`` that + determines whether the command accepts multiple package specifiers at + the same time, accepting: ``always`` (default in ``install``), + ``name-only`` (the command only accepts multiple specifiers if they do + not contain version constraints) or ``never`` (default in ``query``). + Exactly one of the ``command`` items MUST include a ``{}`` placeholder, which will be replaced by the mapped package identifier(s). The - ``install`` command MUST support the placeholder being replaced by - multiple identifiers, ``query`` will only receive a single identifier + ``install`` command SHOULD support the placeholder being replaced by + multiple identifiers, ``query`` MUST only receive a single identifier per command. - True * - ``specifier_syntax`` - ``dict[Literal['name_only', 'exact_version', 'version_ranges'], None | list[str] | dict[Literal['and', 'equal', 'greater_than', 'greater_than_equal', 'less_than', 'less_than_equal', 'not_equal', 'syntax'], None | str | list[str]]`` - Mapping of allowed PEP440 version comparison operators to the syntax - used in this package manager. ``name_only`` takes a list of strings as - the syntax used for specifiers that do not contain any version - information; it MUST include the placeholder ``{name}``. - ``exact_version`` takes a list of strings as the syntax used for - specifiers that only express an exact version constraints; it must - include the placeholders ``{name}`` and ``{version}``. - ``version_ranges`` is a dictionary where: the key ``syntax`` takes a - list of strings that MUST include the ``{ranges}`` placeholder (to be - replaced by the maybe-joined version constraints, to be determined by - the value of ``and``) and MAY include the ``{name}`` placeholder; the keys - ``equal``, ``greater_than``, ``greater_than_equal``, ``less_than``, - ``less_than_equal``, and ``not_equal`` take a string that MUST include - the ``{version}`` placeholder, and MAY include ``{name}``, or ``None`` to indicate - that the respective operator is not supported; and the key ``{and}`` takes a - string used to join multiple version constraints in a single token, or ``None`` - if only a single constraint can be used per token. In the latter case, the - different constraints will be "exploded" into several tokens using - the ``syntax`` template). ``exact_version`` and ``version_ranges`` MAY - be set to ``None`` to indicate that the respective types of specifiers are not - supported by the package manager. + used in this package manager. Three top-level keys are accepted: + + - ``name_only`` takes a list of strings as + the syntax used for specifiers that do not contain any version + information; it MUST include the placeholder ``{name}``. + + - ``exact_version`` takes a list of strings as the syntax used for + specifiers that only express an exact version constraints; it must + include the placeholders ``{name}`` and ``{version}``. + + - ``version_ranges`` is a dictionary where: + + - the key ``syntax`` takes a list of strings that MUST include the + ``{ranges}`` placeholder (to be replaced by the maybe-joined + version constraints, to be determined by the value of ``and``) and + MAY include the ``{name}`` placeholder. + + - the keys ``equal``, ``greater_than``, ``greater_than_equal``, + ``less_than``, ``less_than_equal``, and ``not_equal`` take a string + that MUST include the ``{version}`` placeholder, and MAY include + ``{name}``, or ``None`` to indicate that the respective operator is + not supported; + + - the key ``{and}`` takes a string used to join multiple version + constraints in a single token, or ``None`` if only a single + constraint can be used per token. In the latter case, the different + constraints will be "exploded" into several tokens using the + ``syntax`` template). + + ``exact_version`` and ``version_ranges`` MAY + be set to ``None`` to indicate that the respective types of + specifiers are not supported by the package manager. + - True From e79ac8812cdcc2015878d3b8ee37e7ee43d4d102 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Thu, 28 Aug 2025 16:35:54 +0200 Subject: [PATCH 06/11] clarify requires_elevation and address punctuation --- peps/pep-9999.rst | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index cabc4f1d721..db34e22a9eb 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -559,17 +559,21 @@ Each entry in this list is defined as a dictionary with these fields: with: - a required key ``command`` that takes a list of strings - (as expected by ``subprocess.run``), + (as expected by ``subprocess.run``). - - an optional ``requires_elevation`` - boolean (``False`` by default) to indicate whether the command must run - with elevated permissions, + - an optional ``requires_elevation`` boolean (``False`` by default) + to indicate whether the command must run with elevated permissions ( + e.g. administrator on Windows, superuser on Linux and macOS). - - and an enum ``multiple_specifiers`` that - determines whether the command accepts multiple package specifiers at - the same time, accepting: ``always`` (default in ``install``), - ``name-only`` (the command only accepts multiple specifiers if they do - not contain version constraints) or ``never`` (default in ``query``). + - an enum ``multiple_specifiers`` that determines whether the command + accepts multiple package specifiers at the same time, accepting one of: + + - ``always``, default in ``install``. + + - ``name-only``, the command only accepts multiple specifiers if they do + not contain version constraints. + + - ``never``, default in ``query``. Exactly one of the ``command`` items MUST include a ``{}`` placeholder, which will be replaced by the mapped package identifier(s). The @@ -582,9 +586,9 @@ Each entry in this list is defined as a dictionary with these fields: - Mapping of allowed PEP440 version comparison operators to the syntax used in this package manager. Three top-level keys are accepted: - - ``name_only`` takes a list of strings as - the syntax used for specifiers that do not contain any version - information; it MUST include the placeholder ``{name}``. + - ``name_only`` takes a list of strings as the syntax used for specifiers + that do not contain any version information; it MUST include the placeholder + ``{name}``. - ``exact_version`` takes a list of strings as the syntax used for specifiers that only express an exact version constraints; it must @@ -601,7 +605,7 @@ Each entry in this list is defined as a dictionary with these fields: ``less_than``, ``less_than_equal``, and ``not_equal`` take a string that MUST include the ``{version}`` placeholder, and MAY include ``{name}``, or ``None`` to indicate that the respective operator is - not supported; + not supported. - the key ``{and}`` takes a string used to join multiple version constraints in a single token, or ``None`` if only a single From 33f3085812eef9542a5744e1719f6372eebe4a22 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Tue, 2 Sep 2025 10:48:43 +0200 Subject: [PATCH 07/11] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michał Górny --- peps/pep-9999.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index db34e22a9eb..12038052ef6 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -562,8 +562,8 @@ Each entry in this list is defined as a dictionary with these fields: (as expected by ``subprocess.run``). - an optional ``requires_elevation`` boolean (``False`` by default) - to indicate whether the command must run with elevated permissions ( - e.g. administrator on Windows, superuser on Linux and macOS). + to indicate whether the command must run with elevated permissions + (e.g. administrator on Windows, superuser on Linux and macOS). - an enum ``multiple_specifiers`` that determines whether the command accepts multiple package specifiers at the same time, accepting one of: @@ -603,9 +603,9 @@ Each entry in this list is defined as a dictionary with these fields: - the keys ``equal``, ``greater_than``, ``greater_than_equal``, ``less_than``, ``less_than_equal``, and ``not_equal`` take a string - that MUST include the ``{version}`` placeholder, and MAY include - ``{name}``, or ``None`` to indicate that the respective operator is - not supported. + if the operator is supported, ``None`` otherwise. In the former case, + the value MUST include the ``{version}`` placeholder, and MAY include + ``{name}``. - the key ``{and}`` takes a string used to join multiple version constraints in a single token, or ``None`` if only a single From 3541839500f4ad5aed346a32f1c443abd583f61a Mon Sep 17 00:00:00 2001 From: jaimergp Date: Tue, 2 Sep 2025 15:04:08 +0200 Subject: [PATCH 08/11] make version_ranges keys required --- peps/pep-9999.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index 12038052ef6..c3f591a1e12 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -594,7 +594,7 @@ Each entry in this list is defined as a dictionary with these fields: specifiers that only express an exact version constraints; it must include the placeholders ``{name}`` and ``{version}``. - - ``version_ranges`` is a dictionary where: + - ``version_ranges`` is a dictionary with the following required keys: - the key ``syntax`` takes a list of strings that MUST include the ``{ranges}`` placeholder (to be replaced by the maybe-joined From 42fe19b4eb8207e109f6e0acefad070af59a2807 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Tue, 2 Sep 2025 15:11:24 +0200 Subject: [PATCH 09/11] clarify whether fields are required or not --- peps/pep-9999.rst | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index c3f591a1e12..832b82c6b92 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -583,23 +583,25 @@ Each entry in this list is defined as a dictionary with these fields: - True * - ``specifier_syntax`` - ``dict[Literal['name_only', 'exact_version', 'version_ranges'], None | list[str] | dict[Literal['and', 'equal', 'greater_than', 'greater_than_equal', 'less_than', 'less_than_equal', 'not_equal', 'syntax'], None | str | list[str]]`` - - Mapping of allowed PEP440 version comparison operators to the syntax - used in this package manager. Three top-level keys are accepted: + - Mapping of allowed PEP440 version specifiers to the syntax used in this + package manager. Three top-level keys are expected and required: - - ``name_only`` takes a list of strings as the syntax used for specifiers + - ``name_only`` MUST take a list of strings as the syntax used for specifiers that do not contain any version information; it MUST include the placeholder ``{name}``. - - ``exact_version`` takes a list of strings as the syntax used for - specifiers that only express an exact version constraints; it must - include the placeholders ``{name}`` and ``{version}``. + - ``exact_version`` MUST be ``None`` or a list of strings that describe + the syntax used for specifiers that only express exact version + constraints; the placeholders ``{name}`` and ``{version}`` MUST be + present in at least one string each. - - ``version_ranges`` is a dictionary with the following required keys: + - ``version_ranges`` MUST be ``None`` or a dictionary with the + following required keys: - - the key ``syntax`` takes a list of strings that MUST include the - ``{ranges}`` placeholder (to be replaced by the maybe-joined - version constraints, to be determined by the value of ``and``) and - MAY include the ``{name}`` placeholder. + - the key ``syntax`` takes a list of strings where at least one MUST + include the ``{ranges}`` placeholder (to be replaced by the + maybe-joined version constraints, as determined by the value of + ``and``). They MAY also include the ``{name}`` placeholder. - the keys ``equal``, ``greater_than``, ``greater_than_equal``, ``less_than``, ``less_than_equal``, and ``not_equal`` take a string @@ -611,11 +613,11 @@ Each entry in this list is defined as a dictionary with these fields: constraints in a single token, or ``None`` if only a single constraint can be used per token. In the latter case, the different constraints will be "exploded" into several tokens using the - ``syntax`` template). + ``syntax`` template. - ``exact_version`` and ``version_ranges`` MAY - be set to ``None`` to indicate that the respective types of - specifiers are not supported by the package manager. + When ``exact_version`` or ``version_ranges`` are set to ``None``, it + indicates that the respective types of specifiers are not supported + by the package manager. - True From 699a109ef422ad9c2e3d82f4cc16c85c796f2b49 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Tue, 2 Sep 2025 15:44:37 +0200 Subject: [PATCH 10/11] Update peps/pep-9999.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Michał Górny --- peps/pep-9999.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index 832b82c6b92..187154fe7b6 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -592,8 +592,8 @@ Each entry in this list is defined as a dictionary with these fields: - ``exact_version`` MUST be ``None`` or a list of strings that describe the syntax used for specifiers that only express exact version - constraints; the placeholders ``{name}`` and ``{version}`` MUST be - present in at least one string each. + constraints; in the latter case, each of the placeholders ``{name}`` + and ``{version}`` MUST be present in at least one of the strings. - ``version_ranges`` MUST be ``None`` or a dictionary with the following required keys: From 8fdbf73864be4270360f59fb4d1db74a7cee9af7 Mon Sep 17 00:00:00 2001 From: jaimergp Date: Tue, 2 Sep 2025 15:45:42 +0200 Subject: [PATCH 11/11] further clarify --- peps/pep-9999.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/peps/pep-9999.rst b/peps/pep-9999.rst index 187154fe7b6..a2990470fc9 100644 --- a/peps/pep-9999.rst +++ b/peps/pep-9999.rst @@ -592,8 +592,9 @@ Each entry in this list is defined as a dictionary with these fields: - ``exact_version`` MUST be ``None`` or a list of strings that describe the syntax used for specifiers that only express exact version - constraints; in the latter case, each of the placeholders ``{name}`` - and ``{version}`` MUST be present in at least one of the strings. + constraints; in the latter case, the placeholders ``{name}`` + and ``{version}`` MUST be present in at least one of the strings + (although not necessary the same string for both). - ``version_ranges`` MUST be ``None`` or a dictionary with the following required keys: