Skip to content

Commit

Permalink
pythonGH-121970: Extract changes into a new extension (pythonGH-1…
Browse files Browse the repository at this point in the history
…29105)

(cherry picked from commit e54ac3b)

Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
  • Loading branch information
AA-Turner authored and miss-islington committed Jan 20, 2025
1 parent 9b335cc commit c03abbd
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 57 deletions.
1 change: 1 addition & 0 deletions Doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
'audit_events',
'availability',
'c_annotations',
'changes',
'glossary_search',
'lexers',
'pyspecific',
Expand Down
90 changes: 90 additions & 0 deletions Doc/tools/extensions/changes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
"""Support for documenting version of changes, additions, deprecations."""

from __future__ import annotations

from typing import TYPE_CHECKING

from sphinx.domains.changeset import (
VersionChange,
versionlabel_classes,
versionlabels,
)
from sphinx.locale import _ as sphinx_gettext

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


def expand_version_arg(argument: str, release: str) -> str:
"""Expand "next" to the current version"""
if argument == "next":
return sphinx_gettext("{} (unreleased)").format(release)
return argument


class PyVersionChange(VersionChange):
def run(self) -> list[Node]:
# Replace the 'next' special token with the current development version
self.arguments[0] = expand_version_arg(
self.arguments[0], self.config.release
)
return super().run()


class DeprecatedRemoved(VersionChange):
required_arguments = 2

_deprecated_label = sphinx_gettext(
"Deprecated since version %s, will be removed in version %s"
)
_removed_label = sphinx_gettext(
"Deprecated since version %s, removed in version %s"
)

def run(self) -> list[Node]:
# Replace the first two arguments (deprecated version and removed version)
# with a single tuple of both versions.
version_deprecated = expand_version_arg(
self.arguments[0], self.config.release
)
version_removed = self.arguments.pop(1)
if version_removed == "next":
raise ValueError(
"deprecated-removed:: second argument cannot be `next`"
)
self.arguments[0] = version_deprecated, version_removed

# Set the label based on if we have reached the removal version
current_version = tuple(map(int, self.config.version.split(".")))
removed_version = tuple(map(int, version_removed.split(".")))
if current_version < removed_version:
versionlabels[self.name] = self._deprecated_label
versionlabel_classes[self.name] = "deprecated"
else:
versionlabels[self.name] = self._removed_label
versionlabel_classes[self.name] = "removed"
try:
return super().run()
finally:
# reset versionlabels and versionlabel_classes
versionlabels[self.name] = ""
versionlabel_classes[self.name] = ""


def setup(app: Sphinx) -> ExtensionMetadata:
# Override Sphinx's directives with support for 'next'
app.add_directive("versionadded", PyVersionChange, override=True)
app.add_directive("versionchanged", PyVersionChange, override=True)
app.add_directive("versionremoved", PyVersionChange, override=True)
app.add_directive("deprecated", PyVersionChange, override=True)

# Register the ``.. deprecated-removed::`` directive
app.add_directive("deprecated-removed", DeprecatedRemoved)

return {
"version": "1.0",
"parallel_read_safe": True,
"parallel_write_safe": True,
}
57 changes: 0 additions & 57 deletions Doc/tools/extensions/pyspecific.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from docutils.utils import new_document, unescape
from sphinx import addnodes
from sphinx.builders import Builder
from sphinx.domains.changeset import VersionChange, versionlabels, versionlabel_classes
from sphinx.domains.python import PyFunction, PyMethod, PyModule
from sphinx.locale import _ as sphinx_gettext
from sphinx.util.docutils import SphinxDirective
Expand Down Expand Up @@ -184,57 +183,6 @@ def run(self):
return PyMethod.run(self)


# Support for documenting version of changes, additions, deprecations

def expand_version_arg(argument, release):
"""Expand "next" to the current version"""
if argument == 'next':
return sphinx_gettext('{} (unreleased)').format(release)
return argument


class PyVersionChange(VersionChange):
def run(self):
# Replace the 'next' special token with the current development version
self.arguments[0] = expand_version_arg(self.arguments[0],
self.config.release)
return super().run()


class DeprecatedRemoved(VersionChange):
required_arguments = 2

_deprecated_label = sphinx_gettext('Deprecated since version %s, will be removed in version %s')
_removed_label = sphinx_gettext('Deprecated since version %s, removed in version %s')

def run(self):
# Replace the first two arguments (deprecated version and removed version)
# with a single tuple of both versions.
version_deprecated = expand_version_arg(self.arguments[0],
self.config.release)
version_removed = self.arguments.pop(1)
if version_removed == 'next':
raise ValueError(
'deprecated-removed:: second argument cannot be `next`')
self.arguments[0] = version_deprecated, version_removed

# Set the label based on if we have reached the removal version
current_version = tuple(map(int, self.config.version.split('.')))
removed_version = tuple(map(int, version_removed.split('.')))
if current_version < removed_version:
versionlabels[self.name] = self._deprecated_label
versionlabel_classes[self.name] = 'deprecated'
else:
versionlabels[self.name] = self._removed_label
versionlabel_classes[self.name] = 'removed'
try:
return super().run()
finally:
# reset versionlabels and versionlabel_classes
versionlabels[self.name] = ''
versionlabel_classes[self.name] = ''


# Support for including Misc/NEWS

issue_re = re.compile('(?:[Ii]ssue #|bpo-)([0-9]+)', re.I)
Expand Down Expand Up @@ -417,11 +365,6 @@ def setup(app):
app.add_role('issue', issue_role)
app.add_role('gh', gh_issue_role)
app.add_directive('impl-detail', ImplementationDetail)
app.add_directive('versionadded', PyVersionChange, override=True)
app.add_directive('versionchanged', PyVersionChange, override=True)
app.add_directive('versionremoved', PyVersionChange, override=True)
app.add_directive('deprecated', PyVersionChange, override=True)
app.add_directive('deprecated-removed', DeprecatedRemoved)
app.add_builder(PydocTopicsBuilder)
app.add_object_type('opcode', 'opcode', '%s (opcode)', parse_opcode_signature)
app.add_object_type('pdbcommand', 'pdbcmd', '%s (pdb command)', parse_pdb_command)
Expand Down

0 comments on commit c03abbd

Please sign in to comment.