diff options
59 files changed, 106 insertions, 2348 deletions
diff --git a/doc/extdev/nodes.rst b/doc/extdev/nodes.rst index 5d8272eae..e38393a78 100644 --- a/doc/extdev/nodes.rst +++ b/doc/extdev/nodes.rst @@ -38,7 +38,6 @@ New inline nodes .. autoclass:: index .. autoclass:: pending_xref .. autoclass:: literal_emphasis -.. autoclass:: abbreviation .. autoclass:: download_reference Special nodes diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py index f02f3b5d7..42a0faed6 100644 --- a/sphinx/addnodes.py +++ b/sphinx/addnodes.py @@ -8,14 +8,11 @@ :license: BSD, see LICENSE for details. """ -import warnings from typing import Any, Dict, List, Sequence from typing import TYPE_CHECKING from docutils import nodes -from docutils.nodes import Element, Node - -from sphinx.deprecation import RemovedInSphinx40Warning +from docutils.nodes import Element if TYPE_CHECKING: from sphinx.application import Sphinx @@ -325,20 +322,6 @@ class literal_strong(nodes.strong, not_smartquotable): """ -class abbreviation(nodes.abbreviation): - """Node for abbreviations with explanations. - - .. deprecated:: 2.0 - """ - - def __init__(self, rawsource: str = '', text: str = '', - *children: Node, **attributes: Any) -> None: - warnings.warn("abbrevition node for Sphinx was replaced by docutils'.", - RemovedInSphinx40Warning, stacklevel=2) - - super().__init__(rawsource, text, *children, **attributes) - - class manpage(nodes.Inline, nodes.FixedTextElement): """Node for references to manpages.""" diff --git a/sphinx/application.py b/sphinx/application.py index f782f7639..04d6dc952 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -14,7 +14,6 @@ import os import pickle import platform import sys -import warnings from collections import deque from io import StringIO from os import path @@ -30,14 +29,13 @@ from pygments.lexer import Lexer import sphinx from sphinx import package_dir, locale from sphinx.config import Config -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.domains import Domain, Index from sphinx.environment import BuildEnvironment from sphinx.environment.collectors import EnvironmentCollector from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError from sphinx.events import EventManager from sphinx.extension import Extension -from sphinx.highlighting import lexer_classes, lexers +from sphinx.highlighting import lexer_classes from sphinx.locale import __ from sphinx.project import Project from sphinx.registry import SphinxComponentRegistry @@ -861,13 +859,6 @@ class Sphinx: """ self.registry.add_post_transform(transform) - def add_javascript(self, filename: str, **kwargs: str) -> None: - """An alias of :meth:`add_js_file`.""" - warnings.warn('The app.add_javascript() is deprecated. ' - 'Please use app.add_js_file() instead.', - RemovedInSphinx40Warning, stacklevel=2) - self.add_js_file(filename, **kwargs) - def add_js_file(self, filename: str, **kwargs: str) -> None: """Register a JavaScript file to include in the HTML output. @@ -938,24 +929,6 @@ class Sphinx: if hasattr(self.builder, 'add_css_file'): self.builder.add_css_file(filename, **kwargs) # type: ignore - def add_stylesheet(self, filename: str, alternate: bool = False, title: str = None - ) -> None: - """An alias of :meth:`add_css_file`.""" - warnings.warn('The app.add_stylesheet() is deprecated. ' - 'Please use app.add_css_file() instead.', - RemovedInSphinx40Warning, stacklevel=2) - - attributes = {} # type: Dict[str, str] - if alternate: - attributes['rel'] = 'alternate stylesheet' - else: - attributes['rel'] = 'stylesheet' - - if title: - attributes['title'] = title - - self.add_css_file(filename, **attributes) - def add_latex_package(self, packagename: str, options: str = None) -> None: r"""Register a package to include in the LaTeX source code. @@ -974,7 +947,7 @@ class Sphinx: """ self.registry.add_latex_package(packagename, options) - def add_lexer(self, alias: str, lexer: Union[Lexer, "Type[Lexer]"]) -> None: + def add_lexer(self, alias: str, lexer: Type[Lexer]) -> None: """Register a new lexer for source code. Use *lexer* to highlight code blocks with the given language *alias*. @@ -985,13 +958,7 @@ class Sphinx: still supported until Sphinx-3.x. """ logger.debug('[app] adding lexer: %r', (alias, lexer)) - if isinstance(lexer, Lexer): - warnings.warn('app.add_lexer() API changed; ' - 'Please give lexer class instead instance', - RemovedInSphinx40Warning) - lexers[alias] = lexer - else: - lexer_classes[alias] = lexer + lexer_classes[alias] = lexer def add_autodocumenter(self, cls: Any, override: bool = False) -> None: """Register a new documenter class for the autodoc extension. diff --git a/sphinx/builders/_epub_base.py b/sphinx/builders/_epub_base.py index d39362eb9..7976b4f7c 100644 --- a/sphinx/builders/_epub_base.py +++ b/sphinx/builders/_epub_base.py @@ -11,7 +11,6 @@ import html import os import re -import warnings from os import path from typing import Any, Dict, List, NamedTuple, Set, Tuple from zipfile import ZIP_DEFLATED, ZIP_STORED, ZipFile @@ -22,7 +21,6 @@ from docutils.utils import smartquotes from sphinx import addnodes from sphinx.builders.html import BuildInfo, StandaloneHTMLBuilder -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.locale import __ from sphinx.util import logging from sphinx.util import status_iterator @@ -188,18 +186,6 @@ class EpubBuilder(StandaloneHTMLBuilder): self.id_cache[name] = id return id - def esc(self, name: str) -> str: - """Replace all characters not allowed in text an attribute values.""" - warnings.warn( - '%s.esc() is deprecated. Use html.escape() instead.' % self.__class__.__name__, - RemovedInSphinx40Warning) - name = name.replace('&', '&') - name = name.replace('<', '<') - name = name.replace('>', '>') - name = name.replace('"', '"') - name = name.replace('\'', ''') - return name - def get_refnodes(self, doctree: Node, result: List[Dict[str, Any]]) -> List[Dict[str, Any]]: # NOQA """Collect section titles, their depth in the toc and the refuri.""" # XXX: is there a better way than checking the attribute @@ -476,30 +462,17 @@ class EpubBuilder(StandaloneHTMLBuilder): addctx['doctype'] = self.doctype super().handle_page(pagename, addctx, templatename, outfilename, event_arg) - def build_mimetype(self, outdir: str = None, outname: str = 'mimetype') -> None: + def build_mimetype(self) -> None: """Write the metainfo file mimetype.""" - if outdir: - warnings.warn('The arguments of EpubBuilder.build_mimetype() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - else: - outdir = self.outdir - - logger.info(__('writing %s file...'), outname) - copy_asset_file(path.join(self.template_dir, 'mimetype'), - path.join(outdir, outname)) + logger.info(__('writing mimetype file...')) + copy_asset_file(path.join(self.template_dir, 'mimetype'), self.outdir) - def build_container(self, outdir: str = None, outname: str = 'META-INF/container.xml') -> None: # NOQA + def build_container(self, outname: str = 'META-INF/container.xml') -> None: # NOQA """Write the metainfo file META-INF/container.xml.""" - if outdir: - warnings.warn('The arguments of EpubBuilder.build_container() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - else: - outdir = self.outdir - - logger.info(__('writing %s file...'), outname) - filename = path.join(outdir, outname) - ensuredir(path.dirname(filename)) - copy_asset_file(path.join(self.template_dir, 'container.xml'), filename) + logger.info(__('writing META-INF/container.xml file...')) + outdir = path.join(self.outdir, 'META-INF') + ensuredir(outdir) + copy_asset_file(path.join(self.template_dir, 'container.xml'), outdir) def content_metadata(self) -> Dict[str, Any]: """Create a dictionary with all metadata for the content.opf @@ -520,23 +493,17 @@ class EpubBuilder(StandaloneHTMLBuilder): metadata['guides'] = [] return metadata - def build_content(self, outdir: str = None, outname: str = 'content.opf') -> None: + def build_content(self) -> None: """Write the metainfo file content.opf It contains bibliographic data, a file list and the spine (the reading order). """ - if outdir: - warnings.warn('The arguments of EpubBuilder.build_content() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - else: - outdir = self.outdir - - logger.info(__('writing %s file...'), outname) + logger.info(__('writing content.opf file...')) metadata = self.content_metadata() # files - if not outdir.endswith(os.sep): - outdir += os.sep - olen = len(outdir) + if not self.outdir.endswith(os.sep): + self.outdir += os.sep + olen = len(self.outdir) self.files = [] # type: List[str] self.ignored_files = ['.buildinfo', 'mimetype', 'content.opf', 'toc.ncx', 'META-INF/container.xml', @@ -545,7 +512,7 @@ class EpubBuilder(StandaloneHTMLBuilder): self.config.epub_exclude_files if not self.use_index: self.ignored_files.append('genindex' + self.out_suffix) - for root, dirs, files in os.walk(outdir): + for root, dirs, files in os.walk(self.outdir): dirs.sort() for fn in sorted(files): filename = path.join(root, fn)[olen:] @@ -635,9 +602,7 @@ class EpubBuilder(StandaloneHTMLBuilder): html.escape(self.refnodes[0]['refuri']))) # write the project file - copy_asset_file(path.join(self.template_dir, 'content.opf_t'), - path.join(outdir, outname), - metadata) + copy_asset_file(path.join(self.template_dir, 'content.opf_t'), self.outdir, metadata) def new_navpoint(self, node: Dict[str, Any], level: int, incr: bool = True) -> NavPoint: """Create a new entry in the toc from the node at given level.""" @@ -703,15 +668,9 @@ class EpubBuilder(StandaloneHTMLBuilder): metadata['navpoints'] = navpoints return metadata - def build_toc(self, outdir: str = None, outname: str = 'toc.ncx') -> None: + def build_toc(self) -> None: """Write the metainfo file toc.ncx.""" - if outdir: - warnings.warn('The arguments of EpubBuilder.build_toc() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - else: - outdir = self.outdir - - logger.info(__('writing %s file...'), outname) + logger.info(__('writing toc.ncx file...')) if self.config.epub_tocscope == 'default': doctree = self.env.get_and_resolve_doctree(self.config.master_doc, @@ -726,28 +685,21 @@ class EpubBuilder(StandaloneHTMLBuilder): navpoints = self.build_navpoints(refnodes) level = max(item['level'] for item in self.refnodes) level = min(level, self.config.epub_tocdepth) - copy_asset_file(path.join(self.template_dir, 'toc.ncx_t'), - path.join(outdir, outname), + copy_asset_file(path.join(self.template_dir, 'toc.ncx_t'), self.outdir, self.toc_metadata(level, navpoints)) - def build_epub(self, outdir: str = None, outname: str = None) -> None: + def build_epub(self) -> None: """Write the epub file. It is a zip file with the mimetype file stored uncompressed as the first entry. """ - if outdir: - warnings.warn('The arguments of EpubBuilder.build_epub() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - else: - outdir = self.outdir - outname = self.config.epub_basename + '.epub' - + outname = self.config.epub_basename + '.epub' logger.info(__('writing %s file...'), outname) - epub_filename = path.join(outdir, outname) + epub_filename = path.join(self.outdir, outname) with ZipFile(epub_filename, 'w', ZIP_DEFLATED) as epub: - epub.write(path.join(outdir, 'mimetype'), 'mimetype', ZIP_STORED) + epub.write(path.join(self.outdir, 'mimetype'), 'mimetype', ZIP_STORED) for filename in ['META-INF/container.xml', 'content.opf', 'toc.ncx']: - epub.write(path.join(outdir, filename), filename, ZIP_DEFLATED) + epub.write(path.join(self.outdir, filename), filename, ZIP_DEFLATED) for filename in self.files: - epub.write(path.join(outdir, filename), filename, ZIP_DEFLATED) + epub.write(path.join(self.outdir, filename), filename, ZIP_DEFLATED) diff --git a/sphinx/builders/applehelp.py b/sphinx/builders/applehelp.py deleted file mode 100644 index f081f9fe5..000000000 --- a/sphinx/builders/applehelp.py +++ /dev/null @@ -1,42 +0,0 @@ -""" - sphinx.builders.applehelp - ~~~~~~~~~~~~~~~~~~~~~~~~~ - - Build Apple help books. - - :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import warnings -from typing import Any, Dict - -from sphinxcontrib.applehelp import ( - AppleHelpCodeSigningFailed, - AppleHelpIndexerFailed, - AppleHelpBuilder, -) - -from sphinx.application import Sphinx -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias - - -deprecated_alias('sphinx.builders.applehelp', - { - 'AppleHelpCodeSigningFailed': AppleHelpCodeSigningFailed, - 'AppleHelpIndexerFailed': AppleHelpIndexerFailed, - 'AppleHelpBuilder': AppleHelpBuilder, - }, - RemovedInSphinx40Warning) - - -def setup(app: Sphinx) -> Dict[str, Any]: - warnings.warn('sphinx.builders.applehelp has been moved to sphinxcontrib-applehelp.', - RemovedInSphinx40Warning) - app.setup_extension('sphinxcontrib.applehelp') - - return { - 'version': 'builtin', - 'parallel_read_safe': True, - 'parallel_write_safe': True, - } diff --git a/sphinx/builders/devhelp.py b/sphinx/builders/devhelp.py deleted file mode 100644 index dda7c411f..000000000 --- a/sphinx/builders/devhelp.py +++ /dev/null @@ -1,38 +0,0 @@ -""" - sphinx.builders.devhelp - ~~~~~~~~~~~~~~~~~~~~~~~ - - Build HTML documentation and Devhelp_ support files. - - .. _Devhelp: https://wiki.gnome.org/Apps/Devhelp - - :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import warnings -from typing import Any, Dict - -from sphinxcontrib.devhelp import DevhelpBuilder - -from sphinx.application import Sphinx -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias - - -deprecated_alias('sphinx.builders.devhelp', - { - 'DevhelpBuilder': DevhelpBuilder, - }, - RemovedInSphinx40Warning) - - -def setup(app: Sphinx) -> Dict[str, Any]: - warnings.warn('sphinx.builders.devhelp has been moved to sphinxcontrib-devhelp.', - RemovedInSphinx40Warning) - app.setup_extension('sphinxcontrib.devhelp') - - return { - 'version': 'builtin', - 'parallel_read_safe': True, - 'parallel_write_safe': True, - } diff --git a/sphinx/builders/dirhtml.py b/sphinx/builders/dirhtml.py index ba60c923c..bf940010a 100644 --- a/sphinx/builders/dirhtml.py +++ b/sphinx/builders/dirhtml.py @@ -13,7 +13,6 @@ from typing import Any, Dict from sphinx.application import Sphinx from sphinx.builders.html import StandaloneHTMLBuilder -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.util import logging from sphinx.util.osutil import SEP, os_path @@ -46,14 +45,6 @@ class DirectoryHTMLBuilder(StandaloneHTMLBuilder): return outfilename -# for compatibility -deprecated_alias('sphinx.builders.html', - { - 'DirectoryHTMLBuilder': DirectoryHTMLBuilder, - }, - RemovedInSphinx40Warning) - - def setup(app: Sphinx) -> Dict[str, Any]: app.setup_extension('sphinx.builders.html') diff --git a/sphinx/builders/epub3.py b/sphinx/builders/epub3.py index b70f7b7cb..1bef3c5bb 100644 --- a/sphinx/builders/epub3.py +++ b/sphinx/builders/epub3.py @@ -10,7 +10,6 @@ """ import html -import warnings from os import path from typing import Any, Dict, List, NamedTuple, Set, Tuple @@ -18,7 +17,6 @@ from sphinx import package_dir from sphinx.application import Sphinx from sphinx.builders import _epub_base from sphinx.config import Config, ENUM -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.locale import __ from sphinx.util import logging, xmlname_checker from sphinx.util.fileutil import copy_asset_file @@ -85,10 +83,6 @@ class Epub3Builder(_epub_base.EpubBuilder): self.build_toc() self.build_epub() - def validate_config_value(self) -> None: - warnings.warn('Epub3Builder.validate_config_value() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - def content_metadata(self) -> Dict: """Create a dictionary with all metadata for the content.opf file properly escaped. @@ -166,15 +160,9 @@ class Epub3Builder(_epub_base.EpubBuilder): metadata['navlist'] = navlist return metadata - def build_navigation_doc(self, outdir: str = None, outname: str = 'nav.xhtml') -> None: + def build_navigation_doc(self) -> None: """Write the metainfo file nav.xhtml.""" - if outdir: - warnings.warn('The arguments of Epub3Builder.build_navigation_doc() ' - 'is deprecated.', RemovedInSphinx40Warning, stacklevel=2) - else: - outdir = self.outdir - - logger.info(__('writing %s file...'), outname) + logger.info(__('writing nav.xhtml file...')) if self.config.epub_tocscope == 'default': doctree = self.env.get_and_resolve_doctree( @@ -186,13 +174,12 @@ class Epub3Builder(_epub_base.EpubBuilder): # 'includehidden' refnodes = self.refnodes navlist = self.build_navlist(refnodes) - copy_asset_file(path.join(self.template_dir, 'nav.xhtml_t'), - path.join(outdir, outname), + copy_asset_file(path.join(self.template_dir, 'nav.xhtml_t'), self.outdir, self.navigation_doc_metadata(navlist)) # Add nav.xhtml to epub file - if outname not in self.files: - self.files.append(outname) + if 'nav.xhtml' not in self.files: + self.files.append('nav.xhtml') def validate_config_values(app: Sphinx) -> None: diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py index 3fb7595ee..cfc615847 100644 --- a/sphinx/builders/gettext.py +++ b/sphinx/builders/gettext.py @@ -36,27 +36,6 @@ from sphinx.util.template import SphinxRenderer logger = logging.getLogger(__name__) -POHEADER = r""" -# SOME DESCRIPTIVE TITLE. -# Copyright (C) %(copyright)s -# This file is distributed under the same license as the %(project)s package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: %(project)s %(version)s\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: %(ctime)s\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -"""[1:] # RemovedInSphinx40Warning - class Message: """An entry of translatable message.""" diff --git a/sphinx/builders/html/__init__.py b/sphinx/builders/html/__init__.py index 0e74c0df8..27e1d8e6a 100644 --- a/sphinx/builders/html/__init__.py +++ b/sphinx/builders/html/__init__.py @@ -12,7 +12,6 @@ import html import posixpath import re import sys -import warnings from hashlib import md5 from os import path from typing import Any, Dict, IO, Iterable, Iterator, List, Set, Tuple, Type @@ -28,7 +27,6 @@ from sphinx import package_dir, __display_version__ from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.config import Config -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.domains import Domain, Index, IndexEntry from sphinx.environment.adapters.asset import ImageAdapter from sphinx.environment.adapters.indexentries import IndexEntries @@ -864,21 +862,11 @@ class StandaloneHTMLBuilder(Builder): # only index pages with title if self.indexer is not None and title: filename = self.env.doc2path(pagename, base=None) - try: - metadata = self.env.metadata.get(pagename, {}) - if 'nosearch' in metadata: - self.indexer.feed(pagename, filename, '', new_document('')) - else: - self.indexer.feed(pagename, filename, title, doctree) - except TypeError: - # fallback for old search-adapters - self.indexer.feed(pagename, title, doctree) # type: ignore - indexer_name = self.indexer.__class__.__name__ - warnings.warn( - 'The %s.feed() method signature is deprecated. Update to ' - '%s.feed(docname, filename, title, doctree).' % ( - indexer_name, indexer_name), - RemovedInSphinx40Warning) + metadata = self.env.metadata.get(pagename, {}) + if 'nosearch' in metadata: + self.indexer.feed(pagename, filename, '', new_document('')) + else: + self.indexer.feed(pagename, filename, title, doctree) def _get_local_toctree(self, docname: str, collapse: bool = True, **kwargs: Any) -> str: if 'includehidden' not in kwargs: diff --git a/sphinx/builders/htmlhelp.py b/sphinx/builders/htmlhelp.py deleted file mode 100644 index 8732de7fd..000000000 --- a/sphinx/builders/htmlhelp.py +++ /dev/null @@ -1,42 +0,0 @@ -""" - sphinx.builders.htmlhelp - ~~~~~~~~~~~~~~~~~~~~~~~~ - - Build HTML help support files. - Parts adapted from Python's Doc/tools/prechm.py. - - :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import warnings -from typing import Any, Dict - -from sphinxcontrib.htmlhelp import ( - chm_locales, chm_htmlescape, HTMLHelpBuilder, default_htmlhelp_basename -) - -from sphinx.application import Sphinx -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias - - -deprecated_alias('sphinx.builders.htmlhelp', - { - 'chm_locales': chm_locales, - 'chm_htmlescape': chm_htmlescape, - 'HTMLHelpBuilder': HTMLHelpBuilder, - 'default_htmlhelp_basename': default_htmlhelp_basename, - }, - RemovedInSphinx40Warning) - - -def setup(app: Sphinx) -> Dict[str, Any]: - warnings.warn('sphinx.builders.htmlhelp has been moved to sphinxcontrib-htmlhelp.', - RemovedInSphinx40Warning) - app.setup_extension('sphinxcontrib.htmlhelp') - - return { - 'version': 'builtin', - 'parallel_read_safe': True, - 'parallel_write_safe': True, - } diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py index b1fe4b73e..467a80e99 100644 --- a/sphinx/builders/latex/__init__.py +++ b/sphinx/builders/latex/__init__.py @@ -9,7 +9,6 @@ """ import os -import warnings from os import path from typing import Any, Dict, Iterable, List, Tuple, Union @@ -24,7 +23,6 @@ from sphinx.builders.latex.constants import ADDITIONAL_SETTINGS, DEFAULT_SETTING from sphinx.builders.latex.theming import Theme, ThemeFactory from sphinx.builders.latex.util import ExtBabel from sphinx.config import Config, ENUM -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.environment.adapters.asset import ImageAdapter from sphinx.errors import NoUri, SphinxError from sphinx.locale import _, __ @@ -259,7 +257,6 @@ class LaTeXBuilder(Builder): defaults=self.env.settings, components=(docwriter,), read_config_files=True).get_default_values() # type: Any - patch_settings(docsettings) self.init_document_data() self.write_stylesheet() @@ -361,10 +358,6 @@ class LaTeXBuilder(Builder): pendingnode.replace_self(newnodes) return largetree - def apply_transforms(self, doctree: nodes.document) -> None: - warnings.warn('LaTeXBuilder.apply_transforms() is deprecated.', - RemovedInSphinx40Warning) - def finish(self) -> None: self.copy_image_files() self.write_message_catalog() @@ -447,44 +440,6 @@ class LaTeXBuilder(Builder): copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer()) -def patch_settings(settings: Any) -> Any: - """Make settings object to show deprecation messages.""" - - class Values(type(settings)): # type: ignore - @property - def author(self) -> str: - warnings.warn('settings.author is deprecated', - RemovedInSphinx40Warning, stacklevel=2) - return self._author - - @property - def title(self) -> str: - warnings.warn('settings.title is deprecated', - RemovedInSphinx40Warning, stacklevel=2) - return self._title - - @property - def contentsname(self) -> str: - warnings.warn('settings.contentsname is deprecated', - RemovedInSphinx40Warning, stacklevel=2) - return self._contentsname - - @property - def docname(self) -> str: - warnings.warn('settings.docname is deprecated', - RemovedInSphinx40Warning, stacklevel=2) - return self._docname - - @property - def docclass(self) -> str: - warnings.warn('settings.docclass is deprecated', - RemovedInSphinx40Warning, stacklevel=2) - return self._docclass - - # dynamic subclassing - settings.__class__ = Values - - def validate_config_values(app: Sphinx, config: Config) -> None: for key in list(config.latex_elements): if key not in DEFAULT_SETTINGS: diff --git a/sphinx/builders/qthelp.py b/sphinx/builders/qthelp.py deleted file mode 100644 index a4e73de9b..000000000 --- a/sphinx/builders/qthelp.py +++ /dev/null @@ -1,39 +0,0 @@ -""" - sphinx.builders.qthelp - ~~~~~~~~~~~~~~~~~~~~~~ - - Build input files for the Qt collection generator. - - :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import warnings -from typing import Any, Dict - -from sphinxcontrib.qthelp import QtHelpBuilder, render_file - -import sphinx -from sphinx.application import Sphinx -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias - - -deprecated_alias('sphinx.builders.qthelp', - { - 'render_file': render_file, - 'QtHelpBuilder': QtHelpBuilder, - }, - RemovedInSphinx40Warning) - - -def setup(app: Sphinx) -> Dict[str, Any]: - warnings.warn('sphinx.builders.qthelp has been moved to sphinxcontrib-qthelp.', - RemovedInSphinx40Warning) - - app.setup_extension('sphinxcontrib.qthelp') - - return { - 'version': sphinx.__display_version__, - 'parallel_read_safe': True, - 'parallel_write_safe': True, - } diff --git a/sphinx/builders/singlehtml.py b/sphinx/builders/singlehtml.py index b145109a6..19ad9c08d 100644 --- a/sphinx/builders/singlehtml.py +++ b/sphinx/builders/singlehtml.py @@ -16,7 +16,6 @@ from docutils.nodes import Node from sphinx.application import Sphinx from sphinx.builders.html import StandaloneHTMLBuilder -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.environment.adapters.toctree import TocTree from sphinx.locale import __ from sphinx.util import logging @@ -188,14 +187,6 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder): self.handle_page('opensearch', {}, 'opensearch.xml', outfilename=fn) -# for compatibility -deprecated_alias('sphinx.builders.html', - { - 'SingleFileHTMLBuilder': SingleFileHTMLBuilder, - }, - RemovedInSphinx40Warning) - - def setup(app: Sphinx) -> Dict[str, Any]: app.setup_extension('sphinx.builders.html') diff --git a/sphinx/cmd/quickstart.py b/sphinx/cmd/quickstart.py index 8f8ae58a1..802549304 100644 --- a/sphinx/cmd/quickstart.py +++ b/sphinx/cmd/quickstart.py @@ -11,13 +11,11 @@ import argparse import locale import os -import re import sys import time -import warnings from collections import OrderedDict from os import path -from typing import Any, Callable, Dict, List, Pattern, Union +from typing import Any, Callable, Dict, List, Union # try to import readline, unix specific enhancement try: @@ -35,16 +33,11 @@ from docutils.utils import column_width import sphinx.locale from sphinx import __display_version__, package_dir -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.locale import __ -from sphinx.util.console import ( # type: ignore - colorize, bold, red, turquoise, nocolor, color_terminal -) +from sphinx.util.console import colorize, bold, red, nocolor, color_terminal # type: ignore from sphinx.util.osutil import ensuredir from sphinx.util.template import SphinxRenderer -TERM_ENCODING = getattr(sys.stdin, 'encoding', None) # RemovedInSphinx40Warning - EXTENSIONS = OrderedDict([ ('autodoc', __('automatically insert docstrings from modules')), ('doctest', __('automatically test code snippets in doctest blocks')), @@ -135,30 +128,6 @@ def ok(x: str) -> str: return x -def term_decode(text: Union[bytes, str]) -> str: - warnings.warn('term_decode() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - - if isinstance(text, str): - return text - - # Use the known encoding, if possible - if TERM_ENCODING: - return text.decode(TERM_ENCODING) - - # If ascii is safe, use it with no warning - if text.decode('ascii', 'replace').encode('ascii', 'replace') == text: - return text.decode('ascii') - - print(turquoise(__('* Note: non-ASCII characters entered ' - 'and terminal encoding unknown -- assuming ' - 'UTF-8 or Latin-1.'))) - try: - return text.decode() - except UnicodeDecodeError: - return text.decode('latin1') - - def do_prompt(text: str, default: str = None, validator: Callable[[str], Any] = nonempty) -> Union[str, bool]: # NOQA while True: if default is not None: @@ -184,13 +153,6 @@ def do_prompt(text: str, default: str = None, validator: Callable[[str], Any] = return x -def convert_python_source(source: str, rex: Pattern = re.compile(r"[uU]('.*?')")) -> str: - # remove Unicode literal prefixes - warnings.warn('convert_python_source() is deprecated.', - RemovedInSphinx40Warning) - return rex.sub('\\1', source) - - class QuickstartRenderer(SphinxRenderer): def __init__(self, templatedir: str) -> None: self.templatedir = templatedir or '' diff --git a/sphinx/config.py b/sphinx/config.py index aefb60c2b..deccc3e62 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -11,7 +11,6 @@ import re import traceback import types -import warnings from collections import OrderedDict from os import path, getenv from typing import ( @@ -19,7 +18,6 @@ from typing import ( ) from typing import TYPE_CHECKING -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.errors import ConfigError, ExtensionError from sphinx.locale import _, __ from sphinx.util import logging @@ -75,10 +73,6 @@ class ENUM: return value in self.candidates -# RemovedInSphinx40Warning -string_classes = [str] # type: List - - class Config: """Configuration file abstraction. @@ -442,22 +436,6 @@ def check_confval_types(app: "Sphinx", config: Config) -> None: default=type(default))) -def check_unicode(config: Config) -> None: - """check all string values for non-ASCII characters in bytestrings, - since that can result in UnicodeErrors all over the place - """ - warnings.warn('sphinx.config.check_unicode() is deprecated.', - RemovedInSphinx40Warning) - - nonascii_re = re.compile(br'[\x80-\xff]') - - for name, value in config._raw_config.items(): - if isinstance(value, bytes) and nonascii_re.search(value): - logger.warning(__('the config value %r is set to a string with non-ASCII ' - 'characters; this can lead to Unicode errors occurring. ' - 'Please use Unicode strings, e.g. %r.'), name, 'Content') - - def check_primary_domain(app: "Sphinx", config: Config) -> None: primary_domain = config.primary_domain if primary_domain and not app.registry.has_domain(primary_domain): diff --git a/sphinx/deprecation.py b/sphinx/deprecation.py index 0b980a193..77b462da8 100644 --- a/sphinx/deprecation.py +++ b/sphinx/deprecation.py @@ -18,7 +18,7 @@ class RemovedInSphinx40Warning(DeprecationWarning): pass -class RemovedInSphinx50Warning(PendingDeprecationWarning): +class RemovedInSphinx50Warning(DeprecationWarning): pass @@ -26,7 +26,7 @@ class RemovedInSphinx60Warning(PendingDeprecationWarning): pass -RemovedInNextVersionWarning = RemovedInSphinx40Warning +RemovedInNextVersionWarning = RemovedInSphinx50Warning def deprecated_alias(modname: str, objects: Dict, warning: "Type[Warning]") -> None: diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py index a29a51d95..7684931c7 100644 --- a/sphinx/directives/__init__.py +++ b/sphinx/directives/__init__.py @@ -18,9 +18,7 @@ from docutils.parsers.rst import directives, roles from sphinx import addnodes from sphinx.addnodes import desc_signature -from sphinx.deprecation import ( - RemovedInSphinx40Warning, RemovedInSphinx50Warning, deprecated_alias -) +from sphinx.deprecation import RemovedInSphinx50Warning, deprecated_alias from sphinx.util import docutils from sphinx.util.docfields import DocFieldTransformer, Field, TypedField from sphinx.util.docutils import SphinxDirective @@ -265,39 +263,6 @@ class DefaultDomain(SphinxDirective): self.env.temp_data['default_domain'] = self.env.domains.get(domain_name) return [] -from sphinx.directives.code import ( # noqa - Highlight, CodeBlock, LiteralInclude -) -from sphinx.directives.other import ( # noqa - TocTree, Author, VersionChange, SeeAlso, - TabularColumns, Centered, Acks, HList, Only, Include, Class -) -from sphinx.directives.patches import ( # noqa - Figure, Meta -) -from sphinx.domains.index import IndexDirective # noqa - -deprecated_alias('sphinx.directives', - { - 'Highlight': Highlight, - 'CodeBlock': CodeBlock, - 'LiteralInclude': LiteralInclude, - 'TocTree': TocTree, - 'Author': Author, - 'Index': IndexDirective, - 'VersionChange': VersionChange, - 'SeeAlso': SeeAlso, - 'TabularColumns': TabularColumns, - 'Centered': Centered, - 'Acks': Acks, - 'HList': HList, - 'Only': Only, - 'Include': Include, - 'Class': Class, - 'Figure': Figure, - 'Meta': Meta, - }, - RemovedInSphinx40Warning) deprecated_alias('sphinx.directives', { diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py index c743ec69e..fabf259e8 100644 --- a/sphinx/directives/code.py +++ b/sphinx/directives/code.py @@ -7,7 +7,6 @@ """ import sys -import warnings from difflib import unified_diff from typing import Any, Dict, List, Tuple from typing import TYPE_CHECKING @@ -19,7 +18,6 @@ from docutils.statemachine import StringList from sphinx import addnodes from sphinx.config import Config -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.locale import __ from sphinx.util import logging from sphinx.util import parselinenos @@ -57,16 +55,6 @@ class Highlight(SphinxDirective): linenothreshold=linenothreshold)] -class HighlightLang(Highlight): - """highlightlang directive (deprecated)""" - - def run(self) -> List[Node]: - warnings.warn('highlightlang directive is deprecated. ' - 'Please use highlight directive instead.', - RemovedInSphinx40Warning, stacklevel=2) - return super().run() - - def dedent_lines(lines: List[str], dedent: int, location: Tuple[str, int] = None) -> List[str]: if not dedent: return lines @@ -468,7 +456,6 @@ class LiteralInclude(SphinxDirective): def setup(app: "Sphinx") -> Dict[str, Any]: directives.register_directive('highlight', Highlight) - directives.register_directive('highlightlang', HighlightLang) directives.register_directive('code-block', CodeBlock) directives.register_directive('sourcecode', CodeBlock) directives.register_directive('literalinclude', LiteralInclude) diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py index 949e85235..fc1631edc 100644 --- a/sphinx/directives/other.py +++ b/sphinx/directives/other.py @@ -18,7 +18,6 @@ from docutils.parsers.rst.directives.misc import Class from docutils.parsers.rst.directives.misc import Include as BaseInclude from sphinx import addnodes -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.domains.changeset import VersionChange # NOQA # for compatibility from sphinx.locale import _ from sphinx.util import url_re, docname_join @@ -360,16 +359,6 @@ class Include(BaseInclude, SphinxDirective): return super().run() -# Import old modules here for compatibility -from sphinx.domains.index import IndexDirective # NOQA - -deprecated_alias('sphinx.directives.other', - { - 'Index': IndexDirective, - }, - RemovedInSphinx40Warning) - - def setup(app: "Sphinx") -> Dict[str, Any]: directives.register_directive('toctree', TocTree) directives.register_directive('sectionauthor', Author) diff --git a/sphinx/domains/math.py b/sphinx/domains/math.py index 49c57bda8..02c93433a 100644 --- a/sphinx/domains/math.py +++ b/sphinx/domains/math.py @@ -8,7 +8,6 @@ :license: BSD, see LICENSE for details. """ -import warnings from typing import Any, Dict, Iterable, List, Tuple from typing import TYPE_CHECKING @@ -17,7 +16,6 @@ from docutils.nodes import Element, Node, system_message from docutils.nodes import make_id from sphinx.addnodes import pending_xref -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.domains import Domain from sphinx.environment import BuildEnvironment from sphinx.locale import __ @@ -140,24 +138,6 @@ class MathDomain(Domain): def get_objects(self) -> List: return [] - def add_equation(self, env: BuildEnvironment, docname: str, labelid: str) -> int: - warnings.warn('MathDomain.add_equation() is deprecated.', - RemovedInSphinx40Warning) - if labelid in self.equations: - path = env.doc2path(self.equations[labelid][0]) - msg = __('duplicate label of equation %s, other instance in %s') % (labelid, path) - raise UserWarning(msg) - else: - eqno = self.get_next_equation_number(docname) - self.equations[labelid] = (docname, eqno) - return eqno - - def get_next_equation_number(self, docname: str) -> int: - warnings.warn('MathDomain.get_next_equation_number() is deprecated.', - RemovedInSphinx40Warning) - targets = [eq for eq in self.equations.values() if eq[0] == docname] - return len(targets) + 1 - def has_equations(self) -> bool: return any(self.data['has_equations'].values()) diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index 11bf0ac4d..91ba489c7 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -25,7 +25,7 @@ from sphinx import addnodes from sphinx.addnodes import pending_xref, desc_signature from sphinx.application import Sphinx from sphinx.builders import Builder -from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning +from sphinx.deprecation import RemovedInSphinx50Warning from sphinx.directives import ObjectDescription from sphinx.domains import Domain, ObjType, Index, IndexEntry from sphinx.environment import BuildEnvironment @@ -516,39 +516,6 @@ class PyObject(ObjectDescription): self.env.ref_context.pop('py:module') -class PyModulelevel(PyObject): - """ - Description of an object on module level (functions, data). - """ - - def run(self) -> List[Node]: - for cls in self.__class__.__mro__: - if cls.__name__ != 'DirectiveAdapter': - warnings.warn('PyModulelevel is deprecated. ' - 'Please check the implementation of %s' % cls, - RemovedInSphinx40Warning) - break - else: - warnings.warn('PyModulelevel is deprecated', RemovedInSphinx40Warning) - - return super().run() - - def needs_arglist(self) -> bool: - return self.objtype == 'function' - - def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str: - if self.objtype == 'function': - if not modname: - return _('%s() (built-in function)') % name_cls[0] - return _('%s() (in module %s)') % (name_cls[0], modname) - elif self.objtype == 'data': - if not modname: - return _('%s (built-in variable)') % name_cls[0] - return _('%s (in module %s)') % (name_cls[0], modname) - else: - return '' - - class PyFunction(PyObject): """Description of a function.""" @@ -653,90 +620,6 @@ class PyClasslike(PyObject): return '' -class PyClassmember(PyObject): - """ - Description of a class member (methods, attributes). - """ - - def run(self) -> List[Node]: - for cls in self.__class__.__mro__: - if cls.__name__ != 'DirectiveAdapter': - warnings.warn('PyClassmember is deprecated. ' - 'Please check the implementation of %s' % cls, - RemovedInSphinx40Warning) - break - else: - warnings.warn('PyClassmember is deprecated', RemovedInSphinx40Warning) - - return super().run() - - def needs_arglist(self) -> bool: - return self.objtype.endswith('method') - - def get_signature_prefix(self, sig: str) -> str: - if self.objtype == 'staticmethod': - return 'static ' - elif self.objtype == 'classmethod': - return 'classmethod ' - return '' - - def get_index_text(self, modname: str, name_cls: Tuple[str, str]) -> str: - name, cls = name_cls - add_modules = self.env.config.add_module_names - if self.objtype == 'method': - try: - clsname, methname = name.rsplit('.', 1) - except ValueError: - if modname: - return _('%s() (in module %s)') % (name, modname) - else: - return '%s()' % name - if modname and add_modules: - return _('%s() (%s.%s method)') % (methname, modname, clsname) - else: - return _('%s() (%s method)') % (methname, clsname) - elif self.objtype == 'staticmethod': - try: - clsname, methname = name.rsplit('.', 1) - except ValueError: - if modname: - return _('%s() (in module %s)') % (name, modname) - else: - return '%s()' % name - if modname and add_modules: - return _('%s() (%s.%s static method)') % (methname, modname, - clsname) - else: - return _('%s() (%s static method)') % (methname, clsname) - elif self.objtype == 'classmethod': - try: - clsname, methname = name.rsplit('.', 1) - except ValueError: - if modname: - return _('%s() (in module %s)') % (name, modname) - else: - return '%s()' % name - if modname: - return _('%s() (%s.%s class method)') % (methname, modname, - clsname) - else: - return _('%s() (%s class method)') % (methname, clsname) - elif self.objtype == 'attribute': - try: - clsname, attrname = name.rsplit('.', 1) - except ValueError: - if modname: - return _('%s (in module %s)') % (name, modname) - else: - return name - if modname and add_modules: - return _('%s (%s.%s attribute)') % (attrname, modname, clsname) - else: - return _('%s (%s attribute)') % (attrname, clsname) - else: - return '' - - class PyMethod(PyObject): """Description of a method.""" diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 8663b97b2..cd86f5bc1 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -22,7 +22,7 @@ from docutils.statemachine import StringList from sphinx import addnodes from sphinx.addnodes import desc_signature, pending_xref -from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning +from sphinx.deprecation import RemovedInSphinx50Warning from sphinx.directives import ObjectDescription from sphinx.domains import Domain, ObjType from sphinx.locale import _, __ @@ -272,8 +272,8 @@ def split_term_classifiers(line: str) -> List[Optional[str]]: def make_glossary_term(env: "BuildEnvironment", textnodes: Iterable[Node], index_key: str, - source: str, lineno: int, node_id: str = None, - document: nodes.document = None) -> nodes.term: + source: str, lineno: int, node_id: str, document: nodes.document + ) -> nodes.term: # get a text-only representation of the term and register it # as a cross-reference target term = nodes.term('', '', *textnodes) @@ -284,23 +284,10 @@ def make_glossary_term(env: "BuildEnvironment", textnodes: Iterable[Node], index if node_id: # node_id is given from outside (mainly i18n module), use it forcedly term['ids'].append(node_id) - elif document: + else: node_id = make_id(env, document, 'term', termtext) term['ids'].append(node_id) document.note_explicit_target(term) - else: - warnings.warn('make_glossary_term() expects document is passed as an argument.', - RemovedInSphinx40Warning) - gloss_entries = env.temp_data.setdefault('gloss_entries', set()) - node_id = nodes.make_id('term-' + termtext) - if node_id == 'term': - # "term" is not good for node_id. Generate it by sequence number instead. - node_id = 'term-%d' % env.new_serialno('glossary') - - while node_id in gloss_entries: - node_id = 'term-%d' % env.new_serialno('glossary') - gloss_entries.add(node_id) - term['ids'].append(node_id) std = cast(StandardDomain, env.get_domain('std')) std.note_object('term', termtext, node_id, location=term) @@ -408,7 +395,7 @@ class Glossary(SphinxDirective): # use first classifier as a index key term = make_glossary_term(self.env, textnodes, parts[1], source, lineno, - document=self.state.document) + node_id=None, document=self.state.document) term.rawsource = line system_messages.extend(sysmsg) termtexts.append(term.astext()) @@ -782,11 +769,6 @@ class StandardDomain(Domain): resolver = self._resolve_doc_xref elif typ == 'option': resolver = self._resolve_option_xref - elif typ == 'citation': - warnings.warn('pending_xref(domain=std, type=citation) is deprecated: %r' % node, - RemovedInSphinx40Warning) - domain = env.get_domain('citation') - return domain.resolve_xref(env, fromdocname, builder, typ, target, node, contnode) elif typ == 'term': resolver = self._resolve_term_xref else: @@ -1078,18 +1060,6 @@ class StandardDomain(Domain): else: return None - def note_citations(self, env: "BuildEnvironment", docname: str, document: nodes.document) -> None: # NOQA - warnings.warn('StandardDomain.note_citations() is deprecated.', - RemovedInSphinx40Warning) - - def note_citation_refs(self, env: "BuildEnvironment", docname: str, document: nodes.document) -> None: # NOQA - warnings.warn('StandardDomain.note_citation_refs() is deprecated.', - RemovedInSphinx40Warning) - - def note_labels(self, env: "BuildEnvironment", docname: str, document: nodes.document) -> None: # NOQA - warnings.warn('StandardDomain.note_labels() is deprecated.', - RemovedInSphinx40Warning) - def setup(app: "Sphinx") -> Dict[str, Any]: app.add_domain(StandardDomain) diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py index 89e51ad83..d786decc8 100644 --- a/sphinx/environment/__init__.py +++ b/sphinx/environment/__init__.py @@ -10,19 +10,17 @@ import os import pickle -import warnings from collections import defaultdict from copy import copy from os import path from typing import Any, Callable, Dict, Generator, Iterator, List, Set, Tuple, Union -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING from docutils import nodes from docutils.nodes import Node from sphinx import addnodes from sphinx.config import Config -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.domains import Domain from sphinx.environment.adapters.toctree import TocTree from sphinx.errors import SphinxError, BuildEnvironmentError, DocumentError, ExtensionError @@ -320,28 +318,13 @@ class BuildEnvironment: """ return self.project.path2doc(filename) - def doc2path(self, docname: str, base: Union[bool, str] = True, suffix: str = None) -> str: + def doc2path(self, docname: str, base: bool = True) -> str: """Return the filename for the document name. If *base* is True, return absolute path under self.srcdir. - If *base* is None, return relative path to self.srcdir. - If *base* is a path string, return absolute path under that. - If *suffix* is not None, add it instead of config.source_suffix. + If *base* is False, return relative path to self.srcdir. """ - if suffix: - warnings.warn('The suffix argument for doc2path() is deprecated.', - RemovedInSphinx40Warning) - if base not in (True, False, None): - warnings.warn('The string style base argument for doc2path() is deprecated.', - RemovedInSphinx40Warning) - - pathname = self.project.doc2path(docname, base is True) - if suffix: - filename, _ = path.splitext(pathname) - pathname = filename + suffix - if base and base is not True: - pathname = path.join(base, pathname) # type: ignore - return pathname + return self.project.doc2path(docname, base) def relfn2path(self, filename: str, docname: str = None) -> Tuple[str, str]: """Return paths to a file referenced from a document, relative to @@ -639,19 +622,3 @@ class BuildEnvironment: for domain in self.domains.values(): domain.check_consistency() self.events.emit('env-check-consistency', self) - - @property - def indexentries(self) -> Dict[str, List[Tuple[str, str, str, str, str]]]: - warnings.warn('env.indexentries() is deprecated. Please use IndexDomain instead.', - RemovedInSphinx40Warning, stacklevel=2) - from sphinx.domains.index import IndexDomain - domain = cast(IndexDomain, self.get_domain('index')) - return domain.entries - - @indexentries.setter - def indexentries(self, entries: Dict[str, List[Tuple[str, str, str, str, str]]]) -> None: - warnings.warn('env.indexentries() is deprecated. Please use IndexDomain instead.', - RemovedInSphinx40Warning, stacklevel=2) - from sphinx.domains.index import IndexDomain - domain = cast(IndexDomain, self.get_domain('index')) - domain.data['entries'] = entries diff --git a/sphinx/environment/collectors/indexentries.py b/sphinx/environment/collectors/indexentries.py deleted file mode 100644 index 2ef59909b..000000000 --- a/sphinx/environment/collectors/indexentries.py +++ /dev/null @@ -1,64 +0,0 @@ -""" - sphinx.environment.collectors.indexentries - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Index entries collector for sphinx.environment. - - :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import warnings -from typing import Any, Dict, Set - -from docutils import nodes - -from sphinx import addnodes -from sphinx.application import Sphinx -from sphinx.deprecation import RemovedInSphinx40Warning -from sphinx.environment import BuildEnvironment -from sphinx.environment.collectors import EnvironmentCollector -from sphinx.util import split_index_msg, logging - - -logger = logging.getLogger(__name__) - - -class IndexEntriesCollector(EnvironmentCollector): - name = 'indices' - - def __init__(self) -> None: - warnings.warn('IndexEntriesCollector is deprecated.', - RemovedInSphinx40Warning) - - def clear_doc(self, app: Sphinx, env: BuildEnvironment, docname: str) -> None: - env.indexentries.pop(docname, None) - - def merge_other(self, app: Sphinx, env: BuildEnvironment, - docnames: Set[str], other: BuildEnvironment) -> None: - for docname in docnames: - env.indexentries[docname] = other.indexentries[docname] - - def process_doc(self, app: Sphinx, doctree: nodes.document) -> None: - docname = app.env.docname - entries = app.env.indexentries[docname] = [] - for node in doctree.traverse(addnodes.index): - try: - for entry in node['entries']: - split_index_msg(entry[0], entry[1]) - except ValueError as exc: - logger.warning(str(exc), location=node) - node.parent.remove(node) - else: - for entry in node['entries']: - entries.append(entry) - - -def setup(app: Sphinx) -> Dict[str, Any]: - app.add_env_collector(IndexEntriesCollector) - - return { - 'version': 'builtin', - 'parallel_read_safe': True, - 'parallel_write_safe': True, - } diff --git a/sphinx/events.py b/sphinx/events.py index 46759eccd..4673fddd8 100644 --- a/sphinx/events.py +++ b/sphinx/events.py @@ -10,13 +10,11 @@ :license: BSD, see LICENSE for details. """ -import warnings from collections import defaultdict from operator import attrgetter from typing import Any, Callable, Dict, List, NamedTuple from typing import TYPE_CHECKING -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.errors import ExtensionError from sphinx.locale import __ from sphinx.util import logging @@ -56,10 +54,7 @@ core_events = { class EventManager: """Event manager for Sphinx.""" - def __init__(self, app: "Sphinx" = None) -> None: - if app is None: - warnings.warn('app argument is required for EventManager.', - RemovedInSphinx40Warning) + def __init__(self, app: "Sphinx") -> None: self.app = app self.events = core_events.copy() self.listeners = defaultdict(list) # type: Dict[str, List[EventListener]] @@ -100,11 +95,7 @@ class EventManager: results = [] listeners = sorted(self.listeners[name], key=attrgetter("priority")) for listener in listeners: - if self.app is None: - # for compatibility; RemovedInSphinx40Warning - results.append(listener.handler(*args)) - else: - results.append(listener.handler(self.app, *args)) + results.append(listener.handler(self.app, *args)) return results def emit_firstresult(self, name: str, *args: Any) -> Any: diff --git a/sphinx/ext/apidoc.py b/sphinx/ext/apidoc.py index 23be0a00a..8e3fbd7d0 100644 --- a/sphinx/ext/apidoc.py +++ b/sphinx/ext/apidoc.py @@ -19,7 +19,6 @@ import glob import locale import os import sys -import warnings from copy import copy from fnmatch import fnmatch from importlib.machinery import EXTENSION_SUFFIXES @@ -29,9 +28,7 @@ from typing import Any, List, Tuple import sphinx.locale from sphinx import __display_version__, package_dir from sphinx.cmd.quickstart import EXTENSIONS -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.locale import __ -from sphinx.util import rst from sphinx.util.osutil import FileAvoidWrite, ensuredir from sphinx.util.template import ReSTRenderer @@ -51,20 +48,6 @@ PY_SUFFIXES = ('.py', '.pyx') + tuple(EXTENSION_SUFFIXES) template_dir = path.join(package_dir, 'templates', 'apidoc') -def makename(package: str, module: str) -> str: - """Join package and module with a dot.""" - warnings.warn('makename() is deprecated.', - RemovedInSphinx40Warning) - # Both package and module can be None/empty. - if package: - name = package - if module: - name += '.' + module - else: - name = module - return name - - def is_initpy(filename: str) -> bool: """Check *filename* is __init__ file or not.""" basename = path.basename(filename) @@ -109,26 +92,6 @@ def write_file(name: str, text: str, opts: Any) -> None: f.write(text) -def format_heading(level: int, text: str, escape: bool = True) -> str: - """Create a heading of <level> [1, 2 or 3 supported].""" - warnings.warn('format_warning() is deprecated.', - RemovedInSphinx40Warning) - if escape: - text = rst.escape(text) - underlining = ['=', '-', '~', ][level - 1] * len(text) - return '%s\n%s\n\n' % (text, underlining) - - -def format_directive(module: str, package: str = None) -> str: - """Create the automodule directive and add the options.""" - warnings.warn('format_directive() is deprecated.', - RemovedInSphinx40Warning) - directive = '.. automodule:: %s\n' % module_join(package, module) - for option in OPTIONS: - directive += ' :%s:\n' % option - return directive - - def create_module_file(package: str, basename: str, opts: Any, user_template_dir: str = None) -> None: """Build the text of the file and write the file.""" @@ -206,33 +169,6 @@ def create_modules_toc_file(modules: List[str], opts: Any, name: str = 'modules' write_file(name, text, opts) -def shall_skip(module: str, opts: Any, excludes: List[str] = []) -> bool: - """Check if we want to skip this module.""" - warnings.warn('shall_skip() is deprecated.', - RemovedInSphinx40Warning) - # skip if the file doesn't exist and not using implicit namespaces - if not opts.implicit_namespaces and not path.exists(module): - return True - - # Are we a package (here defined as __init__.py, not the folder in itself) - if is_initpy(module): - # Yes, check if we have any non-excluded modules at all here - all_skipped = True - basemodule = path.dirname(module) - for submodule in glob.glob(path.join(basemodule, '*.py')): - if not is_excluded(path.join(basemodule, submodule), excludes): - # There's a non-excluded module here, we won't skip - all_skipped = False - if all_skipped: - return True - - # skip if it has a "private" name and this is selected - filename = path.basename(module) - if is_initpy(filename) and filename.startswith('_') and not opts.includeprivate: - return True - return False - - def is_skipped_package(dirname: str, opts: Any, excludes: List[str] = []) -> bool: """Check if we want to skip this module.""" if not path.isdir(dirname): @@ -516,13 +452,6 @@ def main(argv: List[str] = sys.argv[1:]) -> int: return 0 -deprecated_alias('sphinx.ext.apidoc', - { - 'INITPY': '__init__.py', - }, - RemovedInSphinx40Warning) - - # So program can be started with "python -m sphinx.apidoc ..." if __name__ == "__main__": main() diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 490a1f689..af6399310 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -24,7 +24,7 @@ from docutils.statemachine import StringList import sphinx from sphinx.application import Sphinx from sphinx.config import ENUM -from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning +from sphinx.deprecation import RemovedInSphinx50Warning from sphinx.environment import BuildEnvironment from sphinx.ext.autodoc.importer import import_object, get_module_members, get_object_members from sphinx.ext.autodoc.mock import mock @@ -428,12 +428,8 @@ class Documenter: # etc. don't support a prepended module name self.add_line(' :module: %s' % self.modname, sourcename) - def get_doc(self, encoding: str = None, ignore: int = 1) -> List[List[str]]: + def get_doc(self, ignore: int = 1) -> List[List[str]]: """Decode and return lines of the docstring(s) for the object.""" - if encoding is not None: - warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated." - % self.__class__.__name__, - RemovedInSphinx40Warning) docstring = getdoc(self.object, self.get_attr, self.env.config.autodoc_inherit_docstrings) if docstring: @@ -939,11 +935,7 @@ class DocstringSignatureMixin: feature of reading the signature from the docstring. """ - def _find_signature(self, encoding: str = None) -> Tuple[str, str]: - if encoding is not None: - warnings.warn("The 'encoding' argument to autodoc.%s._find_signature() is " - "deprecated." % self.__class__.__name__, - RemovedInSphinx40Warning) + def _find_signature(self) -> Tuple[str, str]: docstrings = self.get_doc() self._new_docstrings = docstrings[:] result = None @@ -973,15 +965,11 @@ class DocstringSignatureMixin: break return result - def get_doc(self, encoding: str = None, ignore: int = 1) -> List[List[str]]: - if encoding is not None: - warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated." - % self.__class__.__name__, - RemovedInSphinx40Warning) + def get_doc(self, ignore: int = 1) -> List[List[str]]: lines = getattr(self, '_new_docstrings', None) if lines is not None: return lines - return super().get_doc(None, ignore) # type: ignore + return super().get_doc(ignore) # type: ignore def format_signature(self, **kwargs: Any) -> str: if self.args is None and self.env.config.autodoc_docstring_signature: # type: ignore @@ -1228,11 +1216,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type: self.add_line(' ' + _('Bases: %s') % ', '.join(bases), sourcename) - def get_doc(self, encoding: str = None, ignore: int = 1) -> List[List[str]]: - if encoding is not None: - warnings.warn("The 'encoding' argument to autodoc.%s.get_doc() is deprecated." - % self.__class__.__name__, - RemovedInSphinx40Warning) + def get_doc(self, ignore: int = 1) -> List[List[str]]: lines = getattr(self, '_new_docstrings', None) if lines is not None: return lines @@ -1721,7 +1705,7 @@ class SlotsAttributeDocumenter(AttributeDocumenter): self.env.note_reread() return False - def get_doc(self, encoding: str = None, ignore: int = 1) -> List[List[str]]: + def get_doc(self, ignore: int = 1) -> List[List[str]]: """Decode and return lines of the docstring(s) for the object.""" name = self.objpath[-1] __slots__ = safe_getattr(self.parent, '__slots__', []) diff --git a/sphinx/ext/autodoc/directive.py b/sphinx/ext/autodoc/directive.py index c12d451be..5543059cb 100644 --- a/sphinx/ext/autodoc/directive.py +++ b/sphinx/ext/autodoc/directive.py @@ -6,17 +6,15 @@ :license: BSD, see LICENSE for details. """ -import warnings from typing import Any, Callable, Dict, List, Set, Type from docutils import nodes from docutils.nodes import Element, Node -from docutils.parsers.rst.states import RSTState, Struct +from docutils.parsers.rst.states import RSTState from docutils.statemachine import StringList from docutils.utils import Reporter, assemble_option_dict from sphinx.config import Config -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.environment import BuildEnvironment from sphinx.ext.autodoc import Documenter, Options from sphinx.util import logging @@ -49,23 +47,14 @@ class DocumenterBridge: """A parameters container for Documenters.""" def __init__(self, env: BuildEnvironment, reporter: Reporter, options: Options, - lineno: int, state: Any = None) -> None: + lineno: int, state: Any) -> None: self.env = env self.reporter = reporter self.genopt = options self.lineno = lineno self.filename_set = set() # type: Set[str] self.result = StringList() - - if state: - self.state = state - else: - # create fake object for self.state.document.settings.tab_width - warnings.warn('DocumenterBridge requires a state object on instantiation.', - RemovedInSphinx40Warning) - settings = Struct(tab_width=8) - document = Struct(settings=settings) - self.state = Struct(document=document) + self.state = state def warn(self, msg: str) -> None: logger.warning(msg, location=(self.env.docname, self.lineno)) diff --git a/sphinx/ext/autodoc/importer.py b/sphinx/ext/autodoc/importer.py index a7d68d8fa..67106b77a 100644 --- a/sphinx/ext/autodoc/importer.py +++ b/sphinx/ext/autodoc/importer.py @@ -13,7 +13,6 @@ import traceback import warnings from typing import Any, Callable, Dict, List, Mapping, NamedTuple, Tuple -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.util import logging from sphinx.util.inspect import isclass, isenumclass, safe_getattr @@ -179,18 +178,3 @@ def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable, members[name] = Attribute(name, True, INSTANCEATTR) return members - - -from sphinx.ext.autodoc.mock import ( # NOQA - _MockModule, _MockObject, MockFinder, MockLoader, mock -) - -deprecated_alias('sphinx.ext.autodoc.importer', - { - '_MockModule': _MockModule, - '_MockObject': _MockObject, - 'MockFinder': MockFinder, - 'MockLoader': MockLoader, - 'mock': mock, - }, - RemovedInSphinx40Warning) diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index 539d72057..861b1e6b0 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -66,13 +66,13 @@ from typing import cast from docutils import nodes from docutils.nodes import Element, Node, system_message from docutils.parsers.rst import directives -from docutils.parsers.rst.states import Inliner, RSTStateMachine, Struct, state_classes +from docutils.parsers.rst.states import RSTStateMachine, Struct, state_classes from docutils.statemachine import StringList import sphinx from sphinx import addnodes from sphinx.application import Sphinx -from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning +from sphinx.deprecation import RemovedInSphinx50Warning from sphinx.environment import BuildEnvironment from sphinx.environment.adapters.toctree import TocTree from sphinx.ext.autodoc import Documenter @@ -404,29 +404,6 @@ class Autosummary(SphinxDirective): return [table_spec, table] - def warn(self, msg: str) -> None: - warnings.warn('Autosummary.warn() is deprecated', - RemovedInSphinx40Warning, stacklevel=2) - logger.warning(msg) - - @property - def genopt(self) -> Options: - warnings.warn('Autosummary.genopt is deprecated', - RemovedInSphinx40Warning, stacklevel=2) - return self.bridge.genopt - - @property - def warnings(self) -> List[Node]: - warnings.warn('Autosummary.warnings is deprecated', - RemovedInSphinx40Warning, stacklevel=2) - return [] - - @property - def result(self) -> StringList: - warnings.warn('Autosummary.result is deprecated', - RemovedInSphinx40Warning, stacklevel=2) - return self.bridge.result - def strip_arg_typehint(s: str) -> str: """Strip a type hint from argument definition.""" @@ -647,33 +624,6 @@ def _import_by_name(name: str) -> Tuple[Any, Any, str]: # -- :autolink: (smart default role) ------------------------------------------- -def autolink_role(typ: str, rawtext: str, etext: str, lineno: int, inliner: Inliner, - options: Dict = {}, content: List[str] = [] - ) -> Tuple[List[Node], List[system_message]]: - """Smart linking role. - - Expands to ':obj:`text`' if `text` is an object that can be imported; - otherwise expands to '*text*'. - """ - warnings.warn('autolink_role() is deprecated.', RemovedInSphinx40Warning) - env = inliner.document.settings.env - pyobj_role = env.get_domain('py').role('obj') - objects, msg = pyobj_role('obj', rawtext, etext, lineno, inliner, options, content) - if msg != []: - return objects, msg - - assert len(objects) == 1 - pending_xref = cast(addnodes.pending_xref, objects[0]) - prefixes = get_import_prefixes_from_env(env) - try: - name, obj, parent, modname = import_by_name(pending_xref['reftarget'], prefixes) - except ImportError: - literal = cast(nodes.literal, pending_xref[0]) - objects[0] = nodes.emphasis(rawtext, literal.astext(), classes=literal['classes']) - - return objects, msg - - class AutoLink(SphinxRole): """Smart linking role. diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index acc2a2883..d046a54a7 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -27,7 +27,7 @@ import sys import warnings from gettext import NullTranslations from os import path -from typing import Any, Callable, Dict, List, NamedTuple, Set, Tuple, Type, Union +from typing import Any, Dict, List, NamedTuple, Set, Tuple, Type, Union from jinja2 import TemplateNotFound from jinja2.sandbox import SandboxedEnvironment @@ -38,7 +38,7 @@ from sphinx import package_dir from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.config import Config -from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning +from sphinx.deprecation import RemovedInSphinx50Warning from sphinx.ext.autodoc import Documenter from sphinx.ext.autosummary import import_by_name, get_documenter from sphinx.locale import __ @@ -268,25 +268,10 @@ def generate_autosummary_content(name: str, obj: Any, parent: Any, def generate_autosummary_docs(sources: List[str], output_dir: str = None, - suffix: str = '.rst', warn: Callable = None, - info: Callable = None, base_path: str = None, + suffix: str = '.rst', base_path: str = None, builder: Builder = None, template_dir: str = None, imported_members: bool = False, app: Any = None, overwrite: bool = True) -> None: - if info: - warnings.warn('info argument for generate_autosummary_docs() is deprecated.', - RemovedInSphinx40Warning) - _info = info - else: - _info = logger.info - - if warn: - warnings.warn('warn argument for generate_autosummary_docs() is deprecated.', - RemovedInSphinx40Warning) - _warn = warn - else: - _warn = logger.warning - if builder: warnings.warn('builder argument for generate_autosummary_docs() is deprecated.', RemovedInSphinx50Warning) @@ -298,11 +283,11 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None, showed_sources = list(sorted(sources)) if len(showed_sources) > 20: showed_sources = showed_sources[:10] + ['...'] + showed_sources[-10:] - _info(__('[autosummary] generating autosummary for: %s') % - ', '.join(showed_sources)) + logger.info(__('[autosummary] generating autosummary for: %s') % + ', '.join(showed_sources)) if output_dir: - _info(__('[autosummary] writing to %s') % output_dir) + logger.info(__('[autosummary] writing to %s') % output_dir) if base_path is not None: sources = [os.path.join(base_path, filename) for filename in sources] @@ -328,7 +313,7 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None, try: name, obj, parent, mod_name = import_by_name(entry.name) except ImportError as e: - _warn(__('[autosummary] failed to import %r: %s') % (entry.name, e)) + logger.warning(__('[autosummary] failed to import %r: %s') % (entry.name, e)) continue context = {} @@ -357,8 +342,8 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None, # descend recursively to new files if new_files: generate_autosummary_docs(new_files, output_dir=output_dir, - suffix=suffix, warn=warn, info=info, - base_path=base_path, + suffix=suffix, base_path=base_path, + builder=builder, template_dir=template_dir, imported_members=imported_members, app=app, overwrite=overwrite) diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py index 687bd6e0a..48ebcd34e 100644 --- a/sphinx/ext/doctest.py +++ b/sphinx/ext/doctest.py @@ -13,7 +13,6 @@ import doctest import re import sys import time -import warnings from io import StringIO from os import path from typing import Any, Callable, Dict, Iterable, List, Sequence, Set, Tuple, Type @@ -27,7 +26,6 @@ from packaging.version import Version import sphinx from sphinx.builders import Builder -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.locale import __ from sphinx.util import logging from sphinx.util.console import bold # type: ignore @@ -44,12 +42,6 @@ blankline_re = re.compile(r'^\s*<BLANKLINE>', re.MULTILINE) doctestopt_re = re.compile(r'#\s*doctest:.+$', re.MULTILINE) -def doctest_encode(text: str, encoding: str) -> str: - warnings.warn('doctest_encode() is deprecated.', - RemovedInSphinx40Warning) - return text - - def is_allowed_version(spec: str, version: str) -> bool: """Check `spec` satisfies `version` or not. diff --git a/sphinx/ext/imgmath.py b/sphinx/ext/imgmath.py index 911445a54..90271a6ee 100644 --- a/sphinx/ext/imgmath.py +++ b/sphinx/ext/imgmath.py @@ -27,7 +27,6 @@ from sphinx import package_dir from sphinx.application import Sphinx from sphinx.builders import Builder from sphinx.config import Config -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.errors import SphinxError from sphinx.locale import _, __ from sphinx.util import logging @@ -59,33 +58,6 @@ class InvokeError(SphinxError): SUPPORT_FORMAT = ('png', 'svg') -DOC_HEAD = r''' -\documentclass[12pt]{article} -\usepackage[utf8x]{inputenc} -\usepackage{amsmath} -\usepackage{amsthm} -\usepackage{amssymb} -\usepackage{amsfonts} -\usepackage{anyfontsize} -\usepackage{bm} -\pagestyle{empty} -''' - -DOC_BODY = r''' -\begin{document} -\fontsize{%d}{%d}\selectfont %s -\end{document} -''' - -DOC_BODY_PREVIEW = r''' -\usepackage[active]{preview} -\begin{document} -\begin{preview} -\fontsize{%s}{%s}\selectfont %s -\end{preview} -\end{document} -''' - depth_re = re.compile(r'\[\d+ depth=(-?\d+)\]') depthsvg_re = re.compile(r'.*, depth=(.*)pt') depthsvgcomment_re = re.compile(r'<!-- DEPTH=(-?\d+) -->') @@ -371,15 +343,6 @@ def html_visit_displaymath(self: HTMLTranslator, node: nodes.math_block) -> None raise nodes.SkipNode -deprecated_alias('sphinx.ext.imgmath', - { - 'DOC_BODY': DOC_BODY, - 'DOC_BODY_PREVIEW': DOC_BODY_PREVIEW, - 'DOC_HEAD': DOC_HEAD, - }, - RemovedInSphinx40Warning) - - def setup(app: Sphinx) -> Dict[str, Any]: app.add_html_math_renderer('imgmath', (html_visit_math, None), diff --git a/sphinx/ext/jsmath.py b/sphinx/ext/jsmath.py deleted file mode 100644 index 75369a5ca..000000000 --- a/sphinx/ext/jsmath.py +++ /dev/null @@ -1,36 +0,0 @@ -""" - sphinx.ext.jsmath - ~~~~~~~~~~~~~~~~~ - - Set up everything for use of JSMath to display math in HTML - via JavaScript. - - :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import warnings -from typing import Any, Dict - -from sphinxcontrib.jsmath import ( # NOQA - html_visit_math, - html_visit_displaymath, - install_jsmath, -) - -import sphinx -from sphinx.application import Sphinx -from sphinx.deprecation import RemovedInSphinx40Warning - - -def setup(app: Sphinx) -> Dict[str, Any]: - warnings.warn('sphinx.ext.jsmath has been moved to sphinxcontrib-jsmath.', - RemovedInSphinx40Warning) - - app.setup_extension('sphinxcontrib.jsmath') - - return { - 'version': sphinx.__display_version__, - 'parallel_read_safe': True, - 'parallel_write_safe': True, - } diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py index c5cacc437..44b6acabc 100644 --- a/sphinx/ext/todo.py +++ b/sphinx/ext/todo.py @@ -11,8 +11,7 @@ :license: BSD, see LICENSE for details. """ -import warnings -from typing import Any, Dict, Iterable, List, Tuple +from typing import Any, Dict, List, Tuple from typing import cast from docutils import nodes @@ -22,14 +21,12 @@ from docutils.parsers.rst.directives.admonitions import BaseAdmonition import sphinx from sphinx.application import Sphinx -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.domains import Domain from sphinx.environment import BuildEnvironment from sphinx.errors import NoUri from sphinx.locale import _, __ from sphinx.util import logging, texescape from sphinx.util.docutils import SphinxDirective, new_document -from sphinx.util.nodes import make_refnode from sphinx.writers.html import HTMLTranslator from sphinx.writers.latex import LaTeXTranslator @@ -104,33 +101,6 @@ class TodoDomain(Domain): location=todo) -def process_todos(app: Sphinx, doctree: nodes.document) -> None: - warnings.warn('process_todos() is deprecated.', RemovedInSphinx40Warning) - # collect all todos in the environment - # this is not done in the directive itself because it some transformations - # must have already been run, e.g. substitutions - env = app.builder.env - if not hasattr(env, 'todo_all_todos'): - env.todo_all_todos = [] # type: ignore - for node in doctree.traverse(todo_node): - app.events.emit('todo-defined', node) - - newnode = node.deepcopy() - newnode['ids'] = [] - env.todo_all_todos.append({ # type: ignore - 'docname': env.docname, - 'source': node.source or env.doc2path(env.docname), - 'lineno': node.line, - 'todo': newnode, - 'target': node['ids'][0], - }) - - if env.config.todo_emit_warnings: - label = cast(nodes.Element, node[1]) - logger.warning(__("TODO entry found: %s"), label.astext(), - location=node) - - class TodoList(SphinxDirective): """ A list of all todo entries. @@ -217,79 +187,6 @@ class TodoListProcessor: return para -def process_todo_nodes(app: Sphinx, doctree: nodes.document, fromdocname: str) -> None: - """Replace all todolist nodes with a list of the collected todos. - Augment each todo with a backlink to the original location. - """ - warnings.warn('process_todo_nodes() is deprecated.', RemovedInSphinx40Warning) - - domain = cast(TodoDomain, app.env.get_domain('todo')) - todos = sum(domain.todos.values(), []) # type: List[todo_node] - - for node in doctree.traverse(todolist): - if node.get('ids'): - content = [nodes.target()] # type: List[Element] - else: - content = [] - - if not app.config['todo_include_todos']: - node.replace_self(content) - continue - - for todo_info in todos: - para = nodes.paragraph(classes=['todo-source']) - if app.config['todo_link_only']: - description = _('<<original entry>>') - else: - description = ( - _('(The <<original entry>> is located in %s, line %d.)') % - (todo_info.source, todo_info.line) - ) - desc1 = description[:description.find('<<')] - desc2 = description[description.find('>>') + 2:] - para += nodes.Text(desc1, desc1) - - # Create a reference - innernode = nodes.emphasis(_('original entry'), _('original entry')) - try: - para += make_refnode(app.builder, fromdocname, todo_info['docname'], - todo_info['ids'][0], innernode) - except NoUri: - # ignore if no URI can be determined, e.g. for LaTeX output - pass - para += nodes.Text(desc2, desc2) - - todo_entry = todo_info.deepcopy() - todo_entry['ids'].clear() - - # (Recursively) resolve references in the todo content - app.env.resolve_references(todo_entry, todo_info['docname'], app.builder) # type: ignore # NOQA - - # Insert into the todolist - content.append(todo_entry) - content.append(para) - - node.replace_self(content) - - -def purge_todos(app: Sphinx, env: BuildEnvironment, docname: str) -> None: - warnings.warn('purge_todos() is deprecated.', RemovedInSphinx40Warning) - if not hasattr(env, 'todo_all_todos'): - return - env.todo_all_todos = [todo for todo in env.todo_all_todos # type: ignore - if todo['docname'] != docname] - - -def merge_info(app: Sphinx, env: BuildEnvironment, docnames: Iterable[str], - other: BuildEnvironment) -> None: - warnings.warn('merge_info() is deprecated.', RemovedInSphinx40Warning) - if not hasattr(other, 'todo_all_todos'): - return - if not hasattr(env, 'todo_all_todos'): - env.todo_all_todos = [] # type: ignore - env.todo_all_todos.extend(other.todo_all_todos) # type: ignore - - def visit_todo_node(self: HTMLTranslator, node: todo_node) -> None: if self.config.todo_include_todos: self.visit_admonition(node) diff --git a/sphinx/io.py b/sphinx/io.py index fc3544cb6..3469fcc3d 100644 --- a/sphinx/io.py +++ b/sphinx/io.py @@ -8,7 +8,6 @@ :license: BSD, see LICENSE for details. """ import codecs -import warnings from typing import Any, List, Type from typing import TYPE_CHECKING @@ -23,9 +22,7 @@ from docutils.transforms import Transform from docutils.transforms.references import DanglingReferences from docutils.writers import UnfilteredWriter -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.environment import BuildEnvironment -from sphinx.errors import FiletypeNotFoundError from sphinx.transforms import ( AutoIndexUpgrader, DoctreeReadEvent, FigureAligner, SphinxTransformer ) @@ -63,18 +60,6 @@ class SphinxBaseReader(standalone.Reader): super().__init__(*args, **kwargs) - @property - def app(self) -> "Sphinx": - warnings.warn('SphinxBaseReader.app is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - return self._app - - @property - def env(self) -> BuildEnvironment: - warnings.warn('SphinxBaseReader.env is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - return self._env - def setup(self, app: "Sphinx") -> None: self._app = app # hold application object only for compatibility self._env = app.env @@ -219,11 +204,3 @@ def read_doc(app: "Sphinx", env: BuildEnvironment, filename: str) -> nodes.docum pub.publish() return pub.document - - -deprecated_alias('sphinx.io', - { - 'FiletypeNotFoundError': FiletypeNotFoundError, - 'get_filetype': get_filetype, - }, - RemovedInSphinx40Warning) diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py index 55d5d2c1d..3f6ecaf2b 100644 --- a/sphinx/pycode/__init__.py +++ b/sphinx/pycode/__init__.py @@ -10,14 +10,12 @@ import re import tokenize -import warnings from importlib import import_module from io import StringIO from os import path from typing import Any, Dict, IO, List, Tuple, Optional from zipfile import ZipFile -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.errors import PycodeError from sphinx.pycode.parser import Parser @@ -77,7 +75,7 @@ class ModuleAnalyzer: @classmethod def for_string(cls, string: str, modname: str, srcname: str = '<string>' ) -> "ModuleAnalyzer": - return cls(StringIO(string), modname, srcname, decoded=True) + return cls(StringIO(string), modname, srcname) @classmethod def for_file(cls, filename: str, modname: str) -> "ModuleAnalyzer": @@ -85,7 +83,7 @@ class ModuleAnalyzer: return cls.cache['file', filename] try: with tokenize.open(filename) as f: - obj = cls(f, modname, filename, decoded=True) + obj = cls(f, modname, filename) cls.cache['file', filename] = obj except Exception as err: if '.egg' + path.sep in filename: @@ -125,21 +123,12 @@ class ModuleAnalyzer: cls.cache['module', modname] = obj return obj - def __init__(self, source: IO, modname: str, srcname: str, decoded: bool = False) -> None: + def __init__(self, source: IO, modname: str, srcname: str) -> None: self.modname = modname # name of the module self.srcname = srcname # name of the source file # cache the source code as well - pos = source.tell() - if not decoded: - warnings.warn('decode option for ModuleAnalyzer is deprecated.', - RemovedInSphinx40Warning) - self._encoding, _ = tokenize.detect_encoding(source.readline) - source.seek(pos) - self.code = source.read().decode(self._encoding) - else: - self._encoding = None - self.code = source.read() + self.code = source.read() # will be filled by parse() self.annotations = None # type: Dict[Tuple[str, str], str] @@ -150,7 +139,7 @@ class ModuleAnalyzer: def parse(self) -> None: """Parse the source code.""" try: - parser = Parser(self.code, self._encoding) + parser = Parser(self.code) parser.parse() self.attr_docs = {} @@ -179,9 +168,3 @@ class ModuleAnalyzer: self.parse() return self.tags - - @property - def encoding(self) -> str: - warnings.warn('ModuleAnalyzer.encoding is deprecated.', - RemovedInSphinx40Warning) - return self._encoding diff --git a/sphinx/roles.py b/sphinx/roles.py index 922f2e02c..7bb7ac5e2 100644 --- a/sphinx/roles.py +++ b/sphinx/roles.py @@ -9,22 +9,16 @@ """ import re -import warnings from typing import Any, Dict, List, Tuple, Type from typing import TYPE_CHECKING from docutils import nodes, utils from docutils.nodes import Element, Node, TextElement, system_message -from docutils.parsers.rst.states import Inliner from sphinx import addnodes -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.locale import _ from sphinx.util import ws_re from sphinx.util.docutils import ReferenceRole, SphinxRole -from sphinx.util.nodes import ( - split_explicit_title, process_index_entry, set_role_source_info -) from sphinx.util.typing import RoleFunction if TYPE_CHECKING: @@ -88,22 +82,6 @@ class XRefRole(ReferenceRole): super().__init__() - def _fix_parens(self, env: "BuildEnvironment", has_explicit_title: bool, title: str, - target: str) -> Tuple[str, str]: - warnings.warn('XRefRole._fix_parens() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - if not has_explicit_title: - if title.endswith('()'): - # remove parentheses - title = title[:-2] - if env.config.add_function_parentheses: - # add them back to all occurrences if configured - title += '()' - # remove parentheses from the target too - if target.endswith('()'): - target = target[:-2] - return title, target - def update_title_and_target(self, title: str, target: str) -> Tuple[str, str]: if not self.has_explicit_title: if title.endswith('()'): @@ -194,75 +172,6 @@ class AnyXRefRole(XRefRole): return result -def indexmarkup_role(typ: str, rawtext: str, text: str, lineno: int, inliner: Inliner, - options: Dict = {}, content: List[str] = [] - ) -> Tuple[List[Node], List[system_message]]: - """Role for PEP/RFC references that generate an index entry.""" - warnings.warn('indexmarkup_role() is deprecated. Please use PEP or RFC class instead.', - RemovedInSphinx40Warning, stacklevel=2) - env = inliner.document.settings.env - if not typ: - assert env.temp_data['default_role'] - typ = env.temp_data['default_role'].lower() - else: - typ = typ.lower() - - has_explicit_title, title, target = split_explicit_title(text) - title = utils.unescape(title) - target = utils.unescape(target) - targetid = 'index-%s' % env.new_serialno('index') - indexnode = addnodes.index() - targetnode = nodes.target('', '', ids=[targetid]) - inliner.document.note_explicit_target(targetnode) - if typ == 'pep': - indexnode['entries'] = [ - ('single', _('Python Enhancement Proposals; PEP %s') % target, - targetid, '', None)] - anchor = '' - anchorindex = target.find('#') - if anchorindex > 0: - target, anchor = target[:anchorindex], target[anchorindex:] - if not has_explicit_title: - title = "PEP " + utils.unescape(title) - try: - pepnum = int(target) - except ValueError: - msg = inliner.reporter.error('invalid PEP number %s' % target, - line=lineno) - prb = inliner.problematic(rawtext, rawtext, msg) - return [prb], [msg] - ref = inliner.document.settings.pep_base_url + 'pep-%04d' % pepnum - sn = nodes.strong(title, title) - rn = nodes.reference('', '', internal=False, refuri=ref + anchor, - classes=[typ]) - rn += sn - return [indexnode, targetnode, rn], [] - elif typ == 'rfc': - indexnode['entries'] = [ - ('single', 'RFC; RFC %s' % target, targetid, '', None)] - anchor = '' - anchorindex = target.find('#') - if anchorindex > 0: - target, anchor = target[:anchorindex], target[anchorindex:] - if not has_explicit_title: - title = "RFC " + utils.unescape(title) - try: - rfcnum = int(target) - except ValueError: - msg = inliner.reporter.error('invalid RFC number %s' % target, - line=lineno) - prb = inliner.problematic(rawtext, rawtext, msg) - return [prb], [msg] - ref = inliner.document.settings.rfc_base_url + inliner.rfc_url % rfcnum - sn = nodes.strong(title, title) - rn = nodes.reference('', '', internal=False, refuri=ref + anchor, - classes=[typ]) - rn += sn - return [indexnode, targetnode, rn], [] - else: - raise ValueError('unknown role type: %s' % typ) - - class PEP(ReferenceRole): def run(self) -> Tuple[List[Node], List[system_message]]: target_id = 'index-%s' % self.env.new_serialno('index') @@ -335,44 +244,6 @@ class RFC(ReferenceRole): _amp_re = re.compile(r'(?<!&)&(?![&\s])') -def menusel_role(typ: str, rawtext: str, text: str, lineno: int, inliner: Inliner, - options: Dict = {}, content: List[str] = [] - ) -> Tuple[List[Node], List[system_message]]: - warnings.warn('menusel_role() is deprecated. ' - 'Please use MenuSelection or GUILabel class instead.', - RemovedInSphinx40Warning, stacklevel=2) - env = inliner.document.settings.env - if not typ: - assert env.temp_data['default_role'] - typ = env.temp_data['default_role'].lower() - else: - typ = typ.lower() - - text = utils.unescape(text) - if typ == 'menuselection': - text = text.replace('-->', '\N{TRIANGULAR BULLET}') - spans = _amp_re.split(text) - - node = nodes.inline(rawtext=rawtext) - for i, span in enumerate(spans): - span = span.replace('&&', '&') - if i == 0: - if len(span) > 0: - textnode = nodes.Text(span) - node += textnode - continue - accel_node = nodes.inline() - letter_node = nodes.Text(span[0]) - accel_node += letter_node - accel_node['classes'].append('accelerator') - node += accel_node - textnode = nodes.Text(span[1:]) - node += textnode - - node['classes'].append(typ) - return [node], [] - - class GUILabel(SphinxRole): amp_re = re.compile(r'(?<!&)&(?![&\s])') @@ -403,59 +274,6 @@ _litvar_re = re.compile('{([^}]+)}') parens_re = re.compile(r'(\\*{|\\*})') -def emph_literal_role(typ: str, rawtext: str, text: str, lineno: int, inliner: Inliner, - options: Dict = {}, content: List[str] = [] - ) -> Tuple[List[Node], List[system_message]]: - warnings.warn('emph_literal_role() is deprecated. ' - 'Please use EmphasizedLiteral class instead.', - RemovedInSphinx40Warning, stacklevel=2) - env = inliner.document.settings.env - if not typ: - assert env.temp_data['default_role'] - typ = env.temp_data['default_role'].lower() - else: - typ = typ.lower() - - retnode = nodes.literal(role=typ.lower(), classes=[typ]) - parts = list(parens_re.split(utils.unescape(text))) - stack = [''] - for part in parts: - matched = parens_re.match(part) - if matched: - backslashes = len(part) - 1 - if backslashes % 2 == 1: # escaped - stack[-1] += "\\" * int((backslashes - 1) / 2) + part[-1] - elif part[-1] == '{': # rparen - stack[-1] += "\\" * int(backslashes / 2) - if len(stack) >= 2 and stack[-2] == "{": - # nested - stack[-1] += "{" - else: - # start emphasis - stack.append('{') - stack.append('') - else: # lparen - stack[-1] += "\\" * int(backslashes / 2) - if len(stack) == 3 and stack[1] == "{" and len(stack[2]) > 0: - # emphasized word found - if stack[0]: - retnode += nodes.Text(stack[0], stack[0]) - retnode += nodes.emphasis(stack[2], stack[2]) - stack = [''] - else: - # emphasized word not found; the rparen is not a special symbol - stack.append('}') - stack = [''.join(stack)] - else: - stack[-1] += part - if ''.join(stack): - # remaining is treated as Text - text = ''.join(stack) - retnode += nodes.Text(text, text) - - return [retnode], [] - - class EmphasizedLiteral(SphinxRole): parens_re = re.compile(r'(\\\\|\\{|\\}|{|})') @@ -509,22 +327,6 @@ class EmphasizedLiteral(SphinxRole): _abbr_re = re.compile(r'\((.*)\)$', re.S) -def abbr_role(typ: str, rawtext: str, text: str, lineno: int, inliner: Inliner, - options: Dict = {}, content: List[str] = [] - ) -> Tuple[List[Node], List[system_message]]: - warnings.warn('abbr_role() is deprecated. Please use Abbrevation class instead.', - RemovedInSphinx40Warning, stacklevel=2) - text = utils.unescape(text) - m = _abbr_re.search(text) - if m is None: - return [nodes.abbreviation(text, text, **options)], [] - abbr = text[:m.start()].strip() - expl = m.group(1) - options = options.copy() - options['explanation'] = expl - return [nodes.abbreviation(abbr, abbr, **options)], [] - - class Abbreviation(SphinxRole): abbr_re = re.compile(r'\((.*)\)$', re.S) @@ -539,62 +341,6 @@ class Abbreviation(SphinxRole): return [nodes.abbreviation(self.rawtext, text, **self.options)], [] -def index_role(typ: str, rawtext: str, text: str, lineno: int, inliner: Inliner, - options: Dict = {}, content: List[str] = [] - ) -> Tuple[List[Node], List[system_message]]: - warnings.warn('index_role() is deprecated. Please use Index class instead.', - RemovedInSphinx40Warning, stacklevel=2) - # create new reference target - env = inliner.document.settings.env - targetid = 'index-%s' % env.new_serialno('index') - targetnode = nodes.target('', '', ids=[targetid]) - # split text and target in role content - has_explicit_title, title, target = split_explicit_title(text) - title = utils.unescape(title) - target = utils.unescape(target) - # if an explicit target is given, we can process it as a full entry - if has_explicit_title: - entries = process_index_entry(target, targetid) - # otherwise we just create a "single" entry - else: - # but allow giving main entry - main = '' - if target.startswith('!'): - target = target[1:] - title = title[1:] - main = 'main' - entries = [('single', target, targetid, main, None)] - indexnode = addnodes.index() - indexnode['entries'] = entries - set_role_source_info(inliner, lineno, indexnode) - textnode = nodes.Text(title, title) - return [indexnode, targetnode, textnode], [] - - -class Index(ReferenceRole): - def run(self) -> Tuple[List[Node], List[system_message]]: - warnings.warn('Index role is deprecated.', RemovedInSphinx40Warning) - target_id = 'index-%s' % self.env.new_serialno('index') - if self.has_explicit_title: - # if an explicit target is given, process it as a full entry - title = self.title - entries = process_index_entry(self.target, target_id) - else: - # otherwise we just create a single entry - if self.target.startswith('!'): - title = self.title[1:] - entries = [('single', self.target[1:], target_id, 'main', None)] - else: - title = self.title - entries = [('single', self.target, target_id, '', None)] - - index = addnodes.index(entries=entries) - target = nodes.target('', '', ids=[target_id]) - text = nodes.Text(title, title) - self.set_source_info(index) - return [index, target, text], [] - - specific_docroles = { # links to download references 'download': XRefRole(nodeclass=addnodes.download_reference), diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py index 25a804816..68850a557 100644 --- a/sphinx/search/__init__.py +++ b/sphinx/search/__init__.py @@ -20,7 +20,6 @@ from docutils.nodes import Node from sphinx import addnodes from sphinx import package_dir -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.environment import BuildEnvironment from sphinx.search.jssplitter import splitter_code from sphinx.util import jsdump, rpartition @@ -196,11 +195,7 @@ class WordCollector(nodes.NodeVisitor): self.found_title_words = [] # type: List[str] self.lang = lang - def is_meta_keywords(self, node: addnodes.meta, nodetype: Any = None) -> bool: - if nodetype is not None: - warnings.warn('"nodetype" argument for WordCollector.is_meta_keywords() ' - 'is deprecated.', RemovedInSphinx40Warning) - + def is_meta_keywords(self, node: addnodes.meta) -> bool: if isinstance(node, addnodes.meta) and node.get('name') == 'keywords': meta_lang = node.get('lang') if meta_lang is None: # lang not specified diff --git a/sphinx/testing/fixtures.py b/sphinx/testing/fixtures.py index a864e19d1..0b20e6990 100644 --- a/sphinx/testing/fixtures.py +++ b/sphinx/testing/fixtures.py @@ -8,7 +8,6 @@ :license: BSD, see LICENSE for details. """ -import os import subprocess import sys from collections import namedtuple @@ -221,10 +220,7 @@ def sphinx_test_tempdir(tmpdir_factory: Any) -> "util.path": """ temporary directory that wrapped with `path` class. """ - tmpdir = os.environ.get('SPHINX_TEST_TEMPDIR') # RemovedInSphinx40Warning - if tmpdir is None: - tmpdir = tmpdir_factory.getbasetemp() - + tmpdir = tmpdir_factory.getbasetemp() return util.path(tmpdir).abspath() diff --git a/sphinx/testing/util.py b/sphinx/testing/util.py index 450241f55..6c0e22139 100644 --- a/sphinx/testing/util.py +++ b/sphinx/testing/util.py @@ -21,16 +21,13 @@ from docutils.parsers.rst import directives, roles from sphinx import application, locale from sphinx.builders.latex import LaTeXBuilder -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.pycode import ModuleAnalyzer from sphinx.testing.path import path from sphinx.util.osutil import relpath __all__ = [ - 'Struct', - 'SphinxTestApp', 'SphinxTestAppWrapperForSkipBuilding', - 'remove_unicode_literals', + 'Struct', 'SphinxTestApp', 'SphinxTestAppWrapperForSkipBuilding', ] @@ -179,12 +176,6 @@ class SphinxTestAppWrapperForSkipBuilding: _unicode_literals_re = re.compile(r'u(".*?")|u(\'.*?\')') -def remove_unicode_literals(s: str) -> str: - warnings.warn('remove_unicode_literals() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - return _unicode_literals_re.sub(lambda x: x.group(1) or x.group(2), s) - - def find_files(root: str, suffix: bool = None) -> Generator[str, None, None]: for dirpath, dirs, files in os.walk(root, followlinks=True): dirpath = path(dirpath) diff --git a/sphinx/transforms/__init__.py b/sphinx/transforms/__init__.py index 2185b3de1..1e9abced1 100644 --- a/sphinx/transforms/__init__.py +++ b/sphinx/transforms/__init__.py @@ -22,7 +22,6 @@ from docutils.utils.smartquotes import smartchars from sphinx import addnodes from sphinx.config import Config -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.locale import _, __ from sphinx.util import logging from sphinx.util.docutils import new_document @@ -394,18 +393,6 @@ class ManpageLink(SphinxTransform): node.attributes.update(info) -from sphinx.domains.citation import ( # NOQA - CitationDefinitionTransform, CitationReferenceTransform -) - -deprecated_alias('sphinx.transforms', - { - 'CitationReferences': CitationReferenceTransform, - 'SmartQuotesSkipper': CitationDefinitionTransform, - }, - RemovedInSphinx40Warning) - - def setup(app: "Sphinx") -> Dict[str, Any]: app.add_transform(ApplySourceWorkaround) app.add_transform(ExtraTranslatableNodes) diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index 8e1d4df84..9a1887759 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -8,7 +8,6 @@ :license: BSD, see LICENSE for details. """ -import fnmatch import functools import os import posixpath @@ -17,9 +16,6 @@ import sys import tempfile import traceback import unicodedata -import warnings -from codecs import BOM_UTF8 -from collections import deque from datetime import datetime from hashlib import md5 from importlib import import_module @@ -29,10 +25,7 @@ from typing import Any, Callable, Dict, IO, Iterable, Iterator, List, Pattern, S from typing import TYPE_CHECKING from urllib.parse import urlsplit, urlunsplit, quote_plus, parse_qsl, urlencode -from sphinx.deprecation import RemovedInSphinx40Warning -from sphinx.errors import ( - PycodeError, SphinxParallelError, ExtensionError, FiletypeNotFoundError -) +from sphinx.errors import SphinxParallelError, ExtensionError, FiletypeNotFoundError from sphinx.locale import __ from sphinx.util import logging from sphinx.util.console import strip_colors, colorize, bold, term_width_line # type: ignore @@ -42,7 +35,7 @@ from sphinx.util import smartypants # noqa # import other utilities; partly for backwards compatibility, so don't # prune unused ones indiscriminately from sphinx.util.osutil import ( # noqa - SEP, os_path, relative_uri, ensuredir, walk, mtimes_of_files, movefile, + SEP, os_path, relative_uri, ensuredir, mtimes_of_files, movefile, copyfile, copytimes, make_filename) from sphinx.util.nodes import ( # noqa nested_parse_with_titles, split_explicit_title, explicit_title_re, @@ -101,23 +94,6 @@ def get_matching_files(dirname: str, yield filename -def get_matching_docs(dirname: str, suffixes: List[str], - exclude_matchers: Tuple[PathMatcher, ...] = ()) -> Iterable[str]: - """Get all file names (without suffixes) matching a suffix in a directory, - recursively. - - Exclude files and dirs matching a pattern in *exclude_patterns*. - """ - warnings.warn('get_matching_docs() is now deprecated. Use get_matching_files() instead.', - RemovedInSphinx40Warning) - suffixpatterns = ['*' + s for s in suffixes] - for filename in get_matching_files(dirname, exclude_matchers): - for suffixpattern in suffixpatterns: - if fnmatch.fnmatch(filename, suffixpattern): - yield filename[:-len(suffixpattern) + 1] - break - - def get_filetype(source_suffix: Dict[str, str], filename: str) -> str: for suffix, filetype in source_suffix.items(): if filename.endswith(suffix): @@ -243,53 +219,6 @@ def save_traceback(app: "Sphinx") -> str: return path -def get_module_source(modname: str) -> Tuple[str, str]: - """Try to find the source code for a module. - - Can return ('file', 'filename') in which case the source is in the given - file, or ('string', 'source') which which case the source is the string. - """ - warnings.warn('get_module_source() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - try: - mod = import_module(modname) - except Exception as err: - raise PycodeError('error importing %r' % modname, err) - filename = getattr(mod, '__file__', None) - loader = getattr(mod, '__loader__', None) - if loader and getattr(loader, 'get_filename', None): - try: - filename = loader.get_filename(modname) - except Exception as err: - raise PycodeError('error getting filename for %r' % filename, err) - if filename is None and loader: - try: - filename = loader.get_source(modname) - if filename: - return 'string', filename - except Exception as err: - raise PycodeError('error getting source for %r' % modname, err) - if filename is None: - raise PycodeError('no source found for module %r' % modname) - filename = path.normpath(path.abspath(filename)) - lfilename = filename.lower() - if lfilename.endswith('.pyo') or lfilename.endswith('.pyc'): - filename = filename[:-1] - if not path.isfile(filename) and path.isfile(filename + 'w'): - filename += 'w' - elif not (lfilename.endswith('.py') or lfilename.endswith('.pyw')): - raise PycodeError('source is not a .py file: %r' % filename) - elif ('.egg' + os.path.sep) in filename: - pat = '(?<=\\.egg)' + re.escape(os.path.sep) - eggpath, _ = re.split(pat, filename, 1) - if path.isfile(eggpath): - return 'file', filename - - if not path.isfile(filename): - raise PycodeError('source file is not present: %r' % filename) - return 'file', filename - - def get_full_modname(modname: str, attribute: str) -> str: if modname is None: # Prevents a TypeError: if the last getattr() call will return None @@ -311,58 +240,6 @@ def get_full_modname(modname: str, attribute: str) -> str: _coding_re = re.compile(r'coding[:=]\s*([-\w.]+)') -def detect_encoding(readline: Callable[[], bytes]) -> str: - """Like tokenize.detect_encoding() from Py3k, but a bit simplified.""" - warnings.warn('sphinx.util.detect_encoding() is deprecated', - RemovedInSphinx40Warning) - - def read_or_stop() -> bytes: - try: - return readline() - except StopIteration: - return None - - def get_normal_name(orig_enc: str) -> str: - """Imitates get_normal_name in tokenizer.c.""" - # Only care about the first 12 characters. - enc = orig_enc[:12].lower().replace('_', '-') - if enc == 'utf-8' or enc.startswith('utf-8-'): - return 'utf-8' - if enc in ('latin-1', 'iso-8859-1', 'iso-latin-1') or \ - enc.startswith(('latin-1-', 'iso-8859-1-', 'iso-latin-1-')): - return 'iso-8859-1' - return orig_enc - - def find_cookie(line: bytes) -> str: - try: - line_string = line.decode('ascii') - except UnicodeDecodeError: - return None - - matches = _coding_re.findall(line_string) - if not matches: - return None - return get_normal_name(matches[0]) - - default = sys.getdefaultencoding() - first = read_or_stop() - if first and first.startswith(BOM_UTF8): - first = first[3:] - default = 'utf-8-sig' - if not first: - return default - encoding = find_cookie(first) - if encoding: - return encoding - second = read_or_stop() - if not second: - return default - encoding = find_cookie(second) - if encoding: - return encoding - return default - - class UnicodeDecodeErrorHandler: """Custom error handler for open() that warns and replaces.""" @@ -431,39 +308,6 @@ def parselinenos(spec: str, total: int) -> List[int]: return items -def force_decode(string: str, encoding: str) -> str: - """Forcibly get a unicode string out of a bytestring.""" - warnings.warn('force_decode() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - if isinstance(string, bytes): - try: - if encoding: - string = string.decode(encoding) - else: - # try decoding with utf-8, should only work for real UTF-8 - string = string.decode() - except UnicodeError: - # last resort -- can't fail - string = string.decode('latin1') - return string - - -class attrdict(dict): - def __init__(self, *args: Any, **kwargs: Any) -> None: - super().__init__(*args, **kwargs) - warnings.warn('The attrdict class is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - - def __getattr__(self, key: str) -> str: - return self[key] - - def __setattr__(self, key: str, val: str) -> None: - self[key] = val - - def __delattr__(self, key: str) -> None: - del self[key] - - def rpartition(s: str, t: str) -> Tuple[str, str]: """Similar to str.rpartition from 2.5, but doesn't return the separator.""" i = s.rfind(t) @@ -512,41 +356,6 @@ def format_exception_cut_frames(x: int = 1) -> str: return ''.join(res) -class PeekableIterator: - """ - An iterator which wraps any iterable and makes it possible to peek to see - what's the next item. - """ - def __init__(self, iterable: Iterable) -> None: - self.remaining = deque() # type: deque - self._iterator = iter(iterable) - warnings.warn('PeekableIterator is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - - def __iter__(self) -> "PeekableIterator": - return self - - def __next__(self) -> Any: - """Return the next item from the iterator.""" - if self.remaining: - return self.remaining.popleft() - return next(self._iterator) - - next = __next__ # Python 2 compatibility - - def push(self, item: Any) -> None: - """Push the `item` on the internal stack, it will be returned on the - next :meth:`next` call. - """ - self.remaining.append(item) - - def peek(self) -> Any: - """Return the next item without changing the state of the iterator.""" - item = next(self) - self.push(item) - return item - - def import_object(objname: str, source: str = None) -> Any: """Import python object by qualname.""" try: diff --git a/sphinx/util/cfamily.py b/sphinx/util/cfamily.py index 790a492a5..4cef9a563 100644 --- a/sphinx/util/cfamily.py +++ b/sphinx/util/cfamily.py @@ -9,7 +9,6 @@ """ import re -import warnings from copy import deepcopy from typing import ( Any, Callable, List, Match, Pattern, Tuple, Union @@ -19,7 +18,6 @@ from docutils import nodes from docutils.nodes import TextElement from sphinx.config import Config -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.util import logging logger = logging.getLogger(__name__) @@ -75,12 +73,7 @@ def verify_description_mode(mode: str) -> None: class NoOldIdError(Exception): # Used to avoid implementing unneeded id generation for old id schemes. - @property - def description(self) -> str: - warnings.warn('%s.description is deprecated. ' - 'Coerce the instance to a string instead.' % self.__class__.__name__, - RemovedInSphinx40Warning, stacklevel=2) - return str(self) + pass class ASTBaseBase: @@ -201,21 +194,11 @@ class ASTParenAttribute(ASTAttribute): class UnsupportedMultiCharacterCharLiteral(Exception): - @property - def decoded(self) -> str: - warnings.warn('%s.decoded is deprecated. ' - 'Coerce the instance to a string instead.' % self.__class__.__name__, - RemovedInSphinx40Warning, stacklevel=2) - return str(self) + pass class DefinitionError(Exception): - @property - def description(self) -> str: - warnings.warn('%s.description is deprecated. ' - 'Coerce the instance to a string instead.' % self.__class__.__name__, - RemovedInSphinx40Warning, stacklevel=2) - return str(self) + pass class BaseParser: diff --git a/sphinx/util/compat.py b/sphinx/util/compat.py index 502edb525..2c38f668b 100644 --- a/sphinx/util/compat.py +++ b/sphinx/util/compat.py @@ -9,16 +9,9 @@ """ import sys -import warnings from typing import Any, Dict from typing import TYPE_CHECKING -from docutils.utils import get_source_line - -from sphinx import addnodes -from sphinx.deprecation import RemovedInSphinx40Warning -from sphinx.transforms import SphinxTransform - if TYPE_CHECKING: from sphinx.application import Sphinx @@ -36,22 +29,7 @@ def register_application_for_autosummary(app: "Sphinx") -> None: autosummary._app = app -class IndexEntriesMigrator(SphinxTransform): - """Migrating indexentries from old style (4columns) to new style (5columns).""" - default_priority = 700 - - def apply(self, **kwargs: Any) -> None: - for node in self.document.traverse(addnodes.index): - for i, entries in enumerate(node['entries']): - if len(entries) == 4: - source, line = get_source_line(node) - warnings.warn('An old styled index node found: %r at (%s:%s)' % - (node, source, line), RemovedInSphinx40Warning) - node['entries'][i] = entries + (None,) - - def setup(app: "Sphinx") -> Dict[str, Any]: - app.add_transform(IndexEntriesMigrator) app.connect('builder-inited', register_application_for_autosummary) return { diff --git a/sphinx/util/docfields.py b/sphinx/util/docfields.py index 561271c4f..cb11a799d 100644 --- a/sphinx/util/docfields.py +++ b/sphinx/util/docfields.py @@ -9,7 +9,6 @@ :license: BSD, see LICENSE for details. """ -import warnings from typing import Any, Dict, List, Tuple, Type, Union from typing import TYPE_CHECKING, cast @@ -17,7 +16,6 @@ from docutils import nodes from docutils.nodes import Node from sphinx import addnodes -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.util.typing import TextlikeNode if TYPE_CHECKING: @@ -217,26 +215,7 @@ class DocFieldTransformer: def __init__(self, directive: "ObjectDescription") -> None: self.directive = directive - try: - self.typemap = directive.get_field_type_map() - except Exception: - # for 3rd party extensions directly calls this transformer. - warnings.warn('DocFieldTransformer expects given directive object is a subclass ' - 'of ObjectDescription.', RemovedInSphinx40Warning) - self.typemap = self.preprocess_fieldtypes(directive.__class__.doc_field_types) - - def preprocess_fieldtypes(self, types: List[Field]) -> Dict[str, Tuple[Field, bool]]: - warnings.warn('DocFieldTransformer.preprocess_fieldtypes() is deprecated.', - RemovedInSphinx40Warning) - typemap = {} - for fieldtype in types: - for name in fieldtype.names: - typemap[name] = fieldtype, False - if fieldtype.is_typed: - typed_field = cast(TypedField, fieldtype) - for name in typed_field.typenames: - typemap[name] = typed_field, True - return typemap + self.typemap = directive.get_field_type_map() def transform_all(self, node: addnodes.desc_content) -> None: """Transform all field list children of a node.""" diff --git a/sphinx/util/i18n.py b/sphinx/util/i18n.py index f58b0faaf..398accf1a 100644 --- a/sphinx/util/i18n.py +++ b/sphinx/util/i18n.py @@ -7,24 +7,21 @@ :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. :license: BSD, see LICENSE for details. """ -import gettext + import os import re -import warnings from datetime import datetime, timezone from os import path -from typing import Callable, Generator, List, NamedTuple, Set, Tuple +from typing import Callable, Generator, List, NamedTuple, Tuple from typing import TYPE_CHECKING import babel.dates from babel.messages.mofile import write_mo from babel.messages.pofile import read_po -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.errors import SphinxError from sphinx.locale import __ from sphinx.util import logging -from sphinx.util.matching import Matcher from sphinx.util.osutil import SEP, canon_path, relpath if TYPE_CHECKING: @@ -120,17 +117,6 @@ class CatalogRepository: yield CatalogInfo(basedir, domain, self.encoding) -def find_catalog(docname: str, compaction: bool) -> str: - warnings.warn('find_catalog() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - if compaction: - ret = docname.split(SEP, 1)[0] - else: - ret = docname - - return ret - - def docname_to_domain(docname: str, compation: bool) -> str: """Convert docname to domain for catalogs.""" if compation: @@ -139,69 +125,6 @@ def docname_to_domain(docname: str, compation: bool) -> str: return docname -def find_catalog_files(docname: str, srcdir: str, locale_dirs: List[str], - lang: str, compaction: bool) -> List[str]: - warnings.warn('find_catalog_files() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - if not(lang and locale_dirs): - return [] - - domain = find_catalog(docname, compaction) - files = [gettext.find(domain, path.join(srcdir, dir_), [lang]) - for dir_ in locale_dirs] - files = [relpath(f, srcdir) for f in files if f] - return files - - -def find_catalog_source_files(locale_dirs: List[str], locale: str, domains: List[str] = None, - charset: str = 'utf-8', force_all: bool = False, - excluded: Matcher = Matcher([])) -> Set[CatalogInfo]: - """ - :param list locale_dirs: - list of path as `['locale_dir1', 'locale_dir2', ...]` to find - translation catalogs. Each path contains a structure such as - `<locale>/LC_MESSAGES/domain.po`. - :param str locale: a language as `'en'` - :param list domains: list of domain names to get. If empty list or None - is specified, get all domain names. default is None. - :param boolean force_all: - Set True if you want to get all catalogs rather than updated catalogs. - default is False. - :return: [CatalogInfo(), ...] - """ - warnings.warn('find_catalog_source_files() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - - catalogs = set() # type: Set[CatalogInfo] - - if not locale: - return catalogs # locale is not specified - - for locale_dir in locale_dirs: - if not locale_dir: - continue # skip system locale directory - - base_dir = path.join(locale_dir, locale, 'LC_MESSAGES') - - if not path.exists(base_dir): - continue # locale path is not found - - for dirpath, dirnames, filenames in os.walk(base_dir, followlinks=True): - filenames = [f for f in filenames if f.endswith('.po')] - for filename in filenames: - if excluded(path.join(relpath(dirpath, base_dir), filename)): - continue - base = path.splitext(filename)[0] - domain = relpath(path.join(dirpath, base), base_dir).replace(path.sep, SEP) - if domains and domain not in domains: - continue - cat = CatalogInfo(base_dir, domain, charset) - if force_all or cat.is_outdated(): - catalogs.add(cat) - - return catalogs - - # date_format mappings: ustrftime() to bable.dates.format_datetime() date_format_mappings = { '%a': 'EEE', # Weekday as locale’s abbreviated name. diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index 5a73774c7..17b19ae76 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -20,10 +20,10 @@ from inspect import ( # NOQA Parameter, isclass, ismethod, ismethoddescriptor ) from io import StringIO -from typing import Any, Callable, Mapping, List, Optional, Tuple +from typing import Any, Callable from typing import cast -from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx50Warning +from sphinx.deprecation import RemovedInSphinx50Warning from sphinx.pycode.ast import ast # for py36-37 from sphinx.pycode.ast import unparse as ast_unparse from sphinx.util import logging @@ -323,23 +323,6 @@ def safe_getattr(obj: Any, name: str, *defargs: Any) -> Any: raise AttributeError(name) -def safe_getmembers(object: Any, predicate: Callable[[str], bool] = None, - attr_getter: Callable = safe_getattr) -> List[Tuple[str, Any]]: - """A version of inspect.getmembers() that uses safe_getattr().""" - warnings.warn('safe_getmembers() is deprecated', RemovedInSphinx40Warning) - - results = [] # type: List[Tuple[str, Any]] - for key in dir(object): - try: - value = attr_getter(object, key, None) - except AttributeError: - continue - if not predicate or predicate(value): - results.append((key, value)) - results.sort() - return results - - def object_description(object: Any) -> str: """A repr() implementation that returns text safe to use in reST context.""" if isinstance(object, dict): @@ -542,154 +525,6 @@ def signature_from_str(signature: str) -> inspect.Signature: return inspect.Signature(params, return_annotation=return_annotation) -class Signature: - """The Signature object represents the call signature of a callable object and - its return annotation. - """ - - empty = inspect.Signature.empty - - def __init__(self, subject: Callable, bound_method: bool = False, - has_retval: bool = True) -> None: - warnings.warn('sphinx.util.inspect.Signature() is deprecated', - RemovedInSphinx40Warning) - - # check subject is not a built-in class (ex. int, str) - if (isinstance(subject, type) and - is_builtin_class_method(subject, "__new__") and - is_builtin_class_method(subject, "__init__")): - raise TypeError("can't compute signature for built-in type {}".format(subject)) - - self.subject = subject - self.has_retval = has_retval - self.partialmethod_with_noargs = False - - try: - self.signature = inspect.signature(subject) # type: Optional[inspect.Signature] - except IndexError: - # Until python 3.6.4, cpython has been crashed on inspection for - # partialmethods not having any arguments. - # https://bugs.python.org/issue33009 - if hasattr(subject, '_partialmethod'): - self.signature = None - self.partialmethod_with_noargs = True - else: - raise - - try: - self.annotations = typing.get_type_hints(subject) - except Exception: - # get_type_hints() does not support some kind of objects like partial, - # ForwardRef and so on. For them, it raises an exception. In that case, - # we try to build annotations from argspec. - self.annotations = {} - - if bound_method: - # client gives a hint that the subject is a bound method - - if inspect.ismethod(subject): - # inspect.signature already considers the subject is bound method. - # So it is not need to skip first argument. - self.skip_first_argument = False - else: - self.skip_first_argument = True - else: - # inspect.signature recognizes type of method properly without any hints - self.skip_first_argument = False - - @property - def parameters(self) -> Mapping: - if self.partialmethod_with_noargs: - return {} - else: - return self.signature.parameters - - @property - def return_annotation(self) -> Any: - if self.signature: - if self.has_retval: - return self.signature.return_annotation - else: - return Parameter.empty - else: - return None - - def format_args(self, show_annotation: bool = True) -> str: - def get_annotation(param: Parameter) -> Any: - if isinstance(param.annotation, str) and param.name in self.annotations: - return self.annotations[param.name] - else: - return param.annotation - - args = [] - last_kind = None - for i, param in enumerate(self.parameters.values()): - # skip first argument if subject is bound method - if self.skip_first_argument and i == 0: - continue - - arg = StringIO() - - # insert '*' between POSITIONAL args and KEYWORD_ONLY args:: - # func(a, b, *, c, d): - if param.kind == param.KEYWORD_ONLY and last_kind in (param.POSITIONAL_OR_KEYWORD, - param.POSITIONAL_ONLY, - None): - args.append('*') - - if param.kind in (param.POSITIONAL_ONLY, - param.POSITIONAL_OR_KEYWORD, - param.KEYWORD_ONLY): - arg.write(param.name) - if show_annotation and param.annotation is not param.empty: - arg.write(': ') - arg.write(stringify_annotation(get_annotation(param))) - if param.default is not param.empty: - if param.annotation is param.empty or show_annotation is False: - arg.write('=') - arg.write(object_description(param.default)) - else: - arg.write(' = ') - arg.write(object_description(param.default)) - elif param.kind == param.VAR_POSITIONAL: - arg.write('*') - arg.write(param.name) - if show_annotation and param.annotation is not param.empty: - arg.write(': ') - arg.write(stringify_annotation(get_annotation(param))) - elif param.kind == param.VAR_KEYWORD: - arg.write('**') - arg.write(param.name) - if show_annotation and param.annotation is not param.empty: - arg.write(': ') - arg.write(stringify_annotation(get_annotation(param))) - - args.append(arg.getvalue()) - last_kind = param.kind - - if self.return_annotation is Parameter.empty or show_annotation is False: - return '(%s)' % ', '.join(args) - else: - if 'return' in self.annotations: - annotation = stringify_annotation(self.annotations['return']) - else: - annotation = stringify_annotation(self.return_annotation) - - return '(%s) -> %s' % (', '.join(args), annotation) - - def format_annotation(self, annotation: Any) -> str: - """Return formatted representation of a type annotation.""" - return stringify_annotation(annotation) - - def format_annotation_new(self, annotation: Any) -> str: - """format_annotation() for py37+""" - return stringify_annotation(annotation) - - def format_annotation_old(self, annotation: Any) -> str: - """format_annotation() for py36 or below""" - return stringify_annotation(annotation) - - def getdoc(obj: Any, attrgetter: Callable = safe_getattr, allow_inherited: bool = False) -> str: """Get the docstring for the object. diff --git a/sphinx/util/jsonimpl.py b/sphinx/util/jsonimpl.py deleted file mode 100644 index 35501f03a..000000000 --- a/sphinx/util/jsonimpl.py +++ /dev/null @@ -1,46 +0,0 @@ -""" - sphinx.util.jsonimpl - ~~~~~~~~~~~~~~~~~~~~ - - JSON serializer implementation wrapper. - - :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import json -import warnings -from collections import UserString -from typing import Any, IO - -from sphinx.deprecation import RemovedInSphinx40Warning - - -warnings.warn('sphinx.util.jsonimpl is deprecated', - RemovedInSphinx40Warning, stacklevel=2) - - -class SphinxJSONEncoder(json.JSONEncoder): - """JSONEncoder subclass that forces translation proxies.""" - def default(self, obj: Any) -> str: - if isinstance(obj, UserString): - return str(obj) - return super().default(obj) - - -def dump(obj: Any, fp: IO, *args: Any, **kwargs: Any) -> None: - kwargs['cls'] = SphinxJSONEncoder - json.dump(obj, fp, *args, **kwargs) - - -def dumps(obj: Any, *args: Any, **kwargs: Any) -> str: - kwargs['cls'] = SphinxJSONEncoder - return json.dumps(obj, *args, **kwargs) - - -def load(*args: Any, **kwargs: Any) -> Any: - return json.load(*args, **kwargs) - - -def loads(*args: Any, **kwargs: Any) -> Any: - return json.loads(*args, **kwargs) diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py index 35594c087..1d92ce836 100644 --- a/sphinx/util/nodes.py +++ b/sphinx/util/nodes.py @@ -10,7 +10,6 @@ import re import unicodedata -import warnings from typing import Any, Callable, Iterable, List, Set, Tuple, Type from typing import TYPE_CHECKING, cast @@ -21,7 +20,6 @@ from docutils.parsers.rst.states import Inliner from docutils.statemachine import StringList from sphinx import addnodes -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.locale import __ from sphinx.util import logging @@ -276,12 +274,6 @@ def extract_messages(doctree: Element) -> Iterable[Tuple[Element, str]]: yield node, msg -def find_source_node(node: Element) -> str: - warnings.warn('find_source_node() is deprecated.', - RemovedInSphinx40Warning) - return get_node_source(node) - - def get_node_source(node: Element) -> str: for pnode in traverse_parent(node): if pnode.source: diff --git a/sphinx/util/osutil.py b/sphinx/util/osutil.py index 6f4322535..e3c4ebedb 100644 --- a/sphinx/util/osutil.py +++ b/sphinx/util/osutil.py @@ -9,18 +9,14 @@ """ import contextlib -import errno import filecmp import os import re import shutil import sys -import warnings from io import StringIO from os import path -from typing import Any, Generator, Iterator, List, Optional, Tuple, Type - -from sphinx.deprecation import RemovedInSphinx40Warning +from typing import Any, Generator, Iterator, List, Optional, Type try: # for ALT Linux (#6712) @@ -28,11 +24,6 @@ try: except ImportError: Path = None # type: ignore -# Errnos that we need. -EEXIST = getattr(errno, 'EEXIST', 0) # RemovedInSphinx40Warning -ENOENT = getattr(errno, 'ENOENT', 0) # RemovedInSphinx40Warning -EPIPE = getattr(errno, 'EPIPE', 0) # RemovedInSphinx40Warning -EINVAL = getattr(errno, 'EINVAL', 0) # RemovedInSphinx40Warning # SEP separates path elements in the canonical file names # @@ -79,13 +70,6 @@ def ensuredir(path: str) -> None: os.makedirs(path, exist_ok=True) -def walk(top: str, topdown: bool = True, followlinks: bool = False) -> Iterator[Tuple[str, List[str], List[str]]]: # NOQA - warnings.warn('sphinx.util.osutil.walk() is deprecated for removal. ' - 'Please use os.walk() instead.', - RemovedInSphinx40Warning) - return os.walk(top, topdown=topdown, followlinks=followlinks) - - def mtimes_of_files(dirnames: List[str], suffix: str) -> Iterator[float]: for dirname in dirnames: for root, dirs, files in os.walk(dirname): @@ -171,13 +155,6 @@ def abspath(pathdir: str) -> str: return pathdir -def getcwd() -> str: - warnings.warn('sphinx.util.osutil.getcwd() is deprecated. ' - 'Please use os.getcwd() instead.', - RemovedInSphinx40Warning) - return os.getcwd() - - @contextlib.contextmanager def cd(target_dir: str) -> Generator[None, None, None]: cwd = os.getcwd() diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py index 88e9ac8d5..bcd90a718 100644 --- a/sphinx/util/pycompat.py +++ b/sphinx/util/pycompat.py @@ -8,23 +8,10 @@ :license: BSD, see LICENSE for details. """ -import html -import io -import sys -import textwrap import warnings from typing import Any, Callable -from sphinx.deprecation import ( - RemovedInSphinx40Warning, RemovedInSphinx60Warning, deprecated_alias -) -from sphinx.locale import __ -from sphinx.util import logging -from sphinx.util.console import terminal_safe -from sphinx.util.typing import NoneType - - -logger = logging.getLogger(__name__) +from sphinx.deprecation import RemovedInSphinx60Warning # ------------------------------------------------------------------------------ @@ -51,18 +38,6 @@ def convert_with_2to3(filepath: str) -> str: return str(tree) -class UnicodeMixin: - """Mixin class to handle defining the proper __str__/__unicode__ - methods in Python 2 or 3. - - .. deprecated:: 2.0 - """ - def __str__(self) -> str: - warnings.warn('UnicodeMixin is deprecated', - RemovedInSphinx40Warning, stacklevel=2) - return self.__unicode__() # type: ignore - - def execfile_(filepath: str, _globals: Any, open: Callable = open) -> None: warnings.warn('execfile_() is deprecated', RemovedInSphinx60Warning, stacklevel=2) @@ -72,30 +47,5 @@ def execfile_(filepath: str, _globals: Any, open: Callable = open) -> None: # compile to a code object, handle syntax errors filepath_enc = filepath.encode(fs_encoding) - try: - code = compile(source, filepath_enc, 'exec') - except SyntaxError: - # maybe the file uses 2.x syntax; try to refactor to - # 3.x syntax using 2to3 - source = convert_with_2to3(filepath) - code = compile(source, filepath_enc, 'exec') - # TODO: When support for evaluating Python 2 syntax is removed, - # deprecate convert_with_2to3(). - logger.warning(__('Support for evaluating Python 2 syntax is deprecated ' - 'and will be removed in Sphinx 4.0. ' - 'Convert %s to Python 3 syntax.'), - filepath) + code = compile(source, filepath_enc, 'exec') exec(code, _globals) - - -deprecated_alias('sphinx.util.pycompat', - { - 'NoneType': NoneType, # type: ignore - 'TextIOWrapper': io.TextIOWrapper, - 'htmlescape': html.escape, - 'indent': textwrap.indent, - 'terminal_safe': terminal_safe, - 'sys_encoding': sys.getdefaultencoding(), - 'u': '', - }, - RemovedInSphinx40Warning) diff --git a/sphinx/util/texescape.py b/sphinx/util/texescape.py index afa1c349e..051370481 100644 --- a/sphinx/util/texescape.py +++ b/sphinx/util/texescape.py @@ -11,8 +11,6 @@ import re from typing import Dict -from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias - tex_replacements = [ # map TeX special chars @@ -109,14 +107,6 @@ _tex_hlescape_map = {} # type: Dict[int, str] _tex_hlescape_map_without_unicode = {} # type: Dict[int, str] -deprecated_alias('sphinx.util.texescape', - { - 'tex_escape_map': _tex_escape_map, - 'tex_hl_escape_map_new': _tex_hlescape_map, - }, - RemovedInSphinx40Warning) - - def escape(s: str, latex_engine: str = None) -> str: """Escape text for LaTeX output.""" if latex_engine in ('lualatex', 'xelatex'): diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 07c4a59b8..deed9891c 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -12,8 +12,7 @@ import copy import os import posixpath import re -import warnings -from typing import Any, Iterable, Tuple +from typing import Iterable, Tuple from typing import TYPE_CHECKING, cast from docutils import nodes @@ -22,7 +21,6 @@ from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator from sphinx import addnodes from sphinx.builders import Builder -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.locale import admonitionlabels, _, __ from sphinx.util import logging from sphinx.util.docutils import SphinxTranslator @@ -85,14 +83,7 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator): builder = None # type: StandaloneHTMLBuilder - def __init__(self, *args: Any) -> None: - if isinstance(args[0], nodes.document) and isinstance(args[1], Builder): - document, builder = args - else: - warnings.warn('The order of arguments for HTMLTranslator has been changed. ' - 'Please give "document" as 1st and "builder" as 2nd.', - RemovedInSphinx40Warning, stacklevel=2) - builder, document = args + def __init__(self, document: nodes.document, builder: Builder) -> None: super().__init__(document, builder) self.highlighter = self.builder.highlighter diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py index 57b9f8eb9..9cbd50f6c 100644 --- a/sphinx/writers/html5.py +++ b/sphinx/writers/html5.py @@ -12,7 +12,7 @@ import os import posixpath import re import warnings -from typing import Any, Iterable, Tuple +from typing import Iterable, Tuple from typing import TYPE_CHECKING, cast from docutils import nodes @@ -21,7 +21,7 @@ from docutils.writers.html5_polyglot import HTMLTranslator as BaseTranslator from sphinx import addnodes from sphinx.builders import Builder -from sphinx.deprecation import RemovedInSphinx40Warning, RemovedInSphinx60Warning +from sphinx.deprecation import RemovedInSphinx60Warning from sphinx.locale import admonitionlabels, _, __ from sphinx.util import logging from sphinx.util.docutils import SphinxTranslator @@ -57,14 +57,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): builder = None # type: StandaloneHTMLBuilder - def __init__(self, *args: Any) -> None: - if isinstance(args[0], nodes.document) and isinstance(args[1], Builder): - document, builder = args - else: - warnings.warn('The order of arguments for HTML5Translator has been changed. ' - 'Please give "document" as 1st and "builder" as 2nd.', - RemovedInSphinx40Warning, stacklevel=2) - builder, document = args + def __init__(self, document: nodes.document, builder: Builder) -> None: super().__init__(document, builder) self.highlighter = self.builder.highlighter diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index e97271a18..2dc1e2e8c 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -15,7 +15,7 @@ import re import warnings from collections import defaultdict from os import path -from typing import Any, Dict, Iterable, Iterator, List, Tuple, Set, Union +from typing import Any, Dict, Iterable, List, Tuple, Set from typing import TYPE_CHECKING, cast from docutils import nodes, writers @@ -23,9 +23,7 @@ from docutils.nodes import Element, Node, Text from sphinx import addnodes from sphinx import highlighting -from sphinx.deprecation import ( - RemovedInSphinx40Warning, RemovedInSphinx50Warning, deprecated_alias -) +from sphinx.deprecation import RemovedInSphinx50Warning from sphinx.domains import IndexEntry from sphinx.domains.std import StandardDomain from sphinx.errors import SphinxError @@ -2039,104 +2037,6 @@ class LaTeXTranslator(SphinxTranslator): def unknown_visit(self, node: Node) -> None: raise NotImplementedError('Unknown node: ' + node.__class__.__name__) - # --------- METHODS FOR COMPATIBILITY -------------------------------------- - - def collect_footnotes(self, node: Element) -> Dict[str, List[Union["collected_footnote", bool]]]: # NOQA - def footnotes_under(n: Element) -> Iterator[nodes.footnote]: - if isinstance(n, nodes.footnote): - yield n - else: - for c in n.children: - if isinstance(c, addnodes.start_of_file): - continue - elif isinstance(c, nodes.Element): - yield from footnotes_under(c) - - warnings.warn('LaTeXWriter.collected_footnote() is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - - fnotes = {} # type: Dict[str, List[Union[collected_footnote, bool]]] - for fn in footnotes_under(node): - label = cast(nodes.label, fn[0]) - num = label.astext().strip() - newnode = collected_footnote('', *fn.children, number=num) - fnotes[num] = [newnode, False] - return fnotes - - @property - def no_contractions(self) -> int: - warnings.warn('LaTeXTranslator.no_contractions is deprecated.', - RemovedInSphinx40Warning, stacklevel=2) - return 0 - - def babel_defmacro(self, name: str, definition: str) -> str: - warnings.warn('babel_defmacro() is deprecated.', - RemovedInSphinx40Warning) - - if self.elements['babel']: - prefix = '\\addto\\extras%s{' % self.babel.get_language() - suffix = '}' - else: # babel is disabled (mainly for Japanese environment) - prefix = '' - suffix = '' - - return ('%s\\def%s{%s}%s\n' % (prefix, name, definition, suffix)) - - def generate_numfig_format(self, builder: "LaTeXBuilder") -> str: - warnings.warn('generate_numfig_format() is deprecated.', - RemovedInSphinx40Warning) - ret = [] # type: List[str] - figure = self.builder.config.numfig_format['figure'].split('%s', 1) - if len(figure) == 1: - ret.append('\\def\\fnum@figure{%s}\n' % self.escape(figure[0]).strip()) - else: - definition = escape_abbr(self.escape(figure[0])) - ret.append(self.babel_renewcommand('\\figurename', definition)) - ret.append('\\makeatletter\n') - ret.append('\\def\\fnum@figure{\\figurename\\thefigure{}%s}\n' % - self.escape(figure[1])) - ret.append('\\makeatother\n') - - table = self.builder.config.numfig_format['table'].split('%s', 1) - if len(table) == 1: - ret.append('\\def\\fnum@table{%s}\n' % self.escape(table[0]).strip()) - else: - definition = escape_abbr(self.escape(table[0])) - ret.append(self.babel_renewcommand('\\tablename', definition)) - ret.append('\\makeatletter\n') - ret.append('\\def\\fnum@table{\\tablename\\thetable{}%s}\n' % - self.escape(table[1])) - ret.append('\\makeatother\n') - - codeblock = self.builder.config.numfig_format['code-block'].split('%s', 1) - if len(codeblock) == 1: - pass # FIXME - else: - definition = self.escape(codeblock[0]).strip() - ret.append(self.babel_renewcommand('\\literalblockname', definition)) - if codeblock[1]: - pass # FIXME - - return ''.join(ret) - - -# Import old modules here for compatibility -from sphinx.builders.latex import constants # NOQA -from sphinx.builders.latex.util import ExtBabel # NOQA - - -deprecated_alias('sphinx.writers.latex', - { - 'ADDITIONAL_SETTINGS': constants.ADDITIONAL_SETTINGS, - 'DEFAULT_SETTINGS': constants.DEFAULT_SETTINGS, - 'LUALATEX_DEFAULT_FONTPKG': constants.LUALATEX_DEFAULT_FONTPKG, - 'PDFLATEX_DEFAULT_FONTPKG': constants.PDFLATEX_DEFAULT_FONTPKG, - 'SHORTHANDOFF': constants.SHORTHANDOFF, - 'XELATEX_DEFAULT_FONTPKG': constants.XELATEX_DEFAULT_FONTPKG, - 'XELATEX_GREEK_DEFAULT_FONTPKG': constants.XELATEX_GREEK_DEFAULT_FONTPKG, - 'ExtBabel': ExtBabel, - }, - RemovedInSphinx40Warning) # FIXME: Workaround to avoid circular import # refs: https://github.com/sphinx-doc/sphinx/issues/5433 diff --git a/sphinx/writers/manpage.py b/sphinx/writers/manpage.py index 7da2f4e8f..2af96b530 100644 --- a/sphinx/writers/manpage.py +++ b/sphinx/writers/manpage.py @@ -8,7 +8,6 @@ :license: BSD, see LICENSE for details. """ -import warnings from typing import Any, Dict, Iterable from typing import cast @@ -21,7 +20,6 @@ from docutils.writers.manpage import ( from sphinx import addnodes from sphinx.builders import Builder -from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.locale import admonitionlabels, _ from sphinx.util import logging from sphinx.util.docutils import SphinxTranslator @@ -81,14 +79,7 @@ class ManualPageTranslator(SphinxTranslator, BaseTranslator): _docinfo = {} # type: Dict[str, Any] - def __init__(self, *args: Any) -> None: - if isinstance(args[0], nodes.document) and isinstance(args[1], Builder): - document, builder = args - else: - warnings.warn('The order of arguments for ManualPageTranslator has been changed. ' - 'Please give "document" as 1st and "builder" as 2nd.', - RemovedInSphinx40Warning, stacklevel=2) - builder, document = args + def __init__(self, document: nodes.document, builder: Builder) -> None: super().__init__(document, builder) self.in_productionlist = 0 diff --git a/tests/test_util_pycompat.py b/tests/test_util_pycompat.py deleted file mode 100644 index 67e61bb58..000000000 --- a/tests/test_util_pycompat.py +++ /dev/null @@ -1,38 +0,0 @@ -""" - test_util_pycompat - ~~~~~~~~~~~~~~~~~~ - - Tests sphinx.util.pycompat functions. - - :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -from sphinx.testing.util import strip_escseq -from sphinx.util import logging -from sphinx.util.pycompat import execfile_ - - -def test_execfile_python2(capsys, app, status, warning, tempdir): - logging.setup(app, status, warning) - - conf_py = tempdir / 'conf.py' - conf_py.write_bytes(b'print "hello"\n') - execfile_(conf_py, {}) - - msg = ( - 'Support for evaluating Python 2 syntax is deprecated ' - 'and will be removed in Sphinx 4.0. ' - 'Convert %s to Python 3 syntax.\n' % conf_py) - assert msg in strip_escseq(warning.getvalue()) - captured = capsys.readouterr() - assert captured.out == 'hello\n' - - -def test_execfile(capsys, tempdir): - conf_py = tempdir / 'conf.py' - conf_py.write_bytes(b'print("hello")\n') - execfile_(conf_py, {}) - - captured = capsys.readouterr() - assert captured.out == 'hello\n' |