mirror of
https://github.com/python/cpython.git
synced 2026-05-06 04:37:33 -04:00
[3.14] Add a new Sphinx soft-deprecated directive (GH-148630) (#148714)
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Co-authored-by: Stan Ulbrych <stan@python.org>
This commit is contained in:
committed by
GitHub
parent
5f1b710a28
commit
5b33424120
@@ -2,7 +2,7 @@
|
||||
|
||||
.. _allocating-objects:
|
||||
|
||||
Allocating Objects on the Heap
|
||||
Allocating objects on the heap
|
||||
==============================
|
||||
|
||||
|
||||
@@ -153,10 +153,12 @@ Allocating Objects on the Heap
|
||||
To allocate and create extension modules.
|
||||
|
||||
|
||||
Deprecated aliases
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
Soft-deprecated aliases
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
These are :term:`soft deprecated` aliases to existing functions and macros.
|
||||
.. soft-deprecated:: 3.10
|
||||
|
||||
These are aliases to existing functions and macros.
|
||||
They exist solely for backwards compatibility.
|
||||
|
||||
|
||||
@@ -164,7 +166,7 @@ They exist solely for backwards compatibility.
|
||||
:widths: auto
|
||||
:header-rows: 1
|
||||
|
||||
* * Deprecated alias
|
||||
* * Soft-deprecated alias
|
||||
* Function
|
||||
* * .. c:macro:: PyObject_NEW(type, typeobj)
|
||||
* :c:macro:`PyObject_New`
|
||||
|
||||
+5
-4
@@ -2,7 +2,7 @@
|
||||
|
||||
.. _fileobjects:
|
||||
|
||||
File Objects
|
||||
File objects
|
||||
------------
|
||||
|
||||
.. index:: pair: object; file
|
||||
@@ -136,11 +136,12 @@ the :mod:`io` APIs instead.
|
||||
failure; the appropriate exception will be set.
|
||||
|
||||
|
||||
Deprecated API
|
||||
^^^^^^^^^^^^^^
|
||||
Soft-deprecated API
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
These are :term:`soft deprecated` APIs that were included in Python's C API
|
||||
These are APIs that were included in Python's C API
|
||||
by mistake. They are documented solely for completeness; use other
|
||||
``PyFile*`` APIs instead.
|
||||
|
||||
|
||||
+7
-15
@@ -1,6 +1,6 @@
|
||||
.. highlight:: c
|
||||
|
||||
Frame Objects
|
||||
Frame objects
|
||||
-------------
|
||||
|
||||
.. c:type:: PyFrameObject
|
||||
@@ -147,7 +147,7 @@ See also :ref:`Reflection <reflection>`.
|
||||
Return the line number that *frame* is currently executing.
|
||||
|
||||
|
||||
Frame Locals Proxies
|
||||
Frame locals proxies
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 3.13
|
||||
@@ -169,7 +169,7 @@ See :pep:`667` for more information.
|
||||
Return non-zero if *obj* is a frame :func:`locals` proxy.
|
||||
|
||||
|
||||
Legacy Local Variable APIs
|
||||
Legacy local variable APIs
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
These APIs are :term:`soft deprecated`. As of Python 3.13, they do nothing.
|
||||
@@ -178,40 +178,34 @@ They exist solely for backwards compatibility.
|
||||
|
||||
.. c:function:: void PyFrame_LocalsToFast(PyFrameObject *f, int clear)
|
||||
|
||||
This function is :term:`soft deprecated` and does nothing.
|
||||
|
||||
Prior to Python 3.13, this function would copy the :attr:`~frame.f_locals`
|
||||
attribute of *f* to the internal "fast" array of local variables, allowing
|
||||
changes in frame objects to be visible to the interpreter. If *clear* was
|
||||
true, this function would process variables that were unset in the locals
|
||||
dictionary.
|
||||
|
||||
.. versionchanged:: 3.13
|
||||
.. soft-deprecated:: 3.13
|
||||
This function now does nothing.
|
||||
|
||||
|
||||
.. c:function:: void PyFrame_FastToLocals(PyFrameObject *f)
|
||||
|
||||
This function is :term:`soft deprecated` and does nothing.
|
||||
|
||||
Prior to Python 3.13, this function would copy the internal "fast" array
|
||||
of local variables (which is used by the interpreter) to the
|
||||
:attr:`~frame.f_locals` attribute of *f*, allowing changes in local
|
||||
variables to be visible to frame objects.
|
||||
|
||||
.. versionchanged:: 3.13
|
||||
.. soft-deprecated:: 3.13
|
||||
This function now does nothing.
|
||||
|
||||
|
||||
.. c:function:: int PyFrame_FastToLocalsWithError(PyFrameObject *f)
|
||||
|
||||
This function is :term:`soft deprecated` and does nothing.
|
||||
|
||||
Prior to Python 3.13, this function was similar to
|
||||
:c:func:`PyFrame_FastToLocals`, but would return ``0`` on success, and
|
||||
``-1`` with an exception set on failure.
|
||||
|
||||
.. versionchanged:: 3.13
|
||||
.. soft-deprecated:: 3.13
|
||||
This function now does nothing.
|
||||
|
||||
|
||||
@@ -219,7 +213,7 @@ They exist solely for backwards compatibility.
|
||||
:pep:`667`
|
||||
|
||||
|
||||
Internal Frames
|
||||
Internal frames
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
Unless using :pep:`523`, you will not need this.
|
||||
@@ -249,5 +243,3 @@ Unless using :pep:`523`, you will not need this.
|
||||
Return the currently executing line number, or -1 if there is no line number.
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
|
||||
|
||||
+1
-3
@@ -197,12 +197,10 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate.
|
||||
|
||||
.. c:function:: long PyLong_AS_LONG(PyObject *obj)
|
||||
|
||||
A :term:`soft deprecated` alias.
|
||||
Exactly equivalent to the preferred ``PyLong_AsLong``. In particular,
|
||||
it can fail with :exc:`OverflowError` or another exception.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
The function is soft deprecated.
|
||||
.. soft-deprecated:: 3.14
|
||||
|
||||
.. c:function:: int PyLong_AsInt(PyObject *obj)
|
||||
|
||||
|
||||
@@ -604,9 +604,7 @@ or code that creates modules dynamically.
|
||||
// PyModule_AddObject() stole a reference to obj:
|
||||
// Py_XDECREF(obj) is not needed here.
|
||||
|
||||
.. deprecated:: 3.13
|
||||
|
||||
:c:func:`PyModule_AddObject` is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.13
|
||||
|
||||
|
||||
.. c:function:: int PyModule_AddIntConstant(PyObject *module, const char *name, long value)
|
||||
|
||||
@@ -205,6 +205,4 @@ would typically correspond to a Python function.
|
||||
|
||||
.. versionadded:: 3.13
|
||||
|
||||
.. deprecated:: 3.14
|
||||
|
||||
This function is :term:`soft deprecated`.
|
||||
.. soft-deprecated:: 3.14
|
||||
|
||||
@@ -109,9 +109,8 @@ Sequence Protocol
|
||||
|
||||
Alias for :c:func:`PySequence_Contains`.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
The function is :term:`soft deprecated` and should no longer be used to
|
||||
write new code.
|
||||
.. soft-deprecated:: 3.14
|
||||
The function should no longer be used to write new code.
|
||||
|
||||
|
||||
.. c:function:: Py_ssize_t PySequence_Index(PyObject *o, PyObject *value)
|
||||
|
||||
@@ -56,7 +56,7 @@ the information :func:`init` sets up.
|
||||
.. versionchanged:: 3.8
|
||||
Added support for *url* being a :term:`path-like object`.
|
||||
|
||||
.. deprecated:: 3.13
|
||||
.. soft-deprecated:: 3.13
|
||||
Passing a file path instead of URL is :term:`soft deprecated`.
|
||||
Use :func:`guess_file_type` for this.
|
||||
|
||||
|
||||
+4
-6
@@ -4711,9 +4711,8 @@ written in Python, such as a mail server's external command delivery program.
|
||||
Use :class:`subprocess.Popen` or :func:`subprocess.run` to
|
||||
control options like encodings.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
The function is :term:`soft deprecated` and should no longer be used to
|
||||
write new code. The :mod:`subprocess` module is recommended instead.
|
||||
.. soft-deprecated:: 3.14
|
||||
The :mod:`subprocess` module is recommended instead.
|
||||
|
||||
|
||||
.. function:: posix_spawn(path, argv, env, *, file_actions=None, \
|
||||
@@ -4941,9 +4940,8 @@ written in Python, such as a mail server's external command delivery program.
|
||||
.. versionchanged:: 3.6
|
||||
Accepts a :term:`path-like object`.
|
||||
|
||||
.. deprecated:: 3.14
|
||||
These functions are :term:`soft deprecated` and should no longer be used
|
||||
to write new code. The :mod:`subprocess` module is recommended instead.
|
||||
.. soft-deprecated:: 3.14
|
||||
The :mod:`subprocess` module is recommended instead.
|
||||
|
||||
|
||||
.. data:: P_NOWAIT
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
import re
|
||||
|
||||
from docutils import nodes
|
||||
from sphinx import addnodes
|
||||
from sphinx.domains.changeset import (
|
||||
VersionChange,
|
||||
versionlabel_classes,
|
||||
@@ -11,6 +13,7 @@ from sphinx.domains.changeset import (
|
||||
)
|
||||
from sphinx.locale import _ as sphinx_gettext
|
||||
|
||||
TYPE_CHECKING = False
|
||||
if TYPE_CHECKING:
|
||||
from docutils.nodes import Node
|
||||
from sphinx.application import Sphinx
|
||||
@@ -73,6 +76,76 @@ class DeprecatedRemoved(VersionChange):
|
||||
versionlabel_classes[self.name] = ""
|
||||
|
||||
|
||||
class SoftDeprecated(PyVersionChange):
|
||||
"""Directive for soft deprecations that auto-links to the glossary term.
|
||||
|
||||
Usage::
|
||||
|
||||
.. soft-deprecated:: 3.15
|
||||
|
||||
Use :func:`new_thing` instead.
|
||||
|
||||
Renders as: "Soft deprecated since version 3.15: Use new_thing() instead."
|
||||
with "Soft deprecated" linking to the glossary definition.
|
||||
"""
|
||||
|
||||
_TERM_RE = re.compile(r":term:`([^`]+)`")
|
||||
|
||||
def run(self) -> list[Node]:
|
||||
versionlabels[self.name] = sphinx_gettext(
|
||||
":term:`Soft deprecated` since version %s"
|
||||
)
|
||||
versionlabel_classes[self.name] = "soft-deprecated"
|
||||
try:
|
||||
result = super().run()
|
||||
finally:
|
||||
versionlabels[self.name] = ""
|
||||
versionlabel_classes[self.name] = ""
|
||||
|
||||
for node in result:
|
||||
# Add "versionchanged" class so existing theme CSS applies
|
||||
node["classes"] = node.get("classes", []) + ["versionchanged"]
|
||||
# Replace the plain-text "Soft deprecated" with a glossary reference
|
||||
for inline in node.findall(nodes.inline):
|
||||
if "versionmodified" in inline.get("classes", []):
|
||||
self._add_glossary_link(inline)
|
||||
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def _add_glossary_link(cls, inline: nodes.inline) -> None:
|
||||
"""Replace :term:`soft deprecated` text with a cross-reference to the
|
||||
'Soft deprecated' glossary entry."""
|
||||
for child in inline.children:
|
||||
if not isinstance(child, nodes.Text):
|
||||
continue
|
||||
|
||||
text = str(child)
|
||||
match = cls._TERM_RE.search(text)
|
||||
if match is None:
|
||||
continue
|
||||
|
||||
ref = addnodes.pending_xref(
|
||||
"",
|
||||
nodes.Text(match.group(1)),
|
||||
refdomain="std",
|
||||
reftype="term",
|
||||
reftarget="soft deprecated",
|
||||
refwarn=True,
|
||||
)
|
||||
|
||||
start, end = match.span()
|
||||
new_nodes: list[nodes.Node] = []
|
||||
if start > 0:
|
||||
new_nodes.append(nodes.Text(text[:start]))
|
||||
new_nodes.append(ref)
|
||||
if end < len(text):
|
||||
new_nodes.append(nodes.Text(text[end:]))
|
||||
|
||||
child.parent.replace(child, new_nodes)
|
||||
break
|
||||
|
||||
|
||||
def setup(app: Sphinx) -> ExtensionMetadata:
|
||||
# Override Sphinx's directives with support for 'next'
|
||||
app.add_directive("versionadded", PyVersionChange, override=True)
|
||||
@@ -83,6 +156,9 @@ def setup(app: Sphinx) -> ExtensionMetadata:
|
||||
# Register the ``.. deprecated-removed::`` directive
|
||||
app.add_directive("deprecated-removed", DeprecatedRemoved)
|
||||
|
||||
# Register the ``.. soft-deprecated::`` directive
|
||||
app.add_directive("soft-deprecated", SoftDeprecated)
|
||||
|
||||
return {
|
||||
"version": "1.0",
|
||||
"parallel_read_safe": True,
|
||||
|
||||
@@ -29,6 +29,7 @@ In extensions/changes.py:
|
||||
|
||||
{% trans %}Deprecated since version %s, will be removed in version %s{% endtrans %}
|
||||
{% trans %}Deprecated since version %s, removed in version %s{% endtrans %}
|
||||
{% trans %}:term:`Soft deprecated` since version %s{% endtrans %}
|
||||
|
||||
In docsbuild-scripts, when rewriting indexsidebar.html with actual versions:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user