From ab07e44e92d471f4b8156946d5e091eedeabb5b5 Mon Sep 17 00:00:00 2001 From: Hugo Date: Fri, 10 Jul 2026 10:21:48 +0100 Subject: [PATCH 1/4] Document self-referential extras now that pip officially supports it Relevant PR: https://github.com/pypa/pip/pull/14157 Relevant Issue: https://github.com/pypa/pip/issues/11296 --- source/guides/writing-pyproject-toml.rst | 17 +++++++++++++++++ source/specifications/pyproject-toml.rst | 7 +++++++ 2 files changed, 24 insertions(+) diff --git a/source/guides/writing-pyproject-toml.rst b/source/guides/writing-pyproject-toml.rst index 92a7f25bf..6ce28553e 100644 --- a/source/guides/writing-pyproject-toml.rst +++ b/source/guides/writing-pyproject-toml.rst @@ -175,6 +175,22 @@ Each of the keys defines a "packaging extra". In the example above, one could use, e.g., ``pip install your-project-name[gui]`` to install your project with GUI support, adding the PyQt5 dependency. +.. _self-referential-extras: + +You can also define an extra that refers back to the same project with +other extras. This is useful for convenience extras that combine several +optional features without duplicating their dependency lists: + +.. code-block:: toml + + all = ["your-project-name[gui, cli]"] + +Installing ``your-project-name[all]`` then installs both the ``gui`` and +``cli`` dependencies. You can also list extras separately, for example +``["your-project-name[gui]", "your-project-name[cli]"]``. The name in the +requirement must match the project's ``name`` field. Installers such as +:ref:`pip` and :ref:`uv` support this pattern already (pip since v21.2). + .. _requires-python: .. _python_requires: @@ -555,6 +571,7 @@ A full example "rich", "click", ] + all = ["spam-eggs[gui, cli]"] [project.urls] Homepage = "https://example.com" diff --git a/source/specifications/pyproject-toml.rst b/source/specifications/pyproject-toml.rst index b4625bbb2..4b5a4a780 100644 --- a/source/specifications/pyproject-toml.rst +++ b/source/specifications/pyproject-toml.rst @@ -498,6 +498,13 @@ marker clause on the related ``Requires-Dist`` entries to check the extra name. Optional dependencies are thus only considered for installation if installation if the associated extra name is requested. +A dependency specifier in an extra MAY name the project itself with other extras +(for example, ``all = ["spam[gui, cli]"]``). That way a combined extra does not +need its own manually maintained copy of each referenced extra's dependencies, +which can otherwise fall out of sync. Installers that support self-referential +extras will be able to install the union of these extras' dependencies. See +:ref:`self-referential extras ` for examples. + .. _pyproject-toml-import-names: From d72cd8b978e469b562fc3390c25f9641c9688b00 Mon Sep 17 00:00:00 2001 From: Hugo Date: Fri, 10 Jul 2026 10:36:58 +0100 Subject: [PATCH 2/4] Update to include pip docs link --- source/guides/writing-pyproject-toml.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/guides/writing-pyproject-toml.rst b/source/guides/writing-pyproject-toml.rst index 6ce28553e..90fb7591c 100644 --- a/source/guides/writing-pyproject-toml.rst +++ b/source/guides/writing-pyproject-toml.rst @@ -189,7 +189,8 @@ Installing ``your-project-name[all]`` then installs both the ``gui`` and ``cli`` dependencies. You can also list extras separately, for example ``["your-project-name[gui]", "your-project-name[cli]"]``. The name in the requirement must match the project's ``name`` field. Installers such as -:ref:`pip` and :ref:`uv` support this pattern already (pip since v21.2). +:ref:`pip` and :ref:`uv` support this pattern already (pip since +`version 21.2 `_). .. _requires-python: From 68c3a77baafa24e65ce1bde8ea657001ccb03090 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 09:37:18 +0000 Subject: [PATCH 3/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- source/guides/writing-pyproject-toml.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/guides/writing-pyproject-toml.rst b/source/guides/writing-pyproject-toml.rst index 90fb7591c..fa2760bab 100644 --- a/source/guides/writing-pyproject-toml.rst +++ b/source/guides/writing-pyproject-toml.rst @@ -189,7 +189,7 @@ Installing ``your-project-name[all]`` then installs both the ``gui`` and ``cli`` dependencies. You can also list extras separately, for example ``["your-project-name[gui]", "your-project-name[cli]"]``. The name in the requirement must match the project's ``name`` field. Installers such as -:ref:`pip` and :ref:`uv` support this pattern already (pip since +:ref:`pip` and :ref:`uv` support this pattern already (pip since `version 21.2 `_). From d45adcf5f81677fde743cffc2ee0c0d9f54c0221 Mon Sep 17 00:00:00 2001 From: Hugo Date: Sat, 11 Jul 2026 19:52:13 +0100 Subject: [PATCH 4/4] Rework the writing --- source/guides/writing-pyproject-toml.rst | 26 ++++++++++++++++-------- source/specifications/pyproject-toml.rst | 11 ++++------ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/source/guides/writing-pyproject-toml.rst b/source/guides/writing-pyproject-toml.rst index fa2760bab..665c1277b 100644 --- a/source/guides/writing-pyproject-toml.rst +++ b/source/guides/writing-pyproject-toml.rst @@ -177,20 +177,28 @@ project with GUI support, adding the PyQt5 dependency. .. _self-referential-extras: -You can also define an extra that refers back to the same project with +You can also define an extra that refers back to the current project with other extras. This is useful for convenience extras that combine several -optional features without duplicating their dependency lists: +optional features (such as an ``all`` extra hosting dependencies from both +``gui`` and ``cli``): .. code-block:: toml - all = ["your-project-name[gui, cli]"] + all = ["your-project-name[gui, cli]"] -Installing ``your-project-name[all]`` then installs both the ``gui`` and -``cli`` dependencies. You can also list extras separately, for example -``["your-project-name[gui]", "your-project-name[cli]"]``. The name in the -requirement must match the project's ``name`` field. Installers such as -:ref:`pip` and :ref:`uv` support this pattern already (pip since -`version 21.2 `_). +The combined extra does not need its own manually maintained copy of each +referenced extra's dependencies, which can otherwise fall out of sync after +a few years of maintenance and bug fixes: + +.. code-block:: toml + + gui = ["PyQt5"] + cli = [ + "rich>=14.2", # version range is added after last "all" extra update + "textual", # dependency newly added since last "all" extra update + "click", + ] + all = ["PyQt5", "rich", "click"] .. _requires-python: diff --git a/source/specifications/pyproject-toml.rst b/source/specifications/pyproject-toml.rst index 4b5a4a780..7bc6ffbe1 100644 --- a/source/specifications/pyproject-toml.rst +++ b/source/specifications/pyproject-toml.rst @@ -498,13 +498,10 @@ marker clause on the related ``Requires-Dist`` entries to check the extra name. Optional dependencies are thus only considered for installation if installation if the associated extra name is requested. -A dependency specifier in an extra MAY name the project itself with other extras -(for example, ``all = ["spam[gui, cli]"]``). That way a combined extra does not -need its own manually maintained copy of each referenced extra's dependencies, -which can otherwise fall out of sync. Installers that support self-referential -extras will be able to install the union of these extras' dependencies. See -:ref:`self-referential extras ` for examples. - +Dependency specifiers in an extra may self-reference other extras from the +current project (e.g. ``all = ["your-project-name[gui, cli]"]``). See +:ref:`self-referential extras ` for an example. +Several installers including :ref:`pip` and :ref:`uv` support this pattern. .. _pyproject-toml-import-names: