'changes',
'glossary_search',
'lexers',
+ 'misc_news',
'pyspecific',
'sphinx.ext.coverage',
'sphinx.ext.doctest',
:build
if not exist "%BUILDDIR%" mkdir "%BUILDDIR%"
-rem PY_MISC_NEWS_DIR is also used by our Sphinx extension in tools/extensions/pyspecific.py
-if not defined PY_MISC_NEWS_DIR set PY_MISC_NEWS_DIR=%BUILDDIR%\%1
-if not exist "%PY_MISC_NEWS_DIR%" mkdir "%PY_MISC_NEWS_DIR%"
+if not exist build mkdir build
if exist ..\Misc\NEWS (
- echo.Copying Misc\NEWS to %PY_MISC_NEWS_DIR%\NEWS
- copy ..\Misc\NEWS "%PY_MISC_NEWS_DIR%\NEWS" > nul
+ echo.Copying existing Misc\NEWS file to Doc\build\NEWS
+ copy ..\Misc\NEWS build\NEWS > nul
) else if exist ..\Misc\NEWS.D (
if defined BLURB (
echo.Merging Misc/NEWS with %BLURB%
- %BLURB% merge -f "%PY_MISC_NEWS_DIR%\NEWS"
+ %BLURB% merge -f build\NEWS
) else (
echo.No Misc/NEWS file and Blurb is not available.
exit /B 1
--- /dev/null
+"""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,
+ }
return PyMethod.run(self)
-# Support for including Misc/NEWS
-
-issue_re = re.compile('(?:[Ii]ssue #|bpo-)([0-9]+)', re.I)
-gh_issue_re = re.compile('(?:gh-issue-|gh-)([0-9]+)', re.I)
-whatsnew_re = re.compile(r"(?im)^what's new in (.*?)\??$")
-
-
-class MiscNews(SphinxDirective):
- has_content = False
- required_arguments = 1
- optional_arguments = 0
- final_argument_whitespace = False
- option_spec = {}
-
- def run(self):
- fname = self.arguments[0]
- source = self.state_machine.input_lines.source(
- self.lineno - self.state_machine.input_offset - 1)
- source_dir = getenv('PY_MISC_NEWS_DIR')
- if not source_dir:
- source_dir = path.dirname(path.abspath(source))
- fpath = path.join(source_dir, fname)
- self.env.note_dependency(path.abspath(fpath))
- try:
- with io.open(fpath, encoding='utf-8') as fp:
- content = fp.read()
- except Exception:
- text = 'The NEWS file is not available.'
- node = nodes.strong(text, text)
- return [node]
- content = issue_re.sub(r':issue:`\1`', content)
- # Fallback handling for the GitHub issue
- content = gh_issue_re.sub(r':gh:`\1`', content)
- content = whatsnew_re.sub(r'\1', content)
- # remove first 3 lines as they are the main heading
- lines = ['.. default-role:: obj', ''] + content.splitlines()[3:]
- self.state_machine.insert_input(lines, fname)
- return []
-
-
# Support for building "topic help" for pydoc
pydoc_topic_labels = [
app.add_directive_to_domain('py', 'awaitablefunction', PyAwaitableFunction)
app.add_directive_to_domain('py', 'awaitablemethod', PyAwaitableMethod)
app.add_directive_to_domain('py', 'abstractmethod', PyAbstractMethod)
- app.add_directive('miscnews', MiscNews)
app.connect('env-check-consistency', patch_pairindextypes)
return {'version': '1.0', 'parallel_read_safe': True}
.. _changelog:
+.. default-role:: py:obj
+
+++++++++
Changelog
+++++++++
.. section: Library
A new version of typing.py from https://github.com/python/typing:
-Collection (only for 3.6) (Issue #27598). Add FrozenSet to __all__
+Collection (only for 3.6) (issue #27598). Add FrozenSet to __all__
(upstream #261). Fix crash in _get_type_vars() (upstream #259). Remove the
dict constraint in ForwardRef._eval_type (upstream #252).
.. section: Library
Prevent segfault after interpreter re-initialization due to ref count
-problem introduced in code for Issue #27038 in 3.6.0a3. Patch by Xiang
+problem introduced in code for issue #27038 in 3.6.0a3. Patch by Xiang
Zhang.
..
.. section: Library
A new version of typing.py from https://github.com/python/typing: -
-Collection (only for 3.6) (Issue #27598) - Add FrozenSet to __all__
+Collection (only for 3.6) (issue #27598) - Add FrozenSet to __all__
(upstream #261) - fix crash in _get_type_vars() (upstream #259) - Remove the
dict constraint in ForwardRef._eval_type (upstream #252)