| """Support for referencing issues in the tracker.""" | |
| from __future__ import annotations | |
| from typing import TYPE_CHECKING | |
| from docutils import nodes | |
| from sphinx.util.docutils import SphinxRole | |
| if TYPE_CHECKING: | |
| from docutils.nodes import Element | |
| from sphinx.application import Sphinx | |
| from sphinx.util.typing import ExtensionMetadata | |
| 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", BPOIssue()) | |
| app.add_role("gh", GitHubIssue()) | |
| return { | |
| "version": "1.0", | |
| "parallel_read_safe": True, | |
| "parallel_write_safe": True, | |
| } |