File: misc_news.py

package info (click to toggle)
python3.14 3.14.0~rc1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 126,824 kB
  • sloc: python: 745,274; ansic: 713,752; xml: 31,250; sh: 5,822; cpp: 4,063; makefile: 1,988; objc: 787; lisp: 502; javascript: 136; asm: 75; csh: 12
file content (75 lines) | stat: -rw-r--r-- 2,116 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
"""Support for including Misc/NEWS."""

from __future__ import annotations

import re
from pathlib import Path
from typing import TYPE_CHECKING

from docutils import nodes
from sphinx.locale import _ as sphinx_gettext
from sphinx.util.docutils import SphinxDirective

if TYPE_CHECKING:
    from typing import Final

    from docutils.nodes import Node
    from sphinx.application import Sphinx
    from sphinx.util.typing import ExtensionMetadata


BLURB_HEADER = """\
+++++++++++
Python News
+++++++++++
"""

bpo_issue_re: Final[re.Pattern[str]] = re.compile(
    "(?:issue #|bpo-)([0-9]+)", re.ASCII
)
gh_issue_re: Final[re.Pattern[str]] = re.compile(
    "gh-(?:issue-)?([0-9]+)", re.ASCII | re.IGNORECASE
)
whatsnew_re: Final[re.Pattern[str]] = re.compile(
    r"^what's new in (.*?)\??$", re.ASCII | re.IGNORECASE | re.MULTILINE
)


class MiscNews(SphinxDirective):
    has_content = False
    required_arguments = 1
    optional_arguments = 0
    final_argument_whitespace = False
    option_spec = {}

    def run(self) -> list[Node]:
        # Get content of NEWS file
        source, _ = self.get_source_info()
        news_file = Path(source).resolve().parent / self.arguments[0]
        self.env.note_dependency(news_file)
        try:
            news_text = news_file.read_text(encoding="utf-8")
        except (OSError, UnicodeError):
            text = sphinx_gettext("The NEWS file is not available.")
            return [nodes.strong(text, text)]

        # remove first 3 lines as they are the main heading
        news_text = news_text.removeprefix(BLURB_HEADER)

        news_text = bpo_issue_re.sub(r":issue:`\1`", news_text)
        # Fallback handling for GitHub issues
        news_text = gh_issue_re.sub(r":gh:`\1`", news_text)
        news_text = whatsnew_re.sub(r"\1", news_text)

        self.state_machine.insert_input(news_text.splitlines(), str(news_file))
        return []


def setup(app: Sphinx) -> ExtensionMetadata:
    app.add_directive("miscnews", MiscNews)

    return {
        "version": "1.0",
        "parallel_read_safe": True,
        "parallel_write_safe": True,
    }