[cleanup] remove deprecated objects and improve deprecation private interface (#12185)

This removes the deprecated objects that should have been removed in 7.x.
This commit is contained in:
Bénédikt Tran
2024-03-25 12:45:45 +01:00
committed by GitHub
parent 0ef96a7d52
commit 2e05fd2ffe
7 changed files with 42 additions and 65 deletions

View File

@@ -14,24 +14,6 @@ if TYPE_CHECKING:
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.util.typing import ExtensionMetadata from sphinx.util.typing import ExtensionMetadata
# deprecated name -> (object to return, canonical path or empty string)
_DEPRECATED_OBJECTS = {
'meta': (nodes.meta, 'docutils.nodes.meta'),
'docutils_meta': (nodes.meta, 'docutils.nodes.meta'),
}
def __getattr__(name: str) -> Any:
if name not in _DEPRECATED_OBJECTS:
msg = f'module {__name__!r} has no attribute {name!r}'
raise AttributeError(msg)
from sphinx.deprecation import _deprecation_warning
deprecated_object, canonical_name = _DEPRECATED_OBJECTS[name]
_deprecation_warning(__name__, name, canonical_name, remove=(7, 0))
return deprecated_object
class document(nodes.document): class document(nodes.document):
"""The document root element patched by Sphinx. """The document root element patched by Sphinx.

View File

@@ -307,8 +307,7 @@ class StandaloneHTMLBuilder(Builder):
@property @property
def css_files(self) -> list[_CascadingStyleSheet]: def css_files(self) -> list[_CascadingStyleSheet]:
_deprecation_warning(__name__, f'{self.__class__.__name__}.css_files', '', _deprecation_warning(__name__, f'{self.__class__.__name__}.css_files', remove=(9, 0))
remove=(9, 0))
return self._css_files return self._css_files
def init_css_files(self) -> None: def init_css_files(self) -> None:
@@ -334,8 +333,8 @@ class StandaloneHTMLBuilder(Builder):
@property @property
def script_files(self) -> list[_JavaScript]: def script_files(self) -> list[_JavaScript]:
_deprecation_warning(__name__, f'{self.__class__.__name__}.script_files', '', canonical_name = f'{self.__class__.__name__}.script_files'
remove=(9, 0)) _deprecation_warning(__name__, canonical_name, remove=(9, 0))
return self._js_files return self._js_files
def init_js_files(self) -> None: def init_js_files(self) -> None:
@@ -1340,7 +1339,8 @@ def setup(app: Sphinx) -> ExtensionMetadata:
app.add_config_value('html_search_scorer', '', '') app.add_config_value('html_search_scorer', '', '')
app.add_config_value('html_scaled_image_link', True, 'html') app.add_config_value('html_scaled_image_link', True, 'html')
app.add_config_value('html_baseurl', '', 'html') app.add_config_value('html_baseurl', '', 'html')
app.add_config_value('html_codeblock_linenos_style', 'inline', 'html', # RemovedInSphinx70Warning # NoQA: E501 # removal is indefinitely on hold (ref: https://github.com/sphinx-doc/sphinx/issues/10265)
app.add_config_value('html_codeblock_linenos_style', 'inline', 'html',
ENUM('table', 'inline')) ENUM('table', 'inline'))
app.add_config_value('html_math_renderer', None, 'env') app.add_config_value('html_math_renderer', None, 'env')
app.add_config_value('html4_writer', False, 'html') app.add_config_value('html4_writer', False, 'html')
@@ -1373,8 +1373,8 @@ def setup(app: Sphinx) -> ExtensionMetadata:
} }
# deprecated name -> (object to return, canonical path or empty string) # deprecated name -> (object to return, canonical path or empty string, removal version)
_DEPRECATED_OBJECTS = { _DEPRECATED_OBJECTS: dict[str, tuple[Any, str, tuple[int, int]]] = {
'Stylesheet': (_CascadingStyleSheet, 'sphinx.builders.html._assets._CascadingStyleSheet', (9, 0)), # NoQA: E501 'Stylesheet': (_CascadingStyleSheet, 'sphinx.builders.html._assets._CascadingStyleSheet', (9, 0)), # NoQA: E501
'JavaScript': (_JavaScript, 'sphinx.builders.html._assets._JavaScript', (9, 0)), 'JavaScript': (_JavaScript, 'sphinx.builders.html._assets._JavaScript', (9, 0)),
} }

View File

@@ -19,17 +19,26 @@ RemovedInNextVersionWarning = RemovedInSphinx80Warning
def _deprecation_warning( def _deprecation_warning(
module: str, module: str,
attribute: str, attribute: str,
canonical_name: str, canonical_name: str = '',
*, *,
remove: tuple[int, int], remove: tuple[int, int],
raises: bool = False,
) -> None: ) -> None:
"""Helper function for module-level deprecations using __getattr__ """Helper function for module-level deprecations using ``__getattr__``.
Exemplar usage: :param module: The module containing a deprecated object.
:param attribute: The name of the deprecated object.
:param canonical_name: Optional fully-qualified name for its replacement.
:param remove: Target version for removal.
:param raises: Indicate whether to raise an exception instead of a warning.
.. code:: python When *raises* is ``True``, an :exc:`AttributeError` is raised instead
of emitting a warning so that it is easy to locate deprecated objects
in tests that could suppress deprecation warnings.
# deprecated name -> (object to return, canonical path or empty string) Usage::
# deprecated name -> (object to return, canonical path or empty string, removal version)
_DEPRECATED_OBJECTS = { _DEPRECATED_OBJECTS = {
'deprecated_name': (object_to_return, 'fully_qualified_replacement_name', (8, 0)), 'deprecated_name': (object_to_return, 'fully_qualified_replacement_name', (8, 0)),
} }
@@ -54,14 +63,14 @@ def _deprecation_warning(
msg = f'removal version {remove!r} is invalid!' msg = f'removal version {remove!r} is invalid!'
raise RuntimeError(msg) raise RuntimeError(msg)
qualified_name = f'{module}.{attribute}' qualname = f'{module}.{attribute}'
if canonical_name: if canonical_name:
message = ( message = f'The alias {qualname!r} is deprecated, use {canonical_name!r} instead.'
f'The alias {qualified_name!r} is deprecated, use {canonical_name!r} instead.'
)
else: else:
message = f'{qualified_name!r} is deprecated.' message = f'{qualname!r} is deprecated.'
warnings.warn( if raises:
message + ' Check CHANGES for Sphinx API modifications.', warning_class, stacklevel=3 raise AttributeError(message)
)
message = f'{message} Check CHANGES for Sphinx API modifications.'
warnings.warn(message, warning_class, stacklevel=3)

View File

@@ -24,7 +24,7 @@ from sphinx.util.docutils import additional_nodes
if TYPE_CHECKING: if TYPE_CHECKING:
from collections.abc import Mapping from collections.abc import Mapping
from pathlib import Path from pathlib import Path
from typing import Any, Final from typing import Any
from xml.etree.ElementTree import ElementTree from xml.etree.ElementTree import ElementTree
from docutils.nodes import Node from docutils.nodes import Node
@@ -242,7 +242,8 @@ def _clean_up_global_state() -> None:
sphinx.pycode.ModuleAnalyzer.cache.clear() sphinx.pycode.ModuleAnalyzer.cache.clear()
_DEPRECATED_OBJECTS: Final[dict[str, tuple[object, str, tuple[int, int]]]] = { # deprecated name -> (object to return, canonical path or '', removal version)
_DEPRECATED_OBJECTS: dict[str, tuple[Any, str, tuple[int, int]]] = {
'strip_escseq': (strip_colors, 'sphinx.util.console.strip_colors', (9, 0)), 'strip_escseq': (strip_colors, 'sphinx.util.console.strip_colors', (9, 0)),
} }

View File

@@ -266,7 +266,7 @@ def _xml_name_checker() -> re.Pattern[str]:
# deprecated name -> (object to return, canonical path or empty string) # deprecated name -> (object to return, canonical path or empty string)
_DEPRECATED_OBJECTS = { _DEPRECATED_OBJECTS: dict[str, tuple[Any, str] | tuple[Any, str, tuple[int, int]]] = {
'path_stabilize': (_osutil.path_stabilize, 'sphinx.util.osutil.path_stabilize'), 'path_stabilize': (_osutil.path_stabilize, 'sphinx.util.osutil.path_stabilize'),
'display_chunk': (_display.display_chunk, 'sphinx.util.display.display_chunk'), 'display_chunk': (_display.display_chunk, 'sphinx.util.display.display_chunk'),
'status_iterator': (_display.status_iterator, 'sphinx.util.display.status_iterator'), 'status_iterator': (_display.status_iterator, 'sphinx.util.display.status_iterator'),
@@ -294,6 +294,8 @@ def __getattr__(name: str) -> Any:
from sphinx.deprecation import _deprecation_warning from sphinx.deprecation import _deprecation_warning
deprecated_object, canonical_name = _DEPRECATED_OBJECTS[name] info = _DEPRECATED_OBJECTS[name]
_deprecation_warning(__name__, name, canonical_name, remove=(8, 0)) deprecated_object, canonical_name = info[:2]
remove = info[2] if len(info) == 3 else (8, 0)
_deprecation_warning(__name__, name, canonical_name, remove=remove)
return deprecated_object return deprecated_object

View File

@@ -38,23 +38,6 @@ if TYPE_CHECKING:
from sphinx.environment import BuildEnvironment from sphinx.environment import BuildEnvironment
from sphinx.util.typing import RoleFunction from sphinx.util.typing import RoleFunction
# deprecated name -> (object to return, canonical path or empty string)
_DEPRECATED_OBJECTS = {
'__version_info__': (docutils.__version_info__, 'docutils.__version_info__'),
}
def __getattr__(name: str) -> Any:
if name not in _DEPRECATED_OBJECTS:
msg = f'module {__name__!r} has no attribute {name!r}'
raise AttributeError(msg)
from sphinx.deprecation import _deprecation_warning
deprecated_object, canonical_name = _DEPRECATED_OBJECTS[name]
_deprecation_warning(__name__, name, canonical_name, remove=(7, 0))
return deprecated_object
additional_nodes: set[type[Element]] = set() additional_nodes: set[type[Element]] = set()

View File

@@ -434,9 +434,9 @@ def _format_literal_enum_arg(arg: enum.Enum, /, *, mode: str) -> str:
return f':py:attr:`{enum_cls.__module__}.{enum_cls.__qualname__}.{arg.name}`' return f':py:attr:`{enum_cls.__module__}.{enum_cls.__qualname__}.{arg.name}`'
# deprecated name -> (object to return, canonical path or empty string) # deprecated name -> (object to return, canonical path or empty string, removal version)
_DEPRECATED_OBJECTS = { _DEPRECATED_OBJECTS: dict[str, tuple[Any, str, tuple[int, int]]] = {
'stringify': (stringify_annotation, 'sphinx.util.typing.stringify_annotation'), 'stringify': (stringify_annotation, 'sphinx.util.typing.stringify_annotation', (8, 0)),
} }
@@ -447,6 +447,6 @@ def __getattr__(name: str) -> Any:
from sphinx.deprecation import _deprecation_warning from sphinx.deprecation import _deprecation_warning
deprecated_object, canonical_name = _DEPRECATED_OBJECTS[name] deprecated_object, canonical_name, remove = _DEPRECATED_OBJECTS[name]
_deprecation_warning(__name__, name, canonical_name, remove=(8, 0)) _deprecation_warning(__name__, name, canonical_name, remove=remove)
return deprecated_object return deprecated_object