From 7c66eb2d6fd99e40fe0bb43f4bbdb7efb4a1cee3 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Sat, 7 Mar 2026 20:22:47 +0000 Subject: [PATCH 01/14] Run `check-html-ids.py` in CI --- .github/workflows/reusable-docs.yml | 41 +++++++++++++++++++++++++++++ Doc/tools/check-html-ids.py | 5 +++- Doc/tools/removed-html-ids.txt | 1 + 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 Doc/tools/removed-html-ids.txt diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index c1e58fd44d3790..07f9b7f43168e4 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -75,6 +75,47 @@ jobs: --fail-if-regression \ --fail-if-improved \ --fail-if-new-news-nit + - name: 'Collect HTML IDs' + run: python Doc/tools/check-html-ids.py collect Doc/build/html -o Doc/build/html-ids-head.json.gz + - name: 'Upload HTML IDs' + uses: actions/upload-artifact@v6 + with: + name: html-ids-head + path: Doc/build/html-ids-head.json.gz + + check-html-ids: + name: 'Check for removed HTML IDs' + needs: build-doc + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: 'Check out base commit' + uses: actions/checkout@v6 + with: + persist-credentials: false + ref: ${{ github.event.pull_request.base.sha || github.event.before }} + - name: 'Set up Python' + uses: actions/setup-python@v6 + with: + python-version: '3' + cache: 'pip' + cache-dependency-path: 'Doc/requirements.txt' + - name: 'Install build dependencies' + run: make -C Doc/ venv + - name: 'Build HTML documentation' + run: make -C Doc/ SPHINXOPTS="--quiet" html + - name: 'Collect HTML IDs' + run: python Doc/tools/check-html-ids.py collect Doc/build/html -o /tmp/html-ids-base.json.gz + - name: 'Download PR base HTML IDs' + uses: actions/download-artifact@v6 + with: + name: html-ids-head + path: /tmp + - name: 'Check for removed HTML IDs' + run: >- + python Doc/tools/check-html-ids.py check + /tmp/html-ids-base.json.gz /tmp/html-ids-head.json.gz + --exclude-file Doc/tools/removed-html-ids.txt # Run "doctest" on HEAD as new syntax doesn't exist in the latest stable release doctest: diff --git a/Doc/tools/check-html-ids.py b/Doc/tools/check-html-ids.py index 8e8e0a581df72d..33bb479edb16d2 100644 --- a/Doc/tools/check-html-ids.py +++ b/Doc/tools/check-html-ids.py @@ -1,4 +1,7 @@ -from compression import gzip +try: + from compression import gzip +except ImportError: + import gzip import concurrent.futures from pathlib import Path import html.parser diff --git a/Doc/tools/removed-html-ids.txt b/Doc/tools/removed-html-ids.txt new file mode 100644 index 00000000000000..f2e434d9581d12 --- /dev/null +++ b/Doc/tools/removed-html-ids.txt @@ -0,0 +1 @@ +# HTML IDs excluded from the Doc/tools/check-html-ids.py check From 0d69429c4f3327cf756a0e58217968a7f0e3c759 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Sat, 7 Mar 2026 20:33:00 +0000 Subject: [PATCH 02/14] Adding an exclude file now won't work --- .github/workflows/reusable-docs.yml | 3 ++- Doc/tools/removed-html-ids.txt | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 Doc/tools/removed-html-ids.txt diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index 07f9b7f43168e4..d9eaa83be1b935 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -115,7 +115,8 @@ jobs: run: >- python Doc/tools/check-html-ids.py check /tmp/html-ids-base.json.gz /tmp/html-ids-head.json.gz - --exclude-file Doc/tools/removed-html-ids.txt + # XXX: When an exclude file is added, update this to use it: + # --exclude-file Doc/tools/removed-ids.txt # Run "doctest" on HEAD as new syntax doesn't exist in the latest stable release doctest: diff --git a/Doc/tools/removed-html-ids.txt b/Doc/tools/removed-html-ids.txt deleted file mode 100644 index f2e434d9581d12..00000000000000 --- a/Doc/tools/removed-html-ids.txt +++ /dev/null @@ -1 +0,0 @@ -# HTML IDs excluded from the Doc/tools/check-html-ids.py check From d7d697c4dd2a44601afac8de85dbe5400b67ab86 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Sat, 7 Mar 2026 20:39:44 +0000 Subject: [PATCH 03/14] Remove a title to test --- Doc/library/datetime.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 73217136f14472..849075c7a3d4a6 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -849,9 +849,6 @@ Instance methods: See also :ref:`strftime-strptime-behavior` and :meth:`date.isoformat`. -Examples of usage: :class:`!date` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Example of counting days to an event:: >>> import time From 250472fdee61078bc92d0752419b45ebb935ef3e Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Sat, 7 Mar 2026 20:44:46 +0000 Subject: [PATCH 04/14] `sys.exit(1)` on error --- Doc/tools/check-html-ids.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Doc/tools/check-html-ids.py b/Doc/tools/check-html-ids.py index 33bb479edb16d2..7d86c6cc3264ad 100644 --- a/Doc/tools/check-html-ids.py +++ b/Doc/tools/check-html-ids.py @@ -1,7 +1,4 @@ -try: - from compression import gzip -except ImportError: - import gzip +from compression import gzip import concurrent.futures from pathlib import Path import html.parser @@ -178,6 +175,7 @@ def verbose_print(*args, **kwargs): ) if args.exclude_file: print(f'Alternatively, add them to {args.exclude_file}.') + sys.exit(1) if __name__ == '__main__': From 6306c7d10d5811b015b48e98eae53f99776d41d5 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Sat, 7 Mar 2026 20:52:13 +0000 Subject: [PATCH 05/14] Revert "Remove a title to test" This reverts commit d7d697c4dd2a44601afac8de85dbe5400b67ab86. --- Doc/library/datetime.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/library/datetime.rst b/Doc/library/datetime.rst index 849075c7a3d4a6..73217136f14472 100644 --- a/Doc/library/datetime.rst +++ b/Doc/library/datetime.rst @@ -849,6 +849,9 @@ Instance methods: See also :ref:`strftime-strptime-behavior` and :meth:`date.isoformat`. +Examples of usage: :class:`!date` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + Example of counting days to an event:: >>> import time From 48a708cbca7118baae77ba9949d511d5cc399c95 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 9 Mar 2026 18:18:07 +0000 Subject: [PATCH 06/14] Apply suggestions from code review Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- .github/workflows/reusable-docs.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index d9eaa83be1b935..d1027696bfaba6 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -78,10 +78,11 @@ jobs: - name: 'Collect HTML IDs' run: python Doc/tools/check-html-ids.py collect Doc/build/html -o Doc/build/html-ids-head.json.gz - name: 'Upload HTML IDs' - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: html-ids-head path: Doc/build/html-ids-head.json.gz + archive: false check-html-ids: name: 'Check for removed HTML IDs' @@ -107,7 +108,8 @@ jobs: - name: 'Collect HTML IDs' run: python Doc/tools/check-html-ids.py collect Doc/build/html -o /tmp/html-ids-base.json.gz - name: 'Download PR base HTML IDs' - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v8 + archive: false with: name: html-ids-head path: /tmp From 9a6a7edaa1cf0ab9fadd846f5a3eb89d57fda709 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Mon, 9 Mar 2026 18:19:32 +0000 Subject: [PATCH 07/14] Apply suggestion from @StanFromIreland --- .github/workflows/reusable-docs.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index d1027696bfaba6..f26e990c01b936 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -109,7 +109,6 @@ jobs: run: python Doc/tools/check-html-ids.py collect Doc/build/html -o /tmp/html-ids-base.json.gz - name: 'Download PR base HTML IDs' uses: actions/download-artifact@v8 - archive: false with: name: html-ids-head path: /tmp From c5031ad047bd488b36ed605a60404e7c97066dc1 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Mon, 9 Mar 2026 19:31:36 +0000 Subject: [PATCH 08/14] Update name --- .github/workflows/reusable-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index f26e990c01b936..0a82eb730adc11 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -110,7 +110,7 @@ jobs: - name: 'Download PR base HTML IDs' uses: actions/download-artifact@v8 with: - name: html-ids-head + name: html-ids-head.json.gz path: /tmp - name: 'Check for removed HTML IDs' run: >- From 52ced6f2747fe297f1bfbd1a82bf884d528491bd Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Thu, 19 Mar 2026 18:21:23 +0000 Subject: [PATCH 09/14] Only run on PRs + move to reusable workflow --- .github/workflows/reusable-check-html-ids.yml | 44 +++++++++++++++++++ .github/workflows/reusable-docs.yml | 35 ++------------- 2 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 .github/workflows/reusable-check-html-ids.yml diff --git a/.github/workflows/reusable-check-html-ids.yml b/.github/workflows/reusable-check-html-ids.yml new file mode 100644 index 00000000000000..84fcbc6520655e --- /dev/null +++ b/.github/workflows/reusable-check-html-ids.yml @@ -0,0 +1,44 @@ +name: Reusable Check HTML IDs Check + +on: + workflow_call: + +permissions: + contents: read + +env: + FORCE_COLOR: 1 + +jobs: + check-html-ids: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - name: 'Check out base commit' + uses: actions/checkout@v6 + with: + persist-credentials: false + ref: ${{ github.event.pull_request.base.sha }} + - name: 'Set up Python' + uses: actions/setup-python@v6 + with: + python-version: '3' + cache: 'pip' + cache-dependency-path: 'Doc/requirements.txt' + - name: 'Install build dependencies' + run: make -C Doc/ venv + - name: 'Build HTML documentation' + run: make -C Doc/ SPHINXOPTS="--quiet" html + - name: 'Collect HTML IDs' + run: python Doc/tools/check-html-ids.py collect Doc/build/html -o /tmp/html-ids-base.json.gz + - name: 'Download PR base HTML IDs' + uses: actions/download-artifact@v8 + with: + name: html-ids-head.json.gz + path: /tmp + - name: 'Check for removed HTML IDs' + run: >- + python Doc/tools/check-html-ids.py check + /tmp/html-ids-base.json.gz /tmp/html-ids-head.json.gz + # XXX: When an exclude file is added, update this to use it: + # --exclude-file Doc/tools/removed-ids.txt diff --git a/.github/workflows/reusable-docs.yml b/.github/workflows/reusable-docs.yml index 0a82eb730adc11..14d7783891e229 100644 --- a/.github/workflows/reusable-docs.yml +++ b/.github/workflows/reusable-docs.yml @@ -76,8 +76,10 @@ jobs: --fail-if-improved \ --fail-if-new-news-nit - name: 'Collect HTML IDs' + if: github.event_name == 'pull_request' run: python Doc/tools/check-html-ids.py collect Doc/build/html -o Doc/build/html-ids-head.json.gz - name: 'Upload HTML IDs' + if: github.event_name == 'pull_request' uses: actions/upload-artifact@v7 with: name: html-ids-head @@ -87,37 +89,8 @@ jobs: check-html-ids: name: 'Check for removed HTML IDs' needs: build-doc - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: 'Check out base commit' - uses: actions/checkout@v6 - with: - persist-credentials: false - ref: ${{ github.event.pull_request.base.sha || github.event.before }} - - name: 'Set up Python' - uses: actions/setup-python@v6 - with: - python-version: '3' - cache: 'pip' - cache-dependency-path: 'Doc/requirements.txt' - - name: 'Install build dependencies' - run: make -C Doc/ venv - - name: 'Build HTML documentation' - run: make -C Doc/ SPHINXOPTS="--quiet" html - - name: 'Collect HTML IDs' - run: python Doc/tools/check-html-ids.py collect Doc/build/html -o /tmp/html-ids-base.json.gz - - name: 'Download PR base HTML IDs' - uses: actions/download-artifact@v8 - with: - name: html-ids-head.json.gz - path: /tmp - - name: 'Check for removed HTML IDs' - run: >- - python Doc/tools/check-html-ids.py check - /tmp/html-ids-base.json.gz /tmp/html-ids-head.json.gz - # XXX: When an exclude file is added, update this to use it: - # --exclude-file Doc/tools/removed-ids.txt + if: github.event_name == 'pull_request' + uses: ./.github/workflows/reusable-check-html-ids.yml # Run "doctest" on HEAD as new syntax doesn't exist in the latest stable release doctest: From fb6288bf2ea92994fcfc480a10ceb2be2a6a6997 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Thu, 19 Mar 2026 18:26:32 +0000 Subject: [PATCH 10/14] Add `name` to reusable workflow --- .github/workflows/reusable-check-html-ids.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/reusable-check-html-ids.yml b/.github/workflows/reusable-check-html-ids.yml index 84fcbc6520655e..1c8cfc1dcfba0d 100644 --- a/.github/workflows/reusable-check-html-ids.yml +++ b/.github/workflows/reusable-check-html-ids.yml @@ -11,6 +11,7 @@ env: jobs: check-html-ids: + name: 'Check for removed HTML IDs' runs-on: ubuntu-latest timeout-minutes: 30 steps: From 1c777fdc00a8584ce031f2b05192fb4fe4b1ec74 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Tue, 31 Mar 2026 15:50:33 +0200 Subject: [PATCH 11/14] Hugo's review Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- .github/workflows/reusable-check-html-ids.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-check-html-ids.yml b/.github/workflows/reusable-check-html-ids.yml index 1c8cfc1dcfba0d..9ee7098433cafa 100644 --- a/.github/workflows/reusable-check-html-ids.yml +++ b/.github/workflows/reusable-check-html-ids.yml @@ -1,4 +1,4 @@ -name: Reusable Check HTML IDs Check +name: Reusable check HTML IDs on: workflow_call: @@ -39,7 +39,7 @@ jobs: path: /tmp - name: 'Check for removed HTML IDs' run: >- - python Doc/tools/check-html-ids.py check + python Doc/tools/check-html-ids.py -v check /tmp/html-ids-base.json.gz /tmp/html-ids-head.json.gz # XXX: When an exclude file is added, update this to use it: # --exclude-file Doc/tools/removed-ids.txt From 69df346fed31d9513178d6b26348da4848180287 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Tue, 31 Mar 2026 16:35:08 +0200 Subject: [PATCH 12/14] Create `removed-ids.txt` & use PR *head* tools --- .github/workflows/reusable-check-html-ids.yml | 18 +++++++++++++++--- Doc/tools/removed-ids.txt | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 Doc/tools/removed-ids.txt diff --git a/.github/workflows/reusable-check-html-ids.yml b/.github/workflows/reusable-check-html-ids.yml index 9ee7098433cafa..c45d66bccd5063 100644 --- a/.github/workflows/reusable-check-html-ids.yml +++ b/.github/workflows/reusable-check-html-ids.yml @@ -30,9 +30,22 @@ jobs: run: make -C Doc/ venv - name: 'Build HTML documentation' run: make -C Doc/ SPHINXOPTS="--quiet" html + - name: 'Check out PR head tools' + uses: actions/checkout@v6 + with: + persist-credentials: false + sparse-checkout: | + Doc/tools/check-html-ids.py + Doc/tools/removed-ids.txt + sparse-checkout-cone-mode: false + path: /tmp/tools + - name: 'Use PR head tools' + run: | + cp /tmp/tools/Doc/tools/check-html-ids.py Doc/tools/check-html-ids.py + [ -f /tmp/tools/Doc/tools/removed-ids.txt ] && cp /tmp/tools/Doc/tools/removed-ids.txt Doc/tools/removed-ids.txt - name: 'Collect HTML IDs' run: python Doc/tools/check-html-ids.py collect Doc/build/html -o /tmp/html-ids-base.json.gz - - name: 'Download PR base HTML IDs' + - name: 'Download PR head HTML IDs' uses: actions/download-artifact@v8 with: name: html-ids-head.json.gz @@ -41,5 +54,4 @@ jobs: run: >- python Doc/tools/check-html-ids.py -v check /tmp/html-ids-base.json.gz /tmp/html-ids-head.json.gz - # XXX: When an exclude file is added, update this to use it: - # --exclude-file Doc/tools/removed-ids.txt + $([ -f Doc/tools/removed-ids.txt ] && echo "--exclude-file Doc/tools/removed-ids.txt") diff --git a/Doc/tools/removed-ids.txt b/Doc/tools/removed-ids.txt new file mode 100644 index 00000000000000..f3cd8bf0ef5bb9 --- /dev/null +++ b/Doc/tools/removed-ids.txt @@ -0,0 +1 @@ +# HTML IDs excluded from the check-html-ids.py check. From ff5bafead752ddb001c033ad6c36225c2c2f01bb Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Tue, 31 Mar 2026 16:39:33 +0200 Subject: [PATCH 13/14] silence shellcheck --- .github/workflows/reusable-check-html-ids.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/reusable-check-html-ids.yml b/.github/workflows/reusable-check-html-ids.yml index c45d66bccd5063..4b1420d3b95b8e 100644 --- a/.github/workflows/reusable-check-html-ids.yml +++ b/.github/workflows/reusable-check-html-ids.yml @@ -51,7 +51,8 @@ jobs: name: html-ids-head.json.gz path: /tmp - name: 'Check for removed HTML IDs' - run: >- - python Doc/tools/check-html-ids.py -v check - /tmp/html-ids-base.json.gz /tmp/html-ids-head.json.gz - $([ -f Doc/tools/removed-ids.txt ] && echo "--exclude-file Doc/tools/removed-ids.txt") + run: | + # shellcheck disable=SC2046 + python Doc/tools/check-html-ids.py -v check \ + /tmp/html-ids-base.json.gz /tmp/html-ids-head.json.gz \ + $([ -f Doc/tools/removed-ids.txt ] && echo "--exclude-file Doc/tools/removed-ids.txt") From c4cf4a8285dcde0656f5653865ae0b3834b29818 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Tue, 31 Mar 2026 16:50:07 +0200 Subject: [PATCH 14/14] Move checkout ot workspace --- .github/workflows/reusable-check-html-ids.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/reusable-check-html-ids.yml b/.github/workflows/reusable-check-html-ids.yml index 4b1420d3b95b8e..47a2e25de3624f 100644 --- a/.github/workflows/reusable-check-html-ids.yml +++ b/.github/workflows/reusable-check-html-ids.yml @@ -38,11 +38,11 @@ jobs: Doc/tools/check-html-ids.py Doc/tools/removed-ids.txt sparse-checkout-cone-mode: false - path: /tmp/tools + path: pr-head - name: 'Use PR head tools' run: | - cp /tmp/tools/Doc/tools/check-html-ids.py Doc/tools/check-html-ids.py - [ -f /tmp/tools/Doc/tools/removed-ids.txt ] && cp /tmp/tools/Doc/tools/removed-ids.txt Doc/tools/removed-ids.txt + cp pr-head/Doc/tools/check-html-ids.py Doc/tools/check-html-ids.py + [ -f pr-head/Doc/tools/removed-ids.txt ] && cp pr-head/Doc/tools/removed-ids.txt Doc/tools/removed-ids.txt - name: 'Collect HTML IDs' run: python Doc/tools/check-html-ids.py collect Doc/build/html -o /tmp/html-ids-base.json.gz - name: 'Download PR head HTML IDs'