https://github.com/python/cpython/commit/0a7db3340018400ea20a208bbf7cd4f658a3351f
commit: 0a7db3340018400ea20a208bbf7cd4f658a3351f
branch: 3.13
author: Miss Islington (bot) <[email protected]>
committer: StanFromIreland <[email protected]>
date: 2026-09-12T09:29:24Z
summary:

[3.13] gh-155095: Fix docs changes builder for our custom directives 
(GH-155100) (GH-157357) (#157358)

(cherry picked from commit 94dc05133531d792fb0e14bfe12c3fe65ba3a91f)

Co-authored-by: Stan Ulbrych <[email protected]>

files:
M .github/workflows/reusable-docs.yml
M Doc/tools/extensions/changes.py

diff --git a/.github/workflows/reusable-docs.yml 
b/.github/workflows/reusable-docs.yml
index 3de76dd48c59613..6db7668aef9506e 100644
--- a/.github/workflows/reusable-docs.yml
+++ b/.github/workflows/reusable-docs.yml
@@ -86,6 +86,9 @@ jobs:
           --fail-if-regression \
           --fail-if-improved \
           --fail-if-new-news-nit
+    - name: 'Build list of changes'
+      run: |
+        make -C Doc/ PYTHON=../python changes
 
   # Run "doctest" on HEAD as new syntax doesn't exist in the latest stable 
release
   doctest:
diff --git a/Doc/tools/extensions/changes.py b/Doc/tools/extensions/changes.py
index 02dc51b3a76943a..e6a912cef8810ea 100644
--- a/Doc/tools/extensions/changes.py
+++ b/Doc/tools/extensions/changes.py
@@ -6,6 +6,7 @@
 
 from docutils import nodes
 from sphinx import addnodes
+from sphinx.builders.changes import ChangesBuilder
 from sphinx.domains.changeset import (
     VersionChange,
     versionlabel_classes,
@@ -17,6 +18,7 @@
 if TYPE_CHECKING:
     from docutils.nodes import Node
     from sphinx.application import Sphinx
+    from sphinx.environment import BuildEnvironment
     from sphinx.util.typing import ExtensionMetadata
 
 
@@ -146,6 +148,32 @@ def _add_glossary_link(cls, inline: nodes.inline) -> None:
             break
 
 
+def _fixup_changesets(app: Sphinx, env: BuildEnvironment) -> None:
+    changesets = env.get_domain("changeset").changesets
+
+    # The changeset domain records each entry's plain text before 
SoftDeprecated
+    # replaces the :term:, so strip the markup before the changes builder 
renders it.
+    for entries in changesets.values():
+        for i, entry in enumerate(entries):
+            if entry.type == "soft-deprecated":
+                entries[i] = entry._replace(
+                    content=SoftDeprecated._TERM_RE.sub(r"\1", entry.content)
+                )
+
+    # DeprecatedRemoved entries are recorded under their (deprecated,
+    # removed) version tuple, which the changes builder ignores.
+    # Re-file them under both versions.
+    for versions in [v for v in changesets if isinstance(v, tuple)]:
+        deprecated, removed = versions
+        for entry in changesets.pop(versions):
+            changesets.setdefault(deprecated, []).append(
+                entry._replace(type="deprecated")
+            )
+            changesets.setdefault(removed, []).append(
+                entry._replace(type="versionremoved")
+            )
+
+
 def setup(app: Sphinx) -> ExtensionMetadata:
     # Override Sphinx's directives with support for 'next'
     app.add_directive("versionadded", PyVersionChange, override=True)
@@ -155,9 +183,15 @@ def setup(app: Sphinx) -> ExtensionMetadata:
 
     # Register the ``.. deprecated-removed::`` directive
     app.add_directive("deprecated-removed", DeprecatedRemoved)
+    # _fixup_changesets() changes these entries to 
'deprecated'/'versionremoved'
+    ChangesBuilder.typemap["deprecated-removed"] = "deprecated-removed"
 
     # Register the ``.. soft-deprecated::`` directive
     app.add_directive("soft-deprecated", SoftDeprecated)
+    ChangesBuilder.typemap["soft-deprecated"] = "soft deprecated"
+
+    # Repair the recorded changesets for the couple of custom directives above
+    app.connect("env-updated", _fixup_changesets)
 
     return {
         "version": "1.0",

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to