Skip to content

Commit 5b2f898

Browse files
authored
Fix Python 3.15 doc generation and add artifact-only mode (#9285)
Use inspect's raw own-doc helper on Python 3.15, retaining the old pydoc helper for earlier versions. Separate artifact generation from repository publication, with an explicit main-only artifact mode. Assisted-by: OpenAI Codex:model-version-unavailable
1 parent 4bd4320 commit 5b2f898

2 files changed

Lines changed: 57 additions & 14 deletions

File tree

‎.github/workflows/update-doc-db.yml‎

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ on:
1313
description: Base branch to create the update branch from
1414
type: string
1515
default: "main"
16+
artifact-only:
17+
description: Generate artifacts from main without pushing or creating a PR
18+
type: boolean
19+
default: false
1620

1721
defaults:
1822
run:
@@ -30,9 +34,20 @@ jobs:
3034
- windows-latest
3135
- macos-latest
3236
steps:
37+
- name: Validate artifact-only source
38+
if: ${{ inputs.artifact-only }}
39+
env:
40+
BASE_REF: ${{ inputs.base-ref }}
41+
run: |
42+
if [ "$GITHUB_REF" != "refs/heads/main" ] || [ "$BASE_REF" != "main" ]; then
43+
echo 'Artifact-only generation requires the main workflow ref and main base.' >&2
44+
exit 1
45+
fi
46+
3347
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
3448
with:
3549
persist-credentials: false
50+
ref: ${{ github.sha }}
3651
sparse-checkout: |
3752
crates/doc
3853
@@ -54,19 +69,19 @@ jobs:
5469
merge:
5570
runs-on: ubuntu-latest
5671
needs: generate
72+
outputs:
73+
base-sha: ${{ steps.base.outputs.sha }}
5774
permissions:
58-
contents: write
59-
pull-requests: write
75+
contents: read
6076
steps:
6177
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
6278
with:
63-
persist-credentials: true
64-
ref: ${{ inputs.base-ref }}
79+
persist-credentials: false
80+
ref: ${{ inputs.artifact-only && github.sha || inputs.base-ref }}
6581

66-
- name: Create update branch
67-
run: git switch -c "update-doc-${PYTHON_VERSION}"
68-
env:
69-
PYTHON_VERSION: ${{ inputs.python-version }}
82+
- name: Record merge base
83+
id: base
84+
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
7085

7186
- name: Download generated doc DBs
7287
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
@@ -107,6 +122,30 @@ jobs:
107122
retention-days: 7
108123
overwrite: true
109124

125+
publish:
126+
if: ${{ !inputs.artifact-only }}
127+
runs-on: ubuntu-latest
128+
needs: merge
129+
permissions:
130+
contents: write
131+
pull-requests: write
132+
steps:
133+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
134+
with:
135+
persist-credentials: true
136+
ref: ${{ needs.merge.outputs.base-sha }}
137+
138+
- name: Create update branch
139+
run: git switch -c "update-doc-${PYTHON_VERSION}"
140+
env:
141+
PYTHON_VERSION: ${{ inputs.python-version }}
142+
143+
- name: Download merged doc DB
144+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
145+
with:
146+
name: doc-db-${{ inputs.python-version }}
147+
path: crates/doc/src/
148+
110149
- name: Commit, push and create PR
111150
env:
112151
GH_TOKEN: ${{ github.token }}

‎crates/doc/generate.py‎

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@
66
import os
77
import pathlib
88
import platform
9-
import pydoc
109
import re
1110
import sys
1211
import types
1312
import typing
1413
import warnings
1514
from importlib.machinery import EXTENSION_SUFFIXES, ExtensionFileLoader
1615

16+
try:
17+
from inspect import _getowndoc
18+
except ImportError: # Python 3.14 and earlier
19+
from pydoc import _getowndoc
20+
1721
if typing.TYPE_CHECKING:
1822
from collections.abc import Iterable
1923

@@ -146,7 +150,7 @@ def traverse(
146150
parts += (obj.__name__,)
147151

148152
if any(f(obj) for f in (inspect.ismodule, inspect.isclass, inspect.isbuiltin)):
149-
yield DocEntry(parts, pydoc._getowndoc(obj))
153+
yield DocEntry(parts, _getowndoc(obj))
150154

151155
if inspect.isclass(obj):
152156
# getmembers() shows the class's own metadata for these names (e.g.
@@ -159,7 +163,7 @@ def traverse(
159163
if isinstance(
160164
attr, (types.GetSetDescriptorType, types.MemberDescriptorType)
161165
):
162-
yield DocEntry(parts + (name,), pydoc._getowndoc(attr))
166+
yield DocEntry(parts + (name,), _getowndoc(attr))
163167

164168
for name, attr in inspect.getmembers(obj):
165169
if name in IGNORED_ATTRS:
@@ -211,7 +215,7 @@ def traverse(
211215
)
212216

213217
if is_callable or is_func:
214-
yield DocEntry(new_parts, pydoc._getowndoc(attr))
218+
yield DocEntry(new_parts, _getowndoc(attr))
215219
# A native type the module exposes only through an instance
216220
# (e.g. the type of sys.flags).
217221
if (
@@ -283,7 +287,7 @@ def iter_native_on_python_modules(
283287
if inspect.isclass(attr):
284288
yield from traverse(attr, module, parts)
285289
else:
286-
yield DocEntry(parts, pydoc._getowndoc(attr))
290+
yield DocEntry(parts, _getowndoc(attr))
287291

288292

289293
def find_doc_entries() -> "Iterable[DocEntry]":
@@ -322,7 +326,7 @@ def find_doc_entries() -> "Iterable[DocEntry]":
322326
module_names.append(typ.__module__)
323327
for module_name in module_names:
324328
parts = (module_name, typ.__name__)
325-
yield DocEntry(parts, pydoc._getowndoc(typ))
329+
yield DocEntry(parts, _getowndoc(typ))
326330
yield from traverse(typ, __builtins__, parts)
327331

328332

0 commit comments

Comments
 (0)