https://github.com/python/cpython/commit/b9f6d5a67b37abd75a27c040af7cd5efcc9c08fd
commit: b9f6d5a67b37abd75a27c040af7cd5efcc9c08fd
branch: 3.14
author: Stan Ulbrych <[email protected]>
committer: StanFromIreland <[email protected]>
date: 2026-09-12T09:22:27Z
summary:
[3.14] gh-155095: Fix docs changes builder for our custom directives
(GH-155100) (#157357)
(cherry picked from commit 94dc05133531d792fb0e14bfe12c3fe65ba3a91f)
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 2e54cd9e23cab76..6e0c067cb178d7d 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]