Merge branch '5.x' into patch-1

This commit is contained in:
Takeshi KOMIYA 2022-05-08 02:36:54 +09:00
commit a48e811781
556 changed files with 54696 additions and 54810 deletions

View File

@ -7,6 +7,7 @@ on:
jobs:
test:
if: github.repository_owner == 'sphinx-doc'
runs-on: ubuntu-latest
steps:

View File

@ -10,6 +10,7 @@ permissions:
jobs:
action:
if: github.repository_owner == 'sphinx-doc'
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2

View File

@ -5,43 +5,34 @@ on: [push, pull_request]
jobs:
ubuntu:
runs-on: ubuntu-18.04
name: Python ${{ matrix.python }}
strategy:
fail-fast: false
matrix:
name: [py36, py37, py38, py39, py310]
include:
- name: py36
python: 3.6
- python: "3.6"
docutils: du14
- name: py37
python: 3.7
- python: "3.7"
docutils: du15
- name: py38
python: 3.8
- python: "3.8"
docutils: du16
- name: py39
python: 3.9
- python: "3.9"
docutils: du17
coverage: "--cov ./ --cov-append --cov-config setup.cfg"
- name: py310
python: "3.10"
docutils: du17
- name: py311-dev
python: 3.11-dev
- python: "3.10"
docutils: du18
- python: "3.11-dev"
docutils: py311
env:
PYTEST_ADDOPTS: ${{ matrix.coverage }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python }}
uses: actions/setup-python@v2
uses: actions/setup-python@v3
if: "!endsWith(matrix.python, '-dev')"
with:
python-version: ${{ matrix.python }}
- name: Set up Python ${{ matrix.python }} (deadsnakes)
uses: deadsnakes/action@v2.0.1
if: endsWith(matrix.python, '-dev')
if: "endsWith(matrix.python, '-dev')"
with:
python-version: ${{ matrix.python }}
- name: Check Python version
@ -49,29 +40,48 @@ jobs:
- name: Install graphviz
run: sudo apt-get install graphviz
- name: Install dependencies
run: pip install -U tox codecov
- name: Install the latest py package (for py3.11-dev)
run: pip install -U git+https://github.com/pytest-dev/py
if: ${{ matrix.python == '3.11-dev' }}
run: python -m pip install -U pip tox
- name: Run Tox
run: tox -e ${{ matrix.docutils }} -- -vv
- name: codecov
uses: codecov/codecov-action@v1
if: matrix.coverage
windows:
runs-on: windows-2019
strategy:
matrix:
architecture: [x86, x64]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v1
uses: actions/setup-python@v3
with:
architecture: ${{ matrix.architecture }}
python-version: 3
- name: Install dependencies
run: pip install -U tox
run: python -m pip install -U pip tox
- name: Run Tox
run: tox -e py -- -vv
coverage:
# only run on pushes to branches in the sphinx-doc/sphinx repo
if: github.repository_owner == 'sphinx-doc' && github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3
uses: actions/setup-python@v3
with:
python-version: 3
- name: Check Python version
run: python --version
- name: Install graphviz
run: sudo apt-get install graphviz
- name: Install dependencies
run: python -m pip install -U pip tox pytest-cov
- name: Run Tox
run: tox --sitepackages -e py -- -vv
env:
PYTEST_ADDOPTS: "--cov ./ --cov-append --cov-config setup.cfg"
- name: codecov
uses: codecov/codecov-action@v3

View File

@ -6,14 +6,15 @@ jobs:
build:
runs-on: ubuntu-latest
env:
node-version: 10.7
node-version: 16
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ env.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v2
with:
node-version: ${{ env.node-version }}
cache: "npm"
- run: npm install
- name: Run headless test
uses: GabrielBB/xvfb-action@v1

View File

@ -7,46 +7,52 @@ on:
jobs:
push:
if: github.repository_owner == 'sphinx-doc'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: 4.x
ref: 5.x
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.9 # https://github.com/transifex/transifex-client/pull/330
- name: Install dependencies
run: pip install -U babel jinja2 transifex-client
- name: Install Sphinx
run: pip install .
- name: Extract translations from source code
run: python setup.py extract_messages
run: python utils/babel_runner.py extract
- name: Push translations to transifex.com
run: cd sphinx/locale && tx push -s --no-interactive --parallel
env:
TX_TOKEN: ${{ secrets.TX_TOKEN }}
pull:
if: github.repository_owner == 'sphinx-doc'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: 4.x
ref: 5.x
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.9 # https://github.com/transifex/transifex-client/pull/330
- name: Install dependencies
run: pip install -U babel jinja2 transifex-client
- name: Install Sphinx
run: pip install .
- name: Extract translations from source code
run: python setup.py extract_messages
run: python utils/babel_runner.py extract
- name: Pull translations to transifex.com
run: cd sphinx/locale && tx pull -a -f --no-interactive --parallel
env:
TX_TOKEN: ${{ secrets.TX_TOKEN }}
- name: Compile message catalogs
run: python setup.py compile_catalog
run: python utils/babel_runner.py compile
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:

View File

@ -18,6 +18,7 @@ Other co-maintainers:
Other contributors, listed alphabetically, are:
* Adam Turner -- JavaScript improvements
* Alastair Houghton -- Apple Help builder
* Alexander Todorov -- inheritance_diagram tests and improvements
* Andi Albrecht -- agogo theme
@ -73,6 +74,7 @@ Other contributors, listed alphabetically, are:
* Pauli Virtanen -- autodoc improvements, autosummary extension
* Eric N. Vander Weele -- autodoc improvements
* Stefan van der Walt -- autosummary extension
* Hugo van Kemenade -- support FORCE_COLOR and NO_COLOR
* Thomas Waldmann -- apidoc module fixes
* John Waltman -- Texinfo builder
* Barry Warsaw -- setup command improvements

183
CHANGES
View File

@ -1,4 +1,119 @@
Release 4.5.0 (in development)
Release 5.0.0 (in development)
==============================
Dependencies
------------
* #10164: Support `Docutils 0.18`_. Patch by Adam Turner.
.. _Docutils 0.18: https://docutils.sourceforge.io/RELEASE-NOTES.html#release-0-18-2021-10-26
Incompatible changes
--------------------
* #10031: autosummary: ``sphinx.ext.autosummary.import_by_name()`` now raises
``ImportExceptionGroup`` instead of ``ImportError`` when it failed to import
target object. Please handle the exception if your extension uses the
function to import Python object. As a workaround, you can disable the
behavior via ``grouped_exception=False`` keyword argument until v7.0.
* #9962: texinfo: Customizing styles of emphasized text via ``@definfoenclose``
command was not supported because the command was deprecated since texinfo 6.8
* #2068: :confval:`intersphinx_disabled_reftypes` has changed default value
from an empty list to ``['std:doc']`` as avoid too surprising silent
intersphinx resolutions.
To migrate: either add an explicit inventory name to the references
intersphinx should resolve, or explicitly set the value of this configuration
variable to an empty list.
* #9999: LaTeX: separate terms from their definitions by a CR (refs: #9985)
* #10062: Change the default language to ``'en'`` if any language is not set in
``conf.py``
Deprecated
----------
* #10028: jQuery and underscore.js will no longer be automatically injected into
themes from Sphinx 6.0. If you develop a theme or extension that uses the
``jQuery``, ``$``, or ``$u`` global objects, you need to update your
JavaScript or use the mitigation below.
To re-add jQuery and underscore.js, you will need to copy ``jquery.js`` and
``underscore.js`` from `the Sphinx repository`_ to your ``static`` directory,
and add the following to your ``layout.html``:
.. _the Sphinx repository: https://github.com/sphinx-doc/sphinx/tree/v4.3.2/sphinx/themes/basic/static
.. code-block:: html+jinja
{%- block scripts %}
<script src="{{ pathto('_static/jquery.js', resource=True) }}"></script>
<script src="{{ pathto('_static/underscore.js', resource=True) }}"></script>
{{ super() }}
{%- endblock %}
* setuptools integration. The ``build_sphinx`` sub-command for setup.py is
marked as deprecated to follow the policy of setuptools team.
* The ``locale`` argument of ``sphinx.util.i18n:babel_format_date()`` becomes
required
* The ``language`` argument of ``sphinx.util.i18n:format_date()`` becomes
required
* ``sphinx.builders.html.html5_ready``
* ``sphinx.io.read_doc()``
* ``sphinx.util.docutils.__version_info__``
* ``sphinx.util.docutils.is_html5_writer_available()``
* ``sphinx.writers.latex.LaTeXWriter.docclasses``
Features added
--------------
* #9075: autodoc: The default value of :confval:`autodoc_typehints_format` is
changed to ``'smart'``. It will suppress the leading module names of
typehints (ex. ``io.StringIO`` -> ``StringIO``).
* #8417: autodoc: ``:inherited-members:`` option now takes multiple classes. It
allows to suppress inherited members of several classes on the module at once
by specifying the option to :rst:dir:`automodule` directive
* #9792: autodoc: Add new option for ``autodoc_typehints_description_target`` to
include undocumented return values but not undocumented parameters.
* #10285: autodoc: singledispatch functions having typehints are not documented
* autodoc: :confval:`autodoc_typehints_format` now also applies to attributes,
data, properties, and type variable bounds.
* #10258: autosummary: Recognize a documented attribute of a module as
non-imported
* #10028: Removed internal usages of JavaScript frameworks (jQuery and
underscore.js) and modernised ``doctools.js`` and ``searchtools.js`` to
EMCAScript 2018.
* #10302: C++, add support for conditional expressions (``?:``).
* #5157, #10251: Inline code is able to be highlighted via :rst:dir:`role`
directive
* #10337: Make sphinx-build faster by caching Publisher object during build
Bugs fixed
----------
* #10200: apidoc: Duplicated submodules are shown for modules having both .pyx
and .so files
* #10279: autodoc: Default values for keyword only arguments in overloaded
functions are rendered as a string literal
* #10280: autodoc: :confval:`autodoc_docstring_signature` unexpectedly generates
return value typehint for constructors if docstring has multiple signatures
* #10266: autodoc: :confval:`autodoc_preserve_defaults` does not work for
mixture of keyword only arguments with/without defaults
* #10310: autodoc: class methods are not documented when decorated with mocked
function
* #10305: autodoc: Failed to extract optional forward-ref'ed typehints correctly
via :confval:`autodoc_type_aliases`
* #10214: html: invalid language tag was generated if :confval:`language`
contains a country code (ex. zh_CN)
* #10236: html search: objects are duplicated in search result
* #9962: texinfo: Deprecation message for ``@definfoenclose`` command on
bulding texinfo document
* #10000: LaTeX: glossary terms with common definition are rendered with
too much vertical whitespace
* #10188: LaTeX: alternating multiply referred footnotes produce a ``?`` in
pdf output
* #10318: ``:prepend:`` option of :rst:dir:`literalinclude` directive does not
work with ``:dedent:`` option
Testing
--------
Release 4.5.1 (in development)
==============================
Dependencies
@ -10,26 +125,60 @@ Incompatible changes
Deprecated
----------
Features added
--------------
Bugs fixed
----------
Testing
--------
Release 4.5.0 (released Mar 28, 2022)
=====================================
Incompatible changes
--------------------
* #10112: extlinks: Disable hardcoded links detector by default
* #9993, #10177: std domain: Disallow to refer an inline target via
:rst:role:`ref` role
Deprecated
----------
* ``sphinx.ext.napoleon.docstring.GoogleDocstring._qualify_name()``
Features added
--------------
* #10260: Enable ``FORCE_COLOR`` and ``NO_COLOR`` for terminal colouring
* #10234: autosummary: Add "autosummary" CSS class to summary tables
* #10125: extlinks: Improve suggestion message for a reference having title
* #10112: extlinks: Add :confval:`extlinks_detect_hardcoded_links` to enable
hardcoded links detector feature
* #9494, #9456: html search: Add a config variable
:confval:`html_show_search_summary` to enable/disable the search summaries
* #9337: HTML theme, add option ``enable_search_shortcuts`` that enables :kbd:'/' as
* #9337: HTML theme, add option ``enable_search_shortcuts`` that enables :kbd:`/` as
a Quick search shortcut and :kbd:`Esc` shortcut that
removes search highlighting.
* #10107: i18n: Allow to suppress translation warnings by adding ``#noqa``
comment to the tail of each translation message
* #10252: C++, support attributes on classes, unions, and enums.
* #10253: :rst:dir:`pep` role now generates URLs based on peps.python.org
Bugs fixed
----------
* #9876: autodoc: Failed to document an imported class that is built from native
binary module
* #10133: autodoc: Crashed when mocked module is used for type annotation
* #10146: autodoc: :confval:`autodoc_default_options` does not support
``no-value`` option
* #9971: autodoc: TypeError is raised when the target object is annotated by
unhashable object
* #10205: extlinks: Failed to compile regexp on checking hardcoded links
* #10277: html search: Could not search short words (ex. "use")
* #9529: LaTeX: named auto numbered footnote (ex. ``[#named]``) that is referred
multiple times was rendered to a question mark
* #9924: LaTeX: multi-line :rst:dir:`cpp:function` directive has big vertical
@ -38,38 +187,14 @@ Bugs fixed
variables/structure members
* #10175: LaTeX: named footnote reference is linked to an incorrect footnote if
the name is also used in the different document
* #10269: manpage: Failed to resolve the title of :ref: cross references
* #10179: i18n: suppress "rST localization" warning
* #10118: imgconverter: Unnecessary availablity check is called for remote URIs
* #10181: napoleon: attributes are displayed like class attributes for google
style docstrings when :confval:`napoleon_use_ivar` is enabled
* #10122: sphinx-build: make.bat does not check the installation of sphinx-build
command before showing help
Testing
--------
Release 4.4.1 (in development)
==============================
Dependencies
------------
Incompatible changes
--------------------
Deprecated
----------
Features added
--------------
Bugs fixed
----------
* #9876: autodoc: Failed to document an imported class that is built from native
binary module
Testing
--------
Release 4.4.0 (released Jan 17, 2022)
=====================================

View File

@ -15,9 +15,11 @@ Documentation using the alabaster theme
* `Alabaster <https://alabaster.readthedocs.io/>`__
* `Blinker <https://pythonhosted.org/blinker/>`__
* `Calibre <https://manual.calibre-ebook.com/>`__
* `CherryPy <https://cherrypy.readthedocs.io/>`__
* `Click <https://click.palletsprojects.com/>`__ (customized)
* `coala <https://docs.coala.io/>`__ (customized)
* `CodePy <https://documen.tician.de/codepy/>`__
* `Django Q <https://django-q.readthedocs.io/>`__
* `Eve <https://docs.python-eve.org/>`__ (Python REST API framework)
* `Fabric <https://docs.fabfile.org/>`__
* `Fityk <https://fityk.nieto.pl/>`__
@ -30,19 +32,21 @@ Documentation using the alabaster theme
* `MDAnalysis <https://www.mdanalysis.org/docs/>`__ (customized)
* `MeshPy <https://documen.tician.de/meshpy/>`__
* `Molecule <https://molecule.readthedocs.io/>`__
* `Momotor LTI <https://momotor.org/doc/lti/canvas/>`__
* `Podman <https://docs.podman.io/>`__
* `PyCUDA <https://documen.tician.de/pycuda/>`__
* `PyOpenCL <https://documen.tician.de/pyopencl/>`__
* `PyLangAcq <https://pylangacq.org/>`__
* `pytest <https://docs.pytest.org/>`__ (customized)
* `python-apt <https://apt.alioth.debian.org/python-apt-doc/>`__
* `python-apt <https://apt-team.pages.debian.net/python-apt/>`__
* `PyVisfile <https://documen.tician.de/pyvisfile/>`__
* `Requests <http://www.python-requests.org/>`__
* `Requests <https://docs.python-requests.org/>`__
* `searx <https://asciimoo.github.io/searx/>`__
* `Spyder <https://docs.spyder-ide.org/>`__ (customized)
* `Tablib <http://docs.python-tablib.org/>`__
* `urllib3 <https://urllib3.readthedocs.io/>`__ (customized)
* `Werkzeug <https://werkzeug.palletsprojects.com/>`__
* `Write the Docs <https://writethedocs-www.readthedocs.io/>`__
* `Write the Docs <https://www.writethedocs.org/>`__
Documentation using the classic theme
-------------------------------------
@ -58,8 +62,6 @@ Documentation using the classic theme
* `Buildbot <https://docs.buildbot.net/latest/>`__
* `CMake <https://cmake.org/documentation/>`__ (customized)
* `Chaco <https://docs.enthought.com/chaco/>`__ (customized)
* `CORE <https://downloads.pf.itd.nrl.navy.mil/docs/core/core-html/>`__
* `CORE Python modules <https://downloads.pf.itd.nrl.navy.mil/docs/core/core-python-html/>`__
* `Cormoran <http://cormoran.nhopkg.org/docs/>`__
* `DEAP <https://deap.readthedocs.io/>`__ (customized)
* `Director <https://pythonhosted.org/director/>`__
@ -67,27 +69,26 @@ Documentation using the classic theme
* `F2py <http://f2py.sourceforge.net/docs/>`__
* `Generic Mapping Tools (GMT) <https://gmt.soest.hawaii.edu/doc/latest/>`__ (customized)
* `Genomedata <https://noble.gs.washington.edu/proj/genomedata/doc/1.3.3/>`__
* `GetFEM++ <http://getfem.org/>`__ (customized)
* `GetFEM++ <https://getfem.org/>`__ (customized)
* `Glasgow Haskell Compiler <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/>`__ (customized)
* `Grok <http://grok.zope.org/doc/current/>`__ (customized)
* `GROMACS <https://manual.gromacs.org/documentation/>`__
* `GSL Shell <https://www.nongnu.org/gsl-shell/>`__
* `Hands-on Python Tutorial <https://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/>`__
* `Kaa <https://api.freevo.org/kaa-base/>`__ (customized)
* `Leo <https://leoeditor.com/>`__
* `LEPL <http://www.acooke.org/lepl/>`__ (customized)
* `Hands-on Python Tutorial <http://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/>`__
* `Kaa <https://freevo.github.io/kaa-base/>`__ (customized)
* `Leo <https://leoeditor.com/>`__ (customized)
* `Mayavi <https://docs.enthought.com/mayavi/mayavi/>`__ (customized)
* `MediaGoblin <https://mediagoblin.readthedocs.io/>`__ (customized)
* `mpmath <https://mpmath.org/doc/current/>`__
* `OpenCV <https://docs.opencv.org/>`__ (customized)
* `OpenEXR <https://excamera.com/articles/26/doc/index.html>`__
* `OpenGDA <http://www.opengda.org/gdadoc/html/>`__
* `Peach^3 <https://peach3.nl/doc/latest/userdoc/>`__ (customized)
* `OpenGDA <http://www.opengda.org/documentation/>`__
* `phpDocumentor <https://docs.phpdoc.org/>`__ (customized)
* `Plone <https://docs.plone.org/>`__ (customized)
* `PyEMD <https://pyemd.readthedocs.io/>`__
* `Pyevolve <http://pyevolve.sourceforge.net/>`__
* `Pygame <https://www.pygame.org/docs/>`__ (customized)
* `PyMQI <https://pythonhosted.org/pymqi/>`__
* `PyMQI <https://dsuch.github.io/pymqi/>`__
* `PyQt4 <http://pyqt.sourceforge.net/Docs/PyQt4/>`__ (customized)
* `PyQt5 <http://pyqt.sourceforge.net/Docs/PyQt5/>`__ (customized)
* `Python 2 <https://docs.python.org/2/>`__
@ -120,7 +121,8 @@ Documentation using the sphinxdoc theme
* `MDAnalysis Tutorial <https://www.mdanalysis.org/MDAnalysisTutorial/>`__
* `NetworkX <https://networkx.github.io/>`__
* `PyCantonese <https://pycantonese.org/>`__
* `Pyre <https://docs.danse.us/pyre/sphinx/>`__
* `PyRe <https://hackl.science/pyre/>`__
* `Pyre <https://pyre.readthedocs.io/>`__
* `pySPACE <https://pyspace.github.io/pyspace/>`__
* `Pysparse <http://pysparse.sourceforge.net/>`__
* `PyTango <https://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/pytango/latest/>`__
@ -136,8 +138,7 @@ Documentation using the nature theme
* `Alembic <https://alembic.sqlalchemy.org/>`__
* `Cython <https://docs.cython.org/>`__
* `easybuild <https://easybuild.readthedocs.io/>`__
* `jsFiddle <http://doc.jsfiddle.net/>`__
* `libLAS <https://www.liblas.org/>`__ (customized)
* `libLAS <https://liblas.org/>`__ (customized)
* `Lmod <https://lmod.readthedocs.io/>`__
* `MapServer <https://mapserver.org/>`__ (customized)
* `Pandas <https://pandas.pydata.org/pandas-docs/stable/>`__
@ -154,11 +155,10 @@ Documentation using another builtin theme
* `Breathe <https://breathe.readthedocs.io/>`__ (haiku)
* `MPipe <https://vmlaker.github.io/mpipe/>`__ (sphinx13)
* `NLTK <https://www.nltk.org/>`__ (agogo)
* `Programmieren mit PyGTK und Glade (German) <https://www.florian-diesch.de/doc/python-und-glade/online/>`__ (agogo, customized)
* `PyPubSub <https://pypubsub.readthedocs.io/>`__ (bizstyle)
* `Pylons <https://docs.pylonsproject.org/projects/pylons-webframework/>`__ (pyramid)
* `Pyramid web framework <https://docs.pylonsproject.org/projects/pyramid/>`__ (pyramid)
* `RxDock <https://www.rxdock.org/documentation/html/devel/>`__
* `RxDock <https://www.rxdock.org/documentation/devel/html/>`__
* `Sphinx <https://www.sphinx-doc.org/>`__ (sphinx13) :-)
* `Valence <https://docs.valence.desire2learn.com/>`__ (haiku, customized)
@ -176,9 +176,12 @@ Documentation using sphinx_rtd_theme
* `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/>`__
* `Certbot <https://certbot.eff.org/docs/>`__
* `CKAN <https://docs.ckan.org/>`__
* `Copr Buildsystem <https://docs.pagure.org/copr.copr/>`__ (customized)
* `Coreboot <https://doc.coreboot.org/>`__
* `Chainer <https://docs.chainer.org/>`__ (customized)
* `CherryPy <https://docs.cherrypy.org/>`__
* `citeproc-js <https://citeproc-js.readthedocs.io/>`__
* `cloud-init <https://cloudinit.readthedocs.io/>`__
* `CodeIgniter <https://www.codeigniter.com/user_guide/>`__
* `Conda <https://conda.io/docs/>`__
@ -187,7 +190,9 @@ Documentation using sphinx_rtd_theme
* `Databricks <https://docs.databricks.com/>`__ (customized)
* `Dataiku DSS <https://doc.dataiku.com/>`__
* `DNF <https://dnf.readthedocs.io/>`__
* `Distro Tracker <https://qa.pages.debian.net/distro-tracker/>`__
* `Django-cas-ng <https://djangocas.dev/docs/>`__
* `dj-stripe <https://dj-stripe.readthedocs.io/>`__
* `edX <https://docs.edx.org/>`__
* `Electrum <https://docs.electrum.org/>`__
* `Elemental <https://libelemental.org/documentation/dev/>`__
@ -207,13 +212,15 @@ Documentation using sphinx_rtd_theme
* `Graylog <https://docs.graylog.org/>`__
* `GPAW <https://wiki.fysik.dtu.dk/gpaw/>`__ (customized)
* `HDF5 for Python (h5py) <https://docs.h5py.org/>`__
* `HyperKitty <https://hyperkitty.readthedocs.io/>`__
* `Hyperledger Fabric <https://hyperledger-fabric.readthedocs.io/>`__
* `Hyperledger Sawtooth <https://intelledger.github.io/>`__
* `Hyperledger Sawtooth <https://sawtooth.hyperledger.org/docs/>`__
* `IdentityServer <https://docs.identityserver.io/>`__
* `Idris <https://docs.idris-lang.org/>`__
* `Inkscape <https://inkscape-manuals.readthedocs.io/>`__ (customized)
* `javasphinx <https://bronto-javasphinx.readthedocs.io/>`__
* `Julia <https://julia.readthedocs.io/>`__
* `Jupyter Notebook <https://jupyter-notebook.readthedocs.io/>`__
* `Kanboard <https://docs.kanboard.org/>`__
* `Lasagne <https://lasagne.readthedocs.io/>`__
* `latexindent.pl <https://latexindentpl.readthedocs.io/>`__
* `Learning Apache Spark with Python <https://runawayhorse001.github.io/LearningApacheSpark>`__
@ -226,7 +233,6 @@ Documentation using sphinx_rtd_theme
* `Mesa 3D <https://docs.mesa3d.org/>`__
* `micca - MICrobial Community Analysis <https://micca.readthedocs.io/>`__
* `MicroPython <https://docs.micropython.org/>`__
* `Minds <https://www.minds.org/docs/>`__ (customized)
* `Mink <https://mink.behat.org/>`__
* `Mockery <https://docs.mockery.io/>`__
* `mod_wsgi <https://modwsgi.readthedocs.io/>`__
@ -234,9 +240,14 @@ Documentation using sphinx_rtd_theme
* `Mopidy <https://docs.mopidy.com/>`__
* `mpi4py <https://mpi4py.readthedocs.io/>`__
* `MyHDL <https://docs.myhdl.org/>`__
* `Mypy <https://mypy.readthedocs.io/>`__
* `Netgate Docs <https://docs.netgate.com/>`__
* `Nextcloud Server <https://docs.nextcloud.com/#server>`__
* `Nextflow <https://www.nextflow.io/docs/latest/index.html>`__
* `nghttp2 <https://nghttp2.org/documentation/>`__
* `NICOS <https://forge.frm2.tum.de/nicos/doc/nicos-master/>`__ (customized)
* `OpenFAST <https://openfast.readthedocs.io/>`__
* `Panda3D <https://docs.panda3d.org/>`__ (customized)
* `Pelican <https://docs.getpelican.com/>`__
* `picamera <https://picamera.readthedocs.io/>`__
* `Pillow <https://pillow.readthedocs.io/>`__
@ -245,15 +256,21 @@ Documentation using sphinx_rtd_theme
* `peewee <https://docs.peewee-orm.com/>`__
* `Phinx <https://docs.phinx.org/>`__
* `phpMyAdmin <https://docs.phpmyadmin.net/>`__
* `PHPUnit <https://phpunit.readthedocs.io/>`__
* `PHPWord <https://phpword.readthedocs.io/>`__
* `PROS <https://pros.cs.purdue.edu/v5/>`__ (customized)
* `Pushkin <http://docs.pushkin.io/>`__
* `Pweave <https://mpastell.com/pweave/>`__
* `pyca/cryptograhpy <https://cryptography.io/>`__
* `PyNaCl <https://pynacl.readthedocs.io/>`__
* `pyOpenSSL <https://www.pyopenssl.org/>`__
* `PyPy <https://doc.pypy.org/>`__
* `python-sqlparse <https://sqlparse.readthedocs.io/>`__
* `PyVISA <https://pyvisa.readthedocs.io/>`__
* `pyvista <https://docs.pyvista.org/>`__
* `Read The Docs <https://docs.readthedocs.io/>`__
* `ROCm Platform <https://rocm-documentation.readthedocs.io/>`__
* `RenderDoc <https://renderdoc.org/docs/>`__
* `ROCm Platform <https://rocmdocs.amd.com/>`__
* `Free your information from their silos (French) <https://redaction-technique.org/>`__ (customized)
* `Releases Sphinx extension <https://releases.readthedocs.io/>`__
* `Qtile <https://docs.qtile.org/>`__
@ -269,6 +286,7 @@ Documentation using sphinx_rtd_theme
* `Sonos Controller (SoCo) <https://docs.python-soco.com/>`__
* `Sphinx AutoAPI <https://sphinx-autoapi.readthedocs.io/>`__
* `sphinx-argparse <https://sphinx-argparse.readthedocs.io/>`__
* `sphinx-tabs <https://sphinx-tabs.readthedocs.io/>`__
* `Sphinx-Gallery <https://sphinx-gallery.readthedocs.io/>`__ (customized)
* `Sphinx with Github Webpages <https://runawayhorse001.github.io/SphinxGithub>`__
* `SpotBugs <https://spotbugs.readthedocs.io/>`__
@ -281,15 +299,18 @@ Documentation using sphinx_rtd_theme
* `Topshelf <https://docs.topshelf-project.com/>`__
* `Theano <http://www.deeplearning.net/software/theano/>`__
* `ThreatConnect <https://docs.threatconnect.com/>`__
* `TrueNAS <https://www.ixsystems.com/documentation/truenas/>`__ (customized)
* `Tuleap <https://tuleap.net/doc/en/>`__
* `TYPO3 <https://docs.typo3.org/>`__ (customized)
* `Veyon <https://docs.veyon.io/>`__
* `Ubiquity <https://micro-framework.readthedocs.io/>`__
* `uWSGI <https://uwsgi-docs.readthedocs.io/>`__
* `virtualenv <https://virtualenv.readthedocs.io/>`__
* `Wagtail <https://docs.wagtail.io/>`__
* `Web Application Attack and Audit Framework (w3af) <https://docs.w3af.org/>`__
* `Weblate <https://docs.weblate.org/>`__
* `x265 <https://x265.readthedocs.io/>`__
* `Zeek <https://docs.zeek.org/>`__
* `Zulip <https://zulip.readthedocs.io/>`__
Documentation using sphinx_bootstrap_theme
@ -317,12 +338,12 @@ Documentation using a custom theme or integrated in a website
* `Bokeh <https://bokeh.pydata.org/>`__
* `Boto 3 <https://boto3.readthedocs.io/>`__
* `CakePHP <https://book.cakephp.org/>`__
* `CasperJS <http://docs.casperjs.org/>`__
* `Ceph <https://docs.ceph.com/docs/master/>`__
* `Chef <https://docs.chef.io/>`__
* `CKAN <https://docs.ckan.org/>`__
* `Confluent Platform <https://docs.confluent.io/>`__
* `Django <https://docs.djangoproject.com/>`__
* `django CMS <https://docs.django-cms.org/>`__
* `Doctrine <https://www.doctrine-project.org/>`__
* `Enterprise Toolkit for Acrobat products <https://www.adobe.com/devnet-docs/acrobatetk/>`__
* `FreeFEM <https://doc.freefem.org/introduction/>`__
@ -335,7 +356,7 @@ Documentation using a custom theme or integrated in a website
* `Guzzle <https://docs.guzzlephp.org/>`__
* `H2O.ai <https://docs.h2o.ai/>`__
* `Heka <https://hekad.readthedocs.io/>`__
* `Istihza (Turkish Python documentation project) <https://belgeler.yazbel.com/python-istihza/>`__
* `Istihza (Turkish Python documentation project) <https://python-istihza.yazbel.com/>`__
* `JupyterHub <https://jupyterhub.readthedocs.io/>`__
* `Kombu <http://docs.kombu.me/>`__
* `Lasso <https://lassoguide.com/>`__
@ -356,6 +377,7 @@ Documentation using a custom theme or integrated in a website
* `OpenTURNS <https://openturns.github.io/openturns/master/>`__
* `Open vSwitch <https://docs.openvswitch.org/>`__
* `PlatformIO <https://docs.platformio.org/>`__
* `Psycopg <https://www.psycopg.org/docs/>`__
* `PyEphem <https://rhodesmill.org/pyephem/>`__
* `Pygments <https://pygments.org/docs/>`__
* `Plone User Manual (German) <https://www.hasecke.com/plone-benutzerhandbuch/4.0/>`__
@ -384,14 +406,16 @@ Documentation using a custom theme or integrated in a website
Homepages and other non-documentation sites
-------------------------------------------
* `Alan Crosswell's Using the Django REST Framework and DRF-JSONAPI <http://www.columbia.edu/~alan/django-jsonapi-training/>`__
* `Arizona State University PHY494/PHY598/CHM598 Simulation approaches to Bio-and Nanophysics <https://becksteinlab.physics.asu.edu/pages/courses/2013/SimBioNano/>`__ (classic)
* `Benoit Boissinot <https://bboissin.appspot.com/>`__ (classic, customized)
* `Computer Networks, Parallelization, and Simulation Laboratory (CNPSLab) <https://lab.miletic.net/>`__ (sphinx_rtd_theme)
* `Deep Learning Tutorials <http://www.deeplearning.net/tutorial/>`__ (sphinxdoc)
* `EBI Cloud Consultancy Team <https://tsi-ccdoc.readthedocs.io/>`__ (sphinx_rtd_theme)
* `Eric Holscher <https://ericholscher.com/>`__ (alabaster)
* `Florian Diesch <https://www.florian-diesch.de/>`__
* `Institute for the Design of Advanced Energy Systems (IDAES) <https://idaes-pse.readthedocs.io/>`__ (sphinx_rtd_theme)
* `IDAES Examples <https://idaes.github.io/examples-pse/>`__ (sphinx_rtd_theme)
* `Lei Ma's Statistical Mechanics lecture notes <http://statisticalphysics.openmetric.org/>`__ (sphinx_bootstrap_theme)
* `Loyola University Chicago COMP 339-439 Distributed Systems course <https://books.cs.luc.edu/distributedsystems/>`__ (sphinx_bootstrap_theme)
* `Pylearn2 <http://www.deeplearning.net/software/pylearn2/>`__ (sphinxdoc, customized)
* `Loyola University Chicago CS Academic Programs <https://academics.cs.luc.edu/index.html>`__ (sphinx_rtd_theme, customized)
* `PyXLL <https://www.pyxll.com/>`__ (sphinx_bootstrap_theme, customized)
* `SciPy Cookbook <https://scipy-cookbook.readthedocs.io/>`__ (sphinx_rtd_theme)
* `Tech writer at work blog <https://blog.documatt.com/>`__ (custom theme)
@ -444,6 +468,6 @@ Projects integrating Sphinx functionality
* `Read the Docs <https://readthedocs.org/>`__, a software-as-a-service documentation hosting platform, uses
Sphinx to automatically build documentation updates that are pushed to GitHub.
* `Spyder <https://docs.spyder-ide.org/help.html>`__, the Scientific Python Development Environment, uses Sphinx in its
help pane to render rich documentation for functions, classes and methods
* `Spyder <https://docs.spyder-ide.org/current/panes/help.html>`__, the Scientific Python Development
Environment, uses Sphinx in its help pane to render rich documentation for functions, classes and methods
automatically or on-demand.

View File

@ -1,6 +1,9 @@
License for Sphinx
==================
Unless otherwise indicated, all code in the Sphinx project is licenced under the
two clause BSD licence below.
Copyright (c) 2007-2022 by the Sphinx team (see AUTHORS file).
All rights reserved.

View File

@ -66,11 +66,11 @@ doclinter:
.PHONY: test
test:
@$(PYTHON) -X dev -m pytest -v $(TEST)
@$(PYTHON) -X dev -X warn_default_encoding -m pytest -v $(TEST)
.PHONY: covertest
covertest:
@$(PYTHON) -X dev -m pytest -v --cov=sphinx --junitxml=.junit.xml $(TEST)
@$(PYTHON) -X dev -X warn_default_encoding -m pytest -v --cov=sphinx --junitxml=.junit.xml $(TEST)
.PHONY: build
build:

View File

@ -14,7 +14,7 @@
<form action="https://groups.google.com/group/sphinx-users/boxsubscribe"
class="subscribeform">
<input type="text" name="email" value="your@email"
onfocus="$(this).val('');" />
onfocus="this.value = ''" />
<input type="submit" name="sub" value="Subscribe" />
</form>
</div>

View File

@ -27,31 +27,28 @@
</style>
<script>
// intelligent scrolling of the sidebar content
$(window).scroll(function() {
var sb = $('.sphinxsidebarwrapper');
var win = $(window);
var sbh = sb.height();
var offset = $('.sphinxsidebar').position()['top'];
var wintop = win.scrollTop();
var winbot = wintop + win.innerHeight();
var curtop = sb.position()['top'];
var curbot = curtop + sbh;
window.onscroll = () => {
const sb = document.getElementsByClassName('sphinxsidebarwrapper')[0]
const sbh = sb.offsetHeight
const offset = document.getElementsByClassName('sphinxsidebar')[0].offsetTop;
const wintop = window.scrollTop;
const winbot = wintop + window.offsetHeight
const curtop = sb.offsetTop;
const curbot = curtop + sbh;
// does sidebar fit in window?
if (sbh < win.innerHeight()) {
if (sbh < window.offsetHeight) {
// yes: easy case -- always keep at the top
sb.css('top', $u.min([$u.max([0, wintop - offset - 10]),
$(document).height() - sbh - 200]));
sb.style.top = Math.min(Math.max(0, wintop - offset - 10), window.innerHeight - sbh - 200)
} else {
// no: only scroll if top/bottom edge of sidebar is at
// top/bottom edge of window
if (curtop > wintop && curbot > winbot) {
sb.css('top', $u.max([wintop - offset - 10, 0]));
sb.style.top = Math.max(wintop - offset - 10, 0)
} else if (curtop < wintop && curbot < winbot) {
sb.css('top', $u.min([winbot - sbh - offset - 20,
$(document).height() - sbh - 200]));
sb.style.top = Math.min(winbot - sbh - offset - 20, window.innerHeight - sbh - 200)
}
}
});
}
</script>
{%- endif %}
{% endblock %}

View File

@ -1,5 +1,6 @@
# Sphinx documentation build configuration file
import os
import re
import sphinx
@ -81,11 +82,11 @@ autodoc_member_order = 'groupwise'
autosummary_generate = False
todo_include_todos = True
extlinks = {'duref': ('https://docutils.sourceforge.io/docs/ref/rst/'
'restructuredtext.html#%s', ''),
'restructuredtext.html#%s', '%s'),
'durole': ('https://docutils.sourceforge.io/docs/ref/rst/'
'roles.html#%s', ''),
'roles.html#%s', '%s'),
'dudir': ('https://docutils.sourceforge.io/docs/ref/rst/'
'directives.html#%s', '')}
'directives.html#%s', '%s')}
man_pages = [
('contents', 'sphinx-all', 'Sphinx documentation generator system manual',
@ -108,7 +109,7 @@ texinfo_documents = [
intersphinx_mapping = {
'python': ('https://docs.python.org/3/', None),
'requests': ('https://requests.readthedocs.io/en/master', None),
'requests': ('https://docs.python-requests.org/en/latest/', None),
'readthedocs': ('https://docs.readthedocs.io/en/stable', None),
}
@ -139,10 +140,33 @@ def parse_event(env, sig, signode):
return name
def linkify_issues_in_changelog(app, docname, source):
""" Linkify issue references like #123 in changelog to GitHub. """
if docname == 'changes':
changelog_path = os.path.join(os.path.dirname(__file__), "../CHANGES")
# this path trickery is needed because this script can
# be invoked with different working directories:
# * running make in docs/
# * running tox -e docs in the repo root dir
with open(changelog_path, encoding="utf-8") as f:
changelog = f.read()
def linkify(match):
url = 'https://github.com/sphinx-doc/sphinx/issues/' + match[1]
return '`{} <{}>`_'.format(match[0], url)
linkified_changelog = re.sub(r'(?:PR)?#([0-9]+)\b', linkify, changelog)
source[0] = source[0].replace('.. include:: ../CHANGES', linkified_changelog)
def setup(app):
from sphinx.ext.autodoc import cut_lines
from sphinx.util.docfields import GroupedField
app.connect('autodoc-process-docstring', cut_lines(4, what=['module']))
app.connect('source-read', linkify_issues_in_changelog)
app.add_object_type('confval', 'confval',
objname='configuration value',
indextemplate='pair: %s; configuration value')

View File

@ -265,7 +265,7 @@ Here is some sample code to accomplish this:
copy_asset_file('path/to/myextension/_static/myjsfile.js', staticdir)
def setup(app):
app.connect('builder-inited', copy_custom_files)
app.connect('build-finished', copy_custom_files)
Inject JavaScript based on user configuration

View File

@ -70,7 +70,7 @@ def merge_todos(app, env, docnames, other):
def process_todo_nodes(app, doctree, fromdocname):
if not app.config.todo_include_todos:
for node in doctree.traverse(todo):
for node in doctree.findall(todo):
node.parent.remove(node)
# Replace all todolist nodes with a list of the collected todos.
@ -80,7 +80,7 @@ def process_todo_nodes(app, doctree, fromdocname):
if not hasattr(env, 'todo_all_todos'):
env.todo_all_todos = []
for node in doctree.traverse(todolist):
for node in doctree.findall(todolist):
if not app.config.todo_include_todos:
node.replace_self([])
continue
@ -93,7 +93,7 @@ def process_todo_nodes(app, doctree, fromdocname):
description = (
_('(The original entry is located in %s, line %d and can be found ') %
(filename, todo_info['lineno']))
para += nodes.Text(description, description)
para += nodes.Text(description)
# Create a reference
newnode = nodes.reference('', '')
@ -104,7 +104,7 @@ def process_todo_nodes(app, doctree, fromdocname):
newnode['refuri'] += '#' + todo_info['target']['refid']
newnode.append(innernode)
para += newnode
para += nodes.Text('.)', '.)')
para += nodes.Text('.)')
# Insert into the todolist
content.append(todo_info['todo'])

View File

@ -22,6 +22,51 @@ The following is a list of deprecated interfaces.
- (will be) Removed
- Alternatives
* - ``sphinx.util.jsdump``
- 5.0
- 7.0
- The standard library ``json`` module.
* - :doc:`Setuptools integration </usage/advanced/setuptools>`
- 5.0
- 7.0
- N/A
* - The ``locale`` argument of ``sphinx.util.i18n:babel_format_date()``
- 5.0
- 7.0
- N/A
* - The ``language`` argument of ``sphinx.util.i18n:format_date()``
- 5.0
- 7.0
- N/A
* - ``sphinx.builders.html.html5_ready``
- 5.0
- 7.0
- N/A
* - ``sphinx.io.read_doc()``
- 5.0
- 7.0
- ``sphinx.builders.Builder.read_doc()``
* - ``sphinx.util.docutils.__version_info__``
- 5.0
- 7.0
- ``docutils.__version_info__``
* - ``sphinx.util.docutils.is_html5_writer_available()``
- 5.0
- 7.0
- N/A
* - ``sphinx.writers.latex.LaTeXWriter.docclasses``
- 5.0
- 7.0
- N/A
* - ``sphinx.ext.napoleon.docstring.GoogleDocstring._qualify_name()``
- 4.5
- 6.0

View File

@ -178,7 +178,7 @@ as metadata of the extension. Metadata keys currently recognized are:
* The core logic of the extension is parallelly executable during
the reading phase.
* It has event handlers for :event:`env-merge-info` and
:event:`env-purge-doc` events if it stores dataa to the build
:event:`env-purge-doc` events if it stores data to the build
environment object (env) during the reading phase.
* ``'parallel_write_safe'``: a boolean that specifies if parallel writing of

View File

@ -35,3 +35,4 @@ to configure their settings appropriately.
.. module:: sphinx.parsers
.. autoclass:: Parser
:members:

View File

@ -350,19 +350,3 @@ The following notes may be helpful if you want to create Texinfo files:
scheme ``info``. For example::
info:Texinfo#makeinfo_options
- Inline markup
The standard formatting for ``*strong*`` and ``_emphasis_`` can
result in ambiguous output when used to markup parameter names and
other values. Since this is a fairly common practice, the default
formatting has been changed so that ``emphasis`` and ``strong`` are
now displayed like ```literal'``\s.
The standard formatting can be re-enabled by adding the following to
your :file:`conf.py`::
texinfo_elements = {'preamble': """
@definfoenclose strong,*,*
@definfoenclose emph,_,_
"""}

View File

@ -252,17 +252,19 @@ locales. The translations are kept as gettext ``.po`` files translated from the
master template :file:`sphinx/locale/sphinx.pot`.
Sphinx uses `Babel <https://babel.pocoo.org/en/latest/>`_ to extract messages
and maintain the catalog files. It is integrated in ``setup.py``:
and maintain the catalog files. The ``utils`` directory contains a helper
script, ``babel_runner.py``.
* Use ``python setup.py extract_messages`` to update the ``.pot`` template.
* Use ``python setup.py update_catalog`` to update all existing language
* Use ``python babel_runner.py extract`` to update the ``.pot`` template.
* Use ``python babel_runner.py update`` to update all existing language
catalogs in ``sphinx/locale/*/LC_MESSAGES`` with the current messages in the
template file.
* Use ``python setup.py compile_catalog`` to compile the ``.po`` files to binary
* Use ``python babel_runner.py compile`` to compile the ``.po`` files to binary
``.mo`` files and ``.js`` files.
When an updated ``.po`` file is submitted, run compile_catalog to commit both
the source and the compiled catalogs.
When an updated ``.po`` file is submitted, run
``python babel_runner.py compile`` to commit both the source and the compiled
catalogs.
When a new locale is submitted, add a new directory with the ISO 639-1 language
identifier and put ``sphinx.po`` in there. Don't forget to update the possible
@ -273,9 +275,9 @@ The Sphinx core messages can also be translated on `Transifex
which is provided by the ``transifex_client`` Python package, can be used to
pull translations in ``.po`` format from Transifex. To do this, go to
``sphinx/locale`` and then run ``tx pull -f -l LANG`` where ``LANG`` is an
existing language identifier. It is good practice to run ``python setup.py
update_catalog`` afterwards to make sure the ``.po`` file has the canonical
Babel formatting.
existing language identifier. It is good practice to run
``python babel_runner.py update`` afterwards to make sure the ``.po`` file has the
canonical Babel formatting.
Debugging tips

View File

@ -100,6 +100,27 @@ But you can also explicitly enable the pending ones using e.g.
``PYTHONWARNINGS=default`` (see the :ref:`Python docs on configuring warnings
<python:describing-warning-filters>`) for more details.
Python version support policy
-----------------------------
The minimum Python version Sphinx supports is the default Python version
installed in the oldest `Long Term Support version of
Ubuntu <https://ubuntu.com/about/release-cycle>`_ that has standard support.
For example, as of July 2021, Ubuntu 16.04 has just entered extended
security maintenance (therefore, it doesn't count as standard support) and
the oldest LTS release to consider is Ubuntu 18.04 LTS, supported until
April 2023 and shipping Python 3.6.
This is a summary table with the current policy:
========== ========= ======
Date Ubuntu Python
========== ========= ======
April 2021 18.04 LTS 3.6+
---------- --------- ------
April 2023 20.04 LTS 3.8+
========== ========= ======
Release procedures
------------------

View File

@ -304,6 +304,22 @@ variables to customize behavior:
Additional options for :program:`sphinx-build`. These options can
also be set via the shortcut variable **O** (capital 'o').
.. describe:: NO_COLOR
When set (regardless of value), :program:`sphinx-build` will not use color
in terminal output. ``NO_COLOR`` takes precedence over ``FORCE_COLOR``. See
`no-color.org <https://no-color.org/>`__ for other libraries supporting this
community standard.
.. versionadded:: 4.5.0
.. describe:: FORCE_COLOR
When set (regardless of value), :program:`sphinx-build` will use color in
terminal output. ``NO_COLOR`` takes precedence over ``FORCE_COLOR``.
.. versionadded:: 4.5.0
.. _when-deprecation-warnings-are-displayed:
Deprecation Warnings

View File

@ -4,10 +4,9 @@ Automatic documentation generation from code
In the :ref:`previous section <tutorial-describing-objects>` of the tutorial
you manually documented a Python function in Sphinx. However, the description
was out of sync with the code itself, since the function signature was not
the same. Besides, it would be nice to reuse `Python
docstrings <https://www.python.org/dev/peps/pep-0257/#what-is-a-docstring>`_
in the documentation, rather than having to write the information in two
places.
the same. Besides, it would be nice to reuse :pep:`Python docstrings
<257#what-is-a-docstring>` in the documentation, rather than having to write
the information in two places.
Fortunately, :doc:`the autodoc extension </usage/extensions/autodoc>` provides this
functionality.

View File

@ -57,7 +57,7 @@ Notice several things:
- Sphinx parsed the argument of the ``.. py:function`` directive and
highlighted the module, the function name, and the parameters appropriately.
- The directive content includes a one-line description of the function,
as well as a :ref:`info field list <info-field-lists>` containing the function
as well as an :ref:`info field list <info-field-lists>` containing the function
parameter, its expected type, the return value, and the return type.
.. note::

View File

@ -68,6 +68,24 @@ be translated you need to follow these instructions:
* Run your desired build.
In order to protect against mistakes, a warning is emitted if
cross-references in the translated paragraph do not match those from the
original. This can be turned off globally using the
:confval:`suppress_warnings` configuration variable. Alternatively, to
turn it off for one message only, end the message with ``#noqa`` like
this::
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse
risus tortor, luctus id ultrices at. #noqa
(Write ``\#noqa`` in case you want to have "#noqa" literally in the
text. This does not apply to code blocks, where ``#noqa`` is ignored
because code blocks do not contain references anyway.)
.. versionadded:: 4.5
The ``#noqa`` mechanism.
Translating with sphinx-intl
----------------------------

View File

@ -6,6 +6,10 @@ Setuptools integration
Sphinx supports integration with setuptools and distutils through a custom
command - :class:`~sphinx.setup_command.BuildDoc`.
.. deprecated:: 5.0
This feature will be removed in v7.0.
Using setuptools integration
----------------------------

View File

@ -316,7 +316,11 @@ General configuration
* ``app.add_role``
* ``app.add_generic_role``
* ``app.add_source_parser``
* ``autosectionlabel.*``
* ``download.not_readable``
* ``epub.unknown_project_files``
* ``epub.duplicated_toc_entry``
* ``i18n.inconsistent_references``
* ``image.not_readable``
* ``ref.term``
* ``ref.ref``
@ -332,11 +336,9 @@ General configuration
* ``toc.excluded``
* ``toc.not_readable``
* ``toc.secnum``
* ``epub.unknown_project_files``
* ``epub.duplicated_toc_entry``
* ``autosectionlabel.*``
You can choose from these types.
You can choose from these types. You can also give only the first
component to exclude all warnings attached to it.
Now, this option should be considered *experimental*.
@ -366,6 +368,10 @@ General configuration
Added ``toc.excluded`` and ``toc.not_readable``
.. versionadded:: 4.5
Added ``i18n.inconsistent_references``
.. confval:: needs_sphinx
If set to a ``major.minor`` version string like ``'1.1'``, Sphinx will
@ -392,7 +398,7 @@ General configuration
.. confval:: manpages_url
A URL to cross-reference :rst:role:`manpage` directives. If this is
A URL to cross-reference :rst:role:`manpage` roles. If this is
defined to ``https://manpages.debian.org/{path}``, the
:literal:`:manpage:`man(1)`` role will link to
<https://manpages.debian.org/man(1)>. The patterns available are:
@ -546,7 +552,7 @@ General configuration
make latex O="-D smartquotes_action="
This can follow some ``make html`` with no problem, in contrast to the
situation from the prior note. It requires Docutils 0.14 or later.
situation from the prior note.
.. versionadded:: 1.6.6

View File

@ -41,7 +41,7 @@ you can also enable the :mod:`napoleon <sphinx.ext.napoleon>` extension.
docstrings to correct reStructuredText before :mod:`autodoc` processes them.
.. _Google: https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings
.. _NumPy: https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
.. _NumPy: https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard
Directives
@ -266,6 +266,10 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
``__str__`` will be documented as in the past, but other special method
that are not implemented in your class ``Foo``.
Since v5.0, it can take a comma separated list of ancestor classes. It
allows to suppress inherited members of several classes on the module at
once by specifying the option to :rst:dir:`automodule` directive.
Note: this will lead to markup errors if the inherited members come from a
module whose docstrings are not reST formatted.
@ -275,6 +279,10 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
It takes an ancestor class name as an argument.
.. versionchanged:: 5.0
It takes a comma separated list of ancestor class names.
* It's possible to override the signature for explicitly documented callable
objects (functions, methods, classes) with the regular syntax that will
override the signature gained from introspection::
@ -468,7 +476,7 @@ There are also config values that you can set:
.. confval:: autodoc_class_signature
This value selects how the signautre will be displayed for the class defined
This value selects how the signature will be displayed for the class defined
by :rst:dir:`autoclass` directive. The possible values are:
``"mixed"``
@ -626,16 +634,24 @@ There are also config values that you can set:
When set to ``"documented"``, types will only be documented for a parameter
or a return value that is already documented by the docstring.
With ``"documented_params"``, parameter types will only be annotated if the
parameter is documented in the docstring. The return type is always
annotated (except if it is ``None``).
.. versionadded:: 4.0
.. versionadded:: 5.0
New option ``'documented_params'`` is added.
.. confval:: autodoc_type_aliases
A dictionary for users defined `type aliases`__ that maps a type name to the
full-qualified object name. It is used to keep type aliases not evaluated in
the document. Defaults to empty (``{}``).
The type aliases are only available if your program enables `Postponed
Evaluation of Annotations (PEP 563)`__ feature via ``from __future__ import
The type aliases are only available if your program enables :pep:`Postponed
Evaluation of Annotations (PEP 563) <563>` feature via ``from __future__ import
annotations``.
For example, there is code using a type alias::
@ -662,7 +678,6 @@ There are also config values that you can set:
...
.. __: https://www.python.org/dev/peps/pep-0563/
.. __: https://mypy.readthedocs.io/en/latest/kinds_of_types.html#type-aliases
.. versionadded:: 3.3
@ -672,12 +687,15 @@ There are also config values that you can set:
following values:
* ``'fully-qualified'`` -- Show the module name and its name of typehints
(default)
* ``'short'`` -- Suppress the leading module names of the typehints
(ex. ``io.StringIO`` -> ``StringIO``)
(ex. ``io.StringIO`` -> ``StringIO``) (default)
.. versionadded:: 4.4
.. versionchanged:: 5.0
The default setting was changed to ``'short'``
.. confval:: autodoc_preserve_defaults
If True, the default argument values of functions will be not evaluated on

View File

@ -93,8 +93,8 @@ a comma-separated list of group names.
* ``<``, ``>``: Exclusive ordered comparison clause
* ``===``: Arbitrary equality clause.
``pyversion`` option is followed `PEP-440: Version Specifiers
<https://www.python.org/dev/peps/pep-0440/#version-specifiers>`__.
``pyversion`` option is followed :pep:`PEP-440: Version Specifiers
<440#version-specifiers>`.
.. versionadded:: 1.6

View File

@ -45,7 +45,7 @@ on the first line, separated by a colon.
def function_with_types_in_docstring(param1, param2):
"""Example function with types documented in the docstring.
`PEP 484`_ type annotations are supported. If attribute, parameter, and
:pep:`484` type annotations are supported. If attribute, parameter, and
return types are annotated according to `PEP 484`_, they do not need to be
included in the docstring:
@ -55,10 +55,6 @@ def function_with_types_in_docstring(param1, param2):
Returns:
bool: The return value. True for success, False otherwise.
.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/
"""
@ -311,4 +307,4 @@ class ExamplePEP526Class:
"""
attr1: str
attr2: int
attr2: int

View File

@ -37,8 +37,8 @@ module_level_variable1 : int
with it.
.. _NumPy Documentation HOWTO:
https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt
.. _NumPy docstring standard:
https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard
"""
@ -55,7 +55,7 @@ on the first line, separated by a colon.
def function_with_types_in_docstring(param1, param2):
"""Example function with types documented in the docstring.
`PEP 484`_ type annotations are supported. If attribute, parameter, and
:pep:`484` type annotations are supported. If attribute, parameter, and
return types are annotated according to `PEP 484`_, they do not need to be
included in the docstring:
@ -70,10 +70,6 @@ def function_with_types_in_docstring(param1, param2):
-------
bool
True if successful, False otherwise.
.. _PEP 484:
https://www.python.org/dev/peps/pep-0484/
"""

View File

@ -59,3 +59,11 @@ The extension adds a config value:
Since links are generated from the role in the reading stage, they appear as
ordinary links to e.g. the ``linkcheck`` builder.
.. confval:: extlinks_detect_hardcoded_links
If enabled, extlinks emits a warning if a hardcoded link is replaceable
by an extlink, and suggests a replacement via warning. It defaults to
``False``.
.. versionadded:: 4.5

View File

@ -157,6 +157,10 @@ linking:
.. versionadded:: 4.3
.. versionchanged:: 5.0
Changed default value from an empty list to ``['std:doc']``.
A list of strings being either:
- the name of a specific reference type in a domain,
@ -165,7 +169,7 @@ linking:
``std:*``, ``py:*``, or ``cpp:*``, or
- simply a wildcard ``*``.
The default value is an empty list.
The default value is ``['std:doc']``.
When a non-:rst:role:`external` cross-reference is being resolved by
intersphinx, skip resolution if it matches one of the specifications in this

View File

@ -26,7 +26,7 @@ Are you tired of writing docstrings that look like this::
:rtype: BufferedFileStorage
`reStructuredText`_ is great, but it creates visually dense, hard to read
`docstrings`_. Compare the jumble above to the same thing rewritten
:pep:`docstrings <287>`. Compare the jumble above to the same thing rewritten
according to the `Google Python Style Guide`_::
Args:
@ -50,11 +50,10 @@ the documentation, so it doesn't modify any of the docstrings in your actual
source code files.
.. _ReStructuredText: https://docutils.sourceforge.io/rst.html
.. _docstrings: https://www.python.org/dev/peps/pep-0287/
.. _Google Python Style Guide:
https://google.github.io/styleguide/pyguide.html
.. _Google:
https://google.github.io/styleguide/pyguide.html#Comments
https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings
.. _NumPy:
https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard
.. _Khan Academy:
@ -199,11 +198,11 @@ not be mixed. Choose one style for your project and be consistent with it.
Type Annotations
~~~~~~~~~~~~~~~~
`PEP 484`_ introduced a standard way to express types in Python code.
:pep:`484` introduced a standard way to express types in Python code.
This is an alternative to expressing types directly in docstrings.
One benefit of expressing types according to `PEP 484`_ is that
One benefit of expressing types according to :pep:`484` is that
type checkers and IDEs can take advantage of them for static code
analysis. `PEP 484`_ was then extended by `PEP 526`_ which introduced
analysis. :pep:`484` was then extended by :pep:`526` which introduced
a similar way to annotate variables (and attributes).
Google style with Python 3 type annotations::
@ -267,9 +266,7 @@ Google style with types in docstrings::
`Python 2/3 compatible annotations`_ aren't currently
supported by Sphinx and won't show up in the docs.
.. _PEP 484: https://www.python.org/dev/peps/pep-0484/
.. _PEP 526: https://www.python.org/dev/peps/pep-0526/
.. _Python 2/3 compatible annotations: https://www.python.org/dev/peps/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code
.. _Python 2/3 compatible annotations: https://peps.python.org/pep-0484/#suggested-syntax-for-python-2-7-and-straddling-code
Configuration
@ -301,7 +298,7 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
napoleon_attr_annotations = True
.. _Google style:
https://google.github.io/styleguide/pyguide.html
https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings
.. _NumPy style:
https://numpydoc.readthedocs.io/en/latest/format.html#docstring-standard
@ -548,7 +545,7 @@ sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
.. confval:: napoleon_attr_annotations
True to allow using `PEP 526`_ attributes annotations in classes.
True to allow using :pep:`526` attributes annotations in classes.
If an attribute is documented in the docstring without a type and
has an annotation in the class body, that type is used.

View File

@ -222,8 +222,8 @@ of images:
- `sphinxdoc/sphinx-latexpdf`_
.. _Docker Hub: https://hub.docker.com/
.. _sphinxdoc/sphinx: https://hub.docker.com/repository/docker/sphinxdoc/sphinx
.. _sphinxdoc/sphinx-latexpdf: https://hub.docker.com/repository/docker/sphinxdoc/sphinx-latexpdf
.. _sphinxdoc/sphinx: https://hub.docker.com/r/sphinxdoc/sphinx
.. _sphinxdoc/sphinx-latexpdf: https://hub.docker.com/r/sphinxdoc/sphinx-latexpdf
Former one is used for standard usage of Sphinx, and latter one is mainly used for
PDF builds using LaTeX. Please choose one for your purpose.
@ -243,7 +243,7 @@ PDF builds using LaTeX. Please choose one for your purpose.
$ docker run -it --rm -v /path/to/document:/docs sphinxdoc/sphinx sphinx-quickstart
And you can following command this to build HTML document:
And you can use the following command to build HTML document:
.. code-block:: console
@ -251,7 +251,7 @@ PDF builds using LaTeX. Please choose one for your purpose.
For more details, please read `README file`__ of docker images.
.. __: https://hub.docker.com/repository/docker/sphinxdoc/sphinx
.. __: https://hub.docker.com/r/sphinxdoc/sphinx
Installation from source

View File

@ -499,8 +499,10 @@ __ https://pygments.org/docs/lexers
The directive's alias name :rst:dir:`sourcecode` works as well. This
directive takes a language name as an argument. It can be `any lexer alias
supported by Pygments <https://pygments.org/docs/lexers/>`_. If it is not
given, the setting of :rst:dir:`highlight` directive will be used.
If not set, :confval:`highlight_language` will be used.
given, the setting of :rst:dir:`highlight` directive will be used. If not
set, :confval:`highlight_language` will be used. To display a code example
*inline* within other text, rather than as a separate block, you can use the
:rst:role:`code` role instead.
.. versionchanged:: 2.0
The ``language`` argument becomes optional.

View File

@ -211,6 +211,12 @@ The following directives are provided for module and class contents:
.. versionadded:: 4.0
.. rst::directive:option:: module
:type: text
Describe the location where the object is defined. The default value is
the module specified by :rst:dir:`py:currentmodule`.
.. rst:directive:: .. py:data:: name
Describes global data in a module, including both variables and values used
@ -237,6 +243,12 @@ The following directives are provided for module and class contents:
.. versionadded:: 4.0
.. rst::directive:option:: module
:type: text
Describe the location where the object is defined. The default value is
the module specified by :rst:dir:`py:currentmodule`.
.. rst:directive:: .. py:exception:: name
Describes an exception class. The signature can, but need not include
@ -251,6 +263,12 @@ The following directives are provided for module and class contents:
.. versionadded:: 3.1
.. rst::directive:option:: module
:type: text
Describe the location where the object is defined. The default value is
the module specified by :rst:dir:`py:currentmodule`.
.. rst:directive:: .. py:class:: name
.. py:class:: name(parameters)
@ -291,6 +309,12 @@ The following directives are provided for module and class contents:
.. versionadded:: 3.1
.. rst::directive:option:: module
:type: text
Describe the location where the object is defined. The default value is
the module specified by :rst:dir:`py:currentmodule`.
.. rst:directive:: .. py:attribute:: name
Describes an object data attribute. The description should include
@ -317,6 +341,12 @@ The following directives are provided for module and class contents:
.. versionadded:: 4.0
.. rst::directive:option:: module
:type: text
Describe the location where the object is defined. The default value is
the module specified by :rst:dir:`py:currentmodule`.
.. rst:directive:: .. py:property:: name
Describes an object property.
@ -340,6 +370,12 @@ The following directives are provided for module and class contents:
.. rst:directive:option:: type: type of the property
:type: text
.. rst::directive:option:: module
:type: text
Describe the location where the object is defined. The default value is
the module specified by :rst:dir:`py:currentmodule`.
.. rst:directive:: .. py:method:: name(parameters)
Describes an object method. The parameters should not include the ``self``
@ -385,6 +421,12 @@ The following directives are provided for module and class contents:
.. versionadded:: 3.1
.. rst::directive:option:: module
:type: text
Describe the location where the object is defined. The default value is
the module specified by :rst:dir:`py:currentmodule`.
.. rst:directive:option:: property
:type: no value

View File

@ -276,6 +276,34 @@ The following role creates a cross-reference to a term in a
If you use a term that's not explained in a glossary, you'll get a warning
during build.
Inline code highlighting
------------------------
.. rst:role:: code
An *inline* code example. When used directly, this role just displays the
text *without* syntax highlighting, as a literal.
.. code-block:: rst
By default, inline code such as :code:`1 + 2` just displays without
highlighting.
Unlike the :rst:dir:`code-block` directive, this role does not respect the
default language set by the :rst:dir:`highlight` directive.
To enable syntax highlighting, you must first use the ``role`` directive to
define a custom ``code`` role for a particular language:
.. code-block:: rst
.. role:: python(code)
:language: python
In Python, :python:`1 + 2` is equal to :python:`3`.
To display a multi-line code example, use the :rst:dir:`code-block` directive
instead.
Math
----

View File

@ -15,8 +15,6 @@ module.exports = function(config) {
// list of files / patterns to load in the browser
files: [
'sphinx/themes/basic/static/underscore.js',
'sphinx/themes/basic/static/jquery.js',
'sphinx/themes/basic/static/doctools.js',
'sphinx/themes/basic/static/searchtools.js',
'tests/js/*.js'
@ -59,7 +57,7 @@ module.exports = function(config) {
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome', 'Firefox'],
browsers: ["Firefox"],
// Continuous Integration mode

1637
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,9 +12,8 @@
},
"devDependencies": {
"jasmine-core": "^3.4.0",
"karma": "^6.3.14",
"karma-chrome-launcher": "^3.0.0",
"karma-firefox-launcher": "^1.1.0",
"karma-jasmine": "^2.0.0"
"karma": "^6.3.16",
"karma-firefox-launcher": "^2.0.0",
"karma-jasmine": "^4.0.0"
}
}

View File

@ -1,5 +1,5 @@
[metadata]
license_file = LICENSE
license_files = LICENSE
[egg_info]
tag_build = .dev
@ -9,23 +9,6 @@ tag_date = true
release = egg_info -Db ''
upload = upload --sign --identity=36580288
[build_sphinx]
warning-is-error = 1
[extract_messages]
mapping_file = babel.cfg
output_file = sphinx/locale/sphinx.pot
keywords = _ __ l_ lazy_gettext
[update_catalog]
input_file = sphinx/locale/sphinx.pot
domain = sphinx
output_dir = sphinx/locale/
[compile_catalog]
domain = sphinx
directory = sphinx/locale/
[flake8]
max-line-length = 95
ignore = E116,E241,E251,E741,W504,I101
@ -35,12 +18,6 @@ import-order-style = smarkets
per-file-ignores =
tests/*: E501
[flake8:local-plugins]
extension =
X101 = utils.checks:sphinx_has_header
paths =
.
[isort]
line_length = 95

126
setup.py
View File

@ -1,12 +1,10 @@
import os
import sys
from io import StringIO
from setuptools import find_packages, setup
import sphinx
with open('README.rst') as f:
with open('README.rst', encoding='utf-8') as f:
long_desc = f.read()
if sys.version_info < (3, 6):
@ -22,7 +20,7 @@ install_requires = [
'sphinxcontrib-qthelp',
'Jinja2>=2.3',
'Pygments>=2.0',
'docutils>=0.14,<0.18',
'docutils>=0.14,<0.19',
'snowballstemmer>=1.1',
'babel>=1.3',
'alabaster>=0.7,<0.8',
@ -43,134 +41,19 @@ extras_require = {
'lint': [
'flake8>=3.5.0',
'isort',
'mypy>=0.931',
'mypy>=0.950',
'docutils-stubs',
"types-typed-ast",
"types-requests",
],
'test': [
'pytest',
'pytest-cov',
'pytest>=4.6',
'html5lib',
"typed_ast; python_version < '3.8'",
'cython',
],
}
# Provide a "compile_catalog" command that also creates the translated
# JavaScript files if Babel is available.
cmdclass = {}
class Tee:
def __init__(self, stream):
self.stream = stream
self.buffer = StringIO()
def write(self, s):
self.stream.write(s)
self.buffer.write(s)
def flush(self):
self.stream.flush()
try:
from json import dump
from babel.messages.frontend import compile_catalog
from babel.messages.pofile import read_po
except ImportError:
pass
else:
class compile_catalog_plusjs(compile_catalog):
"""
An extended command that writes all message strings that occur in
JavaScript files to a JavaScript file along with the .mo file.
Unfortunately, babel's setup command isn't built very extensible, so
most of the run() code is duplicated here.
"""
def run(self):
try:
sys.stderr = Tee(sys.stderr)
compile_catalog.run(self)
finally:
if sys.stderr.buffer.getvalue():
print("Compiling failed.")
sys.exit(1)
if isinstance(self.domain, list):
for domain in self.domain:
self._run_domain_js(domain)
else:
self._run_domain_js(self.domain)
def _run_domain_js(self, domain):
po_files = []
js_files = []
if not self.input_file:
if self.locale:
po_files.append((self.locale,
os.path.join(self.directory, self.locale,
'LC_MESSAGES',
domain + '.po')))
js_files.append(os.path.join(self.directory, self.locale,
'LC_MESSAGES',
domain + '.js'))
else:
for locale in os.listdir(self.directory):
po_file = os.path.join(self.directory, locale,
'LC_MESSAGES',
domain + '.po')
if os.path.exists(po_file):
po_files.append((locale, po_file))
js_files.append(os.path.join(self.directory, locale,
'LC_MESSAGES',
domain + '.js'))
else:
po_files.append((self.locale, self.input_file))
if self.output_file:
js_files.append(self.output_file)
else:
js_files.append(os.path.join(self.directory, self.locale,
'LC_MESSAGES',
domain + '.js'))
for js_file, (locale, po_file) in zip(js_files, po_files):
with open(po_file, encoding='utf8') as infile:
catalog = read_po(infile, locale)
if catalog.fuzzy and not self.use_fuzzy:
continue
self.log.info('writing JavaScript strings in catalog %r to %r',
po_file, js_file)
jscatalog = {}
for message in catalog:
if any(x[0].endswith(('.js', '.js_t', '.html'))
for x in message.locations):
msgid = message.id
if isinstance(msgid, (list, tuple)):
msgid = msgid[0]
jscatalog[msgid] = message.string
with open(js_file, 'wt', encoding='utf8') as outfile:
outfile.write('Documentation.addTranslations(')
dump({
'messages': jscatalog,
'plural_expr': catalog.plural_expr,
'locale': str(catalog.locale)
}, outfile, sort_keys=True, indent=4)
outfile.write(');')
cmdclass['compile_catalog'] = compile_catalog_plusjs
setup(
name='Sphinx',
version=sphinx.__version__,
@ -246,5 +129,4 @@ setup(
python_requires=">=3.6",
install_requires=install_requires,
extras_require=extras_require,
cmdclass=cmdclass,
)

View File

@ -1,12 +1,4 @@
"""
Sphinx
~~~~~~
The Sphinx documentation toolchain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The Sphinx documentation toolchain."""
# Keep this file executable as-is in Python 3!
# (Otherwise getting the version out of it from setup.py is impossible.)
@ -26,9 +18,11 @@ if 'PYTHONWARNINGS' not in os.environ:
# docutils.io using mode='rU' for open
warnings.filterwarnings('ignore', "'U' mode is deprecated",
DeprecationWarning, module='docutils.io')
warnings.filterwarnings('ignore', 'The frontend.Option class .*',
DeprecationWarning, module='docutils.frontend')
__version__ = '4.5.0+'
__released__ = '4.5.0' # used when Sphinx builds its own docs
__version__ = '5.0.0+'
__released__ = '5.0.0' # used when Sphinx builds its own docs
#: Version info for better programmatic use.
#:
@ -38,7 +32,7 @@ __released__ = '4.5.0' # used when Sphinx builds its own docs
#:
#: .. versionadded:: 1.2
#: Before version 1.2, check the string ``sphinx.__version__``.
version_info = (4, 5, 0, 'beta', 0)
version_info = (5, 0, 0, 'final', 0)
package_dir = path.abspath(path.dirname(__file__))

View File

@ -1,12 +1,4 @@
"""
sphinx.__main__
~~~~~~~~~~~~~~~
The Sphinx documentation toolchain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The Sphinx documentation toolchain."""
import sys

View File

@ -1,15 +1,8 @@
"""
sphinx.addnodes
~~~~~~~~~~~~~~~
Additional docutils nodes.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Additional docutils nodes."""
from typing import TYPE_CHECKING, Any, Dict, List, Sequence
import docutils
from docutils import nodes
from docutils.nodes import Element
@ -36,7 +29,6 @@ class document(nodes.document):
def set_id(self, node: Element, msgnode: Element = None,
suggested_prefix: str = '') -> str:
from sphinx.util import docutils
if docutils.__version_info__ >= (0, 16):
ret = super().set_id(node, msgnode, suggested_prefix) # type: ignore
else:
@ -535,8 +527,6 @@ class manpage(nodes.Inline, nodes.FixedTextElement):
def setup(app: "Sphinx") -> Dict[str, Any]:
from sphinx.util import docutils # lazy import
app.add_node(toctree)
app.add_node(desc)

View File

@ -1,13 +1,6 @@
"""
sphinx.application
~~~~~~~~~~~~~~~~~~
"""Sphinx application class and extensibility interface.
Sphinx application class and extensibility interface.
Gracefully adapted from the TextPress system by Armin.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
Gracefully adapted from the TextPress system by Armin.
"""
import os
@ -266,7 +259,7 @@ class Sphinx:
"""Load translated strings from the configured localedirs if enabled in
the configuration.
"""
if self.config.language is None:
if self.config.language == 'en':
self.translator, has_translation = locale.init([], None)
else:
logger.info(bold(__('loading translations [%s]... ') % self.config.language),
@ -285,8 +278,7 @@ class Sphinx:
locale_dirs += [path.join(package_dir, 'locale')]
self.translator, has_translation = locale.init(locale_dirs, self.config.language)
if has_translation or self.config.language == 'en':
# "en" never needs to be translated
if has_translation:
logger.info(__('done'))
else:
logger.info(__('not available for built-in messages'))

View File

@ -1,13 +1,6 @@
"""
sphinx.builders
~~~~~~~~~~~~~~~
Builder superclass for all builders.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Builder superclass for all builders."""
import codecs
import pickle
import time
from os import path
@ -22,9 +15,9 @@ from sphinx.environment import CONFIG_CHANGED_REASON, CONFIG_OK, BuildEnvironmen
from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.errors import SphinxError
from sphinx.events import EventManager
from sphinx.io import read_doc
from sphinx.locale import __
from sphinx.util import import_object, logging, progress_message, rst, status_iterator
from sphinx.util import (UnicodeDecodeErrorHandler, get_filetype, import_object, logging,
progress_message, rst, status_iterator)
from sphinx.util.build_phase import BuildPhase
from sphinx.util.console import bold # type: ignore
from sphinx.util.docutils import sphinx_domains
@ -472,8 +465,21 @@ class Builder:
if path.isfile(docutilsconf):
self.env.note_dependency(docutilsconf)
filename = self.env.doc2path(docname)
filetype = get_filetype(self.app.config.source_suffix, filename)
publisher = self.app.registry.get_publisher(self.app, filetype)
with sphinx_domains(self.env), rst.default_role(docname, self.config.default_role):
doctree = read_doc(self.app, self.env, self.env.doc2path(docname))
# set up error_handler for the target document
codecs.register_error('sphinx', UnicodeDecodeErrorHandler(docname)) # type: ignore
publisher.set_source(source_path=filename)
publisher.publish()
doctree = publisher.document
# The settings object is reused by the Publisher for each document.
# Becuase we modify the settings object in ``write_doctree``, we
# need to ensure that each doctree has an independent copy.
doctree.settings = doctree.settings.copy()
# store time of reading, for outdated files detection
# (Some filesystems have coarse timestamp resolution;

View File

@ -1,12 +1,4 @@
"""
sphinx.builders._epub_base
~~~~~~~~~~~~~~~~~~~~~~~~~~
Base class of epub2/epub3 builders.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Base class of epub2/epub3 builders."""
import html
import os
@ -491,7 +483,7 @@ class EpubBuilder(StandaloneHTMLBuilder):
metadata['copyright'] = html.escape(self.config.epub_copyright)
metadata['scheme'] = html.escape(self.config.epub_scheme)
metadata['id'] = html.escape(self.config.epub_identifier)
metadata['date'] = html.escape(format_date("%Y-%m-%d"))
metadata['date'] = html.escape(format_date("%Y-%m-%d", language='en'))
metadata['manifest_items'] = []
metadata['spines'] = []
metadata['guides'] = []

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.changes
~~~~~~~~~~~~~~~~~~~~~~~
Changelog builder.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Changelog builder."""
import html
from os import path

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.dirhtml
~~~~~~~~~~~~~~~~~~~~~~~
Directory HTML builders.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Directory HTML builders."""
from os import path
from typing import Any, Dict

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.dummy
~~~~~~~~~~~~~~~~~~~~~
Do syntax checks, but no writing.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Do syntax checks, but no writing."""
from typing import Any, Dict, Set

View File

@ -1,12 +1,6 @@
"""
sphinx.builders.epub3
~~~~~~~~~~~~~~~~~~~~~
"""Build epub3 files.
Build epub3 files.
Originally derived from epub.py.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
Originally derived from epub.py.
"""
import html
@ -94,7 +88,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
metadata['contributor'] = html.escape(self.config.epub_contributor)
metadata['page_progression_direction'] = PAGE_PROGRESSION_DIRECTIONS.get(writing_mode)
metadata['ibook_scroll_axis'] = IBOOK_SCROLL_AXIS.get(writing_mode)
metadata['date'] = html.escape(format_date("%Y-%m-%dT%H:%M:%SZ"))
metadata['date'] = html.escape(format_date("%Y-%m-%dT%H:%M:%SZ", language='en'))
metadata['version'] = html.escape(self.config.version)
metadata['epub_version'] = self.config.epub_version
return metadata

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.gettext
~~~~~~~~~~~~~~~~~~~~~~~
The MessageCatalogBuilder class.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The MessageCatalogBuilder class."""
from codecs import open
from collections import OrderedDict, defaultdict

View File

@ -1,25 +1,19 @@
"""
sphinx.builders.html
~~~~~~~~~~~~~~~~~~~~
Several HTML builders.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Several HTML builders."""
import html
import os
import posixpath
import re
import sys
import warnings
from datetime import datetime
from os import path
from typing import IO, Any, Dict, Iterable, Iterator, List, Set, Tuple, Type
from typing import IO, Any, Dict, Iterable, Iterator, List, Optional, Set, Tuple, Type
from urllib.parse import quote
import docutils.readers.doctree
from docutils import nodes
from docutils.core import publish_parts
from docutils.core import Publisher
from docutils.frontend import OptionParser
from docutils.io import DocTreeInput, StringOutput
from docutils.nodes import Node
@ -30,6 +24,7 @@ from sphinx import version_info as sphinx_version
from sphinx.application import Sphinx
from sphinx.builders import Builder
from sphinx.config import ENUM, Config
from sphinx.deprecation import RemovedInSphinx70Warning, deprecated_alias
from sphinx.domains import Domain, Index, IndexEntry
from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.environment.adapters.indexentries import IndexEntries
@ -40,7 +35,7 @@ from sphinx.locale import _, __
from sphinx.search import js_index
from sphinx.theming import HTMLThemeFactory
from sphinx.util import isurl, logging, md5, progress_message, status_iterator
from sphinx.util.docutils import is_html5_writer_available, new_document
from sphinx.util.docutils import new_document
from sphinx.util.fileutil import copy_asset
from sphinx.util.i18n import format_date
from sphinx.util.inventory import InventoryFile
@ -48,13 +43,7 @@ from sphinx.util.matching import DOTFILES, Matcher, patmatch
from sphinx.util.osutil import copyfile, ensuredir, os_path, relative_uri
from sphinx.util.tags import Tags
from sphinx.writers.html import HTMLTranslator, HTMLWriter
# HTML5 Writer is available or not
if is_html5_writer_available():
from sphinx.writers.html5 import HTML5Translator
html5_ready = True
else:
html5_ready = False
from sphinx.writers.html5 import HTML5Translator
#: the filename for the inventory of objects
INVENTORY_FILENAME = 'objects.inv'
@ -76,6 +65,17 @@ def get_stable_hash(obj: Any) -> str:
return md5(str(obj).encode()).hexdigest()
def convert_locale_to_language_tag(locale: Optional[str]) -> Optional[str]:
"""Convert a locale string to a language tag (ex. en_US -> en-US).
refs: BCP 47 (:rfc:`5646`)
"""
if locale:
return locale.replace('_', '-')
else:
return None
class Stylesheet(str):
"""A metadata of stylesheet.
@ -208,6 +208,19 @@ class StandaloneHTMLBuilder(Builder):
# JS files
self.script_files: List[JavaScript] = []
# Cached Publisher for writing doctrees to HTML
reader = docutils.readers.doctree.Reader(parser_name='restructuredtext')
pub = Publisher(
reader=reader,
parser=reader.parser,
writer=HTMLWriter(self),
source_class=DocTreeInput,
destination=StringOutput(encoding='unicode'),
)
op = pub.setup_option_parser(output_encoding='unicode', traceback=True)
pub.settings = op.get_default_values()
self._publisher = pub
def init(self) -> None:
self.build_info = self.create_build_info()
# basename of images directory
@ -315,8 +328,11 @@ class StandaloneHTMLBuilder(Builder):
self.script_files = []
self.add_js_file('documentation_options.js', id="documentation_options",
data_url_root='', priority=200)
# Remove frameworks and compatability module below in Sphinx 6.0
# xref RemovedInSphinx60Warning
self.add_js_file('jquery.js', priority=200)
self.add_js_file('underscore.js', priority=200)
self.add_js_file('_sphinx_javascript_frameworks_compat.js', priority=200)
self.add_js_file('doctools.js', priority=200)
for filename, attrs in self.app.registry.js_files:
@ -326,7 +342,7 @@ class StandaloneHTMLBuilder(Builder):
attrs.setdefault('priority', 800) # User's JSs are loaded after extensions'
self.add_js_file(filename, **attrs)
if self.config.language and self._get_translations_js():
if self._get_translations_js():
self.add_js_file('translations.js')
def add_js_file(self, filename: str, **kwargs: Any) -> None:
@ -337,7 +353,7 @@ class StandaloneHTMLBuilder(Builder):
@property
def default_translator_class(self) -> Type[nodes.NodeVisitor]: # type: ignore
if not html5_ready or self.config.html4_writer:
if self.config.html4_writer:
return HTMLTranslator
else:
return HTML5Translator
@ -364,7 +380,7 @@ class StandaloneHTMLBuilder(Builder):
def get_outdated_docs(self) -> Iterator[str]:
try:
with open(path.join(self.outdir, '.buildinfo')) as fp:
with open(path.join(self.outdir, '.buildinfo'), encoding="utf-8") as fp:
buildinfo = BuildInfo.load(fp)
if self.build_info != buildinfo:
@ -415,15 +431,12 @@ class StandaloneHTMLBuilder(Builder):
"""Utility: Render a lone doctree node."""
if node is None:
return {'fragment': ''}
doc = new_document('<partial node>')
doc.append(node)
writer = HTMLWriter(self)
return publish_parts(reader_name='doctree',
writer=writer,
source_class=DocTreeInput,
settings_overrides={'output_encoding': 'unicode'},
source=doc)
self._publisher.set_source(doc)
self._publisher.publish()
return self._publisher.writer.parts
def prepare_writing(self, docnames: Set[str]) -> None:
# create the search indexer
@ -431,18 +444,20 @@ class StandaloneHTMLBuilder(Builder):
if self.search:
from sphinx.search import IndexBuilder
lang = self.config.html_search_language or self.config.language
if not lang:
lang = 'en'
self.indexer = IndexBuilder(self.env, lang,
self.config.html_search_options,
self.config.html_search_scorer)
self.load_indexer(docnames)
self.docwriter = HTMLWriter(self)
self.docsettings: Any = OptionParser(
defaults=self.env.settings,
components=(self.docwriter,),
read_config_files=True).get_default_values()
with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=DeprecationWarning)
# DeprecationWarning: The frontend.OptionParser class will be replaced
# by a subclass of argparse.ArgumentParser in Docutils 0.21 or later.
self.docsettings: Any = OptionParser(
defaults=self.env.settings,
components=(self.docwriter,),
read_config_files=True).get_default_values()
self.docsettings.compact_lists = bool(self.config.html_compact_lists)
# determine the additional indices to include
@ -517,7 +532,7 @@ class StandaloneHTMLBuilder(Builder):
'file_suffix': self.out_suffix,
'link_suffix': self.link_suffix,
'script_files': self.script_files,
'language': self.config.language,
'language': convert_locale_to_language_tag(self.config.language),
'css_files': self.css_files,
'sphinx_version': __display_version__,
'sphinx_version_tuple': sphinx_version,
@ -527,7 +542,7 @@ class StandaloneHTMLBuilder(Builder):
'parents': [],
'logo': logo,
'favicon': favicon,
'html5_doctype': html5_ready and not self.config.html4_writer,
'html5_doctype': not self.config.html4_writer,
}
if self.theme:
self.globalcontext.update(
@ -759,19 +774,20 @@ class StandaloneHTMLBuilder(Builder):
def create_pygments_style_file(self) -> None:
"""create a style file for pygments."""
with open(path.join(self.outdir, '_static', 'pygments.css'), 'w') as f:
with open(path.join(self.outdir, '_static', 'pygments.css'), 'w',
encoding="utf-8") as f:
f.write(self.highlighter.get_stylesheet())
if self.dark_highlighter:
with open(path.join(self.outdir, '_static', 'pygments_dark.css'), 'w') as f:
with open(path.join(self.outdir, '_static', 'pygments_dark.css'), 'w',
encoding="utf-8") as f:
f.write(self.dark_highlighter.get_stylesheet())
def copy_translation_js(self) -> None:
"""Copy a JavaScript file for translations."""
if self.config.language is not None:
jsfile = self._get_translations_js()
if jsfile:
copyfile(jsfile, path.join(self.outdir, '_static', 'translations.js'))
jsfile = self._get_translations_js()
if jsfile:
copyfile(jsfile, path.join(self.outdir, '_static', 'translations.js'))
def copy_stemmer_js(self) -> None:
"""Copy a JavaScript file for stemmer."""
@ -850,7 +866,7 @@ class StandaloneHTMLBuilder(Builder):
def write_buildinfo(self) -> None:
try:
with open(path.join(self.outdir, '.buildinfo'), 'w') as fp:
with open(path.join(self.outdir, '.buildinfo'), 'w', encoding="utf-8") as fp:
self.build_info.dump(fp)
except OSError as exc:
logger.warning(__('Failed to write build info file: %r'), exc)
@ -1305,6 +1321,12 @@ import sphinxcontrib.serializinghtml # NOQA
import sphinx.builders.dirhtml # NOQA
import sphinx.builders.singlehtml # NOQA
deprecated_alias('sphinx.builders.html',
{
'html5_ready': True,
},
RemovedInSphinx70Warning)
def setup(app: Sphinx) -> Dict[str, Any]:
# builders

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.html.transforms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Transforms for HTML builder.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Transforms for HTML builder."""
import re
from typing import Any, Dict, List

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.latex
~~~~~~~~~~~~~~~~~~~~~
LaTeX builder.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""LaTeX builder."""
import os
import warnings
@ -24,7 +16,6 @@ from sphinx.builders.latex.constants import ADDITIONAL_SETTINGS, DEFAULT_SETTING
from sphinx.builders.latex.theming import Theme, ThemeFactory
from sphinx.builders.latex.util import ExtBabel
from sphinx.config import ENUM, Config
from sphinx.deprecation import RemovedInSphinx50Warning
from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.errors import NoUri, SphinxError
from sphinx.locale import _, __
@ -172,9 +163,8 @@ class LaTeXBuilder(Builder):
self.context.update(ADDITIONAL_SETTINGS.get(self.config.latex_engine, {}))
# Add special settings for (latex_engine, language_code)
if self.config.language:
key = (self.config.latex_engine, self.config.language[:2])
self.context.update(ADDITIONAL_SETTINGS.get(key, {}))
key = (self.config.latex_engine, self.config.language[:2])
self.context.update(ADDITIONAL_SETTINGS.get(key, {}))
# Apply user settings to context
self.context.update(self.config.latex_elements)
@ -205,7 +195,7 @@ class LaTeXBuilder(Builder):
def init_babel(self) -> None:
self.babel = ExtBabel(self.config.language, not self.context['babel'])
if self.config.language and not self.babel.is_supported_language():
if not self.babel.is_supported_language():
# emit warning if specified language is invalid
# (only emitting, nothing changed to processing)
logger.warning(__('no Babel option known for language %r'),
@ -234,12 +224,11 @@ class LaTeXBuilder(Builder):
self.context['classoptions'] += ',' + self.babel.get_language()
# this branch is not taken for xelatex/lualatex if default settings
self.context['multilingual'] = self.context['babel']
if self.config.language:
self.context['shorthandoff'] = SHORTHANDOFF
self.context['shorthandoff'] = SHORTHANDOFF
# Times fonts don't work with Cyrillic languages
if self.babel.uses_cyrillic() and 'fontpkg' not in self.config.latex_elements:
self.context['fontpkg'] = ''
# Times fonts don't work with Cyrillic languages
if self.babel.uses_cyrillic() and 'fontpkg' not in self.config.latex_elements:
self.context['fontpkg'] = ''
elif self.context['polyglossia']:
self.context['classoptions'] += ',' + self.babel.get_language()
options = self.babel.get_mainlanguage_options()
@ -253,7 +242,7 @@ class LaTeXBuilder(Builder):
def write_stylesheet(self) -> None:
highlighter = highlighting.PygmentsBridge('latex', self.config.pygments_style)
stylesheet = path.join(self.outdir, 'sphinxhighlight.sty')
with open(stylesheet, 'w') as f:
with open(stylesheet, 'w', encoding="utf-8") as f:
f.write('\\NeedsTeXFormat{LaTeX2e}[1995/12/01]\n')
f.write('\\ProvidesPackage{sphinxhighlight}'
'[2016/05/29 stylesheet for highlighting with pygments]\n')
@ -262,10 +251,14 @@ class LaTeXBuilder(Builder):
def write(self, *ignored: Any) -> None:
docwriter = LaTeXWriter(self)
docsettings: Any = OptionParser(
defaults=self.env.settings,
components=(docwriter,),
read_config_files=True).get_default_values()
with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=DeprecationWarning)
# DeprecationWarning: The frontend.OptionParser class will be replaced
# by a subclass of argparse.ArgumentParser in Docutils 0.21 or later.
docsettings: Any = OptionParser(
defaults=self.env.settings,
components=(docwriter,),
read_config_files=True).get_default_values()
self.init_document_data()
self.write_stylesheet()
@ -359,9 +352,9 @@ class LaTeXBuilder(Builder):
newnodes: List[Node] = [nodes.emphasis(sectname, sectname)]
for subdir, title in self.titles:
if docname.startswith(subdir):
newnodes.append(nodes.Text(_(' (in '), _(' (in ')))
newnodes.append(nodes.Text(_(' (in ')))
newnodes.append(nodes.emphasis(title, title))
newnodes.append(nodes.Text(')', ')'))
newnodes.append(nodes.Text(')'))
break
else:
pass
@ -382,14 +375,10 @@ class LaTeXBuilder(Builder):
# configure usage of xindy (impacts Makefile and latexmkrc)
# FIXME: convert this rather to a confval with suitable default
# according to language ? but would require extra documentation
if self.config.language:
xindy_lang_option = \
XINDY_LANG_OPTIONS.get(self.config.language[:2],
'-L general -C utf8 ')
xindy_cyrillic = self.config.language[:2] in XINDY_CYRILLIC_SCRIPTS
else:
xindy_lang_option = '-L english -C utf8 '
xindy_cyrillic = False
xindy_lang_option = XINDY_LANG_OPTIONS.get(self.config.language[:2],
'-L general -C utf8 ')
xindy_cyrillic = self.config.language[:2] in XINDY_CYRILLIC_SCRIPTS
context = {
'latex_engine': self.config.latex_engine,
'xindy_use': self.config.latex_use_xindy,
@ -449,18 +438,6 @@ class LaTeXBuilder(Builder):
filename = path.join(package_dir, 'templates', 'latex', 'sphinxmessages.sty_t')
copy_asset_file(filename, self.outdir, context=context, renderer=LaTeXRenderer())
@property
def usepackages(self) -> List[Tuple[str, str]]:
warnings.warn('LaTeXBuilder.usepackages is deprecated.',
RemovedInSphinx50Warning, stacklevel=2)
return self.app.registry.latex_packages
@property
def usepackages_after_hyperref(self) -> List[Tuple[str, str]]:
warnings.warn('LaTeXBuilder.usepackages_after_hyperref is deprecated.',
RemovedInSphinx50Warning, stacklevel=2)
return self.app.registry.latex_packages_after_hyperref
def validate_config_values(app: Sphinx, config: Config) -> None:
for key in list(config.latex_elements):
@ -488,7 +465,7 @@ def default_latex_engine(config: Config) -> str:
""" Better default latex_engine settings for specific languages. """
if config.language == 'ja':
return 'uplatex'
elif (config.language or '').startswith('zh'):
elif config.language.startswith('zh'):
return 'xelatex'
elif config.language == 'el':
return 'xelatex'

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.latex.constants
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
consntants for LaTeX builder.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""consntants for LaTeX builder."""
from typing import Any, Dict

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.latex.nodes
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Additional nodes for LaTeX writer.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Additional nodes for LaTeX writer."""
from docutils import nodes

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.latex.theming
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Theming support for LaTeX builder.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Theming support for LaTeX builder."""
import configparser
from os import path
@ -81,7 +73,7 @@ class UserTheme(Theme):
def __init__(self, name: str, filename: str) -> None:
super().__init__(name)
self.config = configparser.RawConfigParser()
self.config.read(path.join(filename))
self.config.read(path.join(filename), encoding='utf-8')
for key in self.REQUIRED_CONFIG_KEYS:
try:

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.latex.transforms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Transforms for LaTeX builder.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Transforms for LaTeX builder."""
from typing import Any, Dict, List, Set, Tuple, cast

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.latex.util
~~~~~~~~~~~~~~~~~~~~~~~~~~
Utilities for LaTeX builder.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Utilities for LaTeX builder."""
from typing import Optional
@ -20,7 +12,7 @@ class ExtBabel(Babel):
self.language_code = language_code
self.use_polyglossia = use_polyglossia
self.supported = True
super().__init__(language_code or '')
super().__init__(language_code)
def uses_cyrillic(self) -> bool:
return self.language in self.cyrillic_languages

View File

@ -1,37 +1,25 @@
"""
sphinx.builders.linkcheck
~~~~~~~~~~~~~~~~~~~~~~~~~
The CheckExternalLinksBuilder class.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The CheckExternalLinksBuilder class."""
import json
import re
import socket
import time
import warnings
from datetime import datetime, timezone
from email.utils import parsedate_to_datetime
from html.parser import HTMLParser
from os import path
from queue import PriorityQueue, Queue
from threading import Thread
from typing import (Any, Dict, Generator, List, NamedTuple, Optional, Pattern, Set, Tuple,
Union, cast)
from typing import Any, Dict, Generator, List, NamedTuple, Optional, Tuple, Union, cast
from urllib.parse import unquote, urlparse, urlunparse
from docutils import nodes
from docutils.nodes import Element
from requests import Response
from requests.exceptions import ConnectionError, HTTPError, TooManyRedirects
from sphinx.application import Sphinx
from sphinx.builders.dummy import DummyBuilder
from sphinx.config import Config
from sphinx.deprecation import RemovedInSphinx50Warning
from sphinx.environment import BuildEnvironment
from sphinx.locale import __
from sphinx.transforms.post_transforms import SphinxPostTransform
@ -80,16 +68,6 @@ QUEUE_POLL_SECS = 1
DEFAULT_DELAY = 60.0
def node_line_or_0(node: Element) -> int:
"""
PriorityQueue items must be comparable. The line number is part of the
tuple used by the PriorityQueue, keep an homogeneous type for comparison.
"""
warnings.warn('node_line_or_0() is deprecated.',
RemovedInSphinx50Warning, stacklevel=2)
return get_node_line(node) or 0
class AnchorCheckParser(HTMLParser):
"""Specialized HTML parser that looks for a specific anchor."""
@ -133,114 +111,11 @@ class CheckExternalLinksBuilder(DummyBuilder):
'%(outdir)s/output.txt')
def init(self) -> None:
self.broken_hyperlinks = 0
self.hyperlinks: Dict[str, Hyperlink] = {}
self._good: Set[str] = set()
self._broken: Dict[str, str] = {}
self._redirected: Dict[str, Tuple[str, int]] = {}
# set a timeout for non-responding servers
socket.setdefaulttimeout(5.0)
# create queues and worker threads
self._wqueue: PriorityQueue[CheckRequestType] = PriorityQueue()
self._rqueue: Queue[CheckResult] = Queue()
@property
def anchors_ignore(self) -> List[Pattern]:
warnings.warn(
"%s.%s is deprecated." % (self.__class__.__name__, "anchors_ignore"),
RemovedInSphinx50Warning,
stacklevel=2,
)
return [re.compile(x) for x in self.config.linkcheck_anchors_ignore]
@property
def auth(self) -> List[Tuple[Pattern, Any]]:
warnings.warn(
"%s.%s is deprecated." % (self.__class__.__name__, "auth"),
RemovedInSphinx50Warning,
stacklevel=2,
)
return [(re.compile(pattern), auth_info) for pattern, auth_info
in self.config.linkcheck_auth]
@property
def to_ignore(self) -> List[Pattern]:
warnings.warn(
"%s.%s is deprecated." % (self.__class__.__name__, "to_ignore"),
RemovedInSphinx50Warning,
stacklevel=2,
)
return [re.compile(x) for x in self.config.linkcheck_ignore]
@property
def good(self) -> Set[str]:
warnings.warn(
"%s.%s is deprecated." % (self.__class__.__name__, "good"),
RemovedInSphinx50Warning,
stacklevel=2,
)
return self._good
@property
def broken(self) -> Dict[str, str]:
warnings.warn(
"%s.%s is deprecated." % (self.__class__.__name__, "broken"),
RemovedInSphinx50Warning,
stacklevel=2,
)
return self._broken
@property
def redirected(self) -> Dict[str, Tuple[str, int]]:
warnings.warn(
"%s.%s is deprecated." % (self.__class__.__name__, "redirected"),
RemovedInSphinx50Warning,
stacklevel=2,
)
return self._redirected
def check_thread(self) -> None:
warnings.warn(
"%s.%s is deprecated." % (self.__class__.__name__, "check_thread"),
RemovedInSphinx50Warning,
stacklevel=2,
)
# do nothing.
def limit_rate(self, response: Response) -> Optional[float]:
warnings.warn(
"%s.%s is deprecated." % (self.__class__.__name__, "limit_rate"),
RemovedInSphinx50Warning,
stacklevel=2,
)
worker = HyperlinkAvailabilityCheckWorker(self.env, self.config,
None, None, {})
return worker.limit_rate(response)
def rqueue(self, response: Response) -> Queue:
warnings.warn(
"%s.%s is deprecated." % (self.__class__.__name__, "rqueue"),
RemovedInSphinx50Warning,
stacklevel=2,
)
return self._rqueue
def workers(self, response: Response) -> List[Thread]:
warnings.warn(
"%s.%s is deprecated." % (self.__class__.__name__, "workers"),
RemovedInSphinx50Warning,
stacklevel=2,
)
return []
def wqueue(self, response: Response) -> Queue:
warnings.warn(
"%s.%s is deprecated." % (self.__class__.__name__, "wqueue"),
RemovedInSphinx50Warning,
stacklevel=2,
)
return self._wqueue
def process_result(self, result: CheckResult) -> None:
filename = self.env.doc2path(result.docname, None)
@ -273,6 +148,7 @@ class CheckExternalLinksBuilder(DummyBuilder):
logger.info(red('broken ') + result.uri + red(' - ' + result.message))
self.write_entry('broken', result.docname, filename, result.lineno,
result.uri + ': ' + result.message)
self.broken_hyperlinks += 1
elif result.status == 'redirected':
try:
text, color = {
@ -305,44 +181,36 @@ class CheckExternalLinksBuilder(DummyBuilder):
self.json_outfile.write('\n')
def finish(self) -> None:
checker = HyperlinkAvailabilityChecker(self.env, self.config, self)
checker = HyperlinkAvailabilityChecker(self.env, self.config)
logger.info('')
with open(path.join(self.outdir, 'output.txt'), 'w') as self.txt_outfile,\
open(path.join(self.outdir, 'output.json'), 'w') as self.json_outfile:
output_text = path.join(self.outdir, 'output.txt')
output_json = path.join(self.outdir, 'output.json')
with open(output_text, 'w', encoding="utf-8") as self.txt_outfile,\
open(output_json, 'w', encoding="utf-8") as self.json_outfile:
for result in checker.check(self.hyperlinks):
self.process_result(result)
if self._broken:
if self.broken_hyperlinks:
self.app.statuscode = 1
class HyperlinkAvailabilityChecker:
def __init__(self, env: BuildEnvironment, config: Config,
builder: CheckExternalLinksBuilder = None) -> None:
# Warning: builder argument will be removed in the sphinx-5.0.
# Don't use it from extensions.
# tag: RemovedInSphinx50Warning
self.builder = builder
def __init__(self, env: BuildEnvironment, config: Config) -> None:
self.config = config
self.env = env
self.rate_limits: Dict[str, RateLimit] = {}
self.rqueue: Queue = Queue()
self.workers: List[Thread] = []
self.wqueue: PriorityQueue = PriorityQueue()
self.to_ignore = [re.compile(x) for x in self.config.linkcheck_ignore]
if builder:
self.rqueue = builder._rqueue
self.wqueue = builder._wqueue
else:
self.rqueue = Queue()
self.wqueue = PriorityQueue()
def invoke_threads(self) -> None:
for _i in range(self.config.linkcheck_workers):
thread = HyperlinkAvailabilityCheckWorker(self.env, self.config,
self.rqueue, self.wqueue,
self.rate_limits, self.builder)
self.rate_limits)
thread.start()
self.workers.append(thread)
@ -378,11 +246,7 @@ class HyperlinkAvailabilityCheckWorker(Thread):
"""A worker class for checking the availability of hyperlinks."""
def __init__(self, env: BuildEnvironment, config: Config, rqueue: Queue,
wqueue: Queue, rate_limits: Dict[str, RateLimit],
builder: CheckExternalLinksBuilder = None) -> None:
# Warning: builder argument will be removed in the sphinx-5.0.
# Don't use it from extensions.
# tag: RemovedInSphinx50Warning
wqueue: Queue, rate_limits: Dict[str, RateLimit]) -> None:
self.config = config
self.env = env
self.rate_limits = rate_limits
@ -396,17 +260,6 @@ class HyperlinkAvailabilityCheckWorker(Thread):
self.auth = [(re.compile(pattern), auth_info) for pattern, auth_info
in self.config.linkcheck_auth]
if builder:
# if given, fill the result of checks as cache
self._good = builder._good
self._broken = builder._broken
self._redirected = builder._redirected
else:
# only for compatibility. Will be removed in Sphinx-5.0
self._good = set()
self._broken = {}
self._redirected = {}
super().__init__(daemon=True)
def run(self) -> None:
@ -554,14 +407,7 @@ class HyperlinkAvailabilityCheckWorker(Thread):
if path.exists(path.join(srcdir, uri)):
return 'working', '', 0
else:
self._broken[uri] = ''
return 'broken', '', 0
elif uri in self._good:
return 'working', 'old', 0
elif uri in self._broken:
return 'broken', self._broken[uri], 0
elif uri in self._redirected:
return 'redirected', self._redirected[uri][0], self._redirected[uri][1]
# need to actually check the URI
for _ in range(self.config.linkcheck_retries):
@ -569,13 +415,6 @@ class HyperlinkAvailabilityCheckWorker(Thread):
if status != "broken":
break
if status == "working":
self._good.add(uri)
elif status == "broken":
self._broken[uri] = info
elif status == "redirected":
self._redirected[uri] = (info, code)
return (status, info, code)
while True:

View File

@ -1,13 +1,6 @@
"""
sphinx.builders.manpage
~~~~~~~~~~~~~~~~~~~~~~~
Manual pages builder.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Manual pages builder."""
import warnings
from os import path
from typing import Any, Dict, List, Set, Tuple, Union
@ -18,7 +11,6 @@ from sphinx import addnodes
from sphinx.application import Sphinx
from sphinx.builders import Builder
from sphinx.config import Config
from sphinx.errors import NoUri
from sphinx.locale import __
from sphinx.util import logging, progress_message
from sphinx.util.console import darkgreen # type: ignore
@ -49,17 +41,19 @@ class ManualPageBuilder(Builder):
return 'all manpages' # for now
def get_target_uri(self, docname: str, typ: str = None) -> str:
if typ == 'token':
return ''
raise NoUri(docname, typ)
return ''
@progress_message(__('writing'))
def write(self, *ignored: Any) -> None:
docwriter = ManualPageWriter(self)
docsettings: Any = OptionParser(
defaults=self.env.settings,
components=(docwriter,),
read_config_files=True).get_default_values()
with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=DeprecationWarning)
# DeprecationWarning: The frontend.OptionParser class will be replaced
# by a subclass of argparse.ArgumentParser in Docutils 0.21 or later.
docsettings: Any = OptionParser(
defaults=self.env.settings,
components=(docwriter,),
read_config_files=True).get_default_values()
for info in self.config.man_pages:
docname, name, description, authors, section = info

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.singlehtml
~~~~~~~~~~~~~~~~~~~~~~~~~~
Single HTML builders.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Single HTML builders."""
from os import path
from typing import Any, Dict, List, Tuple, Union

View File

@ -1,14 +1,7 @@
"""
sphinx.builders.texinfo
~~~~~~~~~~~~~~~~~~~~~~~
Texinfo builder.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Texinfo builder."""
import os
import warnings
from os import path
from typing import Any, Dict, Iterable, List, Tuple, Union
@ -109,10 +102,14 @@ class TexinfoBuilder(Builder):
with progress_message(__("writing")):
self.post_process_images(doctree)
docwriter = TexinfoWriter(self)
settings: Any = OptionParser(
defaults=self.env.settings,
components=(docwriter,),
read_config_files=True).get_default_values()
with warnings.catch_warnings():
warnings.filterwarnings('ignore', category=DeprecationWarning)
# DeprecationWarning: The frontend.OptionParser class will be replaced
# by a subclass of argparse.ArgumentParser in Docutils 0.21 or later.
settings: Any = OptionParser(
defaults=self.env.settings,
components=(docwriter,),
read_config_files=True).get_default_values()
settings.author = author
settings.title = title
settings.texinfo_filename = targetname[:-5] + '.info'
@ -158,9 +155,9 @@ class TexinfoBuilder(Builder):
newnodes: List[Node] = [nodes.emphasis(sectname, sectname)]
for subdir, title in self.titles:
if docname.startswith(subdir):
newnodes.append(nodes.Text(_(' (in '), _(' (in ')))
newnodes.append(nodes.Text(_(' (in ')))
newnodes.append(nodes.emphasis(title, title))
newnodes.append(nodes.Text(')', ')'))
newnodes.append(nodes.Text(')'))
break
else:
pass

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.text
~~~~~~~~~~~~~~~~~~~~
Plain-text Sphinx builder.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Plain-text Sphinx builder."""
from os import path
from typing import Any, Dict, Iterator, Set, Tuple

View File

@ -1,12 +1,4 @@
"""
sphinx.builders.xml
~~~~~~~~~~~~~~~~~~~
Docutils-native XML and pseudo-XML builders.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Docutils-native XML and pseudo-XML builders."""
from os import path
from typing import Any, Dict, Iterator, Set, Type, Union

View File

@ -1,9 +1 @@
"""
sphinx.cmd
~~~~~~~~~~
Modules for command line executables.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Modules for command line executables."""

View File

@ -1,12 +1,4 @@
"""
sphinx.cmd.build
~~~~~~~~~~~~~~~~
Build documentation from a provided source.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Build documentation from a provided source."""
import argparse
import bdb
@ -244,7 +236,7 @@ def build_main(argv: List[str] = sys.argv[1:]) -> int:
try:
warnfile = abspath(args.warnfile)
ensuredir(path.dirname(warnfile))
warnfp = open(args.warnfile, 'w')
warnfp = open(args.warnfile, 'w', encoding="utf-8")
except Exception as exc:
parser.error(__('cannot open warning file %r: %s') % (
args.warnfile, exc))

View File

@ -1,17 +1,10 @@
"""
sphinx.cmd.make_mode
~~~~~~~~~~~~~~~~~~~~
"""sphinx-build -M command-line handling.
sphinx-build -M command-line handling.
This replaces the old, platform-dependent and once-generated content
of Makefile / make.bat.
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-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
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).
"""
import os

View File

@ -1,12 +1,4 @@
"""
sphinx.cmd.quickstart
~~~~~~~~~~~~~~~~~~~~~
Quickly setup documentation source to work with Sphinx.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Quickly setup documentation source to work with Sphinx."""
import argparse
import locale
@ -375,7 +367,7 @@ def generate(d: Dict, overwrite: bool = True, silent: bool = False, templatedir:
conf_path = os.path.join(templatedir, 'conf.py_t') if templatedir else None
if not conf_path or not path.isfile(conf_path):
conf_path = os.path.join(package_dir, 'templates', 'quickstart', 'conf.py_t')
with open(conf_path) as f:
with open(conf_path, encoding="utf-8") as f:
conf_text = f.read()
write_file(path.join(srcdir, 'conf.py'), template.render_string(conf_text, d))

View File

@ -1,12 +1,4 @@
"""
sphinx.config
~~~~~~~~~~~~~
Build configuration file handling.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Build configuration file handling."""
import re
import traceback
@ -100,7 +92,7 @@ class Config:
# the real default is locale-dependent
'today_fmt': (None, 'env', [str]),
'language': (None, 'env', [str]),
'language': ('en', 'env', [str]),
'locale_dirs': (['locales'], 'env', []),
'figure_language_filename': ('{root}.{language}{ext}', 'env', [str]),
'gettext_allow_fuzzy_translations': (False, 'gettext', []),
@ -413,7 +405,7 @@ def correct_copyright_year(app: "Sphinx", config: Config) -> None:
if getenv('SOURCE_DATE_EPOCH') is not None:
for k in ('copyright', 'epub_copyright'):
if k in config:
replace = r'\g<1>%s' % format_date('%Y')
replace = r'\g<1>%s' % format_date('%Y', language='en')
config[k] = copyright_year_re.sub(replace, config[k])

View File

@ -1,12 +1,4 @@
"""
sphinx.deprecation
~~~~~~~~~~~~~~~~~~
Sphinx deprecation classes and utilities.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Sphinx deprecation classes and utilities."""
import sys
import warnings
@ -14,15 +6,15 @@ from importlib import import_module
from typing import Any, Dict, Type
class RemovedInSphinx50Warning(DeprecationWarning):
class RemovedInSphinx60Warning(DeprecationWarning):
pass
class RemovedInSphinx60Warning(PendingDeprecationWarning):
class RemovedInSphinx70Warning(PendingDeprecationWarning):
pass
RemovedInNextVersionWarning = RemovedInSphinx50Warning
RemovedInNextVersionWarning = RemovedInSphinx60Warning
def deprecated_alias(modname: str, objects: Dict[str, object],

View File

@ -1,12 +1,4 @@
"""
sphinx.directives
~~~~~~~~~~~~~~~~~
Handlers for additional ReST directives.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Handlers for additional ReST directives."""
import re
from typing import TYPE_CHECKING, Any, Dict, Generic, List, Tuple, TypeVar, cast
@ -17,7 +9,6 @@ from docutils.parsers.rst import directives, roles
from sphinx import addnodes
from sphinx.addnodes import desc_signature
from sphinx.deprecation import RemovedInSphinx50Warning, deprecated_alias
from sphinx.util import docutils
from sphinx.util.docfields import DocFieldTransformer, Field, TypedField
from sphinx.util.docutils import SphinxDirective
@ -266,16 +257,6 @@ class DefaultDomain(SphinxDirective):
return []
deprecated_alias('sphinx.directives',
{
'DescDirective': ObjectDescription,
},
RemovedInSphinx50Warning,
{
'DescDirective': 'sphinx.directives.ObjectDescription',
})
def setup(app: "Sphinx") -> Dict[str, Any]:
app.add_config_value("strip_signature_backslash", False, 'env')
directives.register_directive('default-role', DefaultRole)

View File

@ -1,11 +1,3 @@
"""
sphinx.directives.code
~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import sys
import textwrap
from difflib import unified_diff
@ -232,9 +224,9 @@ class LiteralIncludeReader:
self.start_filter,
self.end_filter,
self.lines_filter,
self.dedent_filter,
self.prepend_filter,
self.append_filter,
self.dedent_filter]
self.append_filter]
lines = self.read_file(self.filename, location=location)
for func in filters:
lines = func(lines, location=location)

View File

@ -1,11 +1,3 @@
"""
sphinx.directives.other
~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
from typing import TYPE_CHECKING, Any, Dict, List, cast
@ -180,7 +172,7 @@ class Author(SphinxDirective):
text = _('Code author: ')
else:
text = _('Author: ')
emph += nodes.Text(text, text)
emph += nodes.Text(text)
inodes, messages = self.state.inline_text(self.arguments[0], self.lineno)
emph.extend(inodes)

View File

@ -1,11 +1,3 @@
"""
sphinx.directives.patches
~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
import warnings
from os import path

View File

@ -1,12 +1,7 @@
"""
sphinx.domains
~~~~~~~~~~~~~~
"""Support for domains.
Support for domains, which are groupings of description directives
and roles describing e.g. constructs of one programming language.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
Domains are groupings of description directives
and roles describing e.g. constructs of one programming language.
"""
import copy

View File

@ -1,12 +1,4 @@
"""
sphinx.domains.c
~~~~~~~~~~~~~~~~
The C language domain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The C language domain."""
import re
from typing import (Any, Callable, Dict, Generator, Iterator, List, Optional, Tuple, TypeVar,
@ -20,7 +12,7 @@ from sphinx import addnodes
from sphinx.addnodes import pending_xref
from sphinx.application import Sphinx
from sphinx.builders import Builder
from sphinx.deprecation import RemovedInSphinx50Warning
from sphinx.deprecation import RemovedInSphinx60Warning
from sphinx.directives import ObjectDescription
from sphinx.domains import Domain, ObjType
from sphinx.environment import BuildEnvironment
@ -29,8 +21,8 @@ from sphinx.roles import SphinxRole, XRefRole
from sphinx.transforms import SphinxTransform
from sphinx.transforms.post_transforms import ReferencesResolver
from sphinx.util import logging
from sphinx.util.cfamily import (ASTAttribute, ASTBaseBase, ASTBaseParenExprList, BaseParser,
DefinitionError, NoOldIdError, StringifyTransform,
from sphinx.util.cfamily import (ASTAttributeList, ASTBaseBase, ASTBaseParenExprList,
BaseParser, DefinitionError, NoOldIdError, StringifyTransform,
UnsupportedMultiCharacterCharLiteral, anon_identifier_re,
binary_literal_re, char_literal_re, float_literal_re,
float_literal_suffix_re, hex_literal_re, identifier_re,
@ -695,7 +687,7 @@ class ASTFunctionParameter(ASTBase):
class ASTParameters(ASTBase):
def __init__(self, args: List[ASTFunctionParameter], attrs: List[ASTAttribute]) -> None:
def __init__(self, args: List[ASTFunctionParameter], attrs: ASTAttributeList) -> None:
self.args = args
self.attrs = attrs
@ -713,9 +705,9 @@ class ASTParameters(ASTBase):
first = False
res.append(str(a))
res.append(')')
for attr in self.attrs:
if len(self.attrs) != 0:
res.append(' ')
res.append(transform(attr))
res.append(transform(self.attrs))
return ''.join(res)
def describe_signature(self, signode: TextElement, mode: str,
@ -740,14 +732,14 @@ class ASTParameters(ASTBase):
arg.describe_signature(signode, 'markType', env, symbol=symbol)
signode += addnodes.desc_sig_punctuation(')', ')')
for attr in self.attrs:
if len(self.attrs) != 0:
signode += addnodes.desc_sig_space()
attr.describe_signature(signode)
self.attrs.describe_signature(signode)
class ASTDeclSpecsSimple(ASTBaseBase):
def __init__(self, storage: str, threadLocal: str, inline: bool,
restrict: bool, volatile: bool, const: bool, attrs: List[Any]) -> None:
restrict: bool, volatile: bool, const: bool, attrs: ASTAttributeList) -> None:
self.storage = storage
self.threadLocal = threadLocal
self.inline = inline
@ -769,7 +761,8 @@ class ASTDeclSpecsSimple(ASTBaseBase):
def _stringify(self, transform: StringifyTransform) -> str:
res: List[str] = []
res.extend(transform(attr) for attr in self.attrs)
if len(self.attrs) != 0:
res.append(transform(self.attrs))
if self.storage:
res.append(self.storage)
if self.threadLocal:
@ -786,14 +779,15 @@ class ASTDeclSpecsSimple(ASTBaseBase):
def describe_signature(self, modifiers: List[Node]) -> None:
def _add(modifiers: List[Node], text: str) -> None:
if len(modifiers) > 0:
if len(modifiers) != 0:
modifiers.append(addnodes.desc_sig_space())
modifiers.append(addnodes.desc_sig_keyword(text, text))
for attr in self.attrs:
if len(modifiers) > 0:
modifiers.append(addnodes.desc_sig_space())
modifiers.append(attr.describe_signature(modifiers))
if len(modifiers) != 0 and len(self.attrs) != 0:
modifiers.append(addnodes.desc_sig_space())
tempNode = nodes.TextElement()
self.attrs.describe_signature(tempNode)
modifiers.extend(tempNode.children)
if self.storage:
_add(modifiers, self.storage)
if self.threadLocal:
@ -1010,7 +1004,7 @@ class ASTDeclaratorNameBitField(ASTDeclarator):
class ASTDeclaratorPtr(ASTDeclarator):
def __init__(self, next: ASTDeclarator, restrict: bool, volatile: bool, const: bool,
attrs: Any) -> None:
attrs: ASTAttributeList) -> None:
assert next
self.next = next
self.restrict = restrict
@ -1033,9 +1027,8 @@ class ASTDeclaratorPtr(ASTDeclarator):
def _stringify(self, transform: StringifyTransform) -> str:
res = ['*']
for a in self.attrs:
res.append(transform(a))
if len(self.attrs) > 0 and (self.restrict or self.volatile or self.const):
res.append(transform(self.attrs))
if len(self.attrs) != 0 and (self.restrict or self.volatile or self.const):
res.append(' ')
if self.restrict:
res.append('restrict')
@ -1057,9 +1050,8 @@ class ASTDeclaratorPtr(ASTDeclarator):
env: "BuildEnvironment", symbol: "Symbol") -> None:
verify_description_mode(mode)
signode += addnodes.desc_sig_punctuation('*', '*')
for a in self.attrs:
a.describe_signature(signode)
if len(self.attrs) > 0 and (self.restrict or self.volatile or self.const):
self.attrs.describe_signature(signode)
if len(self.attrs) != 0 and (self.restrict or self.volatile or self.const):
signode += addnodes.desc_sig_space()
def _add_anno(signode: TextElement, text: str) -> None:
@ -1382,9 +1374,11 @@ class ASTEnum(ASTBase):
class ASTEnumerator(ASTBase):
def __init__(self, name: ASTNestedName, init: ASTInitializer) -> None:
def __init__(self, name: ASTNestedName, init: Optional[ASTInitializer],
attrs: ASTAttributeList) -> None:
self.name = name
self.init = init
self.attrs = attrs
def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
return symbol.get_full_nested_name().get_id(version)
@ -1392,6 +1386,9 @@ class ASTEnumerator(ASTBase):
def _stringify(self, transform: StringifyTransform) -> str:
res = []
res.append(transform(self.name))
if len(self.attrs) != 0:
res.append(' ')
res.append(transform(self.attrs))
if self.init:
res.append(transform(self.init))
return ''.join(res)
@ -1400,6 +1397,9 @@ class ASTEnumerator(ASTBase):
env: "BuildEnvironment", symbol: "Symbol") -> None:
verify_description_mode(mode)
self.name.describe_signature(signode, mode, env, symbol)
if len(self.attrs) != 0:
signode += addnodes.desc_sig_space()
self.attrs.describe_signature(signode)
if self.init:
self.init.describe_signature(signode, 'markType', env, symbol)
@ -2649,13 +2649,7 @@ class DefinitionParser(BaseParser):
'Expecting "," or ")" in parameters, '
'got "%s".' % self.current_char)
attrs = []
while True:
attr = self._parse_attribute()
if attr is None:
break
attrs.append(attr)
attrs = self._parse_attribute_list()
return ASTParameters(args, attrs)
def _parse_decl_specs_simple(self, outer: str, typed: bool) -> ASTDeclSpecsSimple:
@ -2714,7 +2708,7 @@ class DefinitionParser(BaseParser):
continue
break
return ASTDeclSpecsSimple(storage, threadLocal, inline,
restrict, volatile, const, attrs)
restrict, volatile, const, ASTAttributeList(attrs))
def _parse_decl_specs(self, outer: str, typed: bool = True) -> ASTDeclSpecs:
if outer:
@ -2846,7 +2840,7 @@ class DefinitionParser(BaseParser):
next = self._parse_declarator(named, paramMode, typed)
return ASTDeclaratorPtr(next=next,
restrict=restrict, volatile=volatile, const=const,
attrs=attrs)
attrs=ASTAttributeList(attrs))
if typed and self.current_char == '(': # note: peeking, not skipping
# maybe this is the beginning of params, try that first,
# otherwise assume it's noptr->declarator > ( ptr-declarator )
@ -3041,6 +3035,7 @@ class DefinitionParser(BaseParser):
def _parse_enumerator(self) -> ASTEnumerator:
name = self._parse_nested_name()
attrs = self._parse_attribute_list()
self.skip_ws()
init = None
if self.skip_string('='):
@ -3051,7 +3046,7 @@ class DefinitionParser(BaseParser):
initVal = self._parse_expression_fallback([], parser)
init = ASTInitializer(initVal)
return ASTEnumerator(name, init)
return ASTEnumerator(name, init, attrs)
def parse_pre_v3_type_definition(self) -> ASTDeclaration:
self.skip_ws()
@ -3276,7 +3271,7 @@ class CObject(ObjectDescription[ASTDeclaration]):
msg = "{}: Pre-v3 C type directive '.. c:type:: {}' converted to " \
"'.. c:{}:: {}'." \
"\nThe original parsing error was:\n{}"
msg = msg.format(RemovedInSphinx50Warning.__name__,
msg = msg.format(RemovedInSphinx60Warning.__name__,
sig, ast.objectType, ast, eOrig)
logger.warning(msg, location=signode)
except DefinitionError as e:
@ -3709,7 +3704,7 @@ class CXRefRole(XRefRole):
if self.env.config['c_warn_on_allowed_pre_v3']:
msg = "{}: Pre-v3 C type role ':c:type:`{}`' converted to ':c:expr:`{}`'."
msg += "\nThe original parsing error was:\n{}"
msg = msg.format(RemovedInSphinx50Warning.__name__, text, text, eOrig)
msg = msg.format(RemovedInSphinx60Warning.__name__, text, text, eOrig)
logger.warning(msg, location=self.get_location())
return [signode], []

View File

@ -1,12 +1,4 @@
"""
sphinx.domains.changeset
~~~~~~~~~~~~~~~~~~~~~~~~
The changeset domain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The changeset domain."""
from typing import TYPE_CHECKING, Any, Dict, List, NamedTuple, cast

View File

@ -1,12 +1,4 @@
"""
sphinx.domains.citation
~~~~~~~~~~~~~~~~~~~~~~~
The citation domain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The citation domain."""
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple, cast

View File

@ -1,12 +1,4 @@
"""
sphinx.domains.cpp
~~~~~~~~~~~~~~~~~~
The C++ language domain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The C++ language domain."""
import re
from typing import (Any, Callable, Dict, Generator, Iterator, List, Optional, Tuple, TypeVar,
@ -29,8 +21,8 @@ from sphinx.roles import SphinxRole, XRefRole
from sphinx.transforms import SphinxTransform
from sphinx.transforms.post_transforms import ReferencesResolver
from sphinx.util import logging
from sphinx.util.cfamily import (ASTAttribute, ASTBaseBase, ASTBaseParenExprList, BaseParser,
DefinitionError, NoOldIdError, StringifyTransform,
from sphinx.util.cfamily import (ASTAttributeList, ASTBaseBase, ASTBaseParenExprList,
BaseParser, DefinitionError, NoOldIdError, StringifyTransform,
UnsupportedMultiCharacterCharLiteral, anon_identifier_re,
binary_literal_re, char_literal_re, float_literal_re,
float_literal_suffix_re, hex_literal_re, identifier_re,
@ -267,7 +259,8 @@ T = TypeVar('T')
class_object:
goal: a class declaration, but with specification of a base class
grammar:
nested-name "final"[opt] (":" base-specifier-list)[opt]
attribute-specifier-seq[opt]
nested-name "final"[opt] (":" base-specifier-list)[opt]
base-specifier-list ->
base-specifier "..."[opt]
| base-specifier-list, base-specifier "..."[opt]
@ -281,7 +274,8 @@ T = TypeVar('T')
goal: an unscoped enum or a scoped enum, optionally with the underlying
type specified
grammar:
("class" | "struct")[opt] visibility[opt] nested-name (":" type)[opt]
("class" | "struct")[opt] visibility[opt]
attribute-specifier-seq[opt] nested-name (":" type)[opt]
enumerator_object:
goal: an element in a scoped or unscoped enum. The name should be
injected according to the scopedness.
@ -535,7 +529,8 @@ _id_operator_v2 = {
'->': 'pt',
'()': 'cl',
'[]': 'ix',
'.*': 'ds' # this one is not overloadable, but we need it for expressions
'.*': 'ds', # this one is not overloadable, but we need it for expressions
'?': 'qu',
}
_id_operator_unary_v2 = {
'++': 'pp_',
@ -1524,6 +1519,44 @@ class ASTBinOpExpr(ASTExpression):
self.exprs[i].describe_signature(signode, mode, env, symbol)
class ASTConditionalExpr(ASTExpression):
def __init__(self, ifExpr: ASTExpression, thenExpr: ASTExpression,
elseExpr: ASTExpression):
self.ifExpr = ifExpr
self.thenExpr = thenExpr
self.elseExpr = elseExpr
def _stringify(self, transform: StringifyTransform) -> str:
res = []
res.append(transform(self.ifExpr))
res.append(' ? ')
res.append(transform(self.thenExpr))
res.append(' : ')
res.append(transform(self.elseExpr))
return ''.join(res)
def get_id(self, version: int) -> str:
assert version >= 2
res = []
res.append(_id_operator_v2['?'])
res.append(self.ifExpr.get_id(version))
res.append(self.thenExpr.get_id(version))
res.append(self.elseExpr.get_id(version))
return ''.join(res)
def describe_signature(self, signode: TextElement, mode: str,
env: "BuildEnvironment", symbol: "Symbol") -> None:
self.ifExpr.describe_signature(signode, mode, env, symbol)
signode += addnodes.desc_sig_space()
signode += addnodes.desc_sig_operator('?', '?')
signode += addnodes.desc_sig_space()
self.thenExpr.describe_signature(signode, mode, env, symbol)
signode += addnodes.desc_sig_space()
signode += addnodes.desc_sig_operator(':', ':')
signode += addnodes.desc_sig_space()
self.elseExpr.describe_signature(signode, mode, env, symbol)
class ASTBracedInitList(ASTBase):
def __init__(self, exprs: List[Union[ASTExpression, "ASTBracedInitList"]],
trailingComma: bool) -> None:
@ -1556,42 +1589,39 @@ class ASTBracedInitList(ASTBase):
class ASTAssignmentExpr(ASTExpression):
def __init__(self, exprs: List[Union[ASTExpression, ASTBracedInitList]], ops: List[str]):
assert len(exprs) > 0
assert len(exprs) == len(ops) + 1
self.exprs = exprs
self.ops = ops
def __init__(self, leftExpr: ASTExpression, op: str,
rightExpr: Union[ASTExpression, ASTBracedInitList]):
self.leftExpr = leftExpr
self.op = op
self.rightExpr = rightExpr
def _stringify(self, transform: StringifyTransform) -> str:
res = []
res.append(transform(self.exprs[0]))
for i in range(1, len(self.exprs)):
res.append(' ')
res.append(self.ops[i - 1])
res.append(' ')
res.append(transform(self.exprs[i]))
res.append(transform(self.leftExpr))
res.append(' ')
res.append(self.op)
res.append(' ')
res.append(transform(self.rightExpr))
return ''.join(res)
def get_id(self, version: int) -> str:
# we end up generating the ID from left to right, instead of right to left
res = []
for i in range(len(self.ops)):
res.append(_id_operator_v2[self.ops[i]])
res.append(self.exprs[i].get_id(version))
res.append(self.exprs[-1].get_id(version))
res.append(_id_operator_v2[self.op])
res.append(self.leftExpr.get_id(version))
res.append(self.rightExpr.get_id(version))
return ''.join(res)
def describe_signature(self, signode: TextElement, mode: str,
env: "BuildEnvironment", symbol: "Symbol") -> None:
self.exprs[0].describe_signature(signode, mode, env, symbol)
for i in range(1, len(self.exprs)):
signode += addnodes.desc_sig_space()
op = self.ops[i - 1]
if ord(op[0]) >= ord('a') and ord(op[0]) <= ord('z'):
signode += addnodes.desc_sig_keyword(op, op)
else:
signode += addnodes.desc_sig_operator(op, op)
signode += addnodes.desc_sig_space()
self.exprs[i].describe_signature(signode, mode, env, symbol)
self.leftExpr.describe_signature(signode, mode, env, symbol)
signode += addnodes.desc_sig_space()
if ord(self.op[0]) >= ord('a') and ord(self.op[0]) <= ord('z'):
signode += addnodes.desc_sig_keyword(self.op, self.op)
else:
signode += addnodes.desc_sig_operator(self.op, self.op)
signode += addnodes.desc_sig_space()
self.rightExpr.describe_signature(signode, mode, env, symbol)
class ASTCommaExpr(ASTExpression):
@ -2018,7 +2048,7 @@ class ASTParametersQualifiers(ASTBase):
def __init__(self, args: List[ASTFunctionParameter], volatile: bool, const: bool,
refQual: Optional[str], exceptionSpec: ASTNoexceptSpec,
trailingReturn: "ASTType",
override: bool, final: bool, attrs: List[ASTAttribute],
override: bool, final: bool, attrs: ASTAttributeList,
initializer: Optional[str]) -> None:
self.args = args
self.volatile = volatile
@ -2088,9 +2118,9 @@ class ASTParametersQualifiers(ASTBase):
res.append(' final')
if self.override:
res.append(' override')
for attr in self.attrs:
if len(self.attrs) != 0:
res.append(' ')
res.append(transform(attr))
res.append(transform(self.attrs))
if self.initializer:
res.append(' = ')
res.append(self.initializer)
@ -2141,9 +2171,9 @@ class ASTParametersQualifiers(ASTBase):
_add_anno(signode, 'final')
if self.override:
_add_anno(signode, 'override')
for attr in self.attrs:
if len(self.attrs) != 0:
signode += addnodes.desc_sig_space()
attr.describe_signature(signode)
self.attrs.describe_signature(signode)
if self.initializer:
signode += addnodes.desc_sig_space()
signode += addnodes.desc_sig_punctuation('=', '=')
@ -2181,7 +2211,7 @@ class ASTDeclSpecsSimple(ASTBase):
explicitSpec: Optional[ASTExplicitSpec],
consteval: bool, constexpr: bool, constinit: bool,
volatile: bool, const: bool, friend: bool,
attrs: List[ASTAttribute]) -> None:
attrs: ASTAttributeList) -> None:
self.storage = storage
self.threadLocal = threadLocal
self.inline = inline
@ -2213,7 +2243,8 @@ class ASTDeclSpecsSimple(ASTBase):
def _stringify(self, transform: StringifyTransform) -> str:
res: List[str] = []
res.extend(transform(attr) for attr in self.attrs)
if len(self.attrs) != 0:
res.append(transform(self.attrs))
if self.storage:
res.append(self.storage)
if self.threadLocal:
@ -2240,12 +2271,8 @@ class ASTDeclSpecsSimple(ASTBase):
def describe_signature(self, signode: TextElement,
env: "BuildEnvironment", symbol: "Symbol") -> None:
addSpace = False
for attr in self.attrs:
if addSpace:
signode += addnodes.desc_sig_space()
addSpace = True
attr.describe_signature(signode)
self.attrs.describe_signature(signode)
addSpace = len(self.attrs) != 0
def _add(signode: TextElement, text: str) -> bool:
if addSpace:
@ -2562,7 +2589,7 @@ class ASTDeclaratorNameBitField(ASTDeclarator):
class ASTDeclaratorPtr(ASTDeclarator):
def __init__(self, next: ASTDeclarator, volatile: bool, const: bool,
attrs: List[ASTAttribute]) -> None:
attrs: ASTAttributeList) -> None:
assert next
self.next = next
self.volatile = volatile
@ -2590,9 +2617,8 @@ class ASTDeclaratorPtr(ASTDeclarator):
def _stringify(self, transform: StringifyTransform) -> str:
res = ['*']
for a in self.attrs:
res.append(transform(a))
if len(self.attrs) > 0 and (self.volatile or self.const):
res.append(transform(self.attrs))
if len(self.attrs) != 0 and (self.volatile or self.const):
res.append(' ')
if self.volatile:
res.append('volatile')
@ -2647,9 +2673,8 @@ class ASTDeclaratorPtr(ASTDeclarator):
env: "BuildEnvironment", symbol: "Symbol") -> None:
verify_description_mode(mode)
signode += addnodes.desc_sig_punctuation('*', '*')
for a in self.attrs:
a.describe_signature(signode)
if len(self.attrs) > 0 and (self.volatile or self.const):
self.attrs.describe_signature(signode)
if len(self.attrs) != 0 and (self.volatile or self.const):
signode += addnodes.desc_sig_space()
def _add_anno(signode: TextElement, text: str) -> None:
@ -2667,7 +2692,7 @@ class ASTDeclaratorPtr(ASTDeclarator):
class ASTDeclaratorRef(ASTDeclarator):
def __init__(self, next: ASTDeclarator, attrs: List[ASTAttribute]) -> None:
def __init__(self, next: ASTDeclarator, attrs: ASTAttributeList) -> None:
assert next
self.next = next
self.attrs = attrs
@ -2697,9 +2722,8 @@ class ASTDeclaratorRef(ASTDeclarator):
def _stringify(self, transform: StringifyTransform) -> str:
res = ['&']
for a in self.attrs:
res.append(transform(a))
if len(self.attrs) > 0 and self.next.require_space_after_declSpecs():
res.append(transform(self.attrs))
if len(self.attrs) != 0 and self.next.require_space_after_declSpecs():
res.append(' ')
res.append(transform(self.next))
return ''.join(res)
@ -2728,8 +2752,7 @@ class ASTDeclaratorRef(ASTDeclarator):
env: "BuildEnvironment", symbol: "Symbol") -> None:
verify_description_mode(mode)
signode += addnodes.desc_sig_punctuation('&', '&')
for a in self.attrs:
a.describe_signature(signode)
self.attrs.describe_signature(signode)
if len(self.attrs) > 0 and self.next.require_space_after_declSpecs():
signode += addnodes.desc_sig_space()
self.next.describe_signature(signode, mode, env, symbol)
@ -3318,16 +3341,21 @@ class ASTBaseClass(ASTBase):
class ASTClass(ASTBase):
def __init__(self, name: ASTNestedName, final: bool, bases: List[ASTBaseClass]) -> None:
def __init__(self, name: ASTNestedName, final: bool, bases: List[ASTBaseClass],
attrs: ASTAttributeList) -> None:
self.name = name
self.final = final
self.bases = bases
self.attrs = attrs
def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
return symbol.get_full_nested_name().get_id(version)
def _stringify(self, transform: StringifyTransform) -> str:
res = []
res.append(transform(self.attrs))
if len(self.attrs) != 0:
res.append(' ')
res.append(transform(self.name))
if self.final:
res.append(' final')
@ -3344,6 +3372,9 @@ class ASTClass(ASTBase):
def describe_signature(self, signode: TextElement, mode: str,
env: "BuildEnvironment", symbol: "Symbol") -> None:
verify_description_mode(mode)
self.attrs.describe_signature(signode)
if len(self.attrs) != 0:
signode += addnodes.desc_sig_space()
self.name.describe_signature(signode, mode, env, symbol=symbol)
if self.final:
signode += addnodes.desc_sig_space()
@ -3361,8 +3392,9 @@ class ASTClass(ASTBase):
class ASTUnion(ASTBase):
def __init__(self, name: ASTNestedName) -> None:
def __init__(self, name: ASTNestedName, attrs: ASTAttributeList) -> None:
self.name = name
self.attrs = attrs
def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
if version == 1:
@ -3370,20 +3402,29 @@ class ASTUnion(ASTBase):
return symbol.get_full_nested_name().get_id(version)
def _stringify(self, transform: StringifyTransform) -> str:
return transform(self.name)
res = []
res.append(transform(self.attrs))
if len(self.attrs) != 0:
res.append(' ')
res.append(transform(self.name))
return ''.join(res)
def describe_signature(self, signode: TextElement, mode: str,
env: "BuildEnvironment", symbol: "Symbol") -> None:
verify_description_mode(mode)
self.attrs.describe_signature(signode)
if len(self.attrs) != 0:
signode += addnodes.desc_sig_space()
self.name.describe_signature(signode, mode, env, symbol=symbol)
class ASTEnum(ASTBase):
def __init__(self, name: ASTNestedName, scoped: str,
underlyingType: ASTType) -> None:
def __init__(self, name: ASTNestedName, scoped: str, underlyingType: ASTType,
attrs: ASTAttributeList) -> None:
self.name = name
self.scoped = scoped
self.underlyingType = underlyingType
self.attrs = attrs
def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
if version == 1:
@ -3395,6 +3436,9 @@ class ASTEnum(ASTBase):
if self.scoped:
res.append(self.scoped)
res.append(' ')
res.append(transform(self.attrs))
if len(self.attrs) != 0:
res.append(' ')
res.append(transform(self.name))
if self.underlyingType:
res.append(' : ')
@ -3405,6 +3449,9 @@ class ASTEnum(ASTBase):
env: "BuildEnvironment", symbol: "Symbol") -> None:
verify_description_mode(mode)
# self.scoped has been done by the CPPEnumObject
self.attrs.describe_signature(signode)
if len(self.attrs) != 0:
signode += addnodes.desc_sig_space()
self.name.describe_signature(signode, mode, env, symbol=symbol)
if self.underlyingType:
signode += addnodes.desc_sig_space()
@ -3415,9 +3462,11 @@ class ASTEnum(ASTBase):
class ASTEnumerator(ASTBase):
def __init__(self, name: ASTNestedName, init: ASTInitializer) -> None:
def __init__(self, name: ASTNestedName, init: Optional[ASTInitializer],
attrs: ASTAttributeList) -> None:
self.name = name
self.init = init
self.attrs = attrs
def get_id(self, version: int, objectType: str, symbol: "Symbol") -> str:
if version == 1:
@ -3427,6 +3476,9 @@ class ASTEnumerator(ASTBase):
def _stringify(self, transform: StringifyTransform) -> str:
res = []
res.append(transform(self.name))
if len(self.attrs) != 0:
res.append(' ')
res.append(transform(self.attrs))
if self.init:
res.append(transform(self.init))
return ''.join(res)
@ -3435,6 +3487,9 @@ class ASTEnumerator(ASTBase):
env: "BuildEnvironment", symbol: "Symbol") -> None:
verify_description_mode(mode)
self.name.describe_signature(signode, mode, env, symbol)
if len(self.attrs) != 0:
signode += addnodes.desc_sig_space()
self.attrs.describe_signature(signode)
if self.init:
self.init.describe_signature(signode, 'markType', env, symbol)
@ -5598,50 +5653,60 @@ class DefinitionParser(BaseParser):
return ASTBinOpExpr(exprs, ops)
return _parse_bin_op_expr(self, 0, inTemplate=inTemplate)
def _parse_conditional_expression_tail(self, orExprHead: Any) -> None:
def _parse_conditional_expression_tail(self, orExprHead: ASTExpression,
inTemplate: bool) -> Optional[ASTConditionalExpr]:
# Consumes the orExprHead on success.
# -> "?" expression ":" assignment-expression
return None
self.skip_ws()
if not self.skip_string("?"):
return None
thenExpr = self._parse_expression()
self.skip_ws()
if not self.skip_string(":"):
self.fail('Expected ":" after then-expression in conditional expression.')
elseExpr = self._parse_assignment_expression(inTemplate)
return ASTConditionalExpr(orExprHead, thenExpr, elseExpr)
def _parse_assignment_expression(self, inTemplate: bool) -> ASTExpression:
# -> conditional-expression
# | logical-or-expression assignment-operator initializer-clause
# | throw-expression
# TODO: parse throw-expression: "throw" assignment-expression [opt]
# if not a throw expression, then:
# -> conditional-expression ->
# | yield-expression -> "co_yield" assignment-expression
# | "co_yield" braced-init-list
# | throw-expression -> "throw" assignment-expression[opt]
# TODO: yield-expression
# TODO: throw-expression
# Now we have (after expanding conditional-expression:
# logical-or-expression
# | logical-or-expression "?" expression ":" assignment-expression
# | logical-or-expression assignment-operator initializer-clause
exprs: List[Union[ASTExpression, ASTBracedInitList]] = []
ops = []
orExpr = self._parse_logical_or_expression(inTemplate=inTemplate)
exprs.append(orExpr)
# TODO: handle ternary with _parse_conditional_expression_tail
while True:
oneMore = False
self.skip_ws()
for op in _expression_assignment_ops:
if op[0] in 'anox':
if not self.skip_word(op):
continue
else:
if not self.skip_string(op):
continue
expr = self._parse_initializer_clause()
exprs.append(expr)
ops.append(op)
oneMore = True
if not oneMore:
break
if len(ops) == 0:
return orExpr
else:
return ASTAssignmentExpr(exprs, ops)
leftExpr = self._parse_logical_or_expression(inTemplate=inTemplate)
# the ternary operator
condExpr = self._parse_conditional_expression_tail(leftExpr, inTemplate)
if condExpr is not None:
return condExpr
# and actual assignment
for op in _expression_assignment_ops:
if op[0] in 'anox':
if not self.skip_word(op):
continue
else:
if not self.skip_string(op):
continue
rightExpr = self._parse_initializer_clause()
return ASTAssignmentExpr(leftExpr, op, rightExpr)
# just a logical-or-expression
return leftExpr
def _parse_constant_expression(self, inTemplate: bool) -> ASTExpression:
# -> conditional-expression
# -> conditional-expression ->
# logical-or-expression
# | logical-or-expression "?" expression ":" assignment-expression
orExpr = self._parse_logical_or_expression(inTemplate=inTemplate)
# TODO: use _parse_conditional_expression_tail
condExpr = self._parse_conditional_expression_tail(orExpr, inTemplate)
if condExpr is not None:
return condExpr
return orExpr
def _parse_expression(self) -> ASTExpression:
@ -6057,12 +6122,7 @@ class DefinitionParser(BaseParser):
override = self.skip_word_and_ws(
'override') # they can be permuted
attrs = []
while True:
attr = self._parse_attribute()
if attr is None:
break
attrs.append(attr)
attrs = self._parse_attribute_list()
self.skip_ws()
initializer = None
@ -6174,7 +6234,7 @@ class DefinitionParser(BaseParser):
break
return ASTDeclSpecsSimple(storage, threadLocal, inline, virtual,
explicitSpec, consteval, constexpr, constinit,
volatile, const, friend, attrs)
volatile, const, friend, ASTAttributeList(attrs))
def _parse_decl_specs(self, outer: str, typed: bool = True) -> ASTDeclSpecs:
if outer:
@ -6271,7 +6331,7 @@ class DefinitionParser(BaseParser):
self.skip_ws()
volatile = False
const = False
attrs = []
attrList = []
while 1:
if not volatile:
volatile = self.skip_word_and_ws('volatile')
@ -6283,19 +6343,15 @@ class DefinitionParser(BaseParser):
continue
attr = self._parse_attribute()
if attr is not None:
attrs.append(attr)
attrList.append(attr)
continue
break
next = self._parse_declarator(named, paramMode, typed)
return ASTDeclaratorPtr(next=next, volatile=volatile, const=const, attrs=attrs)
return ASTDeclaratorPtr(next=next, volatile=volatile, const=const,
attrs=ASTAttributeList(attrList))
# TODO: shouldn't we parse an R-value ref here first?
if typed and self.skip_string("&"):
attrs = []
while 1:
attr = self._parse_attribute()
if attr is None:
break
attrs.append(attr)
attrs = self._parse_attribute_list()
next = self._parse_declarator(named, paramMode, typed)
return ASTDeclaratorRef(next=next, attrs=attrs)
if typed and self.skip_string("..."):
@ -6567,6 +6623,7 @@ class DefinitionParser(BaseParser):
return ASTConcept(nestedName, initializer)
def _parse_class(self) -> ASTClass:
attrs = self._parse_attribute_list()
name = self._parse_nested_name()
self.skip_ws()
final = self.skip_word_and_ws('final')
@ -6594,24 +6651,26 @@ class DefinitionParser(BaseParser):
continue
else:
break
return ASTClass(name, final, bases)
return ASTClass(name, final, bases, attrs)
def _parse_union(self) -> ASTUnion:
attrs = self._parse_attribute_list()
name = self._parse_nested_name()
return ASTUnion(name)
return ASTUnion(name, attrs)
def _parse_enum(self) -> ASTEnum:
scoped = None # is set by CPPEnumObject
self.skip_ws()
attrs = self._parse_attribute_list()
name = self._parse_nested_name()
self.skip_ws()
underlyingType = None
if self.skip_string(':'):
underlyingType = self._parse_type(named=False)
return ASTEnum(name, scoped, underlyingType)
return ASTEnum(name, scoped, underlyingType, attrs)
def _parse_enumerator(self) -> ASTEnumerator:
name = self._parse_nested_name()
attrs = self._parse_attribute_list()
self.skip_ws()
init = None
if self.skip_string('='):
@ -6621,7 +6680,7 @@ class DefinitionParser(BaseParser):
return self._parse_constant_expression(inTemplate=False)
initVal = self._parse_expression_fallback([], parser)
init = ASTInitializer(initVal)
return ASTEnumerator(name, init)
return ASTEnumerator(name, init, attrs)
# ==========================================================================
@ -7992,7 +8051,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
return {
'version': 'builtin',
'env_version': 4,
'env_version': 6,
'parallel_read_safe': True,
'parallel_write_safe': True,
}

View File

@ -1,12 +1,4 @@
"""
sphinx.domains.index
~~~~~~~~~~~~~~~~~~~~
The index domain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The index domain."""
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Tuple
@ -110,7 +102,7 @@ class IndexRole(ReferenceRole):
index = addnodes.index(entries=entries)
target = nodes.target('', '', ids=[target_id])
text = nodes.Text(title, title)
text = nodes.Text(title)
self.set_source_info(index)
return [index, target, text], []

View File

@ -1,12 +1,4 @@
"""
sphinx.domains.javascript
~~~~~~~~~~~~~~~~~~~~~~~~~
The JavaScript domain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The JavaScript domain."""
from typing import Any, Dict, Iterator, List, Optional, Tuple, cast
@ -122,13 +114,6 @@ class JSObject(ObjectDescription[Tuple[str, str]]):
fullname = (mod_name + '.' if mod_name else '') + name_obj[0]
node_id = make_id(self.env, self.state.document, '', fullname)
signode['ids'].append(node_id)
# Assign old styled node_id not to break old hyperlinks (if possible)
# Note: Will be removed in Sphinx-5.0 (RemovedInSphinx50Warning)
old_node_id = self.make_old_id(fullname)
if old_node_id not in self.state.document.ids and old_node_id not in signode['ids']:
signode['ids'].append(old_node_id)
self.state.document.note_explicit_target(signode)
domain = cast(JavaScriptDomain, self.env.get_domain('js'))
@ -288,13 +273,6 @@ class JSModule(SphinxDirective):
location=(self.env.docname, self.lineno))
target = nodes.target('', '', ids=[node_id], ismod=True)
# Assign old styled node_id not to break old hyperlinks (if possible)
# Note: Will be removed in Sphinx-5.0 (RemovedInSphinx50Warning)
old_node_id = self.make_old_id(mod_name)
if old_node_id not in self.state.document.ids and old_node_id not in target['ids']:
target['ids'].append(old_node_id)
self.state.document.note_explicit_target(target)
ret.append(target)
indextext = _('%s (module)') % mod_name

View File

@ -1,12 +1,4 @@
"""
sphinx.domains.math
~~~~~~~~~~~~~~~~~~~
The math domain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The math domain."""
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Tuple

View File

@ -1,12 +1,4 @@
"""
sphinx.domains.python
~~~~~~~~~~~~~~~~~~~~~
The Python domain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The Python domain."""
import builtins
import inspect
@ -26,7 +18,7 @@ from sphinx import addnodes
from sphinx.addnodes import desc_signature, pending_xref, pending_xref_condition
from sphinx.application import Sphinx
from sphinx.builders import Builder
from sphinx.deprecation import RemovedInSphinx50Warning, RemovedInSphinx60Warning
from sphinx.deprecation import RemovedInSphinx60Warning
from sphinx.directives import ObjectDescription
from sphinx.domains import Domain, Index, IndexEntry, ObjType
from sphinx.environment import BuildEnvironment
@ -133,7 +125,7 @@ def type_to_xref(target: str, env: BuildEnvironment = None, suppress_prefix: boo
refspecific=refspecific, **kwargs)
def _parse_annotation(annotation: str, env: BuildEnvironment = None) -> List[Node]:
def _parse_annotation(annotation: str, env: BuildEnvironment) -> List[Node]:
"""Parse type annotation."""
def unparse(node: ast.AST) -> List[Node]:
if isinstance(node, ast.Attribute):
@ -227,10 +219,6 @@ def _parse_annotation(annotation: str, env: BuildEnvironment = None) -> List[Nod
raise SyntaxError # unsupported syntax
if env is None:
warnings.warn("The env parameter for _parse_annotation becomes required now.",
RemovedInSphinx50Warning, stacklevel=2)
try:
tree = ast_parse(annotation)
result: List[Node] = []
@ -577,12 +565,6 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
fullname = (modname + '.' if modname else '') + name_cls[0]
node_id = make_id(self.env, self.state.document, '', fullname)
signode['ids'].append(node_id)
# Assign old styled node_id(fullname) not to break old hyperlinks (if possible)
# Note: Will removed in Sphinx-5.0 (RemovedInSphinx50Warning)
if node_id != fullname and fullname not in self.state.document.ids:
signode['ids'].append(fullname)
self.state.document.note_explicit_target(signode)
domain = cast(PythonDomain, self.env.get_domain('py'))
@ -978,29 +960,6 @@ class PyProperty(PyObject):
return _('%s (%s property)') % (attrname, clsname)
class PyDecoratorMixin:
"""
Mixin for decorator directives.
"""
def handle_signature(self, sig: str, signode: desc_signature) -> Tuple[str, str]:
for cls in self.__class__.__mro__:
if cls.__name__ != 'DirectiveAdapter':
warnings.warn('PyDecoratorMixin is deprecated. '
'Please check the implementation of %s' % cls,
RemovedInSphinx50Warning, stacklevel=2)
break
else:
warnings.warn('PyDecoratorMixin is deprecated',
RemovedInSphinx50Warning, stacklevel=2)
ret = super().handle_signature(sig, signode) # type: ignore
signode.insert(0, addnodes.desc_addname('@', '@'))
return ret
def needs_arglist(self) -> bool:
return False
class PyModule(SphinxDirective):
"""
Directive to mark description of a new module.
@ -1029,13 +988,6 @@ class PyModule(SphinxDirective):
node_id = make_id(self.env, self.state.document, 'module', modname)
target = nodes.target('', '', ids=[node_id], ismod=True)
self.set_source_info(target)
# Assign old styled node_id not to break old hyperlinks (if possible)
# Note: Will removed in Sphinx-5.0 (RemovedInSphinx50Warning)
old_node_id = self.make_old_id(modname)
if node_id != old_node_id and old_node_id not in self.state.document.ids:
target['ids'].append(old_node_id)
self.state.document.note_explicit_target(target)
domain.note_module(modname,
@ -1474,7 +1426,7 @@ def builtin_resolver(app: Sphinx, env: BuildEnvironment,
if s.startswith('typing.'):
s = s.split('.', 1)[1]
return s in typing.__all__ # type: ignore
return s in typing.__all__
if node.get('refdomain') != 'py':
return None

View File

@ -1,12 +1,4 @@
"""
sphinx.domains.rst
~~~~~~~~~~~~~~~~~~
The reStructuredText domain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The reStructuredText domain."""
import re
from typing import Any, Dict, Iterator, List, Optional, Tuple, cast
@ -40,13 +32,6 @@ class ReSTMarkup(ObjectDescription[str]):
def add_target_and_index(self, name: str, sig: str, signode: desc_signature) -> None:
node_id = make_id(self.env, self.state.document, self.objtype, name)
signode['ids'].append(node_id)
# Assign old styled node_id not to break old hyperlinks (if possible)
# Note: Will be removed in Sphinx-5.0 (RemovedInSphinx50Warning)
old_node_id = self.make_old_id(name)
if old_node_id not in self.state.document.ids and old_node_id not in signode['ids']:
signode['ids'].append(old_node_id)
self.state.document.note_explicit_target(signode)
domain = cast(ReSTDomain, self.env.get_domain('rst'))
@ -150,13 +135,6 @@ class ReSTDirectiveOption(ReSTMarkup):
node_id = make_id(self.env, self.state.document, prefix, name)
signode['ids'].append(node_id)
# Assign old styled node_id not to break old hyperlinks (if possible)
# Note: Will be removed in Sphinx-5.0 (RemovedInSphinx50Warning)
old_node_id = self.make_old_id(name)
if old_node_id not in self.state.document.ids and old_node_id not in signode['ids']:
signode['ids'].append(old_node_id)
self.state.document.note_explicit_target(signode)
domain.note_object(self.objtype, objname, node_id, location=signode)

View File

@ -1,15 +1,6 @@
"""
sphinx.domains.std
~~~~~~~~~~~~~~~~~~
The standard domain.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The standard domain."""
import re
import warnings
from copy import copy
from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, Iterator, List, Optional,
Tuple, Type, Union, cast)
@ -21,7 +12,6 @@ from docutils.statemachine import StringList
from sphinx import addnodes
from sphinx.addnodes import desc_signature, pending_xref
from sphinx.deprecation import RemovedInSphinx50Warning
from sphinx.directives import ObjectDescription
from sphinx.domains import Domain, ObjType
from sphinx.locale import _, __
@ -65,13 +55,6 @@ class GenericObject(ObjectDescription[str]):
def add_target_and_index(self, name: str, sig: str, signode: desc_signature) -> None:
node_id = make_id(self.env, self.state.document, self.objtype, name)
signode['ids'].append(node_id)
# Assign old styled node_id not to break old hyperlinks (if possible)
# Note: Will be removed in Sphinx-5.0 (RemovedInSphinx50Warning)
old_node_id = self.make_old_id(name)
if old_node_id not in self.state.document.ids and old_node_id not in signode['ids']:
signode['ids'].append(old_node_id)
self.state.document.note_explicit_target(signode)
if self.indextemplate:
@ -139,13 +122,6 @@ class Target(SphinxDirective):
node_id = make_id(self.env, self.state.document, self.name, fullname)
node = nodes.target('', '', ids=[node_id])
self.set_source_info(node)
# Assign old styled node_id not to break old hyperlinks (if possible)
# Note: Will be removed in Sphinx-5.0 (RemovedInSphinx50Warning)
old_node_id = self.make_old_id(fullname)
if old_node_id not in self.state.document.ids and old_node_id not in node['ids']:
node['ids'].append(old_node_id)
self.state.document.note_explicit_target(node)
ret: List[Node] = [node]
if self.indextemplate:
@ -440,7 +416,7 @@ def token_xrefs(text: str, productionGroup: str = '') -> List[Node]:
for m in token_re.finditer(text):
if m.start() > pos:
txt = text[pos:m.start()]
retnodes.append(nodes.Text(txt, txt))
retnodes.append(nodes.Text(txt))
token = m.group(1)
if ':' in token:
if token[0] == '~':
@ -461,7 +437,7 @@ def token_xrefs(text: str, productionGroup: str = '') -> List[Node]:
retnodes.append(refnode)
pos = m.end()
if pos < len(text):
retnodes.append(nodes.Text(text[pos:], text[pos:]))
retnodes.append(nodes.Text(text[pos:]))
return retnodes
@ -502,14 +478,6 @@ class ProductionList(SphinxDirective):
prefix = 'grammar-token-%s' % productionGroup
node_id = make_id(self.env, self.state.document, prefix, name)
subnode['ids'].append(node_id)
# Assign old styled node_id not to break old hyperlinks (if possible)
# Note: Will be removed in Sphinx-5.0 (RemovedInSphinx50Warning)
old_node_id = self.make_old_id(name)
if (old_node_id not in self.state.document.ids and
old_node_id not in subnode['ids']):
subnode['ids'].append(old_node_id)
self.state.document.note_implicit_target(subnode, subnode)
if len(productionGroup) != 0:
@ -667,11 +635,6 @@ class StandardDomain(Domain):
objtype, name, docname, location=location)
self.objects[objtype, name] = (self.env.docname, labelid)
def add_object(self, objtype: str, name: str, docname: str, labelid: str) -> None:
warnings.warn('StandardDomain.add_object() is deprecated.',
RemovedInSphinx50Warning, stacklevel=2)
self.objects[objtype, name] = (docname, labelid)
@property
def _terms(self) -> Dict[str, Tuple[str, str]]:
""".. note:: Will be removed soon. internal use only."""
@ -762,11 +725,10 @@ class StandardDomain(Domain):
sectname = clean_astext(title)
elif node.tagname == 'rubric':
sectname = clean_astext(node)
elif node.tagname == 'target' and len(node) > 0:
# inline target (ex: blah _`blah` blah)
sectname = clean_astext(node)
elif self.is_enumerable_node(node):
sectname = self.get_numfig_title(node)
if not sectname:
continue
else:
toctree = next(node.findall(addnodes.toctree), None)
if toctree and toctree.get('caption'):
@ -774,8 +736,7 @@ class StandardDomain(Domain):
else:
# anonymous-only labels
continue
if sectname:
self.labels[name] = docname, labelid, sectname
self.labels[name] = docname, labelid, sectname
def add_program_option(self, program: str, name: str, docname: str, labelid: str) -> None:
self.progoptions[program, name] = (docname, labelid)

View File

@ -1,12 +1,4 @@
"""
sphinx.environment
~~~~~~~~~~~~~~~~~~
Global creation environment.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Global creation environment."""
import os
import pickle
@ -18,6 +10,7 @@ from os import path
from typing import (TYPE_CHECKING, Any, Callable, Dict, Generator, Iterator, List, Optional,
Set, Tuple, Union)
import docutils
from docutils import nodes
from docutils.nodes import Node
@ -46,10 +39,10 @@ logger = logging.getLogger(__name__)
default_settings: Dict[str, Any] = {
'auto_id_prefix': 'id',
'embed_images': False,
'image_loading': 'link',
'embed_stylesheet': False,
'cloak_email_addresses': True,
'pep_base_url': 'https://www.python.org/dev/peps/',
'pep_base_url': 'https://peps.python.org/',
'pep_references': None,
'rfc_base_url': 'https://datatracker.ietf.org/doc/html/',
'rfc_references': None,
@ -61,6 +54,8 @@ default_settings: Dict[str, Any] = {
'file_insertion_enabled': True,
'smartquotes_locales': [],
}
if docutils.__version_info__[:2] <= (0, 17):
default_settings['embed_images'] = False
# This is increased every time an environment attribute is added
# or changed to properly invalidate pickle files.
@ -261,7 +256,7 @@ class BuildEnvironment:
"""Update settings by new config."""
self.settings['input_encoding'] = config.source_encoding
self.settings['trim_footnote_reference_space'] = config.trim_footnote_reference_space
self.settings['language_code'] = config.language or 'en'
self.settings['language_code'] = config.language
# Allow to disable by 3rd party extension (workaround)
self.settings.setdefault('smart_quotes', True)

View File

@ -1,9 +1 @@
"""
sphinx.environment.adapters
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sphinx environment adapters
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Sphinx environment adapters"""

View File

@ -1,12 +1,4 @@
"""
sphinx.environment.adapters.asset
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Assets adapter for sphinx.environment.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Assets adapter for sphinx.environment."""
from sphinx.environment import BuildEnvironment

View File

@ -1,12 +1,4 @@
"""
sphinx.environment.adapters.indexentries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Index entries adapters for sphinx.environment.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Index entries adapters for sphinx.environment."""
import re
import unicodedata

View File

@ -1,12 +1,4 @@
"""
sphinx.environment.adapters.toctree
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Toctree adapter for sphinx.environment.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Toctree adapter for sphinx.environment."""
from typing import TYPE_CHECKING, Any, Iterable, List, Optional, cast

View File

@ -1,12 +1,4 @@
"""
sphinx.environment.collectors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The data collector components for sphinx.environment.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The data collector components for sphinx.environment."""
from typing import TYPE_CHECKING, Dict, List, Optional, Set

View File

@ -1,12 +1,4 @@
"""
sphinx.environment.collectors.asset
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The image collector for sphinx.environment.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The image collector for sphinx.environment."""
import os
from glob import glob
@ -64,18 +56,16 @@ class ImageCollector(EnvironmentCollector):
rel_imgpath, full_imgpath = app.env.relfn2path(imguri, docname)
node['uri'] = rel_imgpath
if app.config.language:
# Search language-specific figures at first
i18n_imguri = get_image_filename_for_language(imguri, app.env)
_, full_i18n_imgpath = app.env.relfn2path(i18n_imguri, docname)
self.collect_candidates(app.env, full_i18n_imgpath, candidates, node)
# Search language-specific figures at first
i18n_imguri = get_image_filename_for_language(imguri, app.env)
_, full_i18n_imgpath = app.env.relfn2path(i18n_imguri, docname)
self.collect_candidates(app.env, full_i18n_imgpath, candidates, node)
self.collect_candidates(app.env, full_imgpath, candidates, node)
else:
if app.config.language:
# substitute imguri by figure_language_filename
# (ex. foo.png -> foo.en.png)
imguri = search_image_for_language(imguri, app.env)
# substitute imguri by figure_language_filename
# (ex. foo.png -> foo.en.png)
imguri = search_image_for_language(imguri, app.env)
# Update `node['uri']` to a relative path from srcdir
# from a relative path from current document.

View File

@ -1,12 +1,4 @@
"""
sphinx.environment.collectors.dependencies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The dependencies collector components for sphinx.environment.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The dependencies collector components for sphinx.environment."""
import os
from os import path

View File

@ -1,12 +1,4 @@
"""
sphinx.environment.collectors.metadata
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The metadata collector components for sphinx.environment.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The metadata collector components for sphinx.environment."""
from typing import Any, Dict, List, Set, cast

View File

@ -1,12 +1,4 @@
"""
sphinx.environment.collectors.title
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The title collector components for sphinx.environment.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""The title collector components for sphinx.environment."""
from typing import Any, Dict, Set

View File

@ -1,12 +1,4 @@
"""
sphinx.environment.collectors.toctree
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Toctree collector for sphinx.environment.
:copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
"""Toctree collector for sphinx.environment."""
from typing import Any, Dict, List, Set, Tuple, Type, TypeVar, cast

Some files were not shown because too many files have changed in this diff Show More