Skip to content

Commit f9704f1

Browse files
gh-84232: Fix pydoc docs.python.org link generation (#139995)
Co-authored-by: Éric <[email protected]>
1 parent a273bc9 commit f9704f1

File tree

8 files changed

+396
-8
lines changed

8 files changed

+396
-8
lines changed

.gitattributes

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ Include/opcode.h generated
8383
Include/opcode_ids.h generated
8484
Include/token.h generated
8585
Lib/_opcode_metadata.py generated
86-
Lib/keyword.py generated
8786
Lib/idlelib/help.html generated
87+
Lib/keyword.py generated
88+
Lib/pydoc_data/topics.py generated
89+
Lib/pydoc_data/module_docs.py generated
8890
Lib/test/certdata/*.pem generated
8991
Lib/test/certdata/*.0 generated
9092
Lib/test/levenshtein_examples.json generated

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ repos:
4040
files: ^Apple
4141
- id: ruff-format
4242
name: Run Ruff (format) on Doc/
43-
args: [--check]
43+
args: [--exit-non-zero-on-fix]
4444
files: ^Doc/
4545
- id: ruff-format
4646
name: Run Ruff (format) on Tools/build/check_warnings.py
47-
args: [--check, --config=Tools/build/.ruff.toml]
47+
args: [--exit-non-zero-on-fix, --config=Tools/build/.ruff.toml]
4848
files: ^Tools/build/check_warnings.py
4949
- id: ruff-format
5050
name: Run Ruff (format) on Tools/wasm/
51-
args: [--check, --config=Tools/wasm/.ruff.toml]
51+
args: [--exit-non-zero-on-fix, --config=Tools/wasm/.ruff.toml]
5252
files: ^Tools/wasm/
5353

5454
- repo: https://github.com/psf/black-pre-commit-mirror

Doc/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ doctest:
140140
pydoc-topics: BUILDER = pydoc-topics
141141
pydoc-topics: build
142142
@echo "Building finished; now run this:" \
143-
"cp build/pydoc-topics/topics.py ../Lib/pydoc_data/topics.py"
143+
"cp build/pydoc-topics/topics.py ../Lib/pydoc_data/topics.py" \
144+
"&& cp build/pydoc-topics/module_docs.py ../Lib/pydoc_data/module_docs.py"
144145

145146
.PHONY: gettext
146147
gettext: BUILDER = gettext

Doc/tools/extensions/pydoc_topics.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class PydocTopicsBuilder(TextBuilder):
109109
def init(self) -> None:
110110
super().init()
111111
self.topics: dict[str, str] = {}
112+
self.module_docs: dict[str, str] = {}
112113

113114
def get_outdated_docs(self) -> str:
114115
# Return a string describing what an update build will build.
@@ -130,6 +131,15 @@ def write_documents(self, _docnames: Set[str]) -> None:
130131
continue
131132
doc_labels.setdefault(docname, []).append((topic_label, label_id))
132133

134+
py_domain = env.domains['py']
135+
for module_name, module_info in py_domain.data['modules'].items():
136+
docname = module_info[0]
137+
if docname.startswith('library/'):
138+
doc_file = docname.replace('library/', '')
139+
self.module_docs[module_name] = (
140+
f"{doc_file}#module-{module_name}"
141+
)
142+
133143
for docname, label_ids in status_iterator(
134144
doc_labels.items(),
135145
"building topics... ",
@@ -161,6 +171,22 @@ def finish(self) -> None:
161171
"""
162172
self.outdir.joinpath("topics.py").write_text(topics, encoding="utf-8")
163173

174+
module_docs_repr = "\n".join(
175+
f" '{module}': '{doc_file}',"
176+
for module, doc_file in sorted(self.module_docs.items())
177+
)
178+
module_docs = f"""\
179+
# Autogenerated by Sphinx on {asctime()}
180+
# as part of the release process.
181+
182+
module_docs = {{
183+
{module_docs_repr}
184+
}}
185+
"""
186+
self.outdir.joinpath("module_docs.py").write_text(
187+
module_docs, encoding="utf-8"
188+
)
189+
164190

165191
def _display_labels(item: tuple[str, Sequence[tuple[str, str]]]) -> str:
166192
_docname, label_ids = item

Lib/pydoc.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,10 +483,20 @@ def getdocloc(self, object, basedir=None):
483483

484484
if (self._is_stdlib_module(object, basedir) and
485485
object.__name__ not in ('xml.etree', 'test.test_pydoc.pydoc_mod')):
486-
if docloc.startswith(("http://", "https://")):
487-
docloc = "{}/{}.html".format(docloc.rstrip("/"), object.__name__.lower())
486+
487+
try:
488+
from pydoc_data import module_docs
489+
except ImportError:
490+
module_docs = None
491+
492+
if module_docs and object.__name__ in module_docs.module_docs:
493+
doc_name = module_docs.module_docs[object.__name__]
494+
if docloc.startswith(("http://", "https://")):
495+
docloc = "{}/{}".format(docloc.rstrip("/"), doc_name)
496+
else:
497+
docloc = os.path.join(docloc, doc_name)
488498
else:
489-
docloc = os.path.join(docloc, object.__name__.lower() + ".html")
499+
docloc = None
490500
else:
491501
docloc = None
492502
return docloc

0 commit comments

Comments
 (0)