From dd80b62905c3a1890948b861256b32b8549c10bc Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Wed, 26 Feb 2025 22:18:25 +0000 Subject: [PATCH 1/5] Extract ``issue_role`` into a new extension --- Doc/conf.py | 1 + Doc/tools/extensions/issue_role.py | 82 ++++++++++++++++++++++++++++++ Doc/tools/extensions/pyspecific.py | 32 ------------ 3 files changed, 83 insertions(+), 32 deletions(-) create mode 100644 Doc/tools/extensions/issue_role.py diff --git a/Doc/conf.py b/Doc/conf.py index 64d627bc41e6af..19538fe058ba2b 100644 --- a/Doc/conf.py +++ b/Doc/conf.py @@ -30,6 +30,7 @@ 'glossary_search', 'grammar_snippet', 'implementation_detail', + 'issue_role', 'lexers', 'misc_news', 'pydoc_topics', diff --git a/Doc/tools/extensions/issue_role.py b/Doc/tools/extensions/issue_role.py new file mode 100644 index 00000000000000..d6ae5929df8646 --- /dev/null +++ b/Doc/tools/extensions/issue_role.py @@ -0,0 +1,82 @@ +"""Support for marking up and linking to the issues in the tracker.""" + +from __future__ import annotations + +from collections.abc import Sequence +from typing import TYPE_CHECKING + +from docutils import nodes +from docutils.parsers.rst.states import Inliner +from docutils.utils import unescape + + +if TYPE_CHECKING: + from typing import Any + + from docutils.nodes import Node + from sphinx.application import Sphinx + from sphinx.util.typing import ExtensionMetadata + + +ISSUE_URI = "https://bugs.python.org/issue?@action=redirect&bpo=%s" +GH_ISSUE_URI = "https://github.com/python/cpython/issues/%s" + + +def issue_role( + typ: str, + rawtext: str, + text: str, + lineno: int, + inliner: Inliner, + options: dict[str, Any] = {}, + content: Sequence[str] = [], +) -> tuple[list[Node], list[nodes.system_message]]: + issue = unescape(text) + # sanity check: there are no bpo issues within these two values + if 47261 < int(issue) < 400000: + msg = inliner.reporter.error( + f"The BPO ID {text!r} seems too high -- " + "use :gh:`...` for GitHub IDs", + line=lineno, + ) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + text = "bpo-" + issue + refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue) + return [refnode], [] + + +def gh_issue_role( + typ: str, + rawtext: str, + text: str, + lineno: int, + inliner: Inliner, + options: dict[str, Any] = {}, + content: Sequence[str] = [], +) -> tuple[list[Node], list[nodes.system_message]]: + issue = unescape(text) + # sanity check: all GitHub issues have ID >= 32426 + # even though some of them are also valid BPO IDs + if int(issue) < 32426: + msg = inliner.reporter.error( + f"The GitHub ID {text!r} seems too low -- " + "use :issue:`...` for BPO IDs", + line=lineno, + ) + prb = inliner.problematic(rawtext, rawtext, msg) + return [prb], [msg] + text = "gh-" + issue + refnode = nodes.reference(text, text, refuri=GH_ISSUE_URI % issue) + return [refnode], [] + + +def setup(app: Sphinx) -> ExtensionMetadata: + app.add_role("issue", issue_role) + app.add_role("gh", gh_issue_role) + + return { + "version": "1.0", + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 68247d40f682d1..1e61e2518a4fe8 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -34,36 +34,6 @@ Body.enum.converters['lowerroman'] = \ Body.enum.converters['upperroman'] = lambda x: None -# Support for marking up and linking to bugs.python.org issues - -def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): - issue = unescape(text) - # sanity check: there are no bpo issues within these two values - if 47261 < int(issue) < 400000: - msg = inliner.reporter.error(f'The BPO ID {text!r} seems too high -- ' - 'use :gh:`...` for GitHub IDs', line=lineno) - prb = inliner.problematic(rawtext, rawtext, msg) - return [prb], [msg] - text = 'bpo-' + issue - refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue) - return [refnode], [] - - -# Support for marking up and linking to GitHub issues - -def gh_issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): - issue = unescape(text) - # sanity check: all GitHub issues have ID >= 32426 - # even though some of them are also valid BPO IDs - if int(issue) < 32426: - msg = inliner.reporter.error(f'The GitHub ID {text!r} seems too low -- ' - 'use :issue:`...` for BPO IDs', line=lineno) - prb = inliner.problematic(rawtext, rawtext, msg) - return [prb], [msg] - text = 'gh-' + issue - refnode = nodes.reference(text, text, refuri=GH_ISSUE_URI % issue) - return [refnode], [] - class PyAwaitableMixin(object): def handle_signature(self, sig, signode): @@ -160,8 +130,6 @@ def patch_pairindextypes(app, _env) -> None: def setup(app): - app.add_role('issue', issue_role) - app.add_role('gh', gh_issue_role) app.add_object_type('opcode', 'opcode', '%s (opcode)', parse_opcode_signature) app.add_object_type('pdbcommand', 'pdbcmd', '%s (pdb command)', parse_pdb_command) app.add_object_type('monitoring-event', 'monitoring-event', '%s (monitoring event)', parse_monitoring_event) From 28087ba6c27dbd5507972fa96ce710e24c1e7f80 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Wed, 26 Feb 2025 22:46:48 +0000 Subject: [PATCH 2/5] Convert to SphinxRole --- Doc/tools/extensions/issue_role.py | 109 +++++++++++++---------------- 1 file changed, 48 insertions(+), 61 deletions(-) diff --git a/Doc/tools/extensions/issue_role.py b/Doc/tools/extensions/issue_role.py index d6ae5929df8646..302ed7f34153a6 100644 --- a/Doc/tools/extensions/issue_role.py +++ b/Doc/tools/extensions/issue_role.py @@ -1,79 +1,66 @@ -"""Support for marking up and linking to the issues in the tracker.""" +"""Support for referencing issues in the tracker.""" from __future__ import annotations -from collections.abc import Sequence from typing import TYPE_CHECKING from docutils import nodes -from docutils.parsers.rst.states import Inliner -from docutils.utils import unescape - +from sphinx.util.docutils import SphinxRole if TYPE_CHECKING: - from typing import Any - - from docutils.nodes import Node + from docutils.nodes import Element from sphinx.application import Sphinx from sphinx.util.typing import ExtensionMetadata -ISSUE_URI = "https://bugs.python.org/issue?@action=redirect&bpo=%s" -GH_ISSUE_URI = "https://github.com/python/cpython/issues/%s" - - -def issue_role( - typ: str, - rawtext: str, - text: str, - lineno: int, - inliner: Inliner, - options: dict[str, Any] = {}, - content: Sequence[str] = [], -) -> tuple[list[Node], list[nodes.system_message]]: - issue = unescape(text) - # sanity check: there are no bpo issues within these two values - if 47261 < int(issue) < 400000: - msg = inliner.reporter.error( - f"The BPO ID {text!r} seems too high -- " - "use :gh:`...` for GitHub IDs", - line=lineno, - ) - prb = inliner.problematic(rawtext, rawtext, msg) - return [prb], [msg] - text = "bpo-" + issue - refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue) - return [refnode], [] - - -def gh_issue_role( - typ: str, - rawtext: str, - text: str, - lineno: int, - inliner: Inliner, - options: dict[str, Any] = {}, - content: Sequence[str] = [], -) -> tuple[list[Node], list[nodes.system_message]]: - issue = unescape(text) - # sanity check: all GitHub issues have ID >= 32426 - # even though some of them are also valid BPO IDs - if int(issue) < 32426: - msg = inliner.reporter.error( - f"The GitHub ID {text!r} seems too low -- " - "use :issue:`...` for BPO IDs", - line=lineno, - ) - prb = inliner.problematic(rawtext, rawtext, msg) - return [prb], [msg] - text = "gh-" + issue - refnode = nodes.reference(text, text, refuri=GH_ISSUE_URI % issue) - return [refnode], [] +class BPOIssue(SphinxRole): + ISSUE_URI = "https://bugs.python.org/issue?@action=redirect&bpo={0}" + + def run(self) -> tuple[list[Element], list[nodes.system_message]]: + issue = self.text + + # sanity check: there are no bpo issues within these two values + if 47_261 < int(issue) < 400_000: + msg = self.inliner.reporter.error( + f"The BPO ID {issue!r} seems too high. " + "Use :gh:`...` for GitHub IDs", + line=self.lineno, + ) + prb = self.inliner.problematic(self.rawtext, self.rawtext, msg) + return [prb], [msg] + + issue_url = self.ISSUE_URI.format(issue) + refnode = nodes.reference(issue, f"bpo-{issue}", refuri=issue_url) + self.set_source_info(refnode) + return [refnode], [] + + +class GitHubIssue(SphinxRole): + ISSUE_URI = "https://github.com/python/cpython/issues/{0}" + + def run(self) -> tuple[list[Element], list[nodes.system_message]]: + issue = self.text + + # sanity check: all GitHub issues have ID >= 32426 + # even though some of them are also valid BPO IDs + if int(issue) < 32_426: + msg = self.inliner.reporter.error( + f"The GitHub ID {issue!r} seems too low. " + "Use :issue:`...` for BPO IDs", + line=self.lineno, + ) + prb = self.inliner.problematic(self.rawtext, self.rawtext, msg) + return [prb], [msg] + + issue_url = self.ISSUE_URI.format(issue) + refnode = nodes.reference(issue, f"gh-{issue}", refuri=issue_url) + self.set_source_info(refnode) + return [refnode], [] def setup(app: Sphinx) -> ExtensionMetadata: - app.add_role("issue", issue_role) - app.add_role("gh", gh_issue_role) + app.add_role("issue", BPOIssue()) + app.add_role("gh", GitHubIssue()) return { "version": "1.0", From 0282cf3434ac09d2bb3dfdae9af4dc4feecd2b32 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Wed, 26 Feb 2025 22:54:13 +0000 Subject: [PATCH 3/5] Remove {GH_}ISSUE_URI from `pyspecific` --- Doc/tools/extensions/pyspecific.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py index 1e61e2518a4fe8..f5451adb37b0b4 100644 --- a/Doc/tools/extensions/pyspecific.py +++ b/Doc/tools/extensions/pyspecific.py @@ -21,9 +21,6 @@ from sphinx.locale import _ as sphinx_gettext from sphinx.util.docutils import SphinxDirective - -ISSUE_URI = 'https://bugs.python.org/issue?@action=redirect&bpo=%s' -GH_ISSUE_URI = 'https://github.com/python/cpython/issues/%s' # Used in conf.py and updated here by python/release-tools/run_release.py SOURCE_URI = 'https://github.com/python/cpython/tree/main/%s' From 6fa8680b674bae3fca13690c7c26e26396bc3dbe Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+AA-Turner@users.noreply.github.com> Date: Thu, 27 Feb 2025 14:21:37 +0000 Subject: [PATCH 4/5] Hugo's review Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> --- Doc/tools/extensions/issue_role.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Doc/tools/extensions/issue_role.py b/Doc/tools/extensions/issue_role.py index 302ed7f34153a6..19f1dd78b1161a 100644 --- a/Doc/tools/extensions/issue_role.py +++ b/Doc/tools/extensions/issue_role.py @@ -2,11 +2,10 @@ from __future__ import annotations -from typing import TYPE_CHECKING - from docutils import nodes from sphinx.util.docutils import SphinxRole +TYPE_CHECKING = False if TYPE_CHECKING: from docutils.nodes import Element from sphinx.application import Sphinx @@ -23,7 +22,7 @@ def run(self) -> tuple[list[Element], list[nodes.system_message]]: if 47_261 < int(issue) < 400_000: msg = self.inliner.reporter.error( f"The BPO ID {issue!r} seems too high. " - "Use :gh:`...` for GitHub IDs", + "Use :gh:`...` for GitHub IDs.", line=self.lineno, ) prb = self.inliner.problematic(self.rawtext, self.rawtext, msg) @@ -46,7 +45,7 @@ def run(self) -> tuple[list[Element], list[nodes.system_message]]: if int(issue) < 32_426: msg = self.inliner.reporter.error( f"The GitHub ID {issue!r} seems too low. " - "Use :issue:`...` for BPO IDs", + "Use :issue:`...` for BPO IDs.", line=self.lineno, ) prb = self.inliner.problematic(self.rawtext, self.rawtext, msg) From 3b46c04e48ff936c7812ca8a22ec6e02dfef2c0c Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:58:13 +0000 Subject: [PATCH 5/5] Revert TC=False --- Doc/tools/extensions/issue_role.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/tools/extensions/issue_role.py b/Doc/tools/extensions/issue_role.py index 19f1dd78b1161a..477b3a4b2d23b4 100644 --- a/Doc/tools/extensions/issue_role.py +++ b/Doc/tools/extensions/issue_role.py @@ -2,10 +2,11 @@ from __future__ import annotations +from typing import TYPE_CHECKING + from docutils import nodes from sphinx.util.docutils import SphinxRole -TYPE_CHECKING = False if TYPE_CHECKING: from docutils.nodes import Element from sphinx.application import Sphinx