Use hyphenated version directives (#13714)

Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
This commit is contained in:
Stephen FinucaneandAdam Turner authored and GitHub committed 2025-10-06 00:10:35 +01:00
1 parent 42aa5114ba
commit 44a98961b2
13 files changed
+172 -65

No files matched your search

+36 -16
View File
@@ -537,7 +537,8 @@ Describing changes between versions
pair: changes; in version pair: changes; in version
pair: removed; in version pair: removed; in version
.. rst:directive:: .. versionadded:: version [brief explanation] .. rst:directive:: .. version-added:: version [brief explanation]
.. versionadded:: version [brief explanation]
This directive documents the version of the project This directive documents the version of the project
which added the described feature. which added the described feature.
@@ -551,56 +552,75 @@ Describing changes between versions
There must be no blank line between the directive head and the explanation; There must be no blank line between the directive head and the explanation;
this is to make these blocks visually continuous in the markup. this is to make these blocks visually continuous in the markup.
.. version-changed:: 8.3
The :rst:dir:`versionadded` directive was renamed to :rst:dir:`version-added`.
The previous name is retained as an alias.
Example:: Example::
.. versionadded:: 2.5 .. version-added:: 2.5
The *spam* parameter. The *spam* parameter.
.. versionadded:: 2.5 .. version-added:: 2.5
The *spam* parameter. The *spam* parameter.
.. rst:directive:: .. versionchanged:: version [brief explanation] .. rst:directive:: .. version-changed:: version [brief explanation]
.. versionchanged:: version [brief explanation]
Similar to :rst:dir:`versionadded`, but describes when and what changed in Similar to :rst:dir:`version-added`, but describes when and what changed in
the named feature in some way (new parameters, changed side effects, etc.). the named feature in some way (new parameters, changed side effects, etc.).
.. version-changed:: 8.3
The :rst:dir:`versionchanged` directive was renamed to :rst:dir:`version-changed`.
The previous name is retained as an alias.
Example:: Example::
.. versionchanged:: 2.8 .. version-changed:: 2.8
The *spam* parameter is now of type *boson*. The *spam* parameter is now of type *boson*.
.. versionchanged:: 2.8 .. version-changed:: 2.8
The *spam* parameter is now of type *boson*. The *spam* parameter is now of type *boson*.
.. rst:directive:: .. deprecated:: version [brief explanation] .. rst:directive:: .. version-deprecated:: version [brief explanation]
.. deprecated:: version [brief explanation]
Similar to :rst:dir:`versionadded`, but describes when the feature was Similar to :rst:dir:`version-added`, but describes when the feature was
deprecated. deprecated.
A *brief* explanation can also be given, A *brief* explanation can also be given,
for example to tell the reader what to use instead. for example to tell the reader what to use instead.
.. version-changed:: 8.3
The :rst:dir:`deprecated` directive was renamed to :rst:dir:`version-deprecated`.
The previous name is retained as an alias
Example:: Example::
.. deprecated:: 3.1 .. version-deprecated:: 3.1
Use :py:func:`spam` instead. Use :py:func:`spam` instead.
.. deprecated:: 3.1 .. version-deprecated:: 3.1
Use :py:func:`!spam` instead. Use :py:func:`!spam` instead.
.. rst:directive:: .. versionremoved:: version [brief explanation] .. rst:directive:: .. version-removed:: version [brief explanation]
.. versionremoved:: version [brief explanation]
Similar to :rst:dir:`versionadded`, but describes when the feature was removed. Similar to :rst:dir:`version-added`, but describes when the feature was removed.
An explanation may be provided to tell the reader what to use instead, An explanation may be provided to tell the reader what to use instead,
or why the feature was removed. or why the feature was removed.
.. versionadded:: 7.3 .. version-added:: 7.3
.. version-changed:: 8.3
The :rst:dir:`versionremoved` directive was renamed to :rst:dir:`version-removed`.
The previous name is retained as an alias.
Example:: Example::
.. versionremoved:: 4.0 .. version-removed:: 4.0
The :py:func:`spam` function is more flexible, and should be used instead. The :py:func:`spam` function is more flexible, and should be used instead.
.. versionremoved:: 4.0 .. version-removed:: 4.0
The :py:func:`!spam` function is more flexible, and should be used instead. The :py:func:`!spam` function is more flexible, and should be used instead.
+2 -2
View File
@@ -402,8 +402,8 @@ class desc_sig_literal_char(desc_sig_element, _sig_element=True):
class versionmodified(nodes.Admonition, nodes.TextElement): class versionmodified(nodes.Admonition, nodes.TextElement):
"""Node for version change entries. """Node for version change entries.
Currently used for "versionadded", "versionchanged", "deprecated" Currently used for "version-added", "version-changed", "version-deprecated"
and "versionremoved" directives. and "version-removed" directives, along with their aliases.
""" """
+1 -1
View File
@@ -1121,7 +1121,7 @@ class Sphinx:
.. versionchanged:: 0.6 .. versionchanged:: 0.6
Docutils 0.5-style directive classes are now supported. Docutils 0.5-style directive classes are now supported.
.. deprecated:: 1.8 .. versionchanged:: 1.8
Docutils 0.4-style (function based) directives support is deprecated. Docutils 0.4-style (function based) directives support is deprecated.
.. versionchanged:: 1.8 .. versionchanged:: 1.8
Add *override* keyword. Add *override* keyword.
+9 -1
View File
@@ -23,7 +23,7 @@ logger = logging.getLogger(__name__)
class ChangesBuilder(Builder): class ChangesBuilder(Builder):
"""Write a summary with all versionadded/changed/deprecated/removed directives.""" """Write a summary with all version-related directives."""
name = 'changes' name = 'changes'
epilog = __('The overview file is in %(outdir)s.') epilog = __('The overview file is in %(outdir)s.')
@@ -43,9 +43,13 @@ class ChangesBuilder(Builder):
return str(self.outdir) return str(self.outdir)
typemap = { typemap = {
'version-added': 'added',
'versionadded': 'added', 'versionadded': 'added',
'version-changed': 'changed',
'versionchanged': 'changed', 'versionchanged': 'changed',
'version-deprecated': 'deprecated',
'deprecated': 'deprecated', 'deprecated': 'deprecated',
'version-removed': 'removed',
'versionremoved': 'removed', 'versionremoved': 'removed',
} }
@@ -112,9 +116,13 @@ class ChangesBuilder(Builder):
f.write(self.templates.render('changes/versionchanges.html', ctx)) f.write(self.templates.render('changes/versionchanges.html', ctx))
hltext = [ hltext = [
f'.. version-added:: {version}',
f'.. versionadded:: {version}', f'.. versionadded:: {version}',
f'.. version-changed:: {version}',
f'.. versionchanged:: {version}', f'.. versionchanged:: {version}',
f'.. version-deprecated:: {version}',
f'.. deprecated:: {version}', f'.. deprecated:: {version}',
f'.. version-removed:: {version}',
f'.. versionremoved:: {version}', f'.. versionremoved:: {version}',
] ]
+14 -3
View File
@@ -21,6 +21,12 @@ if TYPE_CHECKING:
from sphinx.environment import BuildEnvironment from sphinx.environment import BuildEnvironment
from sphinx.util.typing import ExtensionMetadata, OptionSpec from sphinx.util.typing import ExtensionMetadata, OptionSpec
name_aliases = {
'version-added': 'versionadded',
'version-changed': 'versionchanged',
'version-deprecated': 'deprecated',
'version-removed': 'versionremoved',
}
versionlabels = { versionlabels = {
'versionadded': _('Added in version %s'), 'versionadded': _('Added in version %s'),
@@ -56,12 +62,13 @@ class VersionChange(SphinxDirective):
option_spec: ClassVar[OptionSpec] = {} option_spec: ClassVar[OptionSpec] = {}
def run(self) -> list[Node]: def run(self) -> list[Node]:
name = name_aliases.get(self.name, self.name)
node = addnodes.versionmodified() node = addnodes.versionmodified()
node.document = self.state.document node.document = self.state.document
self.set_source_info(node) self.set_source_info(node)
node['type'] = self.name node['type'] = name
node['version'] = self.arguments[0] node['version'] = self.arguments[0]
text = versionlabels[self.name] % self.arguments[0] text = versionlabels[name] % self.arguments[0]
if len(self.arguments) == 2: if len(self.arguments) == 2:
inodes, messages = self.parse_inline( inodes, messages = self.parse_inline(
self.arguments[1], lineno=self.lineno + 1 self.arguments[1], lineno=self.lineno + 1
@@ -73,7 +80,7 @@ class VersionChange(SphinxDirective):
messages = [] messages = []
if self.content: if self.content:
node += self.parse_content_to_nodes() node += self.parse_content_to_nodes()
classes = ['versionmodified', versionlabel_classes[self.name]] classes = ['versionmodified', versionlabel_classes[name]]
if len(node) > 0 and isinstance(node[0], nodes.paragraph): if len(node) > 0 and isinstance(node[0], nodes.paragraph):
# the contents start with a paragraph # the contents start with a paragraph
if node[0].rawsource: if node[0].rawsource:
@@ -168,9 +175,13 @@ class ChangeSetDomain(Domain):
def setup(app: Sphinx) -> ExtensionMetadata: def setup(app: Sphinx) -> ExtensionMetadata:
app.add_domain(ChangeSetDomain) app.add_domain(ChangeSetDomain)
app.add_directive('version-deprecated', VersionChange)
app.add_directive('deprecated', VersionChange) app.add_directive('deprecated', VersionChange)
app.add_directive('version-added', VersionChange)
app.add_directive('versionadded', VersionChange) app.add_directive('versionadded', VersionChange)
app.add_directive('version-changed', VersionChange)
app.add_directive('versionchanged', VersionChange) app.add_directive('versionchanged', VersionChange)
app.add_directive('version-removed', VersionChange)
app.add_directive('versionremoved', VersionChange) app.add_directive('versionremoved', VersionChange)
return { return {
+24 -9
View File
@@ -1,23 +1,38 @@
Version markup Version markup
-------------- --------------
.. versionadded:: 0.6 .. version-added:: 0.6
Some funny **stuff**. Some funny **stuff**.
.. versionchanged:: 0.6 .. version-changed:: 0.6
Even more funny stuff. Even more funny stuff.
.. deprecated:: 0.6 .. version-deprecated:: 0.6
Boring stuff. Boring stuff.
.. versionremoved:: 0.6 .. version-removed:: 0.6
Goodbye boring stuff. Goodbye boring stuff.
.. versionadded:: 1.2 .. version-added:: 1.2
First paragraph of versionadded. First paragraph of version-added.
.. versionchanged:: 1.2 .. version-changed:: 1.2
First paragraph of versionchanged. First paragraph of version-changed.
Second paragraph of versionchanged. Second paragraph of version-changed.
.. version-deprecated:: 1.3
First paragraph of version-deprecated.
.. version-added:: 0.6
Deprecated alias
.. version-changed:: 0.6
Deprecated alias
.. versionremoved:: 0.6
Deprecated alias
.. deprecated:: 0.6
Deprecated alias
+2 -2
View File
@@ -8,7 +8,7 @@ Memory
Allocate *n* bytes of memory. Allocate *n* bytes of memory.
.. versionchanged:: 0.6 .. version-changed:: 0.6
Can now be replaced with a different allocator. Can now be replaced with a different allocator.
@@ -17,7 +17,7 @@ System
Access to the system allocator. Access to the system allocator.
.. versionadded:: 0.6 .. version-added:: 0.6
.. c:function:: void* Test_SysMalloc(size_t n) .. c:function:: void* Test_SysMalloc(size_t n)
+3 -3
View File
@@ -16,10 +16,10 @@ Classes
Class for handling paths. Class for handling paths.
.. versionadded:: 0.5 .. version-added:: 0.5
Innovative new way to handle paths. Innovative new way to handle paths.
.. deprecated:: 0.6 .. version-deprecated:: 0.6
So, that was a bad idea it turns out. So, that was a bad idea it turns out.
+8 -8
View File
@@ -3,16 +3,16 @@
i18n with versionchange i18n with versionchange
============================ ============================
.. deprecated:: 1.0 .. version-deprecated:: 1.0
This is the *first* paragraph of deprecated. This is the *first* paragraph of version-deprecated.
This is the *second* paragraph of deprecated. This is the *second* paragraph of version-deprecated.
.. versionadded:: 1.0 .. version-added:: 1.0
This is the *first* paragraph of versionadded. This is the *first* paragraph of version-added.
.. versionchanged:: 1.0 .. version-changed:: 1.0
This is the *first* paragraph of versionchanged. This is the *first* paragraph of version-changed.
.. versionremoved:: 1.0 This is the *first* paragraph of versionremoved. .. version-removed:: 1.0 This is the *first* paragraph of version-removed.
@@ -19,12 +19,24 @@ msgstr ""
msgid "i18n with versionchange" msgid "i18n with versionchange"
msgstr "I18N WITH VERSIONCHANGE" msgstr "I18N WITH VERSIONCHANGE"
msgid "This is the *first* paragraph of version-deprecated."
msgstr "THIS IS THE *FIRST* PARAGRAPH OF VERSION-DEPRECATED."
msgid "This is the *second* paragraph of version-deprecated."
msgstr "THIS IS THE *SECOND* PARAGRAPH OF VERSION-DEPRECATED."
msgid "This is the *first* paragraph of version-added."
msgstr "THIS IS THE *FIRST* PARAGRAPH OF VERSION-ADDED."
msgid "This is the *first* paragraph of version-changed."
msgstr "THIS IS THE *FIRST* PARAGRAPH OF VERSION-CHANGED."
msgid "This is the *first* paragraph of version-removed."
msgstr "THIS IS THE *FIRST* PARAGRAPH OF VERSION-REMOVED."
msgid "This is the *first* paragraph of deprecated." msgid "This is the *first* paragraph of deprecated."
msgstr "THIS IS THE *FIRST* PARAGRAPH OF DEPRECATED." msgstr "THIS IS THE *FIRST* PARAGRAPH OF DEPRECATED."
msgid "This is the *second* paragraph of deprecated."
msgstr "THIS IS THE *SECOND* PARAGRAPH OF DEPRECATED."
msgid "This is the *first* paragraph of versionadded." msgid "This is the *first* paragraph of versionadded."
msgstr "THIS IS THE *FIRST* PARAGRAPH OF VERSIONADDED." msgstr "THIS IS THE *FIRST* PARAGRAPH OF VERSIONADDED."
+20 -9
View File
@@ -292,27 +292,38 @@ Figures
Version markup Version markup
-------------- --------------
.. versionadded:: 0.6 .. version-added:: 0.6
Some funny **stuff**. Some funny **stuff**.
.. versionchanged:: 0.6 .. version-changed:: 0.6
Even more funny stuff. Even more funny stuff.
.. deprecated:: 0.6 .. version-deprecated:: 0.6
Boring stuff. Boring stuff.
.. versionremoved:: 0.6 .. version-removed:: 0.6
Goodbye boring stuff. Goodbye boring stuff.
.. versionadded:: 1.2 .. version-added:: 1.2
First paragraph of versionadded. First paragraph of version-added.
.. versionchanged:: 1.2 .. version-changed:: 1.2
First paragraph of versionchanged. First paragraph of version-changed.
Second paragraph of versionchanged. Second paragraph of version-changed.
.. version-added:: 0.6
Deprecated alias for version-added.
.. version-changed:: 0.6
Deprecated alias for version-changed.
.. deprecated:: 0.6
Deprecated alias for version-deprecated.
.. versionremoved:: 0.6
Deprecated alias for version-removed.
Code blocks Code blocks
----------- -----------
@@ -205,23 +205,53 @@ def tail_check(check: str) -> Callable[[Iterable[Element]], Literal[True]]:
( (
'markup.html', 'markup.html',
".//div[@class='versionadded']/p/span", ".//div[@class='versionadded']/p/span",
tail_check('First paragraph of versionadded'), tail_check('First paragraph of version-added'),
),
(
'markup.html',
".//div[@class='versionadded']/p/span",
tail_check('Deprecated alias for version-added'),
), ),
( (
'markup.html', 'markup.html',
".//div[@class='versionchanged']/p/span", ".//div[@class='versionchanged']/p/span",
tail_check('First paragraph of versionchanged'), tail_check('First paragraph of version-changed'),
), ),
( (
'markup.html', 'markup.html',
".//div[@class='versionchanged']/p", ".//div[@class='versionchanged']/p",
'Second paragraph of versionchanged', 'Second paragraph of version-changed',
),
(
'markup.html',
".//div[@class='versionchanged']/p/span",
tail_check('Deprecated alias for version-changed'),
),
(
'markup.html',
".//div[@class='deprecated']/p/span",
'Deprecated since version 0.6: ',
),
(
'markup.html',
".//div[@class='deprecated']/p/span",
tail_check('Boring stuff.'),
),
(
'markup.html',
".//div[@class='deprecated']/p/span",
tail_check('Deprecated alias for version-deprecated'),
), ),
( (
'markup.html', 'markup.html',
".//div[@class='versionremoved']/p/span", ".//div[@class='versionremoved']/p/span",
'Removed in version 0.6: ', 'Removed in version 0.6: ',
), ),
(
'markup.html',
".//div[@class='versionremoved']/p/span",
tail_check('Deprecated alias for version-removed'),
),
# footnote reference # footnote reference
('markup.html', ".//a[@class='footnote-reference brackets']", r'1'), ('markup.html', ".//a[@class='footnote-reference brackets']", r'1'),
# created by reference lookup # created by reference lookup
+5 -5
View File
@@ -1101,29 +1101,29 @@ def test_html_versionchanges(app):
expect1 = ( expect1 = (
"""<p><span class="versionmodified deprecated">Deprecated since version 1.0: </span>""" """<p><span class="versionmodified deprecated">Deprecated since version 1.0: </span>"""
"""THIS IS THE <em>FIRST</em> PARAGRAPH OF DEPRECATED.</p>\n""" """THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSION-DEPRECATED.</p>\n"""
"""<p>THIS IS THE <em>SECOND</em> PARAGRAPH OF DEPRECATED.</p>\n""" """<p>THIS IS THE <em>SECOND</em> PARAGRAPH OF VERSION-DEPRECATED.</p>\n"""
) )
matched_content = get_content(result, 'deprecated') matched_content = get_content(result, 'deprecated')
assert matched_content == expect1 assert matched_content == expect1
expect2 = ( expect2 = (
"""<p><span class="versionmodified added">Added in version 1.0: </span>""" """<p><span class="versionmodified added">Added in version 1.0: </span>"""
"""THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSIONADDED.</p>\n""" """THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSION-ADDED.</p>\n"""
) )
matched_content = get_content(result, 'versionadded') matched_content = get_content(result, 'versionadded')
assert matched_content == expect2 assert matched_content == expect2
expect3 = ( expect3 = (
"""<p><span class="versionmodified changed">Changed in version 1.0: </span>""" """<p><span class="versionmodified changed">Changed in version 1.0: </span>"""
"""THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSIONCHANGED.</p>\n""" """THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSION-CHANGED.</p>\n"""
) )
matched_content = get_content(result, 'versionchanged') matched_content = get_content(result, 'versionchanged')
assert matched_content == expect3 assert matched_content == expect3
expect4 = ( expect4 = (
"""<p><span class="versionmodified removed">Removed in version 1.0: </span>""" """<p><span class="versionmodified removed">Removed in version 1.0: </span>"""
"""THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSIONREMOVED.</p>\n""" """THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSION-REMOVED.</p>\n"""
) )
matched_content = get_content(result, 'versionremoved') matched_content = get_content(result, 'versionremoved')
assert matched_content == expect4 assert matched_content == expect4