From 51fbfdeec3fd0c376a96969f930ddbf2214460ff Mon Sep 17 00:00:00 2001
From: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
Date: Mon, 20 Jan 2025 00:26:24 +0000
Subject: [PATCH 1/2] GH-125722: Increase minimum supported Sphinx to 8.1.3
 (GH-128922) (cherry picked from commit
 d46b577ec026c2e700a9f920f81cfbf698e53eb6)

Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
---
 .github/workflows/reusable-docs.yml           | 20 -----------
 Doc/conf.py                                   | 24 ++-----------
 Doc/constraints.txt                           | 14 ++++----
 Doc/requirements-oldest-sphinx.txt            | 35 -------------------
 Doc/requirements.txt                          |  3 +-
 Doc/tools/extensions/c_annotations.py         | 11 ------
 ...-01-16-18-59-11.gh-issue-125722.eHHRga.rst |  2 ++
 7 files changed, 13 insertions(+), 96 deletions(-)
 delete mode 100644 Doc/requirements-oldest-sphinx.txt
 create mode 100644 Misc/NEWS.d/next/Documentation/2025-01-16-18-59-11.gh-issue-125722.eHHRga.rst

diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml
index c5f71831a005fd..6ac7d40c4aec27 100644
--- a/.github/workflows/reusable-docs.yml
+++ b/.github/workflows/reusable-docs.yml
@@ -73,26 +73,6 @@ jobs:
           --fail-if-improved \
           --fail-if-new-news-nit
 
-  # This build doesn't use problem matchers or check annotations
-  build_doc_oldest_supported_sphinx:
-    name: 'Docs (Oldest Sphinx)'
-    runs-on: ubuntu-latest
-    timeout-minutes: 60
-    steps:
-    - uses: actions/checkout@v4
-      with:
-        persist-credentials: false
-    - name: 'Set up Python'
-      uses: actions/setup-python@v5
-      with:
-        python-version: '3.13'  # known to work with Sphinx 7.2.6
-        cache: 'pip'
-        cache-dependency-path: 'Doc/requirements-oldest-sphinx.txt'
-    - name: 'Install build dependencies'
-      run: make -C Doc/ venv REQUIREMENTS="requirements-oldest-sphinx.txt"
-    - name: 'Build HTML documentation'
-      run: make -C Doc/ SPHINXOPTS="-q" SPHINXERRORHANDLING="-W --keep-going" html
-
   # Run "doctest" on HEAD as new syntax doesn't exist in the latest stable release
   doctest:
     name: 'Doctest'
diff --git a/Doc/conf.py b/Doc/conf.py
index 4b18d02a943f62..b7bbd94b35da11 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -9,9 +9,6 @@
 import importlib
 import os
 import sys
-import time
-
-import sphinx
 
 # Make our custom extensions available to Sphinx
 sys.path.append(os.path.abspath('tools/extensions'))
@@ -85,7 +82,8 @@
 highlight_language = 'python3'
 
 # Minimum version of sphinx required
-needs_sphinx = '7.2.6'
+# Keep this version in sync with ``Doc/requirements.txt``.
+needs_sphinx = '8.1.3'
 
 # Create table of contents entries for domain objects (e.g. functions, classes,
 # attributes, etc.). Default is True.
@@ -350,13 +348,7 @@
 
 # This 'Last updated on:' timestamp is inserted at the bottom of every page.
 html_last_updated_fmt = '%b %d, %Y (%H:%M UTC)'
-if sphinx.version_info[:2] >= (8, 1):
-    html_last_updated_use_utc = True
-else:
-    html_time = int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
-    html_last_updated_fmt = time.strftime(
-        html_last_updated_fmt, time.gmtime(html_time)
-    )
+html_last_updated_use_utc = True
 
 # Path to find HTML templates to override theme
 templates_path = ['tools/templates']
@@ -594,16 +586,6 @@
 }
 extlinks_detect_hardcoded_links = True
 
-if sphinx.version_info[:2] < (8, 1):
-    # Sphinx 8.1 has in-built CVE and CWE roles.
-    extlinks |= {
-        "cve": (
-            "https://www.cve.org/CVERecord?id=CVE-%s",
-            "CVE-%s",
-        ),
-        "cwe": ("https://cwe.mitre.org/data/definitions/%s.html", "CWE-%s"),
-    }
-
 # Options for c_annotations extension
 # -----------------------------------
 
diff --git a/Doc/constraints.txt b/Doc/constraints.txt
index 26ac1862dbac0b..29cd4be1d3c8db 100644
--- a/Doc/constraints.txt
+++ b/Doc/constraints.txt
@@ -13,14 +13,12 @@ packaging<25
 Pygments<3
 requests<3
 snowballstemmer<3
-# keep lower-bounds until Sphinx 8.1 is released
-# https://github.com/sphinx-doc/sphinx/pull/12756
-sphinxcontrib-applehelp>=1.0.7,<3
-sphinxcontrib-devhelp>=1.0.6,<3
-sphinxcontrib-htmlhelp>=2.0.6,<3
-sphinxcontrib-jsmath>=1.0.1,<2
-sphinxcontrib-qthelp>=1.0.6,<3
-sphinxcontrib-serializinghtml>=1.1.9,<3
+sphinxcontrib-applehelp<3
+sphinxcontrib-devhelp<3
+sphinxcontrib-htmlhelp<3
+sphinxcontrib-jsmath<2
+sphinxcontrib-qthelp<3
+sphinxcontrib-serializinghtml<3
 
 # Direct dependencies of Jinja2 (Jinja is a dependency of Sphinx, see above)
 MarkupSafe<3
diff --git a/Doc/requirements-oldest-sphinx.txt b/Doc/requirements-oldest-sphinx.txt
deleted file mode 100644
index c8027a05706c21..00000000000000
--- a/Doc/requirements-oldest-sphinx.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-# Requirements to build the Python documentation, for the oldest supported
-# Sphinx version.
-#
-# We pin Sphinx and all of its dependencies to ensure a consistent environment.
-
-blurb
-python-docs-theme>=2022.1
-
-# Generated from:
-#     pip install "Sphinx~=7.2.6"
-#     pip freeze
-#
-# Sphinx 7.2.6 comes from ``needs_sphinx = '7.2.6'`` in ``Doc/conf.py``.
-
-alabaster==0.7.16
-babel==2.16.0
-certifi==2024.12.14
-charset-normalizer==3.4.0
-docutils==0.20.1
-idna==3.10
-imagesize==1.4.1
-Jinja2==3.1.5
-MarkupSafe==3.0.2
-packaging==24.2
-Pygments==2.18.0
-requests==2.32.3
-snowballstemmer==2.2.0
-Sphinx==7.2.6
-sphinxcontrib-applehelp==2.0.0
-sphinxcontrib-devhelp==2.0.0
-sphinxcontrib-htmlhelp==2.1.0
-sphinxcontrib-jsmath==1.0.1
-sphinxcontrib-qthelp==2.0.0
-sphinxcontrib-serializinghtml==2.0.0
-urllib3==2.3.0
diff --git a/Doc/requirements.txt b/Doc/requirements.txt
index 5105786ccf283c..32ff8f74d05bb6 100644
--- a/Doc/requirements.txt
+++ b/Doc/requirements.txt
@@ -3,9 +3,10 @@
 # Note that when updating this file, you will likely also have to update
 # the Doc/constraints.txt file.
 
-# Sphinx version is pinned so that new versions that introduce new warnings
+# The Sphinx version is pinned so that new versions that introduce new warnings
 # won't suddenly cause build failures. Updating the version is fine as long
 # as no warnings are raised by doing so.
+# Keep this version in sync with ``Doc/conf.py``.
 sphinx~=8.1.0
 
 blurb
diff --git a/Doc/tools/extensions/c_annotations.py b/Doc/tools/extensions/c_annotations.py
index 50065d34a2c27a..089614a1f6c421 100644
--- a/Doc/tools/extensions/c_annotations.py
+++ b/Doc/tools/extensions/c_annotations.py
@@ -16,7 +16,6 @@
 from pathlib import Path
 from typing import TYPE_CHECKING
 
-import sphinx
 from docutils import nodes
 from docutils.statemachine import StringList
 from sphinx import addnodes
@@ -285,16 +284,6 @@ def setup(app: Sphinx) -> ExtensionMetadata:
     app.connect("builder-inited", init_annotations)
     app.connect("doctree-read", add_annotations)
 
-    if sphinx.version_info[:2] < (7, 2):
-        from docutils.parsers.rst import directives
-        from sphinx.domains.c import CObject
-
-        # monkey-patch C object...
-        CObject.option_spec |= {
-            "no-index-entry": directives.flag,
-            "no-contents-entry": directives.flag,
-        }
-
     return {
         "version": "1.0",
         "parallel_read_safe": True,
diff --git a/Misc/NEWS.d/next/Documentation/2025-01-16-18-59-11.gh-issue-125722.eHHRga.rst b/Misc/NEWS.d/next/Documentation/2025-01-16-18-59-11.gh-issue-125722.eHHRga.rst
new file mode 100644
index 00000000000000..bf6253eed2eb90
--- /dev/null
+++ b/Misc/NEWS.d/next/Documentation/2025-01-16-18-59-11.gh-issue-125722.eHHRga.rst
@@ -0,0 +1,2 @@
+Require Sphinx 8.1.3 or later to build the Python documentation. Patch by
+Adam Turner.

From 87854e5395f5ad6dc3fd2c89294b0873f171886b Mon Sep 17 00:00:00 2001
From: Adam Turner <9087854+aa-turner@users.noreply.github.com>
Date: Mon, 20 Jan 2025 00:29:49 +0000
Subject: [PATCH 2/2] post-merge

---
 Doc/conf.py | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/Doc/conf.py b/Doc/conf.py
index b7bbd94b35da11..4c74040976959c 100644
--- a/Doc/conf.py
+++ b/Doc/conf.py
@@ -58,10 +58,7 @@
 
 # General substitutions.
 project = 'Python'
-if sphinx.version_info[:2] >= (8, 1):
-    copyright = "2001-%Y, Python Software Foundation"
-else:
-    copyright = f"2001-{time.strftime('%Y')}, Python Software Foundation"
+copyright = "2001-%Y, Python Software Foundation"
 
 # We look for the Include/patchlevel.h file in the current Python source tree
 # and replace the values accordingly.