diff options
70 files changed, 392 insertions, 1658 deletions
@@ -1,3 +1,31 @@ +Release 3.0.0 (in development) +============================== + +Dependencies +------------ + +Incompatible changes +-------------------- + +* Drop features and APIs deprecated in 1.8.x +* #247: autosummary: stub files are overwritten automatically by default. see + :confval:`autosummary_generate_overwrite` to change the behavior + +Deprecated +---------- + +Features added +-------------- + +* #247: autosummary: Add :confval:`autosummary_generate_overwrite` to overwrite + old stub file + +Bugs fixed +---------- + +Testing +-------- + Release 2.2.0 (in development) ============================== @@ -184,6 +212,8 @@ Features added * #6180: Support ``--keep-going`` with BuildDoc setup command * ``math`` directive now supports ``:class:`` option +* #6310: imgmath: let :confval:`imgmath_use_preview` work also with the SVG + format for images rendering inline math * todo: ``todo`` directive now supports ``:name:`` option * Enable override via environment of ``SPHINXOPTS`` and ``SPHINXBUILD`` Makefile variables (refs: #6232, #6303) @@ -52,7 +52,7 @@ Documentation using the classic theme * `Arb <http://arblib.org/>`__ * `Bazaar <http://doc.bazaar.canonical.com/>`__ (customized) * `Beautiful Soup <https://www.crummy.com/software/BeautifulSoup/bs4/doc/>`__ -* `Blender <https://docs.blender.org/api/current/>`__ +* `Blender API <https://docs.blender.org/api/current/>`__ * `Bugzilla <https://bugzilla.readthedocs.io/>`__ * `Buildbot <https://docs.buildbot.net/latest/>`__ * `CMake <https://cmake.org/documentation/>`__ (customized) @@ -114,6 +114,7 @@ Documentation using the sphinxdoc theme * `ABRT <https://abrt.readthedocs.io/>`__ * `cartopy <https://scitools.org.uk/cartopy/docs/latest/>`__ * `Jython <http://www.jython.org/docs/>`__ +* `LLVM <https://llvm.org/docs/>`__ * `Matplotlib <https://matplotlib.org/>`__ * `MDAnalysis Tutorial <https://www.mdanalysis.org/MDAnalysisTutorial/>`__ * `NetworkX <https://networkx.github.io/>`__ @@ -123,6 +124,7 @@ Documentation using the sphinxdoc theme * `Pysparse <http://pysparse.sourceforge.net/>`__ * `PyTango <https://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/pytango/latest/>`__ * `Python Wild Magic <https://vmlaker.github.io/pythonwildmagic/>`__ (customized) +* `RDKit <https://www.rdkit.org/docs/>`__ * `Reteisi <http://www.reteisi.org/contents.html>`__ (customized) * `Sqlkit <http://sqlkit.argolinux.org/>`__ (customized) * `Turbulenz <http://docs.turbulenz.com/>`__ @@ -167,6 +169,7 @@ Documentation using sphinx_rtd_theme * `ASE <https://wiki.fysik.dtu.dk/ase/>`__ * `Autofac <http://docs.autofac.org/>`__ * `BigchainDB <https://docs.bigchaindb.com/>`__ +* `Blender Reference Manual <https://docs.blender.org/manual/>`__ * `Blocks <https://blocks.readthedocs.io/>`__ * `bootstrap-datepicker <https://bootstrap-datepicker.readthedocs.io/>`__ * `Certbot <https://letsencrypt.readthedocs.io/>`__ @@ -185,12 +188,14 @@ Documentation using sphinx_rtd_theme * `Elemental <http://libelemental.org/documentation/dev/>`__ * `ESWP3 <https://eswp3.readthedocs.io/>`__ * `Ethereum Homestead <http://www.ethdocs.org/>`__ +* `Exhale <https://exhale.readthedocs.io/>`__ * `Faker <https://faker.readthedocs.io/>`__ * `Fidimag <https://fidimag.readthedocs.io/>`__ * `Flake8 <http://flake8.pycqa.org/>`__ * `Flatpak <http://docs.flatpak.org/>`__ * `FluidDyn <https://fluiddyn.readthedocs.io/>`__ * `Fluidsim <https://fluidsim.readthedocs.io/>`__ +* `Gallium <https://gallium.readthedocs.io/>`__ * `GeoNode <http://docs.geonode.org/>`__ * `Glances <https://glances.readthedocs.io/>`__ * `Godot <https://godot.readthedocs.io/>`__ @@ -206,11 +211,13 @@ Documentation using sphinx_rtd_theme * `Jupyter Notebook <https://jupyter-notebook.readthedocs.io/>`__ * `Lasagne <https://lasagne.readthedocs.io/>`__ * `latexindent.pl <https://latexindentpl.readthedocs.io/>`__ +* `Learning Apache Spark with Python <https://runawayhorse001.github.io/LearningApacheSpark>`__ * `Linguistica <https://linguistica-uchicago.github.io/lxa5/>`__ * `Linux kernel <https://www.kernel.org/doc/html/latest/index.html>`__ +* `Mailman <http://docs.list.org/>`__ * `MathJax <https://docs.mathjax.org/>`__ * `MDTraj <http://mdtraj.org/latest/>`__ (customized) -* `MICrobial Community Analysis (micca) <http://micca.org/docs/latest/>`__ +* `micca - MICrobial Community Analysis <https://micca.readthedocs.io/>`__ * `MicroPython <https://docs.micropython.org/>`__ * `Minds <https://www.minds.org/docs/>`__ (customized) * `Mink <http://mink.behat.org/>`__ @@ -252,6 +259,7 @@ Documentation using sphinx_rtd_theme * `Sphinx AutoAPI <https://sphinx-autoapi.readthedocs.io/>`__ * `sphinx-argparse <https://sphinx-argparse.readthedocs.io/>`__ * `Sphinx-Gallery <https://sphinx-gallery.readthedocs.io/>`__ (customized) +* `Sphinx with Github Webpages <https://runawayhorse001.github.io/SphinxGithub>`__ * `SpotBugs <https://spotbugs.readthedocs.io/>`__ * `StarUML <https://docs.staruml.io/>`__ * `Sublime Text Unofficial Documentation <http://docs.sublimetext.info/>`__ @@ -285,6 +293,7 @@ Documentation using sphinx_bootstrap_theme * `Hedge <https://documen.tician.de/hedge/>`__ * `ObsPy <https://docs.obspy.org/>`__ * `Open Dylan <https://opendylan.org/documentation/>`__ +* `OPNFV <https://docs.opnfv.org/>`__ * `Pootle <http://docs.translatehouse.org/projects/pootle/>`__ * `PyUblas <https://documen.tician.de/pyublas/>`__ * `seaborn <https://seaborn.pydata.org/>`__ @@ -321,6 +330,7 @@ Documentation using a custom theme or integrated in a website * `MongoDB <https://docs.mongodb.com/>`__ * `Music21 <https://web.mit.edu/music21/doc/>`__ * `MyHDL <http://docs.myhdl.org/>`__ +* `ndnSIM <https://ndnsim.net/current/>`__ * `nose <https://nose.readthedocs.io/>`__ * `ns-3 <https://www.nsnam.org/documentation/>`__ * `NumPy <https://docs.scipy.org/doc/numpy/reference/>`__ diff --git a/doc/_templates/index.html b/doc/_templates/index.html index be174317d..c22eebbf9 100644 --- a/doc/_templates/index.html +++ b/doc/_templates/index.html @@ -97,6 +97,8 @@ <p>{%trans%}A Japanese book about Sphinx has been published by O'Reilly: <a href="https://www.oreilly.co.jp/books/9784873116488/">Sphinxをはじめよう / Learning Sphinx</a>.{%endtrans%}</p> + <p>{%trans%}In 2019 the second edition of a German book about Sphinx was published: + <a href="https://literatur.hasecke.com/post/software-dokumentation-mit-sphinx/">Software-Dokumentation mit Sphinx</a>.{%endtrans%}</p> <!-- <p><img src="{{ pathto("_static/bookcover.png", 1) }}"/></p> --> diff --git a/doc/extdev/appapi.rst b/doc/extdev/appapi.rst index 7a8ffef10..46540595f 100644 --- a/doc/extdev/appapi.rst +++ b/doc/extdev/appapi.rst @@ -54,8 +54,6 @@ package. .. automethod:: Sphinx.add_domain(domain) -.. automethod:: Sphinx.override_domain(domain) - .. method:: Sphinx.add_directive_to_domain(domain, name, func, content, arguments, \*\*options) .. automethod:: Sphinx.add_directive_to_domain(domain, name, directiveclass) diff --git a/doc/faq.rst b/doc/faq.rst index a46d46216..ba16ceb9a 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -48,12 +48,10 @@ Using Sphinx with... -------------------- Read the Docs - https://readthedocs.org is a documentation hosting service based around - Sphinx. They will host sphinx documentation, along with supporting a number - of other features including version support, PDF generation, and more. The - `Getting Started - <https://read-the-docs.readthedocs.io/en/latest/getting_started.html>`_ - guide is a good place to start. + `Read the Docs <https://readthedocs.org>`_ is a documentation hosting + service based around Sphinx. They will host sphinx documentation, along + with supporting a number of other features including version support, PDF + generation, and more. The `Getting Started`_ guide is a good place to start. Epydoc There's a third-party extension providing an `api role`_ which refers to @@ -146,6 +144,7 @@ Google Search 3. Add ``searchbox.html`` to the :confval:`html_sidebars` configuration value. +.. _Getting Started: https://docs.readthedocs.io/en/stable/intro/getting-started-with-sphinx.html .. _api role: https://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py .. _xhtml to reST: http://docutils.sourceforge.net/sandbox/xhtml2rest/xhtml2rest.py diff --git a/doc/usage/extensions/autosummary.rst b/doc/usage/extensions/autosummary.rst index 16a8cea7e..6d5f33a85 100644 --- a/doc/usage/extensions/autosummary.rst +++ b/doc/usage/extensions/autosummary.rst @@ -143,6 +143,13 @@ also use these config values: The new files will be placed in the directories specified in the ``:toctree:`` options of the directives. +.. confval:: autosummary_generate_overwrite + + If true, autosummary already overwrites stub files by generated contents. + Defaults to true (enabled). + + .. versionadded:: 3.0 + .. confval:: autosummary_mock_imports This value contains a list of modules to be mocked up. See diff --git a/doc/usage/extensions/math.rst b/doc/usage/extensions/math.rst index a3dba8aac..75cafff6b 100644 --- a/doc/usage/extensions/math.rst +++ b/doc/usage/extensions/math.rst @@ -30,13 +30,39 @@ This extension renders math via LaTeX and dvipng_ or dvisvgm_ into PNG or SVG images. This of course means that the computer where the docs are built must have both programs available. -There are various config values you can set to influence how the images are -built: +There are various configuration values you can set to influence how the images +are built: .. confval:: imgmath_image_format - The output image format. The default is ``'png'``. It should be either - ``'png'`` or ``'svg'``. + The output image format. The default is ``'png'``. It should be either + ``'png'`` or ``'svg'``. The image is produced by first executing ``latex`` + on the TeX mathematical mark-up then (depending on the requested format) + either `dvipng`_ or `dvisvgm`_. + +.. confval:: imgmath_use_preview + + ``dvipng`` and ``dvisvgm`` both have the ability to collect from LaTeX the + "depth" of the rendered math: an inline image should use this "depth" in a + ``vertical-align`` style to get correctly aligned with surrounding text. + + This mechanism requires the `LaTeX preview package`_ (available as + ``preview-latex-style`` on Ubuntu xenial). Therefore, the default for this + option is ``False`` but it is strongly recommended to set it to ``True``. + + .. versionchanged:: 2.1 + + This option can be used with the ``'svg'`` :confval:`imgmath_image_format`. + +.. confval:: imgmath_add_tooltips + + Default: ``True``. If false, do not add the LaTeX code as an "alt" attribute + for math images. + +.. confval:: imgmath_font_size + + The font size (in ``pt``) of the displayed math. The default value is + ``12``. It must be a positive integer. .. confval:: imgmath_latex @@ -54,20 +80,6 @@ built: This value should only contain the path to the latex executable, not further arguments; use :confval:`imgmath_latex_args` for that purpose. -.. confval:: imgmath_dvipng - - The command name with which to invoke ``dvipng``. The default is - ``'dvipng'``; you may need to set this to a full path if ``dvipng`` is not in - the executable search path. This option is only used when - ``imgmath_image_format`` is set to ``'png'``. - -.. confval:: imgmath_dvisvgm - - The command name with which to invoke ``dvisvgm``. The default is - ``'dvisvgm'``; you may need to set this to a full path if ``dvisvgm`` is not - in the executable search path. This option is only used when - ``imgmath_image_format`` is ``'svg'``. - .. confval:: imgmath_latex_args Additional arguments to give to latex, as a list. The default is an empty @@ -75,49 +87,43 @@ built: .. confval:: imgmath_latex_preamble - Additional LaTeX code to put into the preamble of the short LaTeX files that - are used to translate the math snippets. This is empty by default. Use it - e.g. to add more packages whose commands you want to use in the math. + Additional LaTeX code to put into the preamble of the LaTeX files used to + translate the math snippets. This is left empty by default. Use it + e.g. to add packages which modify the fonts used for math, such as + ``'\\usepackage{newtxsf}'`` for sans-serif fonts, or + ``'\\usepackage{fouriernc}'`` for serif fonts. Indeed, the default LaTeX + math fonts have rather thin glyphs which (in HTML output) often do not + match well with the font for text. + +.. confval:: imgmath_dvipng + + The command name to invoke ``dvipng``. The default is + ``'dvipng'``; you may need to set this to a full path if ``dvipng`` is not in + the executable search path. This option is only used when + ``imgmath_image_format`` is set to ``'png'``. .. confval:: imgmath_dvipng_args Additional arguments to give to dvipng, as a list. The default value is ``['-gamma', '1.5', '-D', '110', '-bg', 'Transparent']`` which makes the - image a bit darker and larger then it is by default, and produces PNGs with a + image a bit darker and larger then it is by default (this compensates + somewhat for the thinness of default LaTeX math fonts), and produces PNGs with a transparent background. This option is used only when ``imgmath_image_format`` is ``'png'``. -.. confval:: imgmath_dvisvgm_args - - Additional arguments to give to dvisvgm, as a list. The default value is - ``['--no-fonts']``. This option is used only when ``imgmath_image_format`` - is ``'svg'``. - -.. confval:: imgmath_use_preview - - ``dvipng`` has the ability to determine the "depth" of the rendered text: for - example, when typesetting a fraction inline, the baseline of surrounding text - should not be flush with the bottom of the image, rather the image should - extend a bit below the baseline. This is what TeX calls "depth". When this - is enabled, the images put into the HTML document will get a - ``vertical-align`` style that correctly aligns the baselines. - - Unfortunately, this only works when the `preview-latex package`_ is - installed (on Ubuntu xenial, it is available as `preview-latex-style`_). - Therefore, the default for this option is ``False``. - - Currently this option is only used when ``imgmath_image_format`` is - ``'png'``. - -.. confval:: imgmath_add_tooltips +.. confval:: imgmath_dvisvgm - Default: ``True``. If false, do not add the LaTeX code as an "alt" attribute - for math images. + The command name to invoke ``dvisvgm``. The default is + ``'dvisvgm'``; you may need to set this to a full path if ``dvisvgm`` is not + in the executable search path. This option is only used when + ``imgmath_image_format`` is ``'svg'``. -.. confval:: imgmath_font_size +.. confval:: imgmath_dvisvgm_args - The font size (in ``pt``) of the displayed math. The default value is - ``12``. It must be a positive integer. + Additional arguments to give to dvisvgm, as a list. The default value is + ``['--no-fonts']``, which means that ``dvisvgm`` will render glyphs as path + elements (cf the `dvisvgm FAQ`_). This option is used only when + ``imgmath_image_format`` is ``'svg'``. :mod:`sphinx.ext.mathjax` -- Render math via JavaScript @@ -219,7 +225,7 @@ package jsMath_. It provides this config value: .. _dvipng: https://savannah.nongnu.org/projects/dvipng/ .. _dvisvgm: https://dvisvgm.de/ +.. _dvisvgm FAQ: https://dvisvgm.de/FAQ .. _MathJax: https://www.mathjax.org/ .. _jsMath: http://www.math.union.edu/~dpvc/jsmath/ -.. _preview-latex package: https://www.gnu.org/software/auctex/preview-latex.html -.. _preview-latex-style: https://packages.ubuntu.com/xenial/preview-latex-style +.. _LaTeX preview package: https://www.gnu.org/software/auctex/preview-latex.html diff --git a/doc/usage/installation.rst b/doc/usage/installation.rst index f51b3084e..f13b5ff68 100644 --- a/doc/usage/installation.rst +++ b/doc/usage/installation.rst @@ -108,12 +108,13 @@ Windows .. todo:: Could we start packaging this? Most Windows users do not have Python installed by default, so we begin with -the installation of Python itself. If you are unsure, open the *Command -Prompt* (:kbd:`⊞Win-r` and type :command:`cmd`). Once the command prompt is -open, type :command:`python --version` and press Enter. If Python is -available, you will see the version of Python printed to the screen. If you do -not have Python installed, refer to the `Hitchhikers Guide to Python's`__ -Python on Windows installation guides. You must install `Python 3`__. +the installation of Python itself. To check if you already have Python +installed, open the *Command Prompt* (:kbd:`⊞Win-r` and type :command:`cmd`). +Once the command prompt is open, type :command:`python --version` and press +Enter. If Python is installed, you will see the version of Python printed to +the screen. If you do not have Python installed, refer to the `Hitchhikers +Guide to Python's`__ Python on Windows installation guides. You must install +`Python 3`__. Once Python is installed, you can install Sphinx using :command:`pip`. Refer to the :ref:`pip installation instructions <install-pypi>` below for more diff --git a/doc/usage/quickstart.rst b/doc/usage/quickstart.rst index 5279d3f87..8566552e0 100644 --- a/doc/usage/quickstart.rst +++ b/doc/usage/quickstart.rst @@ -6,7 +6,7 @@ Once Sphinx is :doc:`installed </usage/installation>`, you can proceed with setting up your first Sphinx project. To ease the process of getting started, Sphinx provides a tool, :program:`sphinx-quickstart`, which will generate a documentation source directory and populate it with some defaults. We're going -to use the :program:`sphinx-quickstart` tool here, though it's use by no means +to use the :program:`sphinx-quickstart` tool here, though its use is by no means necessary. @@ -26,7 +26,7 @@ configuration values from a few questions it asks you. To use this, run: $ sphinx-quickstart -Answer each question asked. Be sure to say yes to the ``autodoc`` extension, as +Answer each question asked. Be sure to say "yes" to the ``autodoc`` extension, as we will use this later. There is also an automatic "API documentation" generator called @@ -103,7 +103,7 @@ In Sphinx source files, you can use most features of standard For example, you can add cross-file references in a portable way (which works for all output types) using the :rst:role:`ref` role. -For an example, if you are viewing the HTML version you can look at the source +For an example, if you are viewing the HTML version, you can look at the source for this document -- use the "Show Source" link in the sidebar. .. todo:: Update the below link when we add new guides on these. diff --git a/sphinx/__init__.py b/sphinx/__init__.py index 57b3d6062..1c8338643 100644 --- a/sphinx/__init__.py +++ b/sphinx/__init__.py @@ -32,8 +32,8 @@ if 'PYTHONWARNINGS' not in os.environ: warnings.filterwarnings('ignore', "'U' mode is deprecated", DeprecationWarning, module='docutils.io') -__version__ = '2.2.0+' -__released__ = '2.2.0' # used when Sphinx builds its own docs +__version__ = '3.0.0+' +__released__ = '3.0.0' # used when Sphinx builds its own docs #: Version info for better programmatic use. #: @@ -43,7 +43,7 @@ __released__ = '2.2.0' # used when Sphinx builds its own docs #: #: .. versionadded:: 1.2 #: Before version 1.2, check the string ``sphinx.__version__``. -version_info = (2, 2, 0, 'beta', 0) +version_info = (3, 0, 0, 'beta', 0) package_dir = path.abspath(path.dirname(__file__)) diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py index ef3bf3f9e..4180625ca 100644 --- a/sphinx/addnodes.py +++ b/sphinx/addnodes.py @@ -12,7 +12,7 @@ import warnings from docutils import nodes -from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning if False: # For type annotation @@ -188,59 +188,6 @@ class production(nodes.Part, nodes.Inline, nodes.FixedTextElement): """Node for a single grammar production rule.""" -# math nodes - - -class math(nodes.math): - """Node for inline equations. - - .. warning:: This node is provided to keep compatibility only. - It will be removed in nearly future. Don't use this from your extension. - - .. deprecated:: 1.8 - Use ``docutils.nodes.math`` instead. - """ - - def __getitem__(self, key): - """Special accessor for supporting ``node['latex']``.""" - if key == 'latex' and 'latex' not in self.attributes: - warnings.warn("math node for Sphinx was replaced by docutils'. " - "Therefore please use ``node.astext()`` to get an equation instead.", - RemovedInSphinx30Warning, stacklevel=2) - return self.astext() - else: - return super().__getitem__(key) - - -class math_block(nodes.math_block): - """Node for block level equations. - - .. warning:: This node is provided to keep compatibility only. - It will be removed in nearly future. Don't use this from your extension. - - .. deprecated:: 1.8 - """ - - def __getitem__(self, key): - if key == 'latex' and 'latex' not in self.attributes: - warnings.warn("displaymath node for Sphinx was replaced by docutils'. " - "Therefore please use ``node.astext()`` to get an equation instead.", - RemovedInSphinx30Warning, stacklevel=2) - return self.astext() - else: - return super().__getitem__(key) - - -class displaymath(math_block): - """Node for block level equations. - - .. warning:: This node is provided to keep compatibility only. - It will be removed in nearly future. Don't use this from your extension. - - .. deprecated:: 1.8 - """ - - # other directive-level nodes class index(nodes.Invisible, nodes.Inline, nodes.TextElement): @@ -379,7 +326,6 @@ def setup(app): app.add_node(seealso) app.add_node(productionlist) app.add_node(production) - app.add_node(displaymath) app.add_node(index) app.add_node(centered) app.add_node(acks) diff --git a/sphinx/application.py b/sphinx/application.py index a841f52b1..68b221af8 100644 --- a/sphinx/application.py +++ b/sphinx/application.py @@ -15,7 +15,6 @@ import pickle import sys import warnings from collections import deque -from inspect import isclass from io import StringIO from os import path @@ -25,9 +24,7 @@ from pygments.lexer import Lexer import sphinx from sphinx import package_dir, locale from sphinx.config import Config -from sphinx.deprecation import ( - RemovedInSphinx30Warning, RemovedInSphinx40Warning, deprecated_alias -) +from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.environment import BuildEnvironment from sphinx.errors import ApplicationError, ConfigError, VersionRequirementError from sphinx.events import EventManager @@ -36,11 +33,10 @@ from sphinx.locale import __ from sphinx.project import Project from sphinx.registry import SphinxComponentRegistry from sphinx.util import docutils -from sphinx.util import import_object, progress_message from sphinx.util import logging +from sphinx.util import progress_message from sphinx.util.build_phase import BuildPhase from sphinx.util.console import bold # type: ignore -from sphinx.util.docutils import directive_helper from sphinx.util.i18n import CatalogRepository from sphinx.util.logging import prefixed_warnings from sphinx.util.osutil import abspath, ensuredir, relpath @@ -100,7 +96,6 @@ builtin_extensions = ( 'sphinx.transforms.post_transforms', 'sphinx.transforms.post_transforms.code', 'sphinx.transforms.post_transforms.images', - 'sphinx.transforms.post_transforms.compat', 'sphinx.util.compat', 'sphinx.versioning', # collectors should be loaded by specific order @@ -406,18 +401,6 @@ class Sphinx: if version > sphinx.__display_version__[:3]: raise VersionRequirementError(version) - def import_object(self, objname, source=None): - # type: (str, str) -> Any - """Import an object from a ``module.name`` string. - - .. deprecated:: 1.8 - Use ``sphinx.util.import_object()`` instead. - """ - warnings.warn('app.import_object() is deprecated. ' - 'Use sphinx.util.add_object_type() instead.', - RemovedInSphinx30Warning, stacklevel=2) - return import_object(objname, source=None) - # event interface def connect(self, event, callback): # type: (str, Callable) -> int @@ -596,36 +579,14 @@ class Sphinx: self.registry.add_enumerable_node(node, figtype, title_getter, override=override) self.add_node(node, override=override, **kwds) - @property - def enumerable_nodes(self): - # type: () -> Dict[Type[nodes.Node], Tuple[str, TitleGetter]] - warnings.warn('app.enumerable_nodes() is deprecated. ' - 'Use app.get_domain("std").enumerable_nodes instead.', - RemovedInSphinx30Warning, stacklevel=2) - return self.registry.enumerable_nodes - - def add_directive(self, name, obj, content=None, arguments=None, override=False, **options): # NOQA - # type: (str, Any, bool, Tuple[int, int, bool], bool, Any) -> None + def add_directive(self, name, cls, override=False): + # type: (str, Type[Directive], bool) -> None """Register a Docutils directive. - *name* must be the prospective directive name. There are two possible - ways to write a directive: - - - In the docutils 0.4 style, *obj* is the directive function. - *content*, *arguments* and *options* are set as attributes on the - function and determine whether the directive has content, arguments - and options, respectively. **This style is deprecated.** - - - In the docutils 0.5 style, *obj* is the directive class. - It must already have attributes named *has_content*, - *required_arguments*, *optional_arguments*, - *final_argument_whitespace* and *option_spec* that correspond to the - options for the function way. See `the Docutils docs - <http://docutils.sourceforge.net/docs/howto/rst-directives.html>`_ - for details. - - The directive class must inherit from the class - ``docutils.parsers.rst.Directive``. + *name* must be the prospective directive name. *cls* is a directive + class which inherits ``docutils.parsers.rst.Directive``. For more + details, see `the Docutils docs + <http://docutils.sourceforge.net/docs/howto/rst-directives.html>`_ . For example, the (already existing) :rst:dir:`literalinclude` directive would be added like this: @@ -656,17 +617,12 @@ class Sphinx: .. versionchanged:: 1.8 Add *override* keyword. """ - logger.debug('[app] adding directive: %r', - (name, obj, content, arguments, options)) + logger.debug('[app] adding directive: %r', (name, cls)) if not override and docutils.is_directive_registered(name): logger.warning(__('directive %r is already registered, it will be overridden'), name, type='app', subtype='add_directive') - if not isclass(obj) or not issubclass(obj, Directive): - directive = directive_helper(obj, content, arguments, **options) - docutils.register_directive(name, directive) - else: - docutils.register_directive(name, obj) + docutils.register_directive(name, cls) def add_role(self, name, role, override=False): # type: (str, Any, bool) -> None @@ -719,26 +675,8 @@ class Sphinx: """ self.registry.add_domain(domain, override=override) - def override_domain(self, domain): - # type: (Type[Domain]) -> None - """Override a registered domain. - - Make the given *domain* class known to Sphinx, assuming that there is - already a domain with its ``.name``. The new domain must be a subclass - of the existing one. - - .. versionadded:: 1.0 - .. deprecated:: 1.8 - Integrated to :meth:`add_domain`. - """ - warnings.warn('app.override_domain() is deprecated. ' - 'Use app.add_domain() with override option instead.', - RemovedInSphinx30Warning, stacklevel=2) - self.registry.add_domain(domain, override=True) - - def add_directive_to_domain(self, domain, name, obj, has_content=None, argument_spec=None, - override=False, **option_spec): - # type: (str, str, Any, bool, Any, bool, Any) -> None + def add_directive_to_domain(self, domain, name, cls, override=False): + # type: (str, str, Type[Directive], bool) -> None """Register a Docutils directive in a domain. Like :meth:`add_directive`, but the directive is added to the domain @@ -748,9 +686,7 @@ class Sphinx: .. versionchanged:: 1.8 Add *override* keyword. """ - self.registry.add_directive_to_domain(domain, name, obj, - has_content, argument_spec, override=override, - **option_spec) + self.registry.add_directive_to_domain(domain, name, cls, override=override) def add_role_to_domain(self, domain, name, role, override=False): # type: (str, str, Union[RoleFunction, XRefRole], bool) -> None @@ -1215,13 +1151,6 @@ class Sphinx: return True - @property - def _setting_up_extension(self): - # type: () -> List[str] - warnings.warn('app._setting_up_extension is deprecated.', - RemovedInSphinx30Warning) - return ['?'] - class TemplateBridge: """ @@ -1262,12 +1191,3 @@ class TemplateBridge: specified context (a Python dictionary). """ raise NotImplementedError('must be implemented in subclasses') - - -from sphinx.config import CONFIG_FILENAME # NOQA - -deprecated_alias('sphinx.application', - { - 'CONFIG_FILENAME': CONFIG_FILENAME, - }, - RemovedInSphinx30Warning) diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py index 1a7054bdc..2ce5c0315 100644 --- a/sphinx/builders/html.py +++ b/sphinx/builders/html.py @@ -28,7 +28,7 @@ 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 RemovedInSphinx30Warning, RemovedInSphinx40Warning +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 @@ -48,7 +48,7 @@ from sphinx.util.osutil import os_path, relative_uri, ensuredir, movefile, copyf from sphinx.util.tags import Tags from sphinx.writers.html import HTMLWriter, HTMLTranslator -# HTML5 Writer is avialable or not +# HTML5 Writer is available or not if is_html5_writer_available(): from sphinx.writers.html5 import HTML5Translator html5_ready = True @@ -98,35 +98,6 @@ class Stylesheet(str): return self -class JSContainer(list): - """The container for JavaScript scripts.""" - def insert(self, index: int, obj: str) -> None: - warnings.warn('To modify script_files in the theme is deprecated. ' - 'Please insert a <script> tag directly in your theme instead.', - RemovedInSphinx30Warning, stacklevel=3) - super().insert(index, obj) - - def extend(self, other: List[str]) -> None: # type: ignore - warnings.warn('To modify script_files in the theme is deprecated. ' - 'Please insert a <script> tag directly in your theme instead.', - RemovedInSphinx30Warning, stacklevel=3) - for item in other: - self.append(item) - - def __iadd__(self, other: List[str]) -> "JSContainer": # type: ignore - warnings.warn('To modify script_files in the theme is deprecated. ' - 'Please insert a <script> tag directly in your theme instead.', - RemovedInSphinx30Warning, stacklevel=3) - for item in other: - self.append(item) - return self - - def __add__(self, other: List[str]) -> "JSContainer": - ret = JSContainer(self) - ret += other - return ret - - class JavaScript(str): """A metadata of javascript file. @@ -230,7 +201,7 @@ class StandaloneHTMLBuilder(Builder): self.css_files = [] # type: List[Dict[str, str]] # JS files - self.script_files = JSContainer() # type: List[JavaScript] + self.script_files = [] # type: List[JavaScript] def init(self) -> None: self.build_info = self.create_build_info() @@ -999,15 +970,6 @@ class StandaloneHTMLBuilder(Builder): return False ctx['hasdoc'] = hasdoc - def warn(*args, **kwargs) -> str: - """Simple warn() wrapper for themes.""" - warnings.warn('The template function warn() was deprecated. ' - 'Use warning() instead.', - RemovedInSphinx30Warning, stacklevel=2) - logger.warning(*args, **kwargs) - return '' # return empty string - ctx['warn'] = warn - ctx['toctree'] = lambda **kw: self._get_local_toctree(pagename, **kw) self.add_sidebars(pagename, ctx) ctx.update(addctx) diff --git a/sphinx/builders/latex/util.py b/sphinx/builders/latex/util.py index 8155d1fd7..b7d79121c 100644 --- a/sphinx/builders/latex/util.py +++ b/sphinx/builders/latex/util.py @@ -8,12 +8,8 @@ :license: BSD, see LICENSE for details. """ -import warnings - from docutils.writers.latex2e import Babel -from sphinx.deprecation import RemovedInSphinx30Warning - class ExtBabel(Babel): cyrillic_languages = ('bulgarian', 'kazakh', 'mongolian', 'russian', 'ukrainian') @@ -24,12 +20,6 @@ class ExtBabel(Babel): self.supported = True super().__init__(language_code or '') - def get_shorthandoff(self) -> str: - warnings.warn('ExtBabel.get_shorthandoff() is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - from sphinx.writers.latex import SHORTHANDOFF - return SHORTHANDOFF - def uses_cyrillic(self) -> bool: return self.language in self.cyrillic_languages diff --git a/sphinx/cmd/quickstart.py b/sphinx/cmd/quickstart.py index 846750a68..b28cd3519 100644 --- a/sphinx/cmd/quickstart.py +++ b/sphinx/cmd/quickstart.py @@ -54,10 +54,8 @@ EXTENSIONS = OrderedDict([ ('imgmath', __('include math, rendered as PNG or SVG images')), ('mathjax', __('include math, rendered in the browser by MathJax')), ('ifconfig', __('conditional inclusion of content based on config values')), - ('viewcode', - __('include links to the source code of documented Python objects')), - ('githubpages', - __('create .nojekyll file to publish the document on GitHub pages')), + ('viewcode', __('include links to the source code of documented Python objects')), + ('githubpages', __('create .nojekyll file to publish the document on GitHub pages')), ]) DEFAULTS = { @@ -129,8 +127,7 @@ def boolean(x: str) -> bool: def suffix(x: str) -> str: if not (x[0:1] == '.' and len(x) > 1): - raise ValidationError(__("Please enter a file suffix, " - "e.g. '.rst' or '.txt'.")) + raise ValidationError(__("Please enter a file suffix, e.g. '.rst' or '.txt'.")) return x @@ -228,16 +225,16 @@ def ask_user(d: Dict) -> None: """ print(bold(__('Welcome to the Sphinx %s quickstart utility.')) % __display_version__) - print(__(''' -Please enter values for the following settings (just press Enter to -accept a default value, if one is given in brackets).''')) + print() + print(__('Please enter values for the following settings (just press Enter to\n' + 'accept a default value, if one is given in brackets).')) if 'path' in d: - print(bold(__(''' -Selected root path: %s''') % d['path'])) + print() + print(bold(__('Selected root path: %s')) % d['path']) else: - print(__(''' -Enter the root path for documentation.''')) + print() + print(__('Enter the root path for documentation.')) d['path'] = do_prompt(__('Root path for the documentation'), '.', is_path) while path.isfile(path.join(d['path'], 'conf.py')) or \ @@ -247,70 +244,68 @@ Enter the root path for documentation.''')) 'selected root path.'))) print(__('sphinx-quickstart will not overwrite existing Sphinx projects.')) print() - d['path'] = do_prompt(__('Please enter a new root path (or just Enter ' - 'to exit)'), '', is_path) + d['path'] = do_prompt(__('Please enter a new root path (or just Enter to exit)'), + '', is_path) if not d['path']: sys.exit(1) if 'sep' not in d: - print(__(''' -You have two options for placing the build directory for Sphinx output. -Either, you use a directory "_build" within the root path, or you separate -"source" and "build" directories within the root path.''')) - d['sep'] = do_prompt(__('Separate source and build directories (y/n)'), - 'n', boolean) + print() + print(__('You have two options for placing the build directory for Sphinx output.\n' + 'Either, you use a directory "_build" within the root path, or you separate\n' + '"source" and "build" directories within the root path.')) + d['sep'] = do_prompt(__('Separate source and build directories (y/n)'), 'n', boolean) if 'dot' not in d: - print(__(''' -Inside the root directory, two more directories will be created; "_templates" -for custom HTML templates and "_static" for custom stylesheets and other static -files. You can enter another prefix (such as ".") to replace the underscore.''')) + print() + print(__('Inside the root directory, two more directories will be created; "_templates"\n' # NOQA + 'for custom HTML templates and "_static" for custom stylesheets and other static\n' # NOQA + 'files. You can enter another prefix (such as ".") to replace the underscore.')) # NOQA d['dot'] = do_prompt(__('Name prefix for templates and static dir'), '_', ok) if 'project' not in d: - print(__(''' -The project name will occur in several places in the built documentation.''')) + print() + print(__('The project name will occur in several places in the built documentation.')) d['project'] = do_prompt(__('Project name')) if 'author' not in d: d['author'] = do_prompt(__('Author name(s)')) if 'version' not in d: - print(__(''' -Sphinx has the notion of a "version" and a "release" for the -software. Each version can have multiple releases. For example, for -Python the version is something like 2.5 or 3.0, while the release is -something like 2.5.1 or 3.0a1. If you don't need this dual structure, -just set both to the same value.''')) + print() + print(__('Sphinx has the notion of a "version" and a "release" for the\n' + 'software. Each version can have multiple releases. For example, for\n' + 'Python the version is something like 2.5 or 3.0, while the release is\n' + 'something like 2.5.1 or 3.0a1. If you don\'t need this dual structure,\n' + 'just set both to the same value.')) d['version'] = do_prompt(__('Project version'), '', allow_empty) if 'release' not in d: d['release'] = do_prompt(__('Project release'), d['version'], allow_empty) if 'language' not in d: - print(__(''' -If the documents are to be written in a language other than English, -you can select a language here by its language code. Sphinx will then -translate text that it generates into that language. - -For a list of supported codes, see -https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language.''')) + print() + print(__('If the documents are to be written in a language other than English,\n' + 'you can select a language here by its language code. Sphinx will then\n' + 'translate text that it generates into that language.\n' + '\n' + 'For a list of supported codes, see\n' + 'https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-language.')) # NOQA d['language'] = do_prompt(__('Project language'), 'en') if d['language'] == 'en': d['language'] = None if 'suffix' not in d: - print(__(''' -The file name suffix for source files. Commonly, this is either ".txt" -or ".rst". Only files with this suffix are considered documents.''')) + print() + print(__('The file name suffix for source files. Commonly, this is either ".txt"\n' + 'or ".rst". Only files with this suffix are considered documents.')) d['suffix'] = do_prompt(__('Source file suffix'), '.rst', suffix) if 'master' not in d: - print(__(''' -One document is special in that it is considered the top node of the -"contents tree", that is, it is the root of the hierarchical structure -of the documents. Normally, this is "index", but if your "index" -document is a custom template, you can also set this to another filename.''')) - d['master'] = do_prompt(__('Name of your master document (without suffix)'), - 'index') + print() + print(__('One document is special in that it is considered the top node of the\n' + '"contents tree", that is, it is the root of the hierarchical structure\n' + 'of the documents. Normally, this is "index", but if your "index"\n' + 'document is a custom template, you can also set this to another filename.')) + d['master'] = do_prompt(__('Name of your master document (without suffix)'), 'index') while path.isfile(path.join(d['path'], d['master'] + d['suffix'])) or \ path.isfile(path.join(d['path'], 'source', d['master'] + d['suffix'])): @@ -323,8 +318,7 @@ document is a custom template, you can also set this to another filename.''')) 'existing file and press Enter'), d['master']) if 'extensions' not in d: - print(__('Indicate which of the following Sphinx extensions should be ' - 'enabled:')) + print(__('Indicate which of the following Sphinx extensions should be enabled:')) d['extensions'] = [] for name, description in EXTENSIONS.items(): if do_prompt('%s: %s (y/n)' % (name, description), 'n', boolean): @@ -332,20 +326,19 @@ document is a custom template, you can also set this to another filename.''')) # Handle conflicting options if {'sphinx.ext.imgmath', 'sphinx.ext.mathjax'}.issubset(d['extensions']): - print(__('Note: imgmath and mathjax cannot be enabled at the same ' - 'time. imgmath has been deselected.')) + print(__('Note: imgmath and mathjax cannot be enabled at the same time. ' + 'imgmath has been deselected.')) d['extensions'].remove('sphinx.ext.imgmath') if 'makefile' not in d: - print(__(''' -A Makefile and a Windows command file can be generated for you so that you -only have to run e.g. `make html' instead of invoking sphinx-build -directly.''')) + print() + print(__('A Makefile and a Windows command file can be generated for you so that you\n' + 'only have to run e.g. `make html\' instead of invoking sphinx-build\n' + 'directly.')) d['makefile'] = do_prompt(__('Create Makefile? (y/n)'), 'y', boolean) if 'batchfile' not in d: - d['batchfile'] = do_prompt(__('Create Windows command file? (y/n)'), - 'y', boolean) + d['batchfile'] = do_prompt(__('Create Windows command file? (y/n)'), 'y', boolean) print() @@ -428,17 +421,18 @@ def generate(d: Dict, overwrite: bool = True, silent: bool = False, templatedir: return print() print(bold(__('Finished: An initial directory structure has been created.'))) - print(__(''' -You should now populate your master file %s and create other documentation -source files. ''') % masterfile + ((d['makefile'] or d['batchfile']) and __('''\ -Use the Makefile to build the docs, like so: - make builder -''') or __('''\ -Use the sphinx-build command to build the docs, like so: - sphinx-build -b builder %s %s -''') % (srcdir, builddir)) + __('''\ -where "builder" is one of the supported builders, e.g. html, latex or linkcheck. -''')) + print() + print(__('You should now populate your master file %s and create other documentation\n' + 'source files. ') % masterfile, end='') + if d['makefile'] or d['batchfile']: + print(__('Use the Makefile to build the docs, like so:\n' + ' make builder')) + else: + print(__('Use the sphinx-build command to build the docs, like so:\n' + ' sphinx-build -b builder %s %s') % (srcdir, builddir)) + print(__('where "builder" is one of the supported builders, ' + 'e.g. html, latex or linkcheck.')) + print() def valid_dir(d: Dict) -> bool: @@ -471,16 +465,18 @@ def valid_dir(d: Dict) -> bool: def get_parser() -> argparse.ArgumentParser: + description = __( + "\n" + "Generate required files for a Sphinx project.\n" + "\n" + "sphinx-quickstart is an interactive tool that asks some questions about your\n" + "project and then generates a complete documentation directory and sample\n" + "Makefile to be used with sphinx-build.\n" + ) parser = argparse.ArgumentParser( usage='%(prog)s [OPTIONS] <PROJECT_DIR>', epilog=__("For more information, visit <http://sphinx-doc.org/>."), - description=__(""" -Generate required files for a Sphinx project. - -sphinx-quickstart is an interactive tool that asks some questions about your -project and then generates a complete documentation directory and sample -Makefile to be used with sphinx-build. -""")) + description=description) parser.add_argument('-q', '--quiet', action='store_true', dest='quiet', default=None, @@ -579,8 +575,8 @@ def main(argv: List[str] = sys.argv[1:]) -> int: try: if 'quiet' in d: if not {'project', 'author'}.issubset(d): - print(__('''"quiet" is specified, but any of "project" or \ -"author" is not specified.''')) + print(__('"quiet" is specified, but any of "project" or ' + '"author" is not specified.')) return 1 if {'quiet', 'project', 'author'}.issubset(d): diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py deleted file mode 100644 index 5247eb157..000000000 --- a/sphinx/cmdline.py +++ /dev/null @@ -1,49 +0,0 @@ -""" - sphinx.cmdline - ~~~~~~~~~~~~~~ - - sphinx-build command-line handling. - - :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import sys -import warnings - -from sphinx.cmd import build -from sphinx.deprecation import RemovedInSphinx30Warning - -if False: - # For type annotation - import argparse # NOQA - from typing import Any, IO, List, Union # NOQA - from sphinx.application import Sphinx # NOQA - - -def handle_exception(app, args, exception, stderr=sys.stderr): - # type: (Sphinx, Any, Union[Exception, KeyboardInterrupt], IO) -> None - warnings.warn('sphinx.cmdline module is deprecated. Use sphinx.cmd.build instead.', - RemovedInSphinx30Warning, stacklevel=2) - build.handle_exception(app, args, exception, stderr) - - -def jobs_argument(value): - # type: (str) -> int - warnings.warn('sphinx.cmdline module is deprecated. Use sphinx.cmd.build instead.', - RemovedInSphinx30Warning, stacklevel=2) - return build.jobs_argument(value) - - -def get_parser(): - # type: () -> argparse.ArgumentParser - warnings.warn('sphinx.cmdline module is deprecated. Use sphinx.cmd.build instead.', - RemovedInSphinx30Warning, stacklevel=2) - return build.get_parser() - - -def main(argv=sys.argv[1:]): - # type: (List[str]) -> int - warnings.warn('sphinx.cmdline module is deprecated. Use sphinx.cmd.build instead.', - RemovedInSphinx30Warning, stacklevel=2) - return build.main(argv) diff --git a/sphinx/config.py b/sphinx/config.py index 5ba2c2a3d..06718eb2b 100644 --- a/sphinx/config.py +++ b/sphinx/config.py @@ -16,7 +16,7 @@ from collections import OrderedDict from os import path, getenv from typing import Any, NamedTuple, Union -from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.errors import ConfigError, ExtensionError from sphinx.locale import _, __ from sphinx.util import logging @@ -155,27 +155,8 @@ class Config: 'env', []), } # type: Dict[str, Tuple] - def __init__(self, *args): - # type: (Any) -> None - if len(args) == 4: - # old style arguments: (dirname, filename, overrides, tags) - warnings.warn('The argument of Config() class has been changed. ' - 'Use Config.read() to read configuration from conf.py.', - RemovedInSphinx30Warning, stacklevel=2) - dirname, filename, overrides, tags = args - if dirname is None: - config = {} # type: Dict[str, Any] - else: - config = eval_config_file(path.join(dirname, filename), tags) - else: - # new style arguments: (config={}, overrides={}) - if len(args) == 0: - config, overrides = {}, {} - elif len(args) == 1: - config, overrides = args[0], {} - else: - config, overrides = args[:2] - + def __init__(self, config={}, overrides={}): + # type: (Dict[str, Any], Dict[str, Any]) -> None self.overrides = overrides self.values = Config.config_values.copy() self._raw_config = config @@ -196,18 +177,6 @@ class Config: namespace = eval_config_file(filename, tags) return cls(namespace, overrides or {}) - def check_types(self): - # type: () -> None - warnings.warn('Config.check_types() is deprecated. Use check_confval_types() instead.', - RemovedInSphinx30Warning, stacklevel=2) - check_confval_types(None, self) - - def check_unicode(self): - # type: () -> None - warnings.warn('Config.check_unicode() is deprecated. Use check_unicode() instead.', - RemovedInSphinx30Warning, stacklevel=2) - check_unicode(self) - def convert_overrides(self, name, value): # type: (str, Any) -> Any if not isinstance(value, str): diff --git a/sphinx/deprecation.py b/sphinx/deprecation.py index be01ca65f..23efe8ba7 100644 --- a/sphinx/deprecation.py +++ b/sphinx/deprecation.py @@ -17,15 +17,15 @@ if False: from typing import Any, Dict, Type # NOQA -class RemovedInSphinx30Warning(DeprecationWarning): +class RemovedInSphinx40Warning(DeprecationWarning): pass -class RemovedInSphinx40Warning(PendingDeprecationWarning): +class RemovedInSphinx50Warning(PendingDeprecationWarning): pass -RemovedInNextVersionWarning = RemovedInSphinx30Warning +RemovedInNextVersionWarning = RemovedInSphinx40Warning def deprecated_alias(modname, objects, warning): diff --git a/sphinx/domains/changeset.py b/sphinx/domains/changeset.py index 53cdec41c..067587a96 100644 --- a/sphinx/domains/changeset.py +++ b/sphinx/domains/changeset.py @@ -16,8 +16,6 @@ from docutils import nodes from docutils.nodes import Node from sphinx import addnodes -from sphinx import locale -from sphinx.deprecation import DeprecatedDict, RemovedInSphinx30Warning from sphinx.domains import Domain from sphinx.locale import _ from sphinx.util.docutils import SphinxDirective @@ -41,13 +39,6 @@ versionlabel_classes = { 'deprecated': 'deprecated', } -locale.versionlabels = DeprecatedDict( - versionlabels, - 'sphinx.locale.versionlabels is deprecated. ' - 'Please use sphinx.domains.changeset.versionlabels instead.', - RemovedInSphinx30Warning -) - # TODO: move to typing.NamedTuple after dropping py35 support (see #5958) ChangeSet = namedtuple('ChangeSet', diff --git a/sphinx/domains/math.py b/sphinx/domains/math.py index d3cacc5ba..21a3fac76 100644 --- a/sphinx/domains/math.py +++ b/sphinx/domains/math.py @@ -15,7 +15,6 @@ from docutils import nodes from docutils.nodes import Element, Node, system_message from docutils.nodes import make_id -from sphinx.addnodes import math_block as displaymath from sphinx.addnodes import pending_xref from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.domains import Domain @@ -54,7 +53,6 @@ class MathDomain(Domain): 'eq': 'equation not found: %(target)s', } enumerable_nodes = { # node_class -> (figtype, title_getter) - displaymath: ('displaymath', None), nodes.math_block: ('displaymath', None), } roles = { diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py index b70481198..b401ffd3c 100644 --- a/sphinx/domains/python.py +++ b/sphinx/domains/python.py @@ -17,13 +17,11 @@ from docutils import nodes from docutils.nodes import Element, Node from docutils.parsers.rst import directives -from sphinx import addnodes, locale +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 ( - DeprecatedDict, RemovedInSphinx30Warning, RemovedInSphinx40Warning -) +from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.directives import ObjectDescription from sphinx.domains import Domain, ObjType, Index, IndexEntry from sphinx.environment import BuildEnvironment @@ -59,13 +57,6 @@ pairindextypes = { 'builtin': _('built-in function'), } -locale.pairindextypes = DeprecatedDict( - pairindextypes, - 'sphinx.locale.pairindextypes is deprecated. ' - 'Please use sphinx.domains.python.pairindextypes instead.', - RemovedInSphinx30Warning -) - def _pseudo_parse_arglist(signode: desc_signature, arglist: str) -> None: """"Parse" a list of arguments separated by commas. diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py index 66171646a..9d094d1a9 100644 --- a/sphinx/domains/std.py +++ b/sphinx/domains/std.py @@ -22,10 +22,9 @@ from docutils.statemachine import StringList from sphinx import addnodes from sphinx.addnodes import desc_signature, pending_xref -from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.directives import ObjectDescription from sphinx.domains import Domain, ObjType -from sphinx.errors import NoUri from sphinx.locale import _, __ from sphinx.roles import XRefRole from sphinx.util import ws_re, logging, docname_join @@ -804,30 +803,6 @@ class StandardDomain(Domain): return make_refnode(builder, fromdocname, docname, labelid, contnode) - def _resolve_citation_xref(self, env: "BuildEnvironment", fromdocname: str, - builder: "Builder", typ: str, target: str, - node: pending_xref, contnode: Element) -> Element: - warnings.warn('StandardDomain._resolve_citation_xref() is deprecated.', - RemovedInSphinx30Warning) - docname, labelid, lineno = self.data['citations'].get(target, ('', '', 0)) - if not docname: - if 'ids' in node: - # remove ids attribute that annotated at - # transforms.CitationReference.apply. - del node['ids'][:] - return None - - try: - return make_refnode(builder, fromdocname, docname, - labelid, contnode) - except NoUri: - # remove the ids we added in the CitationReferences - # transform since they can't be transfered to - # the contnode (if it's a Text node) - if not isinstance(contnode, nodes.Element): - del node['ids'][:] - raise - def _resolve_obj_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder", typ: str, target: str, node: pending_xref, contnode: Element) -> Element: @@ -924,16 +899,6 @@ class StandardDomain(Domain): figtype, _ = self.enumerable_nodes.get(node.__class__, (None, None)) return figtype - def get_figtype(self, node: Node) -> str: - """Get figure type of nodes. - - .. deprecated:: 1.8 - """ - warnings.warn('StandardDomain.get_figtype() is deprecated. ' - 'Please use get_enumerable_node_type() instead.', - RemovedInSphinx30Warning, stacklevel=2) - return self.get_enumerable_node_type(node) - def get_fignumber(self, env: "BuildEnvironment", builder: "Builder", figtype: str, docname: str, target_node: Element) -> Tuple[int, ...]: if figtype == 'section': diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py index 59d120e82..8e2db2b4e 100644 --- a/sphinx/environment/__init__.py +++ b/sphinx/environment/__init__.py @@ -13,18 +13,15 @@ import pickle import warnings from collections import defaultdict from copy import copy -from io import BytesIO from os import path -from typing import Any, Callable, Dict, Generator, IO, Iterator, List, Set, Tuple, Union +from typing import Any, Callable, Dict, Generator, Iterator, List, Set, Tuple, Union from docutils import nodes from docutils.nodes import Node from sphinx import addnodes from sphinx.config import Config -from sphinx.deprecation import ( - RemovedInSphinx30Warning, RemovedInSphinx40Warning, deprecated_alias -) +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 @@ -43,6 +40,7 @@ if False: from sphinx.application import Sphinx from sphinx.builders import Builder + logger = logging.getLogger(__name__) default_settings = { @@ -632,120 +630,3 @@ class BuildEnvironment: for domain in self.domains.values(): domain.check_consistency() self.events.emit('env-check-consistency', self) - - # --------- METHODS FOR COMPATIBILITY -------------------------------------- - - def update(self, config: Config, srcdir: str, doctreedir: str) -> List[str]: - warnings.warn('env.update() is deprecated. Please use builder.read() instead.', - RemovedInSphinx30Warning, stacklevel=2) - return self.app.builder.read() - - def _read_serial(self, docnames: List[str], app: "Sphinx") -> None: - warnings.warn('env._read_serial() is deprecated. Please use builder.read() instead.', - RemovedInSphinx30Warning, stacklevel=2) - return self.app.builder._read_serial(docnames) - - def _read_parallel(self, docnames: List[str], app: "Sphinx", nproc: int) -> None: - warnings.warn('env._read_parallel() is deprecated. Please use builder.read() instead.', - RemovedInSphinx30Warning, stacklevel=2) - return self.app.builder._read_parallel(docnames, nproc) - - def read_doc(self, docname: str, app: "Sphinx" = None) -> None: - warnings.warn('env.read_doc() is deprecated. Please use builder.read_doc() instead.', - RemovedInSphinx30Warning, stacklevel=2) - self.app.builder.read_doc(docname) - - def write_doctree(self, docname: str, doctree: nodes.document) -> None: - warnings.warn('env.write_doctree() is deprecated. ' - 'Please use builder.write_doctree() instead.', - RemovedInSphinx30Warning, stacklevel=2) - self.app.builder.write_doctree(docname, doctree) - - @property - def _nitpick_ignore(self) -> List[str]: - warnings.warn('env._nitpick_ignore is deprecated. ' - 'Please use config.nitpick_ignore instead.', - RemovedInSphinx30Warning, stacklevel=2) - return self.config.nitpick_ignore - - @staticmethod - def load(f: IO, app: "Sphinx" = None) -> "BuildEnvironment": - warnings.warn('BuildEnvironment.load() is deprecated. ' - 'Please use pickle.load() instead.', - RemovedInSphinx30Warning, stacklevel=2) - try: - env = pickle.load(f) - except Exception as exc: - # This can happen for example when the pickle is from a - # different version of Sphinx. - raise OSError(exc) - if app: - env.app = app - env.config.values = app.config.values - return env - - @classmethod - def loads(cls, string: bytes, app: "Sphinx" = None) -> "BuildEnvironment": - warnings.warn('BuildEnvironment.loads() is deprecated. ' - 'Please use pickle.loads() instead.', - RemovedInSphinx30Warning, stacklevel=2) - io = BytesIO(string) - return cls.load(io, app) - - @classmethod - def frompickle(cls, filename: str, app: "Sphinx") -> "BuildEnvironment": - warnings.warn('BuildEnvironment.frompickle() is deprecated. ' - 'Please use pickle.load() instead.', - RemovedInSphinx30Warning, stacklevel=2) - with open(filename, 'rb') as f: - return cls.load(f, app) - - @staticmethod - def dump(env: "BuildEnvironment", f: IO) -> None: - warnings.warn('BuildEnvironment.dump() is deprecated. ' - 'Please use pickle.dump() instead.', - RemovedInSphinx30Warning, stacklevel=2) - pickle.dump(env, f, pickle.HIGHEST_PROTOCOL) - - @classmethod - def dumps(cls, env: "BuildEnvironment") -> bytes: - warnings.warn('BuildEnvironment.dumps() is deprecated. ' - 'Please use pickle.dumps() instead.', - RemovedInSphinx30Warning, stacklevel=2) - io = BytesIO() - cls.dump(env, io) - return io.getvalue() - - def topickle(self, filename: str) -> None: - warnings.warn('env.topickle() is deprecated. ' - 'Please use pickle.dump() instead.', - RemovedInSphinx30Warning, stacklevel=2) - with open(filename, 'wb') as f: - self.dump(self, f) - - @property - def versionchanges(self) -> Dict[str, List[Tuple[str, str, int, str, str, str]]]: - warnings.warn('env.versionchanges() is deprecated. ' - 'Please use ChangeSetDomain instead.', - RemovedInSphinx30Warning, stacklevel=2) - return self.domaindata['changeset']['changes'] - - def note_versionchange(self, type: str, version: str, - node: addnodes.versionmodified, lineno: int) -> None: - warnings.warn('env.note_versionchange() is deprecated. ' - 'Please use ChangeSetDomain.note_changeset() instead.', - RemovedInSphinx30Warning, stacklevel=2) - node['type'] = type - node['version'] = version - node.line = lineno - self.get_domain('changeset').note_changeset(node) # type: ignore - - -from sphinx.errors import NoUri # NOQA - - -deprecated_alias('sphinx.environment', - { - 'NoUri': NoUri, - }, - RemovedInSphinx30Warning) diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py index 4273351bf..8169d19e7 100644 --- a/sphinx/ext/autodoc/__init__.py +++ b/sphinx/ext/autodoc/__init__.py @@ -19,10 +19,8 @@ from docutils.statemachine import StringList import sphinx from sphinx.application import Sphinx -from sphinx.config import Config, ENUM -from sphinx.deprecation import ( - RemovedInSphinx30Warning, RemovedInSphinx40Warning, deprecated_alias -) +from sphinx.config import ENUM +from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.environment import BuildEnvironment from sphinx.ext.autodoc.importer import import_object, get_object_members from sphinx.ext.autodoc.mock import mock @@ -1498,38 +1496,6 @@ def autodoc_attrgetter(app: Sphinx, obj: Any, name: str, *defargs) -> Any: return safe_getattr(obj, name, *defargs) -def merge_autodoc_default_flags(app: Sphinx, config: Config) -> None: - """This merges the autodoc_default_flags to autodoc_default_options.""" - if not config.autodoc_default_flags: - return - - # Note: this option will be removed in Sphinx-4.0. But I marked this as - # RemovedInSphinx *30* Warning because we have to emit warnings for users - # who will be still in use with Sphinx-3.x. So we should replace this by - # logger.warning() on 3.0.0 release. - warnings.warn('autodoc_default_flags is now deprecated. ' - 'Please use autodoc_default_options instead.', - RemovedInSphinx30Warning, stacklevel=2) - - for option in config.autodoc_default_flags: - if isinstance(option, str): - config.autodoc_default_options[option] = None - else: - logger.warning( - __("Ignoring invalid option in autodoc_default_flags: %r"), - option, type='autodoc' - ) - - -from sphinx.ext.autodoc.mock import _MockImporter # NOQA - -deprecated_alias('sphinx.ext.autodoc', - { - '_MockImporter': _MockImporter, - }, - RemovedInSphinx40Warning) - - def setup(app: Sphinx) -> Dict[str, Any]: app.add_autodocumenter(ModuleDocumenter) app.add_autodocumenter(ClassDocumenter) @@ -1556,6 +1522,4 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_event('autodoc-process-signature') app.add_event('autodoc-skip-member') - app.connect('config-inited', merge_autodoc_default_flags) - return {'version': sphinx.__display_version__, 'parallel_read_safe': True} diff --git a/sphinx/ext/autodoc/importer.py b/sphinx/ext/autodoc/importer.py index fc934958d..b6cb6cd2d 100644 --- a/sphinx/ext/autodoc/importer.py +++ b/sphinx/ext/autodoc/importer.py @@ -154,12 +154,11 @@ def get_object_members(subject: Any, objpath: List[str], attrgetter: Callable, from sphinx.ext.autodoc.mock import ( # NOQA - _MockImporter, _MockModule, _MockObject, MockFinder, MockLoader, mock + _MockModule, _MockObject, MockFinder, MockLoader, mock ) deprecated_alias('sphinx.ext.autodoc.importer', { - '_MockImporter': _MockImporter, '_MockModule': _MockModule, '_MockObject': _MockObject, 'MockFinder': MockFinder, diff --git a/sphinx/ext/autodoc/mock.py b/sphinx/ext/autodoc/mock.py index 4f534a452..b13c5ee61 100644 --- a/sphinx/ext/autodoc/mock.py +++ b/sphinx/ext/autodoc/mock.py @@ -11,13 +11,11 @@ import contextlib import os import sys -import warnings from importlib.abc import Loader, MetaPathFinder from importlib.machinery import ModuleSpec from types import FunctionType, MethodType, ModuleType from typing import Any, Generator, Iterator, List, Sequence, Tuple, Union -from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.util import logging logger = logging.getLogger(__name__) @@ -81,15 +79,11 @@ class _MockModule(ModuleType): """Used by autodoc_mock_imports.""" __file__ = os.devnull - def __init__(self, name: str, loader: "_MockImporter" = None) -> None: + def __init__(self, name: str) -> None: super().__init__(name) self.__all__ = [] # type: List[str] self.__path__ = [] # type: List[str] - if loader is not None: - warnings.warn('The loader argument for _MockModule is deprecated.', - RemovedInSphinx30Warning) - def __getattr__(self, name: str) -> _MockObject: return _make_subclass(name, self.__name__)() @@ -97,44 +91,6 @@ class _MockModule(ModuleType): return self.__name__ -class _MockImporter(MetaPathFinder): - def __init__(self, names: List[str]) -> None: - self.names = names - self.mocked_modules = [] # type: List[str] - # enable hook by adding itself to meta_path - sys.meta_path.insert(0, self) - - warnings.warn('_MockImporter is now deprecated.', - RemovedInSphinx30Warning) - - def disable(self) -> None: - # remove `self` from `sys.meta_path` to disable import hook - sys.meta_path = [i for i in sys.meta_path if i is not self] - # remove mocked modules from sys.modules to avoid side effects after - # running auto-documenter - for m in self.mocked_modules: - if m in sys.modules: - del sys.modules[m] - - def find_module(self, name: str, path: Sequence[Union[bytes, str]] = None) -> Any: - # check if name is (or is a descendant of) one of our base_packages - for n in self.names: - if n == name or name.startswith(n + '.'): - return self - return None - - def load_module(self, name: str) -> ModuleType: - if name in sys.modules: - # module has already been imported, return it - return sys.modules[name] - else: - logger.debug('[autodoc] adding a mock module %s!', name) - module = _MockModule(name, self) - sys.modules[name] = module - self.mocked_modules.append(name) - return module - - class MockLoader(Loader): """A loader for mocking.""" def __init__(self, finder: "MockFinder") -> None: diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py index 7c92bb8b5..65b12dbae 100644 --- a/sphinx/ext/autosummary/__init__.py +++ b/sphinx/ext/autosummary/__init__.py @@ -741,7 +741,8 @@ def process_generate_options(app: Sphinx) -> None: with mock(app.config.autosummary_mock_imports): generate_autosummary_docs(genfiles, builder=app.builder, suffix=suffix, base_path=app.srcdir, - app=app, imported_members=imported_members) + app=app, imported_members=imported_members, + overwrite=app.config.autosummary_generate_overwrite) def setup(app: Sphinx) -> Dict[str, Any]: @@ -764,6 +765,7 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.connect('doctree-read', process_autosummary_toc) app.connect('builder-inited', process_generate_options) app.add_config_value('autosummary_generate', [], True, [bool]) + app.add_config_value('autosummary_generate_overwrite', True, False) app.add_config_value('autosummary_mock_imports', lambda config: config.autodoc_mock_imports, 'env') app.add_config_value('autosummary_imported_members', [], False, [bool]) diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py index 2a23f1289..43898d48f 100644 --- a/sphinx/ext/autosummary/generate.py +++ b/sphinx/ext/autosummary/generate.py @@ -194,7 +194,8 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None, suffix: str = '.rst', warn: Callable = None, info: Callable = None, base_path: str = None, builder: Builder = None, template_dir: str = None, - imported_members: bool = False, app: Any = None) -> 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) @@ -245,26 +246,32 @@ def generate_autosummary_docs(sources: List[str], output_dir: str = None, _warn('[autosummary] failed to import %r: %s' % (name, e)) continue - fn = os.path.join(path, name + suffix) + content = generate_autosummary_content(name, obj, parent, template, template_name, + imported_members, app) - # skip it if it exists - if os.path.isfile(fn): - continue - - new_files.append(fn) + filename = os.path.join(path, name + suffix) + if os.path.isfile(filename): + with open(filename) as f: + old_content = f.read() - with open(fn, 'w') as f: - rendered = generate_autosummary_content(name, obj, parent, - template, template_name, - imported_members, app) - f.write(rendered) + if content == old_content: + continue + elif overwrite: # content has changed + with open(filename, 'w') as f: + f.write(content) + new_files.append(filename) + else: + with open(filename, 'w') as f: + f.write(content) + new_files.append(filename) # 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, builder=builder, - template_dir=template_dir, app=app) + template_dir=template_dir, app=app, + overwrite=overwrite) # -- Finding documented entries in files --------------------------------------- diff --git a/sphinx/ext/imgmath.py b/sphinx/ext/imgmath.py index 327be8973..992be7e95 100644 --- a/sphinx/ext/imgmath.py +++ b/sphinx/ext/imgmath.py @@ -87,14 +87,40 @@ DOC_BODY_PREVIEW = r''' ''' depth_re = re.compile(br'\[\d+ depth=(-?\d+)\]') +depthsvg_re = re.compile(br'.*, depth=(.*)pt') +depthsvgcomment_re = re.compile(r'<!-- DEPTH=(-?\d+) -->') -def generate_latex_macro(math: str, config: Config, confdir: str = '') -> str: +def read_svg_depth(filename): + # type: (str) -> int + """Read the depth from comment at last line of SVG file + """ + with open(filename, 'r') as f: + for line in f: + pass + # Only last line is checked + matched = depthsvgcomment_re.match(line) + if matched: + return int(matched.group(1)) + return None + + +def write_svg_depth(filename, depth): + # type: (str, int) -> None + """Write the depth to SVG file as a comment at end of file + """ + with open(filename, 'a') as f: + f.write('\n<!-- DEPTH=%s -->' % depth) + + +def generate_latex_macro(image_format: str, math: str, + config: Config, confdir: str = '') -> str: """Generate LaTeX macro.""" variables = { 'fontsize': config.imgmath_font_size, 'baselineskip': int(round(config.imgmath_font_size * 1.2)), 'preamble': config.imgmath_latex_preamble, + 'tightpage': '' if image_format == 'png' else ',tightpage', 'math': math } @@ -201,8 +227,18 @@ def convert_dvi_to_svg(dvipath: str, builder: Builder) -> Tuple[str, int]: command.extend(builder.config.imgmath_dvisvgm_args) command.append(dvipath) - convert_dvi_to_image(command, name) - return filename, None + stdout, stderr = convert_dvi_to_image(command, name) + + depth = None + if builder.config.imgmath_use_preview: + for line in stderr.splitlines(): # not stdout ! + matched = depthsvg_re.match(line) + if matched: + depth = round(float(matched.group(1)) * 100 / 72.27) # assume 100ppi + write_svg_depth(filename, depth) + break + + return filename, depth def render_math(self: HTMLTranslator, math: str) -> Tuple[str, int]: @@ -223,13 +259,19 @@ def render_math(self: HTMLTranslator, math: str) -> Tuple[str, int]: if image_format not in SUPPORT_FORMAT: raise MathExtError('imgmath_image_format must be either "png" or "svg"') - latex = generate_latex_macro(math, self.builder.config, self.builder.confdir) + latex = generate_latex_macro(image_format, + math, + self.builder.config, + self.builder.confdir) filename = "%s.%s" % (sha1(latex.encode()).hexdigest(), image_format) relfn = posixpath.join(self.builder.imgpath, 'math', filename) outfn = path.join(self.builder.outdir, self.builder.imagedir, 'math', filename) if path.isfile(outfn): - depth = read_png_depth(outfn) + if image_format == 'png': + depth = read_png_depth(outfn) + elif image_format == 'svg': + depth = read_svg_depth(outfn) return relfn, depth # if latex or dvipng (dvisvgm) has failed once, don't bother to try again diff --git a/sphinx/ext/mathbase.py b/sphinx/ext/mathbase.py deleted file mode 100644 index 34e8cf0b2..000000000 --- a/sphinx/ext/mathbase.py +++ /dev/null @@ -1,80 +0,0 @@ -""" - sphinx.ext.mathbase - ~~~~~~~~~~~~~~~~~~~ - - Set up math support in source files and LaTeX/text output. - - :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import warnings -from typing import Callable, List, Tuple - -from docutils import nodes -from docutils.nodes import Element, Node -from docutils.parsers.rst.roles import math_role as math_role_base - -from sphinx.addnodes import math, math_block as displaymath # NOQA # to keep compatibility -from sphinx.application import Sphinx -from sphinx.builders.latex.nodes import math_reference as eqref # NOQA # to keep compatibility -from sphinx.deprecation import RemovedInSphinx30Warning -from sphinx.directives.patches import MathDirective as MathDirectiveBase -from sphinx.domains.math import MathDomain # NOQA # to keep compatibility -from sphinx.domains.math import MathReferenceRole as EqXRefRole # NOQA # to keep compatibility -from sphinx.writers.html import HTMLTranslator - - -class MathDirective(MathDirectiveBase): - def run(self) -> List[Node]: - warnings.warn('sphinx.ext.mathbase.MathDirective is moved to ' - 'sphinx.directives.patches package.', - RemovedInSphinx30Warning, stacklevel=2) - return super().run() - - -def math_role(role, rawtext, text, lineno, inliner, options={}, content=[]): - warnings.warn('sphinx.ext.mathbase.math_role() is deprecated. ' - 'Please use docutils.parsers.rst.roles.math_role() instead.', - RemovedInSphinx30Warning, stacklevel=2) - return math_role_base(role, rawtext, text, lineno, inliner, options, content) - - -def get_node_equation_number(writer: HTMLTranslator, node: nodes.math_block) -> str: - warnings.warn('sphinx.ext.mathbase.get_node_equation_number() is moved to ' - 'sphinx.util.math package.', - RemovedInSphinx30Warning, stacklevel=2) - from sphinx.util.math import get_node_equation_number - return get_node_equation_number(writer, node) - - -def wrap_displaymath(text: str, label: str, numbering: bool) -> str: - warnings.warn('sphinx.ext.mathbase.wrap_displaymath() is moved to ' - 'sphinx.util.math package.', - RemovedInSphinx30Warning, stacklevel=2) - from sphinx.util.math import wrap_displaymath - return wrap_displaymath(text, label, numbering) - - -def is_in_section_title(node: Element) -> bool: - """Determine whether the node is in a section title""" - from sphinx.util.nodes import traverse_parent - - warnings.warn('is_in_section_title() is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - - for ancestor in traverse_parent(node): - if isinstance(ancestor, nodes.title) and \ - isinstance(ancestor.parent, nodes.section): - return True - return False - - -def setup_math(app: Sphinx, - htmlinlinevisitors: Tuple[Callable, Callable], - htmldisplayvisitors: Tuple[Callable, Callable]) -> None: - warnings.warn('setup_math() is deprecated. ' - 'Please use app.add_html_math_renderer() instead.', - RemovedInSphinx30Warning, stacklevel=2) - - app.add_html_math_renderer('unknown', htmlinlinevisitors, htmldisplayvisitors) diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py index 36ddfb580..5bbec60a9 100644 --- a/sphinx/ext/viewcode.py +++ b/sphinx/ext/viewcode.py @@ -9,7 +9,6 @@ """ import traceback -import warnings from typing import Any, Dict, Iterable, Iterator, Set, Tuple from docutils import nodes @@ -18,8 +17,6 @@ from docutils.nodes import Element, Node import sphinx from sphinx import addnodes from sphinx.application import Sphinx -from sphinx.config import Config -from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.environment import BuildEnvironment from sphinx.locale import _, __ from sphinx.pycode import ModuleAnalyzer @@ -234,18 +231,10 @@ def collect_pages(app: Sphinx) -> Iterator[Tuple[str, Dict[str, Any], str]]: yield ('_modules/index', context, 'page.html') -def migrate_viewcode_import(app: Sphinx, config: Config) -> None: - if config.viewcode_import is not None: - warnings.warn('viewcode_import was renamed to viewcode_follow_imported_members. ' - 'Please update your configuration.', - RemovedInSphinx30Warning, stacklevel=2) - - def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value('viewcode_import', None, False) app.add_config_value('viewcode_enable_epub', False, False) app.add_config_value('viewcode_follow_imported_members', True, False) - app.connect('config-inited', migrate_viewcode_import) app.connect('doctree-read', doctree_read) app.connect('env-merge-info', env_merge_info) app.connect('html-collect-pages', collect_pages) diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py index b4e63209f..16de39edc 100644 --- a/sphinx/highlighting.py +++ b/sphinx/highlighting.py @@ -8,8 +8,6 @@ :license: BSD, see LICENSE for details. """ -import html -import warnings from functools import partial from pygments import highlight @@ -22,8 +20,6 @@ from pygments.lexers import PythonLexer, Python3Lexer, PythonConsoleLexer, \ from pygments.styles import get_style_by_name from pygments.util import ClassNotFound -from sphinx.deprecation import RemovedInSphinx30Warning -from sphinx.ext import doctest from sphinx.locale import __ from sphinx.pygments_styles import SphinxStyle, NoneStyle from sphinx.util import logging @@ -67,8 +63,8 @@ class PygmentsBridge: html_formatter = HtmlFormatter latex_formatter = LatexFormatter - def __init__(self, dest='html', stylename='sphinx', trim_doctest_flags=None): - # type: (str, str, bool) -> None + def __init__(self, dest='html', stylename='sphinx'): + # type: (str, str) -> None self.dest = dest style = self.get_style(stylename) @@ -79,11 +75,6 @@ class PygmentsBridge: self.formatter = self.latex_formatter self.formatter_args['commandprefix'] = 'PYG' - self.trim_doctest_flags = trim_doctest_flags - if trim_doctest_flags is not None: - warnings.warn('trim_doctest_flags option for PygmentsBridge is now deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - def get_style(self, stylename): # type: (str) -> Style if stylename is None or stylename == 'sphinx': @@ -101,20 +92,6 @@ class PygmentsBridge: kwargs.update(self.formatter_args) return self.formatter(**kwargs) - def unhighlighted(self, source): - # type: (str) -> str - warnings.warn('PygmentsBridge.unhighlighted() is now deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - if self.dest == 'html': - return '<pre>' + html.escape(source) + '</pre>\n' - else: - # first, escape highlighting characters like Pygments does - source = source.translate(escape_hl_chars) - # then, escape all characters nonrepresentable in LaTeX - source = source.translate(tex_hl_escape_map_new) - return '\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n' + \ - source + '\\end{Verbatim}\n' - def get_lexer(self, source, lang, opts=None, force=False, location=None): # type: (str, str, Dict, bool, Any) -> Lexer if not opts: @@ -166,11 +143,6 @@ class PygmentsBridge: lexer = self.get_lexer(source, lang, opts, force, location) - # trim doctest options if wanted - if isinstance(lexer, PythonConsoleLexer) and self.trim_doctest_flags: - source = doctest.blankline_re.sub('', source) - source = doctest.doctestopt_re.sub('', source) - # highlight via Pygments formatter = self.get_formatter(**kwargs) try: diff --git a/sphinx/io.py b/sphinx/io.py index 5f4ec3351..354121c86 100644 --- a/sphinx/io.py +++ b/sphinx/io.py @@ -8,18 +8,15 @@ :license: BSD, see LICENSE for details. """ import codecs -import warnings from typing import Any from docutils.core import Publisher from docutils.io import FileInput, NullOutput from docutils.parsers.rst import Parser as RSTParser from docutils.readers import standalone -from docutils.statemachine import StringList, string2lines from docutils.transforms.references import DanglingReferences from docutils.writers import UnfilteredWriter -from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.transforms import ( AutoIndexUpgrader, DoctreeReadEvent, FigureAligner, SphinxTransformer ) @@ -30,7 +27,6 @@ from sphinx.transforms.references import SphinxDomains from sphinx.util import logging from sphinx.util import UnicodeDecodeErrorHandler from sphinx.util.docutils import LoggingReporter -from sphinx.util.rst import append_epilog, docinfo_re, prepend_prolog from sphinx.versioning import UIDTransform if False: @@ -145,19 +141,6 @@ class SphinxI18nReader(SphinxBaseReader): super().__init__(app, *args, **kwargs) - def set_lineno_for_reporter(self, lineno): - # type: (int) -> None - """Stores the source line number of original text.""" - warnings.warn('SphinxI18nReader.set_lineno_for_reporter() is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - - @property - def line(self): - # type: () -> int - warnings.warn('SphinxI18nReader.line is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return 0 - class SphinxDummyWriter(UnfilteredWriter): """Dummy writer module used for generating doctree.""" @@ -175,99 +158,14 @@ def SphinxDummySourceClass(source, *args, **kwargs): return source -class SphinxBaseFileInput(FileInput): - """A base class of SphinxFileInput. - - It supports to replace unknown Unicode characters to '?'. - """ - - def __init__(self, app, env, *args, **kwds): - # type: (Sphinx, BuildEnvironment, Any, Any) -> None - self.app = app - self.env = env - - warnings.warn('%s is deprecated.' % self.__class__.__name__, - RemovedInSphinx30Warning, stacklevel=2) - - kwds['error_handler'] = 'sphinx' # py3: handle error on open. - super().__init__(*args, **kwds) - - def warn_and_replace(self, error): - # type: (Any) -> Tuple - return UnicodeDecodeErrorHandler(self.env.docname)(error) - - class SphinxFileInput(FileInput): """A basic FileInput for Sphinx.""" - supported = ('*',) # RemovedInSphinx30Warning - def __init__(self, *args, **kwargs): # type: (Any, Any) -> None kwargs['error_handler'] = 'sphinx' super().__init__(*args, **kwargs) -class SphinxRSTFileInput(SphinxBaseFileInput): - """A reST FileInput for Sphinx. - - This FileInput automatically prepends and appends text by :confval:`rst_prolog` and - :confval:`rst_epilog`. - - .. important:: - - This FileInput uses an instance of ``StringList`` as a return value of ``read()`` - method to indicate original source filename and line numbers after prepending and - appending. - For that reason, ``sphinx.parsers.RSTParser`` should be used with this to parse - a content correctly. - """ - supported = ('restructuredtext',) - - def prepend_prolog(self, text, prolog): - # type: (StringList, str) -> None - docinfo = self.count_docinfo_lines(text) - if docinfo: - # insert a blank line after docinfo - text.insert(docinfo, '', '<generated>', 0) - docinfo += 1 - - # insert prolog (after docinfo if exists) - for lineno, line in enumerate(prolog.splitlines()): - text.insert(docinfo + lineno, line, '<rst_prolog>', lineno) - - text.insert(docinfo + lineno + 1, '', '<generated>', 0) - - def append_epilog(self, text, epilog): - # type: (StringList, str) -> None - # append a blank line and rst_epilog - text.append('', '<generated>', 0) - for lineno, line in enumerate(epilog.splitlines()): - text.append(line, '<rst_epilog>', lineno) - - def read(self): # type: ignore - # type: () -> StringList - inputstring = super().read() - lines = string2lines(inputstring, convert_whitespace=True) - content = StringList() - for lineno, line in enumerate(lines): - content.append(line, self.source_path, lineno) - - prepend_prolog(content, self.env.config.rst_prolog) - append_epilog(content, self.env.config.rst_epilog) - - return content - - def count_docinfo_lines(self, content): - # type: (StringList) -> int - if len(content) == 0: - return 0 - else: - for lineno, line in enumerate(content.data): - if not docinfo_re.match(line): - break - return lineno - - class FiletypeNotFoundError(Exception): pass diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py index 6ae20d0d0..d18d075d4 100644 --- a/sphinx/locale/__init__.py +++ b/sphinx/locale/__init__.py @@ -10,12 +10,9 @@ import gettext import locale -import warnings from collections import UserString, defaultdict from gettext import NullTranslations -from sphinx.deprecation import RemovedInSphinx30Warning - if False: # For type annotation from typing import Any, Callable, Dict, Iterable, List, Tuple, Union # NOQA @@ -127,26 +124,6 @@ class _TranslationProxy(UserString): return '<%s broken>' % self.__class__.__name__ -def mygettext(string): - # type: (str) -> str - """Used instead of _ when creating TranslationProxies, because _ is - not bound yet at that time. - """ - warnings.warn('sphinx.locale.mygettext() is deprecated. Please use `_()` instead.', - RemovedInSphinx30Warning, stacklevel=2) - return _(string) - - -def lazy_gettext(string): - # type: (str) -> str - """A lazy version of `gettext`.""" - # if isinstance(string, _TranslationProxy): - # return string - warnings.warn('sphinx.locale.laxy_gettext() is deprecated. Please use `_()` instead.', - RemovedInSphinx30Warning, stacklevel=2) - return _TranslationProxy(mygettext, string) # type: ignore - - translators = defaultdict(NullTranslations) # type: Dict[Tuple[str, str], NullTranslations] @@ -295,12 +272,6 @@ _ = get_translation('sphinx') __ = get_translation('sphinx', 'console') -def l_(*args): - warnings.warn('sphinx.locale.l_() is deprecated. Please use `_()` instead.', - RemovedInSphinx30Warning, stacklevel=2) - return _(*args) - - # labels admonitionlabels = { 'attention': _('Attention'), diff --git a/sphinx/make_mode.py b/sphinx/make_mode.py deleted file mode 100644 index c1da2a5fa..000000000 --- a/sphinx/make_mode.py +++ /dev/null @@ -1,38 +0,0 @@ -""" - sphinx.make_mode - ~~~~~~~~~~~~~~~~ - - sphinx-build -M command-line handling. - - This replaces the old, platform-dependent and once-generated content - of Makefile / make.bat. - - This is in its own module so that importing it is fast. It should not - import the main Sphinx modules (like sphinx.applications, sphinx.builders). - - :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import warnings - -from sphinx.cmd import make_mode -from sphinx.deprecation import RemovedInSphinx30Warning - - -BUILDERS = make_mode.BUILDERS - - -class Make(make_mode.Make): - def __init__(self, *args): - warnings.warn('sphinx.make_mode.Make is deprecated. ' - 'Please use sphinx.cmd.make_mode.Make instead.', - RemovedInSphinx30Warning, stacklevel=2) - super().__init__(*args) - - -def run_make_mode(args): - warnings.warn('sphinx.make_mode.run_make_mode() is deprecated. ' - 'Please use sphinx.cmd.make_mode.run_make_mode() instead.', - RemovedInSphinx30Warning, stacklevel=2) - return make_mode.run_make_mode(args) diff --git a/sphinx/registry.py b/sphinx/registry.py index 311270ccb..32dbd2f55 100644 --- a/sphinx/registry.py +++ b/sphinx/registry.py @@ -9,14 +9,11 @@ """ import traceback -import warnings -from inspect import isclass from types import MethodType from docutils.parsers.rst import Directive from pkg_resources import iter_entry_points -from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.domains import ObjType from sphinx.domains.std import GenericObject, Target from sphinx.errors import ExtensionError, SphinxError, VersionRequirementError @@ -25,7 +22,6 @@ from sphinx.locale import __ from sphinx.parsers import Parser as SphinxParser from sphinx.roles import XRefRole from sphinx.util import logging -from sphinx.util.docutils import directive_helper from sphinx.util.logging import prefixed_warnings if False: @@ -181,18 +177,9 @@ class SphinxComponentRegistry: yield domain - def override_domain(self, domain): - # type: (Type[Domain]) -> None - warnings.warn('registry.override_domain() is deprecated. ' - 'Use app.add_domain(domain, override=True) instead.', - RemovedInSphinx30Warning, stacklevel=2) - self.add_domain(domain, override=True) - - def add_directive_to_domain(self, domain, name, obj, has_content=None, argument_spec=None, - override=False, **option_spec): - # type: (str, str, Any, bool, Any, bool, Any) -> None - logger.debug('[app] adding directive to domain: %r', - (domain, name, obj, has_content, argument_spec, option_spec)) + def add_directive_to_domain(self, domain, name, cls, override=False): + # type: (str, str, Type[Directive], bool) -> None + logger.debug('[app] adding directive to domain: %r', (domain, name, cls)) if domain not in self.domains: raise ExtensionError(__('domain %s not yet registered') % domain) @@ -200,10 +187,7 @@ class SphinxComponentRegistry: if name in directives and not override: raise ExtensionError(__('The %r directive is already registered to domain %s') % (name, domain)) - if not isclass(obj) or not issubclass(obj, Directive): - directives[name] = directive_helper(obj, has_content, argument_spec, **option_spec) - else: - directives[name] = obj + directives[name] = cls def add_role_to_domain(self, domain, name, role, override=False): # type: (str, str, Union[RoleFunction, XRefRole], bool) -> None @@ -279,29 +263,9 @@ class SphinxComponentRegistry: else: self.source_suffix[suffix] = filetype - def add_source_parser(self, *args, **kwargs): - # type: (Any, bool) -> None - logger.debug('[app] adding search source_parser: %r', args) - if len(args) == 1: - # new sytle arguments: (source_parser) - suffix = None # type: str - parser = args[0] # type: Type[Parser] - else: - # old style arguments: (suffix, source_parser) - warnings.warn('app.add_source_parser() does not support suffix argument. ' - 'Use app.add_source_suffix() instead.', - RemovedInSphinx30Warning, stacklevel=3) - suffix = args[0] - parser = args[1] - - if suffix: - self.add_source_suffix(suffix, suffix, override=True) - - if len(parser.supported) == 0: - warnings.warn('Old source_parser has been detected. Please fill Parser.supported ' - 'attribute: %s' % parser.__name__, - RemovedInSphinx30Warning, stacklevel=3) - + def add_source_parser(self, parser, **kwargs): + # type: (Type[Parser], bool) -> None + logger.debug('[app] adding search source_parser: %r', parser) # create a map from filetype to parser for filetype in parser.supported: if filetype in self.source_parsers and not kwargs.get('override'): @@ -310,12 +274,6 @@ class SphinxComponentRegistry: else: self.source_parsers[filetype] = parser - # also maps suffix to parser - # - # This rescues old styled parsers which does not have ``supported`` filetypes. - if suffix: - self.source_parsers[suffix] = parser - def get_source_parser(self, filetype): # type: (str) -> Type[Parser] try: @@ -335,16 +293,6 @@ class SphinxComponentRegistry: parser.set_application(app) return parser - def add_source_input(self, input_class, override=False): - # type: (Type[SphinxFileInput], bool) -> None - warnings.warn('registry.source_input() is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - for filetype in input_class.supported: - if filetype in self.source_inputs and not override: - raise ExtensionError(__('source_input for %r is already registered') % - filetype) - self.source_inputs[filetype] = input_class - def get_source_input(self, filetype): # type: (str) -> Type[Input] try: diff --git a/sphinx/search/ja.py b/sphinx/search/ja.py index 0c11af74d..e1f18209a 100644 --- a/sphinx/search/ja.py +++ b/sphinx/search/ja.py @@ -19,7 +19,6 @@ import os import re import sys -import warnings try: import MeCab @@ -33,7 +32,6 @@ try: except ImportError: janome_module = False -from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.errors import SphinxError, ExtensionError from sphinx.search import SearchLanguage from sphinx.util import import_object @@ -543,22 +541,10 @@ class SearchJapanese(SearchLanguage): """ lang = 'ja' language_name = 'Japanese' - splitters = { - 'default': 'sphinx.search.ja.DefaultSplitter', - 'mecab': 'sphinx.search.ja.MecabSplitter', - 'janome': 'sphinx.search.ja.JanomeSplitter', - } def init(self, options): # type: (Dict) -> None - type = options.get('type', 'sphinx.search.ja.DefaultSplitter') - if type in self.splitters: - dotted_path = self.splitters[type] - warnings.warn('html_search_options["type"]: %s is deprecated. ' - 'Please give "%s" instead.' % (type, dotted_path), - RemovedInSphinx30Warning, stacklevel=2) - else: - dotted_path = type + dotted_path = options.get('type', 'sphinx.search.ja.DefaultSplitter') try: self.splitter = import_object(dotted_path)(options) except ExtensionError: diff --git a/sphinx/templates/imgmath/preview.tex_t b/sphinx/templates/imgmath/preview.tex_t index 8dd24c108..f3fdcda07 100644 --- a/sphinx/templates/imgmath/preview.tex_t +++ b/sphinx/templates/imgmath/preview.tex_t @@ -9,7 +9,7 @@ \pagestyle{empty} <%= preamble %> -\usepackage[active]{preview} +\usepackage[active<%= tightpage %>]{preview} \begin{document} \begin{preview} diff --git a/sphinx/templates/latex/longtable.tex_t b/sphinx/templates/latex/longtable.tex_t index 8fe5369df..5c9a63253 100644 --- a/sphinx/templates/latex/longtable.tex_t +++ b/sphinx/templates/latex/longtable.tex_t @@ -26,7 +26,7 @@ \endhead \hline -\multicolumn{<%= table.colcount %>}{r}{\makebox[0pt][r]{\sphinxtablecontinued{<%= _('Continued on next page') %>}}}\\ +\multicolumn{<%= table.colcount %>}{r}{\makebox[0pt][r]{\sphinxtablecontinued{<%= _('continues on next page') %>}}}\\ \endfoot \endlastfoot diff --git a/sphinx/transforms/post_transforms/compat.py b/sphinx/transforms/post_transforms/compat.py deleted file mode 100644 index 67b67f8d4..000000000 --- a/sphinx/transforms/post_transforms/compat.py +++ /dev/null @@ -1,90 +0,0 @@ -""" - sphinx.transforms.post_transforms.compat - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Post transforms for compatibility - - :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import warnings - -from docutils import nodes -from docutils.writers.docutils_xml import XMLTranslator - -from sphinx.addnodes import math_block, displaymath -from sphinx.deprecation import RemovedInSphinx30Warning -from sphinx.transforms import SphinxTransform -from sphinx.util import logging - -if False: - # For type annotation - from typing import Any, Dict # NOQA - from sphinx.application import Sphinx # NOQA - -logger = logging.getLogger(__name__) - - -class MathNodeMigrator(SphinxTransform): - """Migrate a math node to docutils'. - - For a long time, Sphinx uses an original node for math. Since 1.8, - Sphinx starts to use a math node of docutils'. This transform converts - old and new nodes to keep compatibility. - """ - default_priority = 999 - - def apply(self, **kwargs): - # type: (Any) -> None - for math_node in self.document.traverse(nodes.math): - # case: old styled ``math`` node generated by old extensions - if len(math_node) == 0: - warnings.warn("math node for Sphinx was replaced by docutils'. " - "Please use ``docutils.nodes.math`` instead.", - RemovedInSphinx30Warning) - equation = math_node['latex'] - math_node += nodes.Text(equation, equation) - - translator = self.app.builder.get_translator_class() - if hasattr(translator, 'visit_displaymath') and translator != XMLTranslator: - # case: old translators which does not support ``math_block`` node - warnings.warn("Translator for %s does not support math_block node'. " - "Please update your extension." % translator, - RemovedInSphinx30Warning) - for old_math_block_node in self.document.traverse(math_block): - alt = displaymath(latex=old_math_block_node.astext(), - number=old_math_block_node.get('number'), - label=old_math_block_node.get('label'), - nowrap=old_math_block_node.get('nowrap'), - docname=old_math_block_node.get('docname')) - old_math_block_node.replace_self(alt) - elif getattr(self.app.builder, 'math_renderer_name', None) == 'unknown': - # case: math extension provides old styled math renderer - for math_block_node in self.document.traverse(nodes.math_block): - math_block_node['latex'] = math_block_node.astext() - - # case: old styled ``displaymath`` node generated by old extensions - for math_block_node in self.document.traverse(math_block): - if len(math_block_node) == 0: - warnings.warn("math node for Sphinx was replaced by docutils'. " - "Please use ``docutils.nodes.math_block`` instead.", - RemovedInSphinx30Warning) - if isinstance(math_block_node, displaymath): - newnode = nodes.math_block('', math_block_node['latex'], - **math_block_node.attributes) - math_block_node.replace_self(newnode) - else: - latex = math_block_node['latex'] - math_block_node += nodes.Text(latex, latex) - - -def setup(app): - # type: (Sphinx) -> Dict[str, Any] - app.add_post_transform(MathNodeMigrator) - - return { - 'version': 'builtin', - 'parallel_read_safe': True, - 'parallel_write_safe': True, - } diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index a36c256d3..7bfb3ad3e 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -29,14 +29,11 @@ from typing import ( ) from urllib.parse import urlsplit, urlunsplit, quote_plus, parse_qsl, urlencode -from docutils.utils import relative_path - -from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.errors import PycodeError, SphinxParallelError, ExtensionError from sphinx.locale import __ from sphinx.util import logging from sphinx.util.console import strip_colors, colorize, bold, term_width_line # type: ignore -from sphinx.util.fileutil import copy_asset_file from sphinx.util.typing import PathMatcher from sphinx.util import smartypants # noqa @@ -44,7 +41,7 @@ from sphinx.util import smartypants # noqa # prune unused ones indiscriminately from sphinx.util.osutil import ( # noqa SEP, os_path, relative_uri, ensuredir, walk, mtimes_of_files, movefile, - copyfile, copytimes, make_filename, ustrftime) + copyfile, copytimes, make_filename) from sphinx.util.nodes import ( # noqa nested_parse_with_titles, split_explicit_title, explicit_title_re, caption_ref_re) @@ -54,7 +51,7 @@ from sphinx.util.matching import patfilter # noqa if False: # For type annotation from sphinx.application import Sphinx - from sphinx.builders import Builder + logger = logging.getLogger(__name__) @@ -190,35 +187,6 @@ class DownloadFiles(dict): self.add_file(docname, filename) -def copy_static_entry(source: str, targetdir: str, builder: "Builder", context: Dict = {}, - exclude_matchers: Tuple[PathMatcher, ...] = (), level: int = 0) -> None: - """[DEPRECATED] Copy a HTML builder static_path entry from source to targetdir. - - Handles all possible cases of files, directories and subdirectories. - """ - warnings.warn('sphinx.util.copy_static_entry is deprecated for removal', - RemovedInSphinx30Warning, stacklevel=2) - - if exclude_matchers: - relpath = relative_path(path.join(builder.srcdir, 'dummy'), source) - for matcher in exclude_matchers: - if matcher(relpath): - return - if path.isfile(source): - copy_asset_file(source, targetdir, context, builder.templates) - elif path.isdir(source): - ensuredir(targetdir) - for entry in os.listdir(source): - if entry.startswith('.'): - continue - newtarget = targetdir - if path.isdir(path.join(source, entry)): - newtarget = path.join(targetdir, entry) - copy_static_entry(path.join(source, entry), newtarget, - builder, context, level=level + 1, - exclude_matchers=exclude_matchers) - - _DEBUG_HEADER = '''\ # Sphinx version: %s # Python version: %s (%s) diff --git a/sphinx/util/compat.py b/sphinx/util/compat.py index 75ef90350..4f756b0b0 100644 --- a/sphinx/util/compat.py +++ b/sphinx/util/compat.py @@ -15,27 +15,14 @@ from typing import Any, Dict from docutils.utils import get_source_line from sphinx import addnodes -from sphinx.config import Config -from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.transforms import SphinxTransform -from sphinx.util import import_object if False: # For type annotation from sphinx.application import Sphinx -def deprecate_source_parsers(app: "Sphinx", config: Config) -> None: - if config.source_parsers: - warnings.warn('The config variable "source_parsers" is deprecated. ' - 'Please update your extension for the parser and remove the setting.', - RemovedInSphinx30Warning) - for suffix, parser in config.source_parsers.items(): - if isinstance(parser, str): - parser = import_object(parser, 'source parser') - app.add_source_parser(suffix, parser) - - def register_application_for_autosummary(app: "Sphinx") -> None: """Register application object to autosummary module. @@ -65,7 +52,6 @@ class IndexEntriesMigrator(SphinxTransform): def setup(app: "Sphinx") -> Dict[str, Any]: app.add_transform(IndexEntriesMigrator) - app.connect('config-inited', deprecate_source_parsers) app.connect('builder-inited', register_application_for_autosummary) return { diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py index e2513b141..25010c41f 100644 --- a/sphinx/util/docutils.py +++ b/sphinx/util/docutils.py @@ -10,8 +10,6 @@ import os import re -import types -import warnings from contextlib import contextmanager from copy import copy from distutils.version import LooseVersion @@ -24,14 +22,12 @@ import docutils from docutils import nodes from docutils.io import FileOutput from docutils.nodes import Element, Node, system_message -from docutils.parsers.rst import Directive, directives, roles, convert_directive_function +from docutils.parsers.rst import Directive, directives, roles from docutils.parsers.rst.states import Inliner from docutils.statemachine import StateMachine, State, StringList from docutils.utils import Reporter, unescape -from sphinx.deprecation import RemovedInSphinx30Warning -from sphinx.errors import ExtensionError, SphinxError -from sphinx.locale import __ +from sphinx.errors import SphinxError from sphinx.util import logging from sphinx.util.typing import RoleFunction @@ -279,23 +275,6 @@ def is_html5_writer_available() -> bool: return __version_info__ > (0, 13, 0) -def directive_helper(obj: Any, has_content: bool = None, argument_spec: Tuple[int, int, bool] = None, **option_spec) -> Any: # NOQA - warnings.warn('function based directive support is now deprecated. ' - 'Use class based directive instead.', - RemovedInSphinx30Warning) - - if isinstance(obj, (types.FunctionType, types.MethodType)): - obj.content = has_content # type: ignore - obj.arguments = argument_spec or (0, 0, False) # type: ignore - obj.options = option_spec # type: ignore - return convert_directive_function(obj) - else: - if has_content or argument_spec or option_spec: - raise ExtensionError(__('when adding directive classes, no ' - 'additional arguments may be given')) - return obj - - @contextmanager def switch_source_input(state: State, content: StringList) -> Generator[None, None, None]: """Switch current source input of state temporarily.""" diff --git a/sphinx/util/i18n.py b/sphinx/util/i18n.py index bfd43e19e..5466e5459 100644 --- a/sphinx/util/i18n.py +++ b/sphinx/util/i18n.py @@ -20,7 +20,7 @@ import babel.dates from babel.messages.mofile import write_mo from babel.messages.pofile import read_po -from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.errors import SphinxError from sphinx.locale import __ from sphinx.util import logging @@ -151,9 +151,8 @@ def find_catalog_files(docname: str, srcdir: str, locale_dirs: List[str], def find_catalog_source_files(locale_dirs: List[str], locale: str, domains: List[str] = None, - gettext_compact: bool = None, charset: str = 'utf-8', - force_all: bool = False, excluded: Matcher = Matcher([]) - ) -> Set[CatalogInfo]: + 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 @@ -169,9 +168,6 @@ def find_catalog_source_files(locale_dirs: List[str], locale: str, domains: List """ warnings.warn('find_catalog_source_files() is deprecated.', RemovedInSphinx40Warning, stacklevel=2) - if gettext_compact is not None: - warnings.warn('gettext_compact argument for find_catalog_source_files() ' - 'is deprecated.', RemovedInSphinx30Warning, stacklevel=2) catalogs = set() # type: Set[CatalogInfo] diff --git a/sphinx/util/images.py b/sphinx/util/images.py index 4cefe99d5..8471e56df 100644 --- a/sphinx/util/images.py +++ b/sphinx/util/images.py @@ -10,16 +10,12 @@ import base64 import imghdr -import warnings from collections import OrderedDict -from io import BytesIO from os import path from typing import IO, NamedTuple, Tuple import imagesize -from sphinx.deprecation import RemovedInSphinx30Warning - try: from PIL import Image except ImportError: @@ -66,16 +62,10 @@ def guess_mimetype_for_stream(stream: IO, default: str = None) -> str: return default -def guess_mimetype(filename: str = '', content: bytes = None, default: str = None) -> str: +def guess_mimetype(filename: str = '', default: str = None) -> str: _, ext = path.splitext(filename.lower()) if ext in mime_suffixes: return mime_suffixes[ext] - elif content: - # TODO: When the content argument is removed, make filename a required - # argument. - warnings.warn('The content argument of guess_mimetype() is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return guess_mimetype_for_stream(BytesIO(content), default=default) elif path.exists(filename): with open(filename, 'rb') as f: return guess_mimetype_for_stream(f, default=default) diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index c1fc0e960..fc6dafe9f 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -14,7 +14,6 @@ import inspect import re import sys import typing -import warnings from functools import partial, partialmethod from inspect import ( # NOQA isclass, ismethod, ismethoddescriptor, isroutine @@ -22,7 +21,6 @@ from inspect import ( # NOQA from io import StringIO from typing import Any, Callable, Mapping, List, Tuple -from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.util import logging from sphinx.util.typing import NoneType @@ -312,26 +310,6 @@ def is_builtin_class_method(obj: Any, attr_name: str) -> bool: return getattr(builtins, safe_getattr(cls, '__name__', '')) is cls -class Parameter: - """Fake parameter class for python2.""" - POSITIONAL_ONLY = 0 - POSITIONAL_OR_KEYWORD = 1 - VAR_POSITIONAL = 2 - KEYWORD_ONLY = 3 - VAR_KEYWORD = 4 - empty = object() - - def __init__(self, name: str, kind: int = POSITIONAL_OR_KEYWORD, - default: Any = empty) -> None: - self.name = name - self.kind = kind - self.default = default - self.annotation = self.empty - - warnings.warn('sphinx.util.inspect.Parameter is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - - class Signature: """The Signature object represents the call signature of a callable object and its return annotation. diff --git a/sphinx/util/osutil.py b/sphinx/util/osutil.py index 3751fcc08..08c7349dd 100644 --- a/sphinx/util/osutil.py +++ b/sphinx/util/osutil.py @@ -15,13 +15,12 @@ import os import re import shutil import sys -import time import warnings from io import StringIO from os import path from typing import Any, Generator, Iterator, List, Tuple, Type -from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.testing.path import path as Path # Errnos that we need. @@ -135,27 +134,6 @@ def make_filename_from_project(project: str) -> str: return make_filename(project_suffix_re.sub('', project)).lower() -def ustrftime(format: str, *args) -> str: - """[DEPRECATED] strftime for unicode strings.""" - warnings.warn('sphinx.util.osutil.ustrtime is deprecated for removal', - RemovedInSphinx30Warning, stacklevel=2) - - if not args: - # If time is not specified, try to use $SOURCE_DATE_EPOCH variable - # See https://wiki.debian.org/ReproducibleBuilds/TimestampsProposal - source_date_epoch = os.getenv('SOURCE_DATE_EPOCH') - if source_date_epoch is not None: - time_struct = time.gmtime(float(source_date_epoch)) - args = [time_struct] # type: ignore - # On Windows, time.strftime() and Unicode characters will raise UnicodeEncodeError. - # https://bugs.python.org/issue8304 - try: - return time.strftime(format, *args) - except UnicodeEncodeError: - r = time.strftime(format.encode('unicode-escape').decode(), *args) - return r.encode().decode('unicode-escape') - - def relpath(path: str, start: str = os.curdir) -> str: """Return a relative filepath to *path* either from the current directory or from an optional *start* directory. diff --git a/sphinx/util/requests.py b/sphinx/util/requests.py index a279b4eb4..64bd8773f 100644 --- a/sphinx/util/requests.py +++ b/sphinx/util/requests.py @@ -13,7 +13,6 @@ from contextlib import contextmanager from typing import Generator, Union from urllib.parse import urlsplit -import pkg_resources import requests from sphinx.config import Config @@ -35,28 +34,6 @@ except ImportError: # for requests < 2.4.0 InsecureRequestWarning = None # type: ignore -try: - from requests.packages.urllib3.exceptions import InsecurePlatformWarning -except ImportError: - try: - # for Debian-jessie - from urllib3.exceptions import InsecurePlatformWarning # type: ignore - except ImportError: - # for requests < 2.4.0 - InsecurePlatformWarning = None # type: ignore - -# try to load requests[security] (but only if SSL is available) -try: - import ssl # NOQA -except ImportError: - pass -else: - try: - pkg_resources.require(['requests[security]']) - except (pkg_resources.DistributionNotFound, - pkg_resources.VersionConflict): - pass # ignored - useragent_header = [('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64; rv:25.0) Gecko/20100101 Firefox/25.0')] diff --git a/sphinx/versioning.py b/sphinx/versioning.py index c98d166bc..56c126da2 100644 --- a/sphinx/versioning.py +++ b/sphinx/versioning.py @@ -9,13 +9,11 @@ :license: BSD, see LICENSE for details. """ import pickle -import warnings from itertools import product, zip_longest from operator import itemgetter from os import path from uuid import uuid4 -from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.transforms import SphinxTransform if False: @@ -180,15 +178,6 @@ class UIDTransform(SphinxTransform): list(merge_doctrees(old_doctree, self.document, env.versioning_condition)) -def prepare(document): - # type: (nodes.document) -> None - """Simple wrapper for UIDTransform.""" - warnings.warn('versioning.prepare() is deprecated. Use UIDTransform instead.', - RemovedInSphinx30Warning, stacklevel=2) - transform = UIDTransform(document) - transform.apply() - - def setup(app): # type: (Sphinx) -> Dict[str, Any] app.add_transform(UIDTransform) diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py index 381457926..9ac76901b 100644 --- a/sphinx/writers/html.py +++ b/sphinx/writers/html.py @@ -11,7 +11,6 @@ import copy import os import posixpath -import sys import warnings from typing import Iterable, cast @@ -20,7 +19,7 @@ from docutils.writers.html4css1 import Writer, HTMLTranslator as BaseTranslator from sphinx import addnodes from sphinx.builders import Builder -from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.locale import admonitionlabels, _, __ from sphinx.util import logging from sphinx.util.docutils import SphinxTranslator @@ -945,33 +944,3 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator): def unknown_visit(self, node): # type: (nodes.Node) -> None raise NotImplementedError('Unknown node: ' + node.__class__.__name__) - - # --------- METHODS FOR COMPATIBILITY -------------------------------------- - - @property - def highlightlang(self): - # type: () -> str - warnings.warn('HTMLTranslator.highlightlang is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return self.builder.config.highlight_language - - @property - def highlightlang_base(self): - # type: () -> str - warnings.warn('HTMLTranslator.highlightlang_base is deprecated.', - RemovedInSphinx30Warning) - return self.builder.config.highlight_language - - @property - def highlightopts(self): - # type: () -> str - warnings.warn('HTMLTranslator.highlightopts is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return self.builder.config.highlight_options - - @property - def highlightlinenothreshold(self): - # type: () -> int - warnings.warn('HTMLTranslator.highlightlinenothreshold is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return sys.maxsize diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py index e412ea167..fe57f42bf 100644 --- a/sphinx/writers/html5.py +++ b/sphinx/writers/html5.py @@ -10,7 +10,6 @@ import os import posixpath -import sys import warnings from typing import Iterable, cast @@ -19,7 +18,7 @@ from docutils.writers.html5_polyglot import HTMLTranslator as BaseTranslator from sphinx import addnodes from sphinx.builders import Builder -from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning +from sphinx.deprecation import RemovedInSphinx40Warning from sphinx.locale import admonitionlabels, _, __ from sphinx.util import logging from sphinx.util.docutils import SphinxTranslator @@ -883,33 +882,3 @@ class HTML5Translator(SphinxTranslator, BaseTranslator): def unknown_visit(self, node): # type: (nodes.Node) -> None raise NotImplementedError('Unknown node: ' + node.__class__.__name__) - - # --------- METHODS FOR COMPATIBILITY -------------------------------------- - - @property - def highlightlang(self): - # type: () -> str - warnings.warn('HTMLTranslator.highlightlang is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return self.builder.config.highlight_language - - @property - def highlightlang_base(self): - # type: () -> str - warnings.warn('HTMLTranslator.highlightlang_base is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return self.builder.config.highlight_language - - @property - def highlightopts(self): - # type: () -> str - warnings.warn('HTMLTranslator.highlightopts is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return self.builder.config.highlight_options - - @property - def highlightlinenothreshold(self): - # type: () -> int - warnings.warn('HTMLTranslator.highlightlinenothreshold is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return sys.maxsize diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py index 5fdcb5b93..d0bd38ce2 100644 --- a/sphinx/writers/latex.py +++ b/sphinx/writers/latex.py @@ -12,7 +12,6 @@ """ import re -import sys import warnings from collections import defaultdict from os import path @@ -22,9 +21,7 @@ from docutils import nodes, writers from sphinx import addnodes from sphinx import highlighting -from sphinx.deprecation import ( - RemovedInSphinx30Warning, RemovedInSphinx40Warning, deprecated_alias -) +from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias from sphinx.domains.std import StandardDomain from sphinx.errors import SphinxError from sphinx.locale import admonitionlabels, _, __ @@ -294,20 +291,6 @@ class Table: # (cell = rectangular area) self.cell_id = 0 # last assigned cell_id - @property - def caption_footnotetexts(self): - # type: () -> List[str] - warnings.warn('table.caption_footnotetexts is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return [] - - @property - def header_footnotetexts(self): - # type: () -> List[str] - warnings.warn('table.header_footnotetexts is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return [] - def is_longtable(self): # type: () -> bool """True if and only if table uses longtable environment.""" @@ -664,27 +647,6 @@ class LaTeXTranslator(SphinxTranslator): self.body = self.bodystack.pop() return body - def restrict_footnote(self, node): - # type: (nodes.Element) -> None - warnings.warn('LaTeXWriter.restrict_footnote() is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - - if self.footnote_restricted is None: - self.footnote_restricted = node - self.pending_footnotes = [] - - def unrestrict_footnote(self, node): - # type: (nodes.Element) -> None - warnings.warn('LaTeXWriter.unrestrict_footnote() is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - - if self.footnote_restricted == node: - self.footnote_restricted = None - for footnode in self.pending_footnotes: - footnode['footnotetext'] = True - footnode.walkabout(self) - self.pending_footnotes = [] - def format_docclass(self, docclass): # type: (str) -> str """ prepends prefix to sphinx document classes @@ -1796,8 +1758,8 @@ class LaTeXTranslator(SphinxTranslator): # type: (nodes.Element) -> None self.body.append('\n\\end{flushright}\n') - def visit_index(self, node, scre = None): - # type: (nodes.Element, Pattern) -> None + def visit_index(self, node): + # type: (nodes.Element) -> None def escape(value): value = self.encode(value) value = value.replace(r'\{', r'\sphinxleftcurlybrace{}') @@ -1814,10 +1776,6 @@ class LaTeXTranslator(SphinxTranslator): else: return '\\spxentry{%s}' % string - if scre: - warnings.warn(('LaTeXTranslator.visit_index() optional argument ' - '"scre" is deprecated. It is ignored.'), - RemovedInSphinx30Warning, stacklevel=2) if not node.get('inline', True): self.body.append('\n') entries = node['entries'] @@ -2511,70 +2469,6 @@ class LaTeXTranslator(SphinxTranslator): fnotes[num] = [newnode, False] return fnotes - @property - def footnotestack(self): - # type: () -> List[Dict[str, List[Union[collected_footnote, bool]]]] - warnings.warn('LaTeXWriter.footnotestack is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return [] - - @property - def bibitems(self): - # type: () -> List[List[str]] - warnings.warn('LaTeXTranslator.bibitems() is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return [] - - @property - def in_container_literal_block(self): - # type: () -> int - warnings.warn('LaTeXTranslator.in_container_literal_block is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return 0 - - @property - def next_section_ids(self): - # type: () -> Set[str] - warnings.warn('LaTeXTranslator.next_section_ids is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return set() - - @property - def next_hyperlink_ids(self): - # type: () -> Dict - warnings.warn('LaTeXTranslator.next_hyperlink_ids is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return {} - - def push_hyperlink_ids(self, figtype, ids): - # type: (str, Set[str]) -> None - warnings.warn('LaTeXTranslator.push_hyperlink_ids() is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - pass - - def pop_hyperlink_ids(self, figtype): - # type: (str) -> Set[str] - warnings.warn('LaTeXTranslator.pop_hyperlink_ids() is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return set() - - @property - def hlsettingstack(self): - # type: () -> List[List[Union[str, int]]] - warnings.warn('LaTeXTranslator.hlsettingstack is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - return [[self.builder.config.highlight_language, sys.maxsize]] - - def check_latex_elements(self): - # type: () -> None - warnings.warn('check_latex_elements() is deprecated.', - RemovedInSphinx30Warning, stacklevel=2) - - for key in self.builder.config.latex_elements: - if key not in self.elements: - msg = __("Unknown configure key: latex_elements[%r] is ignored.") - logger.warning(msg % key) - def babel_defmacro(self, name, definition): # type: (str, str) -> str warnings.warn('babel_defmacro() is deprecated.', @@ -2589,17 +2483,6 @@ class LaTeXTranslator(SphinxTranslator): return ('%s\\def%s{%s}%s\n' % (prefix, name, definition, suffix)) - def _make_visit_admonition(name): # type: ignore - # type: (str) -> Callable[[LaTeXTranslator, nodes.Element], None] - warnings.warn('LaTeXTranslator._make_visit_admonition() is deprecated.', - RemovedInSphinx30Warning) - - def visit_admonition(self, node): - # type: (LaTeXTranslator, nodes.Element) -> None - self.body.append('\n\\begin{sphinxadmonition}{%s}{%s:}' % - (name, admonitionlabels[name])) - return visit_admonition - def generate_numfig_format(self, builder): # type: (LaTeXBuilder) -> str warnings.warn('generate_numfig_format() is deprecated.', @@ -2642,18 +2525,11 @@ class LaTeXTranslator(SphinxTranslator): # Import old modules here for compatibility -from sphinx.builders.latex.transforms import URI_SCHEMES, ShowUrlsTransform # NOQA from sphinx.builders.latex.util import ExtBabel # NOQA deprecated_alias('sphinx.writers.latex', { - 'ShowUrlsTransform': ShowUrlsTransform, - 'URI_SCHEMES': URI_SCHEMES, - }, - RemovedInSphinx30Warning) -deprecated_alias('sphinx.writers.latex', - { 'ExtBabel': ExtBabel, }, RemovedInSphinx40Warning) diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py index b952812f0..77d3dcb69 100644 --- a/sphinx/writers/texinfo.py +++ b/sphinx/writers/texinfo.py @@ -10,14 +10,12 @@ import re import textwrap -import warnings from os import path from typing import Iterable, cast from docutils import nodes, writers from sphinx import addnodes, __display_version__ -from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.errors import ExtensionError from sphinx.locale import admonitionlabels, _, __ from sphinx.util import logging @@ -1745,13 +1743,3 @@ class TexinfoTranslator(SphinxTranslator): self.body.append('\n\n@example\n%s\n@end example\n\n' % self.escape_arg(node.astext())) raise nodes.SkipNode - - def _make_visit_admonition(name): # type: ignore - # type: (str) -> Callable[[TexinfoTranslator, nodes.Element], None] - warnings.warn('TexinfoTranslator._make_visit_admonition() is deprecated.', - RemovedInSphinx30Warning) - - def visit(self, node): - # type: (TexinfoTranslator, nodes.Element) -> None - self.visit_admonition(node, admonitionlabels[name]) - return visit diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py index dc8a7963a..47ab9f2e4 100644 --- a/sphinx/writers/text.py +++ b/sphinx/writers/text.py @@ -11,7 +11,6 @@ import math import os import re import textwrap -import warnings from itertools import groupby, chain from typing import Iterable, cast @@ -19,7 +18,6 @@ from docutils import nodes, writers from docutils.utils import column_width from sphinx import addnodes -from sphinx.deprecation import RemovedInSphinx30Warning from sphinx.locale import admonitionlabels, _ from sphinx.util.docutils import SphinxTranslator @@ -1368,13 +1366,3 @@ class TextTranslator(SphinxTranslator): def unknown_visit(self, node): # type: (nodes.Node) -> None raise NotImplementedError('Unknown node: ' + node.__class__.__name__) - - def _make_depart_admonition(name): # type: ignore - # type: (str) -> Callable[[TextTranslator, nodes.Element], None] - warnings.warn('TextTranslator._make_depart_admonition() is deprecated.', - RemovedInSphinx30Warning) - - def depart_admonition(self, node): - # type: (TextTranslator, nodes.Element) -> None - self.end_state(first=admonitionlabels[name] + ': ') - return depart_admonition diff --git a/tests/roots/test-add_source_parser/conf.py b/tests/roots/test-add_source_parser/conf.py index 9ff50b21e..2acd4d24c 100644 --- a/tests/roots/test-add_source_parser/conf.py +++ b/tests/roots/test-add_source_parser/conf.py @@ -1,17 +1,8 @@ import os import sys -from docutils.parsers import Parser - sys.path.insert(0, os.path.abspath('.')) -class DummyMarkdownParser(Parser): - supported = ('markdown',) - - extensions = ['source_parser'] -source_suffix = ['.rst', '.md'] -source_parsers = { - '.md': DummyMarkdownParser -} +source_suffix = ['.rst'] diff --git a/tests/roots/test-ext-math-compat/conf.py b/tests/roots/test-ext-math-compat/conf.py index 30d26f97c..85e3950a5 100644 --- a/tests/roots/test-ext-math-compat/conf.py +++ b/tests/roots/test-ext-math-compat/conf.py @@ -1,17 +1,18 @@ +from docutils import nodes from docutils.parsers.rst import Directive -from sphinx.ext.mathbase import math, displaymath - extensions = ['sphinx.ext.mathjax'] def my_math_role(role, rawtext, text, lineno, inliner, options={}, content=[]): - return [math(latex='E = mc^2')], [] + text = 'E = mc^2' + return [nodes.math(text, text)], [] class MyMathDirective(Directive): def run(self): - return [displaymath(latex='E = mc^2')] + text = 'E = mc^2' + return [nodes.math_block(text, text)] def setup(app): diff --git a/tests/roots/test-latex-table/expects/longtable.tex b/tests/roots/test-latex-table/expects/longtable.tex index ecc156a50..5eb62541d 100644 --- a/tests/roots/test-latex-table/expects/longtable.tex +++ b/tests/roots/test-latex-table/expects/longtable.tex @@ -22,7 +22,7 @@ header2 \endhead \hline -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{Continued on next page}}}\\ +\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot \endlastfoot diff --git a/tests/roots/test-latex-table/expects/longtable_having_align.tex b/tests/roots/test-latex-table/expects/longtable_having_align.tex index cfb9f1fcc..945169a4e 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_align.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_align.tex @@ -22,7 +22,7 @@ header2 \endhead \hline -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{Continued on next page}}}\\ +\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot \endlastfoot diff --git a/tests/roots/test-latex-table/expects/longtable_having_caption.tex b/tests/roots/test-latex-table/expects/longtable_having_caption.tex index 1ac901794..0d0bb430f 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_caption.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_caption.tex @@ -24,7 +24,7 @@ header2 \endhead \hline -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{Continued on next page}}}\\ +\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot \endlastfoot diff --git a/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex index 2b9d4f8c5..53f8982b9 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_problematic_cell.tex @@ -22,7 +22,7 @@ header2 \endhead \hline -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{Continued on next page}}}\\ +\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot \endlastfoot diff --git a/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex index e0c2b87ec..a098c7ef2 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_stub_columns_and_problematic_cell.tex @@ -26,7 +26,7 @@ header3 \endhead \hline -\multicolumn{3}{r}{\makebox[0pt][r]{\sphinxtablecontinued{Continued on next page}}}\\ +\multicolumn{3}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot \endlastfoot diff --git a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex index 1891b2416..e4a138270 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_verbatim.tex @@ -22,7 +22,7 @@ header2 \endhead \hline -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{Continued on next page}}}\\ +\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot \endlastfoot diff --git a/tests/roots/test-latex-table/expects/longtable_having_widths.tex b/tests/roots/test-latex-table/expects/longtable_having_widths.tex index aa78608f6..238379f57 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_widths.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_widths.tex @@ -22,7 +22,7 @@ header2 \endhead \hline -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{Continued on next page}}}\\ +\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot \endlastfoot diff --git a/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex b/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex index 26da90781..0fb5af037 100644 --- a/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex +++ b/tests/roots/test-latex-table/expects/longtable_having_widths_and_problematic_cell.tex @@ -22,7 +22,7 @@ header2 \endhead \hline -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{Continued on next page}}}\\ +\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot \endlastfoot diff --git a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex index 7710f75a1..61af905ae 100644 --- a/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex +++ b/tests/roots/test-latex-table/expects/longtable_with_tabularcolumn.tex @@ -22,7 +22,7 @@ header2 \endhead \hline -\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{Continued on next page}}}\\ +\multicolumn{2}{r}{\makebox[0pt][r]{\sphinxtablecontinued{continues on next page}}}\\ \endfoot \endlastfoot diff --git a/tests/test_application.py b/tests/test_application.py index f10592b51..8c48e7500 100644 --- a/tests/test_application.py +++ b/tests/test_application.py @@ -61,20 +61,13 @@ def test_extension_in_blacklist(app, status, warning): @pytest.mark.sphinx(testroot='add_source_parser') -@pytest.mark.filterwarnings('ignore:The config variable "source_parsers"') -@pytest.mark.filterwarnings('ignore:app.add_source_parser\\(\\) does not support suffix') def test_add_source_parser(app, status, warning): - assert set(app.config.source_suffix) == {'.rst', '.md', '.test'} + assert set(app.config.source_suffix) == {'.rst', '.test'} # .rst; only in :confval:`source_suffix` assert '.rst' not in app.registry.get_source_parsers() assert app.registry.source_suffix['.rst'] is None - # .md; configured by :confval:`source_suffix` and :confval:`source_parsers` - assert '.md' in app.registry.get_source_parsers() - assert app.registry.source_suffix['.md'] == '.md' - assert app.registry.get_source_parsers()['.md'].__name__ == 'DummyMarkdownParser' - # .test; configured by API assert app.registry.source_suffix['.test'] == 'test' assert 'test' in app.registry.get_source_parsers() diff --git a/tests/test_ext_autodoc_configs.py b/tests/test_ext_autodoc_configs.py index bbf3debaa..1ae7a2a23 100644 --- a/tests/test_ext_autodoc_configs.py +++ b/tests/test_ext_autodoc_configs.py @@ -12,7 +12,6 @@ import platform import pytest -from sphinx.ext.autodoc import merge_autodoc_default_flags from test_autodoc import do_autodoc IS_PYPY = platform.python_implementation() == 'PyPy' @@ -476,27 +475,6 @@ def test_autodoc_typehints_none(app): @pytest.mark.sphinx('html', testroot='ext-autodoc') -@pytest.mark.filterwarnings('ignore:autodoc_default_flags is now deprecated.') -def test_merge_autodoc_default_flags1(app): - app.config.autodoc_default_flags = ['members', 'undoc-members'] - merge_autodoc_default_flags(app, app.config) - assert app.config.autodoc_default_options == {'members': None, - 'undoc-members': None} - - -@pytest.mark.sphinx('html', testroot='ext-autodoc') -@pytest.mark.filterwarnings('ignore:autodoc_default_flags is now deprecated.') -def test_merge_autodoc_default_flags2(app): - app.config.autodoc_default_flags = ['members', 'undoc-members'] - app.config.autodoc_default_options = {'members': 'this,that,order', - 'inherited-members': 'this'} - merge_autodoc_default_flags(app, app.config) - assert app.config.autodoc_default_options == {'members': None, - 'undoc-members': None, - 'inherited-members': 'this'} - - -@pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_default_options(app): # no settings actual = do_autodoc(app, 'class', 'target.enum.EnumCls') @@ -505,7 +483,7 @@ def test_autodoc_default_options(app): actual = do_autodoc(app, 'class', 'target.CustomIter') assert ' .. py:method:: target.CustomIter' not in actual actual = do_autodoc(app, 'module', 'target') - assert '.. py:function:: save_traceback(app: Sphinx) -> str' not in actual + assert '.. py:function:: save_traceback(app)' not in actual # with :members: app.config.autodoc_default_options = {'members': None} @@ -569,16 +547,6 @@ def test_autodoc_default_options(app): assert ' .. py:method:: CustomIter.snafucate()' in actual assert ' Makes this snafucated.' in actual - # with :imported-members: - app.config.autodoc_default_options = { - 'members': None, - 'imported-members': None, - 'ignore-module-all': None, - } - actual = do_autodoc(app, 'module', 'target') - print('\n'.join(actual)) - assert '.. py:function:: save_traceback(app: Sphinx) -> str' in actual - @pytest.mark.sphinx('html', testroot='ext-autodoc') def test_autodoc_default_options_with_values(app): diff --git a/tests/test_ext_autodoc_mock.py b/tests/test_ext_autodoc_mock.py index 767232bcc..79a2782d3 100644 --- a/tests/test_ext_autodoc_mock.py +++ b/tests/test_ext_autodoc_mock.py @@ -17,7 +17,7 @@ from sphinx.ext.autodoc.mock import _MockModule, _MockObject, mock def test_MockModule(): - mock = _MockModule('mocked_module', None) + mock = _MockModule('mocked_module') assert isinstance(mock.some_attr, _MockObject) assert isinstance(mock.some_method, _MockObject) assert isinstance(mock.attr1.attr2, _MockObject) diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py index 21841cc74..9e5654ac4 100644 --- a/tests/test_ext_autosummary.py +++ b/tests/test_ext_autosummary.py @@ -31,6 +31,7 @@ default_kw = { 'confoverrides': { 'extensions': ['sphinx.ext.autosummary'], 'autosummary_generate': True, + 'autosummary_generate_overwrite': False, 'source_suffix': '.rst' } } @@ -223,6 +224,36 @@ def test_autosummary_generate(app, status, warning): ' \n' in Foo) +@pytest.mark.sphinx('dummy', testroot='ext-autosummary', + confoverrides={'autosummary_generate_overwrite': False}) +def test_autosummary_generate_overwrite1(app_params, make_app): + args, kwargs = app_params + srcdir = kwargs.get('srcdir') + + (srcdir / 'generated').makedirs(exist_ok=True) + (srcdir / 'generated' / 'autosummary_dummy_module.rst').write_text('') + + app = make_app(*args, **kwargs) + content = (srcdir / 'generated' / 'autosummary_dummy_module.rst').text() + assert content == '' + assert 'autosummary_dummy_module.rst' not in app._warning.getvalue() + + +@pytest.mark.sphinx('dummy', testroot='ext-autosummary', + confoverrides={'autosummary_generate_overwrite': True}) +def test_autosummary_generate_overwrite2(app_params, make_app): + args, kwargs = app_params + srcdir = kwargs.get('srcdir') + + (srcdir / 'generated').makedirs(exist_ok=True) + (srcdir / 'generated' / 'autosummary_dummy_module.rst').write_text('') + + app = make_app(*args, **kwargs) + content = (srcdir / 'generated' / 'autosummary_dummy_module.rst').text() + assert content != '' + assert 'autosummary_dummy_module.rst' not in app._warning.getvalue() + + @pytest.mark.sphinx('latex', **default_kw) def test_autosummary_latex_table_colspec(app, status, warning): app.builder.build_all() diff --git a/tests/test_util_images.py b/tests/test_util_images.py index 5e0f2801c..dbe155035 100644 --- a/tests/test_util_images.py +++ b/tests/test_util_images.py @@ -20,20 +20,15 @@ PDF_FILENAME = 'img.pdf' TXT_FILENAME = 'index.txt' -@pytest.fixture(scope='module') -def testroot(rootdir): - return rootdir / 'test-root' - - -def test_get_image_size(testroot): - assert get_image_size(testroot / GIF_FILENAME) == (200, 181) - assert get_image_size(testroot / PNG_FILENAME) == (200, 181) - assert get_image_size(testroot / PDF_FILENAME) is None - assert get_image_size(testroot / TXT_FILENAME) is None +def test_get_image_size(rootdir): + assert get_image_size(rootdir / 'test-root' / GIF_FILENAME) == (200, 181) + assert get_image_size(rootdir / 'test-root' / PNG_FILENAME) == (200, 181) + assert get_image_size(rootdir / 'test-root' / PDF_FILENAME) is None + assert get_image_size(rootdir / 'test-root' / TXT_FILENAME) is None @pytest.mark.filterwarnings('ignore:The content argument') -def test_guess_mimetype(testroot): +def test_guess_mimetype(): # guess by filename assert guess_mimetype('img.png') == 'image/png' assert guess_mimetype('img.jpg') == 'image/jpeg' @@ -42,24 +37,9 @@ def test_guess_mimetype(testroot): assert guess_mimetype('no_extension') is None assert guess_mimetype('IMG.PNG') == 'image/png' - # guess by content - assert guess_mimetype(content=(testroot / GIF_FILENAME).bytes()) == 'image/gif' - assert guess_mimetype(content=(testroot / PNG_FILENAME).bytes()) == 'image/png' - assert guess_mimetype(content=(testroot / PDF_FILENAME).bytes()) is None - assert guess_mimetype(content=(testroot / TXT_FILENAME).bytes()) is None - assert guess_mimetype(content=(testroot / TXT_FILENAME).bytes(), - default='text/plain') == 'text/plain' - - # the priority of params: filename > content > default - assert guess_mimetype('img.png', - content=(testroot / GIF_FILENAME).bytes(), - default='text/plain') == 'image/png' - assert guess_mimetype('no_extension', - content=(testroot / GIF_FILENAME).bytes(), - default='text/plain') == 'image/gif' - assert guess_mimetype('no_extension', - content=(testroot / TXT_FILENAME).bytes(), - default='text/plain') == 'text/plain' + # default parameter is used when no extension + assert guess_mimetype('img.png', 'text/plain') == 'image/png' + assert guess_mimetype('no_extension', 'text/plain') == 'text/plain' def test_get_image_extension(): |