Merge branch '4.x' into humitos/add-html-assets-in-all-pages

This commit is contained in:
Manuel Kaufmann 2021-06-14 17:04:09 +02:00 committed by GitHub
commit f312792023
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
293 changed files with 61945 additions and 49095 deletions

View File

@ -8,9 +8,9 @@ jobs:
working_directory: /sphinx working_directory: /sphinx
steps: steps:
- checkout - checkout
- run: /python3.6/bin/pip install -U pip setuptools - run: /python3.8/bin/pip install -U pip setuptools
- run: /python3.6/bin/pip install -U .[test] - run: /python3.8/bin/pip install -U .[test]
- run: mkdir -p test-reports/pytest - run: mkdir -p test-reports/pytest
- run: make test PYTHON=/python3.6/bin/python TEST="--junitxml=test-reports/pytest/results.xml -vv" - run: make test PYTHON=/python3.8/bin/python TEST="--junitxml=test-reports/pytest/results.xml -vv"
- store_test_results: - store_test_results:
path: test-reports path: test-reports

51
.github/workflows/transifex.yml vendored Normal file
View File

@ -0,0 +1,51 @@
name: Sync translations on repository and transifex.com
on:
schedule:
- cron: "0 0 * * SUN"
workflow_dispatch:
jobs:
push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: 4.x
- name: Set up Python
uses: actions/setup-python@v2
- name: Install dependencies
run: pip install -U babel jinja2 transifex-client
- name: Extract translations from source code
run: python setup.py extract_messages
- name: Push translations to transifex.com
run: cd sphinx/locale && tx push -s --no-interactive --parallel
env:
TX_TOKEN: ${{ secrets.TX_TOKEN }}
pull:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: 4.x
- name: Set up Python
uses: actions/setup-python@v2
- name: Install dependencies
run: pip install -U babel jinja2 transifex-client
- name: Extract translations from source code
run: python setup.py extract_messages
- 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
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
commit-message: 'Update message catalogs'
branch: bot/pull-translations
title: Update message catalogs

165
CHANGES
View File

@ -12,6 +12,10 @@ Incompatible changes
Deprecated Deprecated
---------- ----------
* The ``app`` argument of ``sphinx.environment.BuildEnvironment`` becomes
required
* ``sphinx.application.Sphinx.html_theme``
* ``sphinx.ext.autosummary._app``
* ``sphinx.util.docstrings.extract_metadata()`` * ``sphinx.util.docstrings.extract_metadata()``
Features added Features added
@ -23,10 +27,29 @@ Features added
* #8588: autodoc: :confval:`autodoc_type_aliases` now supports dotted name. It * #8588: autodoc: :confval:`autodoc_type_aliases` now supports dotted name. It
allows you to define an alias for a class with module name like allows you to define an alias for a class with module name like
``foo.bar.BazClass`` ``foo.bar.BazClass``
* #9175: autodoc: Special member is not documented in the module
* #9195: autodoc: The arguments of ``typing.Literal`` are wrongly rendered
* #9185: autodoc: :confval:`autodoc_typehints` allows ``'both'`` setting to
allow typehints to be included both in the signature and description
* #4257: autodoc: Add :confval:`autodoc_class_signature` to separate the class
entry and the definition of ``__init__()`` method
* #8061, #9218: autodoc: Support variable comment for alias classes
* #3014: autodoc: Add :event:`autodoc-process-bases` to modify the base classes
of the class definitions
* #9272: autodoc: Render enum values for the default argument value better
* #3257: autosummary: Support instance attributes for classes * #3257: autosummary: Support instance attributes for classes
* #9129: html search: Show search summaries when html_copy_source = False * #9129: html search: Show search summaries when html_copy_source = False
* #9307: html search: Prevent corrections and completions in search field
* #9120: html theme: Eliminate prompt characters of code-block from copyable * #9120: html theme: Eliminate prompt characters of code-block from copyable
text text
* #9176: i18n: Emit a debug message if message catalog file not found under
:confval:`locale_dirs`
* #9016: linkcheck: Support checking anchors on github.com
* #9016: linkcheck: Add a new event :event:`linkcheck-process-uri` to modify
URIs before checking hyperlinks
* #1874: py domain: Support union types using ``|`` in info-field-list
* #9268: py domain: :confval:`python_use_unqualified_type_names` supports type
field in info-field-list
* #9097: Optimize the paralell build * #9097: Optimize the paralell build
* #9131: Add :confval:`nitpick_ignore_regex` to ignore nitpicky warnings using * #9131: Add :confval:`nitpick_ignore_regex` to ignore nitpicky warnings using
regular expressions regular expressions
@ -41,12 +64,27 @@ Bugs fixed
* #8872: autodoc: stacked singledispatches are wrongly rendered * #8872: autodoc: stacked singledispatches are wrongly rendered
* #8597: autodoc: a docsting having metadata only should be treated as * #8597: autodoc: a docsting having metadata only should be treated as
undocumented undocumented
* #9185: autodoc: typehints for overloaded functions and methods are inaccurate
* #9250: autodoc: The inherited method not having docstring is wrongly parsed
* #9283: autodoc: autoattribute directive failed to generate document for an
attribute not having any comment
* #9317: html: Pushing left key causes visiting the next page at the first page
* #9270: html theme : pyramid theme generates incorrect logo links
* #9217: manpage: The name of manpage directory that is generated by
:confval:`man_make_section_directory` is not correct
* #9306: Linkcheck reports broken link when remote server closes the connection
on HEAD request
* #9280: py domain: "exceptions" module is not displayed
* #9224: ``:param:`` and ``:type:`` fields does not support a type containing
whitespace (ex. ``Dict[str, str]``)
* #8945: when transforming typed fields, call the specified role instead of
making an single xref. For C and C++, use the ``expr`` role for typed fields.
Testing Testing
-------- --------
Release 4.0.0 beta3 (in development) Release 4.0.3 (in development)
==================================== ==============================
Dependencies Dependencies
------------ ------------
@ -63,15 +101,63 @@ Features added
Bugs fixed Bugs fixed
---------- ----------
* 9313: LaTeX: complex table with merged cells broken since 4.0
Testing Testing
-------- --------
Release 4.0.0 beta2 (released Apr 29, 2021) Release 4.0.2 (released May 20, 2021)
=========================================== =====================================
Dependencies Dependencies
------------ ------------
* #9216: Support jinja2-3.0
Incompatible changes
--------------------
* #9222: Update Underscore.js to 1.13.1
* #9217: manpage: Stop creating a section directory on build manpage by default
(see :confval:`man_make_section_directory`)
Bugs fixed
----------
* #9210: viewcode: crashed if non importable modules found on parallel build
* #9240: Unknown node error for pending_xref_condition is raised if an extension
that does not support the node installs a missing-reference handler
Release 4.0.1 (released May 11, 2021)
=====================================
Bugs fixed
----------
* #9189: autodoc: crashed when ValueError is raised on generating signature
from a property of the class
* #9188: autosummary: warning is emitted if list value is set to
autosummary_generate
* #8380: html search: tags for search result are broken
* #9198: i18n: Babel emits errors when running compile_catalog
* #9205: py domain: The :canonical: option causes "more than one target for
cross-reference" warning
* #9201: websupport: UndefinedError is raised: 'css_tag' is undefined
Release 4.0.0 (released May 09, 2021)
=====================================
Dependencies
------------
4.0.0b1
* Drop python 3.5 support
* Drop docutils 0.12 and 0.13 support
* LaTeX: add ``tex-gyre`` font dependency
4.0.0b2
* Support docutils-0.17. Please notice it changes the output of HTML builder. * Support docutils-0.17. Please notice it changes the output of HTML builder.
Some themes do not support it, and you need to update your custom CSS to Some themes do not support it, and you need to update your custom CSS to
upgrade it. upgrade it.
@ -79,43 +165,7 @@ Dependencies
Incompatible changes Incompatible changes
-------------------- --------------------
* #9023: Change the CSS classes on :rst:role:`cpp:expr` and 4.0.0b1
:rst:role:`cpp:texpr`.
Features added
--------------
* #8818: autodoc: Super class having ``Any`` arguments causes nit-picky warning
* #9095: autodoc: TypeError is raised on processing broken metaclass
* #9110: autodoc: metadata of GenericAlias is not rendered as a reference in
py37+
* #9098: html: copy-range protection for doctests doesn't work in Safari
* #9103: LaTeX: imgconverter: conversion runs even if not needed
* #8127: py domain: Ellipsis in info-field-list causes nit-picky warning
* #9121: py domain: duplicated warning is emitted when both canonical and its
alias objects are defined on the document
* #9023: More CSS classes on domain descriptions, see :ref:`nodes` for details.
* #8195: mathjax: Rename :confval:`mathjax_config` to
:confval:`mathjax2_config` and add :confval:`mathjax3_config`
Bugs fixed
----------
* C, C++, fix ``KeyError`` when an ``alias`` directive is the first C/C++
directive in a file with another C/C++ directive later.
Release 4.0.0 beta1 (released Apr 12, 2021)
===========================================
Dependencies
------------
* Drop python 3.5 support
* Drop docutils 0.12 and 0.13 support
* LaTeX: add ``tex-gyre`` font dependency
Incompatible changes
--------------------
* #8539: autodoc: info-field-list is generated into the class description when * #8539: autodoc: info-field-list is generated into the class description when
``autodoc_typehints='description'`` and ``autoclass_content='class'`` set ``autodoc_typehints='description'`` and ``autoclass_content='class'`` set
@ -152,6 +202,11 @@ Incompatible changes
* #8487: The :file: option for csv-table directive now recognizes an absolute * #8487: The :file: option for csv-table directive now recognizes an absolute
path as a relative path from source directory path as a relative path from source directory
4.0.0b2
* #9023: Change the CSS classes on :rst:role:`cpp:expr` and
:rst:role:`cpp:texpr`.
Deprecated Deprecated
---------- ----------
@ -173,6 +228,8 @@ Deprecated
Features added Features added
-------------- --------------
4.0.0b1
* #8924: autodoc: Support ``bound`` argument for TypeVar * #8924: autodoc: Support ``bound`` argument for TypeVar
* #7383: autodoc: Support typehints for properties * #7383: autodoc: Support typehints for properties
* #5603: autodoc: Allow to refer to a python class using its canonical name * #5603: autodoc: Allow to refer to a python class using its canonical name
@ -202,9 +259,26 @@ Features added
* #7199: A new node, ``sphinx.addnodes.pending_xref_condition`` has been added. * #7199: A new node, ``sphinx.addnodes.pending_xref_condition`` has been added.
It can be used to choose appropriate content of the reference by conditions. It can be used to choose appropriate content of the reference by conditions.
4.0.0b2
* #8818: autodoc: Super class having ``Any`` arguments causes nit-picky warning
* #9095: autodoc: TypeError is raised on processing broken metaclass
* #9110: autodoc: metadata of GenericAlias is not rendered as a reference in
py37+
* #9098: html: copy-range protection for doctests doesn't work in Safari
* #9103: LaTeX: imgconverter: conversion runs even if not needed
* #8127: py domain: Ellipsis in info-field-list causes nit-picky warning
* #9121: py domain: duplicated warning is emitted when both canonical and its
alias objects are defined on the document
* #9023: More CSS classes on domain descriptions, see :ref:`nodes` for details.
* #8195: mathjax: Rename :confval:`mathjax_config` to
:confval:`mathjax2_config` and add :confval:`mathjax3_config`
Bugs fixed Bugs fixed
---------- ----------
4.0.0b1
* #8917: autodoc: Raises a warning if function has wrong __globals__ value * #8917: autodoc: Raises a warning if function has wrong __globals__ value
* #8415: autodoc: a TypeVar imported from other module is not resolved (in * #8415: autodoc: a TypeVar imported from other module is not resolved (in
Python 3.7 or above) Python 3.7 or above)
@ -239,6 +313,15 @@ Bugs fixed
(function) declarators, and in the argument to ``sizeof...``. (function) declarators, and in the argument to ``sizeof...``.
* C, fix linking of names in array declarators. * C, fix linking of names in array declarators.
4.0.0b2
* C, C++, fix ``KeyError`` when an ``alias`` directive is the first C/C++
directive in a file with another C/C++ directive later.
4.0.0b3
* #9167: html: Failed to add CSS files to the specific page
Release 3.5.5 (in development) Release 3.5.5 (in development)
============================== ==============================

133
EXAMPLES
View File

@ -25,14 +25,14 @@ Documentation using the alabaster theme
* `Flask-OpenID <https://pythonhosted.org/Flask-OpenID/>`__ * `Flask-OpenID <https://pythonhosted.org/Flask-OpenID/>`__
* `Invoke <https://docs.pyinvoke.org/>`__ * `Invoke <https://docs.pyinvoke.org/>`__
* `Jinja <https://jinja.palletsprojects.com/>`__ * `Jinja <https://jinja.palletsprojects.com/>`__
* `Lino <http://www.lino-framework.org/>`__ (customized) * `Lino <https://www.lino-framework.org/>`__ (customized)
* `marbl <https://getmarbl.readthedocs.io/>`__ * `marbl <https://getmarbl.readthedocs.io/>`__
* `MDAnalysis <https://www.mdanalysis.org/docs/>`__ (customized) * `MDAnalysis <https://www.mdanalysis.org/docs/>`__ (customized)
* `MeshPy <https://documen.tician.de/meshpy/>`__ * `MeshPy <https://documen.tician.de/meshpy/>`__
* `Molecule <https://molecule.readthedocs.io/>`__ * `Molecule <https://molecule.readthedocs.io/>`__
* `PyCUDA <https://documen.tician.de/pycuda/>`__ * `PyCUDA <https://documen.tician.de/pycuda/>`__
* `PyOpenCL <https://documen.tician.de/pyopencl/>`__ * `PyOpenCL <https://documen.tician.de/pyopencl/>`__
* `PyLangAcq <http://pylangacq.org/>`__ * `PyLangAcq <https://pylangacq.org/>`__
* `pytest <https://docs.pytest.org/>`__ (customized) * `pytest <https://docs.pytest.org/>`__ (customized)
* `python-apt <https://apt.alioth.debian.org/python-apt-doc/>`__ * `python-apt <https://apt.alioth.debian.org/python-apt-doc/>`__
* `PyVisfile <https://documen.tician.de/pyvisfile/>`__ * `PyVisfile <https://documen.tician.de/pyvisfile/>`__
@ -47,10 +47,10 @@ Documentation using the alabaster theme
Documentation using the classic theme Documentation using the classic theme
------------------------------------- -------------------------------------
* `Advanced Generic Widgets <http://xoomer.virgilio.it/infinity77/AGW_Docs/>`__ (customized) * `Advanced Generic Widgets <https://xoomer.virgilio.it/infinity77/AGW_Docs/>`__ (customized)
* `Apache CouchDB <http://docs.couchdb.org/>`__ (customized) * `Apache CouchDB <https://docs.couchdb.org/>`__ (customized)
* `APSW <https://rogerbinns.github.io/apsw/>`__ * `APSW <https://rogerbinns.github.io/apsw/>`__
* `Arb <http://arblib.org/>`__ * `Arb <https://arblib.org/>`__
* `Bazaar <http://doc.bazaar.canonical.com/>`__ (customized) * `Bazaar <http://doc.bazaar.canonical.com/>`__ (customized)
* `Beautiful Soup <https://www.crummy.com/software/BeautifulSoup/bs4/doc/>`__ * `Beautiful Soup <https://www.crummy.com/software/BeautifulSoup/bs4/doc/>`__
* `Blender API <https://docs.blender.org/api/current/>`__ * `Blender API <https://docs.blender.org/api/current/>`__
@ -70,7 +70,7 @@ Documentation using the classic theme
* `GetFEM++ <http://getfem.org/>`__ (customized) * `GetFEM++ <http://getfem.org/>`__ (customized)
* `Glasgow Haskell Compiler <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/>`__ (customized) * `Glasgow Haskell Compiler <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/>`__ (customized)
* `Grok <http://grok.zope.org/doc/current/>`__ (customized) * `Grok <http://grok.zope.org/doc/current/>`__ (customized)
* `GROMACS <http://manual.gromacs.org/documentation/>`__ * `GROMACS <https://manual.gromacs.org/documentation/>`__
* `GSL Shell <https://www.nongnu.org/gsl-shell/>`__ * `GSL Shell <https://www.nongnu.org/gsl-shell/>`__
* `Hands-on Python Tutorial <https://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/>`__ * `Hands-on Python Tutorial <https://anh.cs.luc.edu/python/hands-on/3.1/handsonHtml/>`__
* `Kaa <https://api.freevo.org/kaa-base/>`__ (customized) * `Kaa <https://api.freevo.org/kaa-base/>`__ (customized)
@ -78,9 +78,9 @@ Documentation using the classic theme
* `LEPL <http://www.acooke.org/lepl/>`__ (customized) * `LEPL <http://www.acooke.org/lepl/>`__ (customized)
* `Mayavi <https://docs.enthought.com/mayavi/mayavi/>`__ (customized) * `Mayavi <https://docs.enthought.com/mayavi/mayavi/>`__ (customized)
* `MediaGoblin <https://mediagoblin.readthedocs.io/>`__ (customized) * `MediaGoblin <https://mediagoblin.readthedocs.io/>`__ (customized)
* `mpmath <http://mpmath.org/doc/current/>`__ * `mpmath <https://mpmath.org/doc/current/>`__
* `OpenCV <https://docs.opencv.org/>`__ (customized) * `OpenCV <https://docs.opencv.org/>`__ (customized)
* `OpenEXR <http://excamera.com/articles/26/doc/index.html>`__ * `OpenEXR <https://excamera.com/articles/26/doc/index.html>`__
* `OpenGDA <http://www.opengda.org/gdadoc/html/>`__ * `OpenGDA <http://www.opengda.org/gdadoc/html/>`__
* `Peach^3 <https://peach3.nl/doc/latest/userdoc/>`__ (customized) * `Peach^3 <https://peach3.nl/doc/latest/userdoc/>`__ (customized)
* `Plone <https://docs.plone.org/>`__ (customized) * `Plone <https://docs.plone.org/>`__ (customized)
@ -119,8 +119,8 @@ Documentation using the sphinxdoc theme
* `Matplotlib <https://matplotlib.org/>`__ * `Matplotlib <https://matplotlib.org/>`__
* `MDAnalysis Tutorial <https://www.mdanalysis.org/MDAnalysisTutorial/>`__ * `MDAnalysis Tutorial <https://www.mdanalysis.org/MDAnalysisTutorial/>`__
* `NetworkX <https://networkx.github.io/>`__ * `NetworkX <https://networkx.github.io/>`__
* `PyCantonese <http://pycantonese.org/>`__ * `PyCantonese <https://pycantonese.org/>`__
* `Pyre <http://docs.danse.us/pyre/sphinx/>`__ * `Pyre <https://docs.danse.us/pyre/sphinx/>`__
* `pySPACE <https://pyspace.github.io/pyspace/>`__ * `pySPACE <https://pyspace.github.io/pyspace/>`__
* `Pysparse <http://pysparse.sourceforge.net/>`__ * `Pysparse <http://pysparse.sourceforge.net/>`__
* `PyTango <https://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/pytango/latest/>`__ * `PyTango <https://www.esrf.eu/computing/cs/tango/tango_doc/kernel_doc/pytango/latest/>`__
@ -134,7 +134,7 @@ Documentation using the nature theme
------------------------------------ ------------------------------------
* `Alembic <https://alembic.sqlalchemy.org/>`__ * `Alembic <https://alembic.sqlalchemy.org/>`__
* `Cython <http://docs.cython.org/>`__ * `Cython <https://docs.cython.org/>`__
* `easybuild <https://easybuild.readthedocs.io/>`__ * `easybuild <https://easybuild.readthedocs.io/>`__
* `jsFiddle <http://doc.jsfiddle.net/>`__ * `jsFiddle <http://doc.jsfiddle.net/>`__
* `libLAS <https://www.liblas.org/>`__ (customized) * `libLAS <https://www.liblas.org/>`__ (customized)
@ -159,18 +159,19 @@ Documentation using another builtin theme
* `Pylons <https://docs.pylonsproject.org/projects/pylons-webframework/>`__ (pyramid) * `Pylons <https://docs.pylonsproject.org/projects/pylons-webframework/>`__ (pyramid)
* `Pyramid web framework <https://docs.pylonsproject.org/projects/pyramid/>`__ (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/html/devel/>`__
* `Sphinx <http://www.sphinx-doc.org/>`__ (sphinx13) :-) * `Sphinx <https://www.sphinx-doc.org/>`__ (sphinx13) :-)
* `Valence <https://docs.valence.desire2learn.com/>`__ (haiku, customized) * `Valence <https://docs.valence.desire2learn.com/>`__ (haiku, customized)
Documentation using sphinx_rtd_theme Documentation using sphinx_rtd_theme
------------------------------------ ------------------------------------
* `Annotator <http://docs.annotatorjs.org/>`__ * `Annotator <https://docs.annotatorjs.org/>`__
* `Ansible <https://docs.ansible.com/>`__ (customized) * `Ansible <https://docs.ansible.com/>`__ (customized)
* `Arcade <http://arcade.academy/>`__ * `Arcade <https://arcade.academy/>`__
* `aria2 <https://aria2.github.io/manual/en/html/>`__ * `aria2 <https://aria2.github.io/manual/en/html/>`__
* `ASE <https://wiki.fysik.dtu.dk/ase/>`__ * `ASE <https://wiki.fysik.dtu.dk/ase/>`__
* `Autofac <http://docs.autofac.org/>`__ * `asvin <https://asvin.readthedocs.io/>`__
* `Autofac <https://docs.autofac.org/>`__
* `BigchainDB <https://docs.bigchaindb.com/>`__ * `BigchainDB <https://docs.bigchaindb.com/>`__
* `Blender Reference Manual <https://docs.blender.org/manual/>`__ * `Blender Reference Manual <https://docs.blender.org/manual/>`__
* `Blocks <https://blocks.readthedocs.io/>`__ * `Blocks <https://blocks.readthedocs.io/>`__
@ -188,28 +189,28 @@ Documentation using sphinx_rtd_theme
* `DNF <https://dnf.readthedocs.io/>`__ * `DNF <https://dnf.readthedocs.io/>`__
* `Django-cas-ng <https://djangocas.dev/docs/>`__ * `Django-cas-ng <https://djangocas.dev/docs/>`__
* `edX <https://docs.edx.org/>`__ * `edX <https://docs.edx.org/>`__
* `Electrum <http://docs.electrum.org/>`__ * `Electrum <https://docs.electrum.org/>`__
* `Elemental <http://libelemental.org/documentation/dev/>`__ * `Elemental <https://libelemental.org/documentation/dev/>`__
* `ESWP3 <https://eswp3.readthedocs.io/>`__ * `ESWP3 <https://eswp3.readthedocs.io/>`__
* `Ethereum Homestead <http://www.ethdocs.org/>`__ * `Ethereum Homestead <https://www.ethdocs.org/>`__
* `Exhale <https://exhale.readthedocs.io/>`__ * `Exhale <https://exhale.readthedocs.io/>`__
* `Faker <https://faker.readthedocs.io/>`__ * `Faker <https://faker.readthedocs.io/>`__
* `Fidimag <https://fidimag.readthedocs.io/>`__ * `Fidimag <https://fidimag.readthedocs.io/>`__
* `Flake8 <http://flake8.pycqa.org/>`__ * `Flake8 <https://flake8.pycqa.org/>`__
* `Flatpak <http://docs.flatpak.org/>`__ * `Flatpak <https://docs.flatpak.org/>`__
* `FluidDyn <https://fluiddyn.readthedocs.io/>`__ * `FluidDyn <https://fluiddyn.readthedocs.io/>`__
* `Fluidsim <https://fluidsim.readthedocs.io/>`__ * `Fluidsim <https://fluidsim.readthedocs.io/>`__
* `Gallium <https://gallium.readthedocs.io/>`__ * `Gallium <https://gallium.readthedocs.io/>`__
* `GeoNode <http://docs.geonode.org/>`__ * `GeoNode <https://docs.geonode.org/>`__
* `Glances <https://glances.readthedocs.io/>`__ * `Glances <https://glances.readthedocs.io/>`__
* `Godot <https://godot.readthedocs.io/>`__ * `Godot <https://godot.readthedocs.io/>`__
* `Graylog <http://docs.graylog.org/>`__ * `Graylog <https://docs.graylog.org/>`__
* `GPAW <https://wiki.fysik.dtu.dk/gpaw/>`__ (customized) * `GPAW <https://wiki.fysik.dtu.dk/gpaw/>`__ (customized)
* `HDF5 for Python (h5py) <http://docs.h5py.org/>`__ * `HDF5 for Python (h5py) <https://docs.h5py.org/>`__
* `Hyperledger Fabric <https://hyperledger-fabric.readthedocs.io/>`__ * `Hyperledger Fabric <https://hyperledger-fabric.readthedocs.io/>`__
* `Hyperledger Sawtooth <https://intelledger.github.io/>`__ * `Hyperledger Sawtooth <https://intelledger.github.io/>`__
* `IdentityServer <http://docs.identityserver.io/>`__ * `IdentityServer <https://docs.identityserver.io/>`__
* `Idris <http://docs.idris-lang.org/>`__ * `Idris <https://docs.idris-lang.org/>`__
* `javasphinx <https://bronto-javasphinx.readthedocs.io/>`__ * `javasphinx <https://bronto-javasphinx.readthedocs.io/>`__
* `Julia <https://julia.readthedocs.io/>`__ * `Julia <https://julia.readthedocs.io/>`__
* `Jupyter Notebook <https://jupyter-notebook.readthedocs.io/>`__ * `Jupyter Notebook <https://jupyter-notebook.readthedocs.io/>`__
@ -219,45 +220,45 @@ Documentation using sphinx_rtd_theme
* `LibCEED <https://libceed.readthedocs.io/>`__ * `LibCEED <https://libceed.readthedocs.io/>`__
* `Linguistica <https://linguistica-uchicago.github.io/lxa5/>`__ * `Linguistica <https://linguistica-uchicago.github.io/lxa5/>`__
* `Linux kernel <https://www.kernel.org/doc/html/latest/index.html>`__ * `Linux kernel <https://www.kernel.org/doc/html/latest/index.html>`__
* `Mailman <http://docs.list.org/>`__ * `Mailman <https://docs.list.org/>`__
* `MathJax <https://docs.mathjax.org/>`__ * `MathJax <https://docs.mathjax.org/>`__
* `MDTraj <http://mdtraj.org/latest/>`__ (customized) * `MDTraj <http://mdtraj.org/latest/>`__ (customized)
* `Mesa 3D <https://docs.mesa3d.org/>`__ * `Mesa 3D <https://docs.mesa3d.org/>`__
* `micca - MICrobial Community Analysis <https://micca.readthedocs.io/>`__ * `micca - MICrobial Community Analysis <https://micca.readthedocs.io/>`__
* `MicroPython <https://docs.micropython.org/>`__ * `MicroPython <https://docs.micropython.org/>`__
* `Minds <https://www.minds.org/docs/>`__ (customized) * `Minds <https://www.minds.org/docs/>`__ (customized)
* `Mink <http://mink.behat.org/>`__ * `Mink <https://mink.behat.org/>`__
* `Mockery <http://docs.mockery.io/>`__ * `Mockery <https://docs.mockery.io/>`__
* `mod_wsgi <https://modwsgi.readthedocs.io/>`__ * `mod_wsgi <https://modwsgi.readthedocs.io/>`__
* `MoinMoin <https://moin-20.readthedocs.io/>`__ * `MoinMoin <https://moin-20.readthedocs.io/>`__
* `Mopidy <https://docs.mopidy.com/>`__ * `Mopidy <https://docs.mopidy.com/>`__
* `mpi4py <https://mpi4py.readthedocs.io/>`__ * `mpi4py <https://mpi4py.readthedocs.io/>`__
* `MyHDL <http://docs.myhdl.org/>`__ * `MyHDL <https://docs.myhdl.org/>`__
* `Nextflow <https://www.nextflow.io/docs/latest/index.html>`__ * `Nextflow <https://www.nextflow.io/docs/latest/index.html>`__
* `NICOS <https://forge.frm2.tum.de/nicos/doc/nicos-master/>`__ (customized) * `NICOS <https://forge.frm2.tum.de/nicos/doc/nicos-master/>`__ (customized)
* `OpenFAST <https://openfast.readthedocs.io/>`__ * `OpenFAST <https://openfast.readthedocs.io/>`__
* `Pelican <http://docs.getpelican.com/>`__ * `Pelican <https://docs.getpelican.com/>`__
* `picamera <https://picamera.readthedocs.io/>`__ * `picamera <https://picamera.readthedocs.io/>`__
* `Pillow <https://pillow.readthedocs.io/>`__ * `Pillow <https://pillow.readthedocs.io/>`__
* `pip <https://pip.pypa.io/>`__ * `pip <https://pip.pypa.io/>`__
* `Paver <https://paver.readthedocs.io/>`__ * `Paver <https://paver.readthedocs.io/>`__
* `peewee <http://docs.peewee-orm.com/>`__ * `peewee <https://docs.peewee-orm.com/>`__
* `Phinx <http://docs.phinx.org/>`__ * `Phinx <https://docs.phinx.org/>`__
* `phpMyAdmin <https://docs.phpmyadmin.net/>`__ * `phpMyAdmin <https://docs.phpmyadmin.net/>`__
* `PROS <https://pros.cs.purdue.edu/v5/>`__ (customized) * `PROS <https://pros.cs.purdue.edu/v5/>`__ (customized)
* `Pushkin <http://docs.pushkin.io/>`__ * `Pushkin <http://docs.pushkin.io/>`__
* `Pweave <http://mpastell.com/pweave/>`__ * `Pweave <https://mpastell.com/pweave/>`__
* `PyPy <http://doc.pypy.org/>`__ * `PyPy <https://doc.pypy.org/>`__
* `python-sqlparse <https://sqlparse.readthedocs.io/>`__ * `python-sqlparse <https://sqlparse.readthedocs.io/>`__
* `PyVISA <https://pyvisa.readthedocs.io/>`__ * `PyVISA <https://pyvisa.readthedocs.io/>`__
* `pyvista <https://docs.pyvista.org/>`__ * `pyvista <https://docs.pyvista.org/>`__
* `Read The Docs <https://docs.readthedocs.io/>`__ * `Read The Docs <https://docs.readthedocs.io/>`__
* `ROCm Platform <https://rocm-documentation.readthedocs.io/>`__ * `ROCm Platform <https://rocm-documentation.readthedocs.io/>`__
* `Free your information from their silos (French) <http://redaction-technique.org/>`__ (customized) * `Free your information from their silos (French) <https://redaction-technique.org/>`__ (customized)
* `Releases Sphinx extension <https://releases.readthedocs.io/>`__ * `Releases Sphinx extension <https://releases.readthedocs.io/>`__
* `Qtile <http://docs.qtile.org/>`__ * `Qtile <https://docs.qtile.org/>`__
* `Quex <http://quex.sourceforge.net/doc/html/main.html>`__ * `Quex <http://quex.sourceforge.net/doc/html/main.html>`__
* `QuTiP <http://qutip.org/docs/latest/>`__ * `QuTiP <https://qutip.org/docs/latest/>`__
* `Satchmo <http://docs.satchmoproject.com/>`__ * `Satchmo <http://docs.satchmoproject.com/>`__
* `Scapy <https://scapy.readthedocs.io/>`__ * `Scapy <https://scapy.readthedocs.io/>`__
* `SimGrid <https://simgrid.org/doc/latest/>`__ * `SimGrid <https://simgrid.org/doc/latest/>`__
@ -265,7 +266,7 @@ Documentation using sphinx_rtd_theme
* `six <https://six.readthedocs.io/>`__ * `six <https://six.readthedocs.io/>`__
* `SlamData <https://newdocs.slamdata.com>`__ * `SlamData <https://newdocs.slamdata.com>`__
* `Solidity <https://solidity.readthedocs.io/>`__ * `Solidity <https://solidity.readthedocs.io/>`__
* `Sonos Controller (SoCo) <http://docs.python-soco.com/>`__ * `Sonos Controller (SoCo) <https://docs.python-soco.com/>`__
* `Sphinx AutoAPI <https://sphinx-autoapi.readthedocs.io/>`__ * `Sphinx AutoAPI <https://sphinx-autoapi.readthedocs.io/>`__
* `sphinx-argparse <https://sphinx-argparse.readthedocs.io/>`__ * `sphinx-argparse <https://sphinx-argparse.readthedocs.io/>`__
* `Sphinx-Gallery <https://sphinx-gallery.readthedocs.io/>`__ (customized) * `Sphinx-Gallery <https://sphinx-gallery.readthedocs.io/>`__ (customized)
@ -277,7 +278,7 @@ Documentation using sphinx_rtd_theme
* `Sylius <http://docs.sylius.org/>`__ * `Sylius <http://docs.sylius.org/>`__
* `Syncthing <https://docs.syncthing.net/>`__ * `Syncthing <https://docs.syncthing.net/>`__
* `Tango Controls <https://tango-controls.readthedocs.io/>`__ (customized) * `Tango Controls <https://tango-controls.readthedocs.io/>`__ (customized)
* `Topshelf <http://docs.topshelf-project.com/>`__ * `Topshelf <https://docs.topshelf-project.com/>`__
* `Theano <http://www.deeplearning.net/software/theano/>`__ * `Theano <http://www.deeplearning.net/software/theano/>`__
* `ThreatConnect <https://docs.threatconnect.com/>`__ * `ThreatConnect <https://docs.threatconnect.com/>`__
* `Tuleap <https://tuleap.net/doc/en/>`__ * `Tuleap <https://tuleap.net/doc/en/>`__
@ -286,7 +287,7 @@ Documentation using sphinx_rtd_theme
* `uWSGI <https://uwsgi-docs.readthedocs.io/>`__ * `uWSGI <https://uwsgi-docs.readthedocs.io/>`__
* `virtualenv <https://virtualenv.readthedocs.io/>`__ * `virtualenv <https://virtualenv.readthedocs.io/>`__
* `Wagtail <https://docs.wagtail.io/>`__ * `Wagtail <https://docs.wagtail.io/>`__
* `Web Application Attack and Audit Framework (w3af) <http://docs.w3af.org/>`__ * `Web Application Attack and Audit Framework (w3af) <https://docs.w3af.org/>`__
* `Weblate <https://docs.weblate.org/>`__ * `Weblate <https://docs.weblate.org/>`__
* `x265 <https://x265.readthedocs.io/>`__ * `x265 <https://x265.readthedocs.io/>`__
* `Zulip <https://zulip.readthedocs.io/>`__ * `Zulip <https://zulip.readthedocs.io/>`__
@ -296,14 +297,14 @@ Documentation using sphinx_bootstrap_theme
* `Bootstrap Theme <https://ryan-roemer.github.io/sphinx-bootstrap-theme/>`__ * `Bootstrap Theme <https://ryan-roemer.github.io/sphinx-bootstrap-theme/>`__
* `C/C++ Software Development with Eclipse <https://eclipsebook.in/>`__ * `C/C++ Software Development with Eclipse <https://eclipsebook.in/>`__
* `Dataverse <http://guides.dataverse.org/>`__ * `Dataverse <https://guides.dataverse.org/>`__
* `e-cidadania <https://e-cidadania.readthedocs.io/>`__ * `e-cidadania <https://e-cidadania.readthedocs.io/>`__
* `Hangfire <http://docs.hangfire.io/>`__ * `Hangfire <https://docs.hangfire.io/>`__
* `Hedge <https://documen.tician.de/hedge/>`__ * `Hedge <https://documen.tician.de/hedge/>`__
* `ObsPy <https://docs.obspy.org/>`__ * `ObsPy <https://docs.obspy.org/>`__
* `Open Dylan <https://opendylan.org/documentation/>`__ * `Open Dylan <https://opendylan.org/documentation/>`__
* `OPNFV <https://docs.opnfv.org/>`__ * `OPNFV <https://docs.opnfv.org/>`__
* `Pootle <http://docs.translatehouse.org/projects/pootle/>`__ * `Pootle <https://docs.translatehouse.org/projects/pootle/>`__
* `PyUblas <https://documen.tician.de/pyublas/>`__ * `PyUblas <https://documen.tician.de/pyublas/>`__
* `seaborn <https://seaborn.pydata.org/>`__ * `seaborn <https://seaborn.pydata.org/>`__
@ -312,12 +313,12 @@ Documentation using a custom theme or integrated in a website
* `AIOHTTP <https://docs.aiohttp.org/>`__ * `AIOHTTP <https://docs.aiohttp.org/>`__
* `Apache Cassandra <https://cassandra.apache.org/doc/>`__ * `Apache Cassandra <https://cassandra.apache.org/doc/>`__
* `Astropy <http://docs.astropy.org/>`__ * `Astropy <https://docs.astropy.org/>`__
* `Bokeh <https://bokeh.pydata.org/>`__ * `Bokeh <https://bokeh.pydata.org/>`__
* `Boto 3 <https://boto3.readthedocs.io/>`__ * `Boto 3 <https://boto3.readthedocs.io/>`__
* `CakePHP <https://book.cakephp.org/>`__ * `CakePHP <https://book.cakephp.org/>`__
* `CasperJS <http://docs.casperjs.org/>`__ * `CasperJS <http://docs.casperjs.org/>`__
* `Ceph <http://docs.ceph.com/docs/master/>`__ * `Ceph <https://docs.ceph.com/docs/master/>`__
* `Chef <https://docs.chef.io/>`__ * `Chef <https://docs.chef.io/>`__
* `CKAN <https://docs.ckan.org/>`__ * `CKAN <https://docs.ckan.org/>`__
* `Confluent Platform <https://docs.confluent.io/>`__ * `Confluent Platform <https://docs.confluent.io/>`__
@ -326,24 +327,24 @@ Documentation using a custom theme or integrated in a website
* `Enterprise Toolkit for Acrobat products <https://www.adobe.com/devnet-docs/acrobatetk/>`__ * `Enterprise Toolkit for Acrobat products <https://www.adobe.com/devnet-docs/acrobatetk/>`__
* `FreeFEM <https://doc.freefem.org/introduction/>`__ * `FreeFEM <https://doc.freefem.org/introduction/>`__
* `fmt <https://fmt.dev/>`__ * `fmt <https://fmt.dev/>`__
* `Gameduino <http://excamera.com/sphinx/gameduino/>`__ * `Gameduino <https://excamera.com/sphinx/gameduino/>`__
* `gensim <https://radimrehurek.com/gensim/>`__ * `gensim <https://radimrehurek.com/gensim/>`__
* `GeoServer <http://docs.geoserver.org/>`__ * `GeoServer <https://docs.geoserver.org/>`__
* `gevent <http://www.gevent.org/>`__ * `gevent <https://www.gevent.org/>`__
* `GHC - Glasgow Haskell Compiler <https://downloads.haskell.org/~ghc/master/users-guide/>`__ * `GHC - Glasgow Haskell Compiler <https://downloads.haskell.org/~ghc/master/users-guide/>`__
* `Guzzle <http://docs.guzzlephp.org/>`__ * `Guzzle <https://docs.guzzlephp.org/>`__
* `H2O.ai <http://docs.h2o.ai/>`__ * `H2O.ai <https://docs.h2o.ai/>`__
* `Heka <https://hekad.readthedocs.io/>`__ * `Heka <https://hekad.readthedocs.io/>`__
* `Istihza (Turkish Python documentation project) <https://belgeler.yazbel.com/python-istihza/>`__ * `Istihza (Turkish Python documentation project) <https://belgeler.yazbel.com/python-istihza/>`__
* `JupyterHub <https://jupyterhub.readthedocs.io/>`__ * `JupyterHub <https://jupyterhub.readthedocs.io/>`__
* `Kombu <http://docs.kombu.me/>`__ * `Kombu <http://docs.kombu.me/>`__
* `Lasso <http://lassoguide.com/>`__ * `Lasso <https://lassoguide.com/>`__
* `Mako <http://docs.makotemplates.org/>`__ * `Mako <https://docs.makotemplates.org/>`__
* `MirrorBrain <http://mirrorbrain.org/docs/>`__ * `MirrorBrain <https://mirrorbrain.org/docs/>`__
* `Mitiq <https://mitiq.readthedocs.io/>`__ * `Mitiq <https://mitiq.readthedocs.io/>`__
* `MongoDB <https://docs.mongodb.com/>`__ * `MongoDB <https://docs.mongodb.com/>`__
* `Music21 <https://web.mit.edu/music21/doc/>`__ * `Music21 <https://web.mit.edu/music21/doc/>`__
* `MyHDL <http://docs.myhdl.org/>`__ * `MyHDL <https://docs.myhdl.org/>`__
* `ndnSIM <https://ndnsim.net/current/>`__ * `ndnSIM <https://ndnsim.net/current/>`__
* `nose <https://nose.readthedocs.io/>`__ * `nose <https://nose.readthedocs.io/>`__
* `ns-3 <https://www.nsnam.org/documentation/>`__ * `ns-3 <https://www.nsnam.org/documentation/>`__
@ -353,30 +354,30 @@ Documentation using a custom theme or integrated in a website
* `OpenCV <https://docs.opencv.org/>`__ * `OpenCV <https://docs.opencv.org/>`__
* `OpenLayers <http://docs.openlayers.org/>`__ * `OpenLayers <http://docs.openlayers.org/>`__
* `OpenTURNS <https://openturns.github.io/openturns/master/>`__ * `OpenTURNS <https://openturns.github.io/openturns/master/>`__
* `Open vSwitch <http://docs.openvswitch.org/>`__ * `Open vSwitch <https://docs.openvswitch.org/>`__
* `PlatformIO <https://docs.platformio.org/>`__ * `PlatformIO <https://docs.platformio.org/>`__
* `PyEphem <http://rhodesmill.org/pyephem/>`__ * `PyEphem <https://rhodesmill.org/pyephem/>`__
* `Pygments <http://pygments.org/docs/>`__ * `Pygments <https://pygments.org/docs/>`__
* `Plone User Manual (German) <https://www.hasecke.com/plone-benutzerhandbuch/4.0/>`__ * `Plone User Manual (German) <https://www.hasecke.com/plone-benutzerhandbuch/4.0/>`__
* `PSI4 <http://www.psicode.org/psi4manual/master/index.html>`__ * `PSI4 <https://www.psicode.org/psi4manual/master/index.html>`__
* `PyMOTW <https://pymotw.com/2/>`__ * `PyMOTW <https://pymotw.com/2/>`__
* `python-aspectlib <https://python-aspectlib.readthedocs.io/>`__ (`sphinx_py3doc_enhanced_theme <https://pypi.org/project/sphinx_py3doc_enhanced_theme/>`__) * `python-aspectlib <https://python-aspectlib.readthedocs.io/>`__ (`sphinx_py3doc_enhanced_theme <https://pypi.org/project/sphinx_py3doc_enhanced_theme/>`__)
* `QGIS <https://qgis.org/en/docs/index.html>`__ * `QGIS <https://qgis.org/en/docs/index.html>`__
* `qooxdoo <https://www.qooxdoo.org/current/>`__ * `qooxdoo <https://www.qooxdoo.org/current/>`__
* `Roundup <http://www.roundup-tracker.org/>`__ * `Roundup <https://www.roundup-tracker.org/>`__
* `SaltStack <https://docs.saltstack.com/>`__ * `SaltStack <https://docs.saltstack.com/>`__
* `scikit-learn <http://scikit-learn.org/stable/>`__ * `scikit-learn <https://scikit-learn.org/stable/>`__
* `SciPy <https://docs.scipy.org/doc/scipy/reference/>`__ * `SciPy <https://docs.scipy.org/doc/scipy/reference/>`__
* `Scrapy <https://doc.scrapy.org/>`__ * `Scrapy <https://doc.scrapy.org/>`__
* `Seaborn <https://seaborn.pydata.org/>`__ * `Seaborn <https://seaborn.pydata.org/>`__
* `Selenium <https://docs.seleniumhq.org/docs/>`__ * `Selenium <https://docs.seleniumhq.org/docs/>`__
* `Self <http://www.selflanguage.org/>`__ * `Self <https://www.selflanguage.org/>`__
* `Substance D <https://docs.pylonsproject.org/projects/substanced/>`__ * `Substance D <https://docs.pylonsproject.org/projects/substanced/>`__
* `Sulu <http://docs.sulu.io/>`__ * `Sulu <https://docs.sulu.io/>`__
* `SQLAlchemy <https://docs.sqlalchemy.org/>`__ * `SQLAlchemy <https://docs.sqlalchemy.org/>`__
* `tinyTiM <http://tinytim.sourceforge.net/docs/2.0/>`__ * `tinyTiM <http://tinytim.sourceforge.net/docs/2.0/>`__
* `Twisted <https://twistedmatrix.com/documents/current/>`__ * `Twisted <https://twistedmatrix.com/documents/current/>`__
* `Ubuntu Packaging Guide <http://packaging.ubuntu.com/html/>`__ * `Ubuntu Packaging Guide <https://packaging.ubuntu.com/html/>`__
* `WebFaction <https://docs.webfaction.com/>`__ * `WebFaction <https://docs.webfaction.com/>`__
* `WTForms <https://wtforms.readthedocs.io/>`__ * `WTForms <https://wtforms.readthedocs.io/>`__
@ -387,7 +388,7 @@ Homepages and other non-documentation sites
* `Benoit Boissinot <https://bboissin.appspot.com/>`__ (classic, customized) * `Benoit Boissinot <https://bboissin.appspot.com/>`__ (classic, customized)
* `Computer Networks, Parallelization, and Simulation Laboratory (CNPSLab) <https://lab.miletic.net/>`__ (sphinx_rtd_theme) * `Computer Networks, Parallelization, and Simulation Laboratory (CNPSLab) <https://lab.miletic.net/>`__ (sphinx_rtd_theme)
* `Deep Learning Tutorials <http://www.deeplearning.net/tutorial/>`__ (sphinxdoc) * `Deep Learning Tutorials <http://www.deeplearning.net/tutorial/>`__ (sphinxdoc)
* `Eric Holscher <http://ericholscher.com/>`__ (alabaster) * `Eric Holscher <https://ericholscher.com/>`__ (alabaster)
* `Lei Ma's Statistical Mechanics lecture notes <http://statisticalphysics.openmetric.org/>`__ (sphinx_bootstrap_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) * `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) * `Pylearn2 <http://www.deeplearning.net/software/pylearn2/>`__ (sphinxdoc, customized)
@ -408,7 +409,7 @@ Books produced using Sphinx
* `"Expert Python Programming" (Japanese translation) <https://www.amazon.co.jp/dp/4048686291/>`__ * `"Expert Python Programming" (Japanese translation) <https://www.amazon.co.jp/dp/4048686291/>`__
* `"Expert Python Programming 2nd Edition" (Japanese translation) <https://www.amazon.co.jp/dp/4048930613/>`__ * `"Expert Python Programming 2nd Edition" (Japanese translation) <https://www.amazon.co.jp/dp/4048930613/>`__
* `"The Hitchhiker's Guide to Python" <https://docs.python-guide.org/>`__ * `"The Hitchhiker's Guide to Python" <https://docs.python-guide.org/>`__
* `"LassoGuide" <http://www.lassosoft.com/Lasso-Documentation>`__ * `"LassoGuide" <https://www.lassosoft.com/Lasso-Documentation>`__
* `"Learning Sphinx" (in Japanese) <https://www.oreilly.co.jp/books/9784873116488/>`__ * `"Learning Sphinx" (in Japanese) <https://www.oreilly.co.jp/books/9784873116488/>`__
* `"Learning System Programming with Go (Japanese)" <https://www.lambdanote.com/products/go>`__ * `"Learning System Programming with Go (Japanese)" <https://www.lambdanote.com/products/go>`__
* `"Mercurial: the definitive guide (Second edition)" <https://book.mercurial-scm.org/>`__ * `"Mercurial: the definitive guide (Second edition)" <https://book.mercurial-scm.org/>`__
@ -416,7 +417,7 @@ Books produced using Sphinx
* `"Pioneers and Prominent Men of Utah" <http://pioneers.rstebbing.com/>`__ * `"Pioneers and Prominent Men of Utah" <http://pioneers.rstebbing.com/>`__
* `"Pomodoro Technique Illustrated" (Japanese translation) <https://www.amazon.co.jp/dp/4048689525/>`__ * `"Pomodoro Technique Illustrated" (Japanese translation) <https://www.amazon.co.jp/dp/4048689525/>`__
* `"Professional Software Development" <https://mixmastamyk.bitbucket.io/pro_soft_dev/>`__ * `"Professional Software Development" <https://mixmastamyk.bitbucket.io/pro_soft_dev/>`__
* `"Python Professional Programming" (in Japanese) <http://www.amazon.co.jp/dp/4798032948/>`__ * `"Python Professional Programming" (in Japanese) <https://www.amazon.co.jp/dp/4798032948/>`__
* `"Python Professional Programming 2nd Edition" (in Japanese) <https://www.amazon.co.jp/dp/479804315X/>`__ * `"Python Professional Programming 2nd Edition" (in Japanese) <https://www.amazon.co.jp/dp/479804315X/>`__
* `"Python Professional Programming 3rd Edition" (in Japanese) <https://www.amazon.co.jp/dp/4798053821/>`__ * `"Python Professional Programming 3rd Edition" (in Japanese) <https://www.amazon.co.jp/dp/4798053821/>`__
* `Python Course by Yuri Petrov (Russian) <https://www.yuripetrov.ru/edu/python>`__ * `Python Course by Yuri Petrov (Russian) <https://www.yuripetrov.ru/edu/python>`__

View File

@ -10,10 +10,6 @@
:target: http://www.sphinx-doc.org/ :target: http://www.sphinx-doc.org/
:alt: Documentation Status :alt: Documentation Status
.. image:: https://travis-ci.org/sphinx-doc/sphinx.svg?branch=master
:target: https://travis-ci.org/sphinx-doc/sphinx
:alt: Build Status (Travis CI)
.. image:: https://ci.appveyor.com/api/projects/status/github/sphinx-doc/sphinx?branch=master&svg=true .. image:: https://ci.appveyor.com/api/projects/status/github/sphinx-doc/sphinx?branch=master&svg=true
:target: https://ci.appveyor.com/project/sphinxdoc/sphinx :target: https://ci.appveyor.com/project/sphinxdoc/sphinx
:alt: Build Status (AppVeyor) :alt: Build Status (AppVeyor)

View File

@ -1,7 +1,7 @@
# How to setup this file # How to setup this file
# http://babel.pocoo.org/en/latest/installation.html # https://babel.pocoo.org/en/latest/installation.html
# this file description: # this file description:
# http://babel.pocoo.org/en/latest/messages.html # https://babel.pocoo.org/en/latest/messages.html
# Extraction from Python source files # Extraction from Python source files
[python: **.py] [python: **.py]

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -29,7 +29,7 @@
<li>{%trans%}<b>Automatic indices:</b> general index as well as a language-specific <li>{%trans%}<b>Automatic indices:</b> general index as well as a language-specific
module indices{%endtrans%}</li> module indices{%endtrans%}</li>
<li>{%trans%}<b>Code handling:</b> automatic highlighting using the <a <li>{%trans%}<b>Code handling:</b> automatic highlighting using the <a
href="http://pygments.org">Pygments</a> highlighter{%endtrans%}</li> href="https://pygments.org">Pygments</a> highlighter{%endtrans%}</li>
<li>{%trans path=pathto('ext/builtins')%}<b>Extensions:</b> automatic testing of code snippets, inclusion of <li>{%trans path=pathto('ext/builtins')%}<b>Extensions:</b> automatic testing of code snippets, inclusion of
docstrings from Python modules (API docs), and docstrings from Python modules (API docs), and
<a href="{{ path }}#builtin-sphinx-extensions">more</a>{%endtrans%}</li> <a href="{{ path }}#builtin-sphinx-extensions">more</a>{%endtrans%}</li>
@ -38,10 +38,10 @@
most of them installable from PyPI{%endtrans%}</li> most of them installable from PyPI{%endtrans%}</li>
</ul> </ul>
<p>{%trans%} <p>{%trans%}
Sphinx uses <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> Sphinx uses <a href="https://docutils.sourceforge.io/rst.html">reStructuredText</a>
as its markup language, and many of its strengths come from the power and as its markup language, and many of its strengths come from the power and
straightforwardness of reStructuredText and its parsing and translating straightforwardness of reStructuredText and its parsing and translating
suite, the <a href="http://docutils.sourceforge.net/">Docutils</a>.{%endtrans%} suite, the <a href="https://docutils.sourceforge.io/">Docutils</a>.{%endtrans%}
</p> </p>
<h2 style="margin-bottom: 0">{%trans%}Documentation{%endtrans%}</h2> <h2 style="margin-bottom: 0">{%trans%}Documentation{%endtrans%}</h2>
@ -52,23 +52,25 @@
<p class="biglink"><a class="biglink" href="{{ pathto("usage/quickstart") }}">{%trans%}First steps with Sphinx{%endtrans%}</a><br/> <p class="biglink"><a class="biglink" href="{{ pathto("usage/quickstart") }}">{%trans%}First steps with Sphinx{%endtrans%}</a><br/>
<span class="linkdescr">{%trans%}overview of basic tasks{%endtrans%}</span></p> <span class="linkdescr">{%trans%}overview of basic tasks{%endtrans%}</span></p>
</td><td> </td><td>
{%- if hasdoc('search') %}<p class="biglink"><a class="biglink" href="{{ pathto("search") }}">{%trans%}Search page{%endtrans%}</a><br/> <p class="biglink"><a class="biglink" href="{{ pathto("tutorial/index") }}">{%trans%}Tutorial{%endtrans%}</a><br/>
<span class="linkdescr">{%trans%}search the documentation{%endtrans%}</span></p>{%- endif %} <span class="linkdescr">{%trans%}beginners tutorial{%endtrans%}</span></p>
</td> </td>
</tr><tr> </tr><tr>
<td> <td>
<p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">{%trans%}Contents{%endtrans%}</a><br/> <p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">{%trans%}Contents{%endtrans%}</a><br/>
<span class="linkdescr">{%trans%}for a complete overview{%endtrans%}</span></p> <span class="linkdescr">{%trans%}for a complete overview{%endtrans%}</span></p>
</td><td> </td><td>
{%- if hasdoc('genindex') %}<p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">{%trans%}General Index{%endtrans%}</a><br/> {%- if hasdoc('search') %}<p class="biglink"><a class="biglink" href="{{ pathto("search") }}">{%trans%}Search page{%endtrans%}</a><br/>
<span class="linkdescr">{%trans%}all functions, classes, terms{%endtrans%}</span></p>{%- endif %} <span class="linkdescr">{%trans%}search the documentation{%endtrans%}</span></p>{%- endif %}
</td> </td>
</tr><tr> </tr><tr>
<td> <td>
<p class="biglink"><a class="biglink" href="{{ pathto("changes") }}">{%trans%}Changes{%endtrans%}</a><br/> <p class="biglink"><a class="biglink" href="{{ pathto("changes") }}">{%trans%}Changes{%endtrans%}</a><br/>
<span class="linkdescr">{%trans%}release history{%endtrans%}</span></p> <span class="linkdescr">{%trans%}release history{%endtrans%}</span></p>
</td><td> </td><td>
</td> {%- if hasdoc('genindex') %}<p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">{%trans%}General Index{%endtrans%}</a><br/>
<span class="linkdescr">{%trans%}all functions, classes, terms{%endtrans%}</span></p>{%- endif %}
</td><td>
</tr> </tr>
</table> </table>

View File

@ -35,7 +35,7 @@ htmlhelp_basename = 'Sphinxdoc'
epub_theme = 'epub' epub_theme = 'epub'
epub_basename = 'sphinx' epub_basename = 'sphinx'
epub_author = 'Georg Brandl' epub_author = 'Georg Brandl'
epub_publisher = 'http://sphinx-doc.org/' epub_publisher = 'https://sphinx-doc.org/'
epub_uid = 'web-site' epub_uid = 'web-site'
epub_scheme = 'url' epub_scheme = 'url'
epub_identifier = epub_publisher epub_identifier = epub_publisher
@ -80,11 +80,11 @@ latex_use_xindy = True
autodoc_member_order = 'groupwise' autodoc_member_order = 'groupwise'
autosummary_generate = False autosummary_generate = False
todo_include_todos = True todo_include_todos = True
extlinks = {'duref': ('http://docutils.sourceforge.net/docs/ref/rst/' extlinks = {'duref': ('https://docutils.sourceforge.io/docs/ref/rst/'
'restructuredtext.html#%s', ''), 'restructuredtext.html#%s', ''),
'durole': ('http://docutils.sourceforge.net/docs/ref/rst/' 'durole': ('https://docutils.sourceforge.io/docs/ref/rst/'
'roles.html#%s', ''), 'roles.html#%s', ''),
'dudir': ('http://docutils.sourceforge.net/docs/ref/rst/' 'dudir': ('https://docutils.sourceforge.io/docs/ref/rst/'
'directives.html#%s', '')} 'directives.html#%s', '')}
man_pages = [ man_pages = [

View File

@ -7,6 +7,7 @@ Sphinx documentation contents
:maxdepth: 2 :maxdepth: 2
usage/index usage/index
tutorial/index
development/index development/index
man/index man/index

View File

@ -207,9 +207,9 @@ inside your module:
First, define the registration function, which accepts the arguments for First, define the registration function, which accepts the arguments for
:event:`html-page-context`. :event:`html-page-context`.
Within the registration function, define the template function that you'd like to use Within the registration function, define the template function that you'd like to
within Jinja. The template function should return a string or Python objects (lists, use within Jinja. The template function should return a string or Python objects
dictionaries) with strings inside that Jinja uses in the templating process (lists, dictionaries) with strings inside that Jinja uses in the templating process
.. note:: .. note::

View File

@ -181,9 +181,9 @@ This is the very basic principle of an extension that creates a new directive.
For a more advanced example, refer to :doc:`todo`. For a more advanced example, refer to :doc:`todo`.
.. _docutils: http://docutils.sourceforge.net/ .. _docutils: https://docutils.sourceforge.io/
.. _docutils directives: http://docutils.sourceforge.net/docs/howto/rst-directives.html .. _docutils directives: https://docutils.sourceforge.io/docs/howto/rst-directives.html
.. _docutils nodes: http://docutils.sourceforge.net/docs/ref/doctree.html .. _docutils nodes: https://docutils.sourceforge.io/docs/ref/doctree.html
.. _PyPI: https://pypi.org/ .. _PyPI: https://pypi.org/
.. _Python package: https://packaging.python.org/ .. _Python package: https://packaging.python.org/
.. _Python path: https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH .. _Python path: https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH

View File

@ -223,4 +223,4 @@ Further reading
For more information, refer to the `docutils`_ documentation and For more information, refer to the `docutils`_ documentation and
:doc:`/extdev/index`. :doc:`/extdev/index`.
.. _docutils: http://docutils.sourceforge.net/docs/ .. _docutils: https://docutils.sourceforge.io/docs/

View File

@ -105,7 +105,7 @@ is just a "general" node.
Many extensions will not have to create their own node classes and work fine Many extensions will not have to create their own node classes and work fine
with the nodes already provided by `docutils with the nodes already provided by `docutils
<http://docutils.sourceforge.net/docs/ref/doctree.html>`__ and :ref:`Sphinx <https://docutils.sourceforge.io/docs/ref/doctree.html>`__ and :ref:`Sphinx
<nodes>`. <nodes>`.
.. attention:: .. attention::
@ -362,6 +362,6 @@ For more information, refer to the `docutils`_ documentation and
:doc:`/extdev/index`. :doc:`/extdev/index`.
.. _docutils: http://docutils.sourceforge.net/docs/ .. _docutils: https://docutils.sourceforge.io/docs/
.. _Python path: https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH .. _Python path: https://docs.python.org/3/using/cmdline.html#envvar-PYTHONPATH
.. _docutils documentation: http://docutils.sourceforge.net/docs/ref/rst/directives.html .. _docutils documentation: https://docutils.sourceforge.io/docs/ref/rst/directives.html

View File

@ -159,7 +159,9 @@ connect handlers to the events. Example:
Below is an overview of each event that happens during a build. In the list Below is an overview of each event that happens during a build. In the list
below, we include the event name, its callback parameters, and the input and output below, we include the event name, its callback parameters, and the input and output
type for that event:: type for that event:
.. code-block:: none
1. event.config-inited(app,config) 1. event.config-inited(app,config)
2. event.builder-inited(app) 2. event.builder-inited(app)
@ -377,13 +379,22 @@ Here is a more detailed list of these events.
``'page.html'`` as the HTML template for this page. ``'page.html'`` as the HTML template for this page.
.. note:: You can install JS/CSS files for the specific page via .. note:: You can install JS/CSS files for the specific page via
:meth:`Sphinx.add_js_file` and :meth:`Sphinx.add_css_file` since v3.5.0. :meth:`Sphinx.add_js_file` and :meth:`Sphinx.add_css_file` since
v3.5.0.
.. versionadded:: 0.4 .. versionadded:: 0.4
.. versionchanged:: 1.3 .. versionchanged:: 1.3
The return value can now specify a template name. The return value can now specify a template name.
.. event:: linkcheck-process-uri (app, uri)
Emitted when the linkcheck builder collects hyperlinks from document. *uri*
is a collected URI. The event handlers can modify the URI by returning a
string.
.. versionadded:: 4.1
.. event:: build-finished (app, exception) .. event:: build-finished (app, exception)
Emitted when a build has finished, before Sphinx exits, usually used for Emitted when a build has finished, before Sphinx exits, usually used for

View File

@ -22,6 +22,21 @@ The following is a list of deprecated interfaces.
- (will be) Removed - (will be) Removed
- Alternatives - Alternatives
* - The optional argument ``app`` for ``sphinx.environment.BuildEnvironment``
- 4.1
- 6.0
- The required argument
* - ``sphinx.application.Sphinx.html_theme``
- 4.1
- 6.0
- ``sphinx.registry.SphinxComponentRegistry.html_themes``
* - ``sphinx.ext.autosummary._app``
- 4.1
- 6.0
- N/A
* - ``sphinx.util.docstrings.extract_metadata()`` * - ``sphinx.util.docstrings.extract_metadata()``
- 4.1 - 4.1
- 6.0 - 6.0
@ -40,12 +55,12 @@ The following is a list of deprecated interfaces.
* - ``sphinx.directives.patches.ListTable`` * - ``sphinx.directives.patches.ListTable``
- 4.0 - 4.0
- 6.0 - 6.0
- ``docutils.parsers.rst.diretives.tables.ListSVTable`` - ``docutils.parsers.rst.directives.tables.ListSVTable``
* - ``sphinx.directives.patches.RSTTable`` * - ``sphinx.directives.patches.RSTTable``
- 4.0 - 4.0
- 6.0 - 6.0
- ``docutils.parsers.rst.diretives.tables.RSTTable`` - ``docutils.parsers.rst.directives.tables.RSTTable``
* - ``sphinx.ext.autodoc.directive.DocumenterBridge.filename_set`` * - ``sphinx.ext.autodoc.directive.DocumenterBridge.filename_set``
- 4.0 - 4.0
@ -85,7 +100,7 @@ The following is a list of deprecated interfaces.
* - ``sphinx.util.smartypants`` * - ``sphinx.util.smartypants``
- 4.0 - 4.0
- 6.0 - 6.0
- ``docutils.utils.smartyquotes`` - ``docutils.utils.smartquotes``
* - ``sphinx.util.typing.DirectiveOption`` * - ``sphinx.util.typing.DirectiveOption``
- 4.0 - 4.0

View File

@ -94,4 +94,4 @@ message catalog template and message catalogs, for example via `Babel`_:
$ pybabel extract --output=src/locale/myextension.pot src/ $ pybabel extract --output=src/locale/myextension.pot src/
$ pybabel update --input-file=src/locale/myextension.pot --domain=myextension --output-dir=src/locale $ pybabel update --input-file=src/locale/myextension.pot --domain=myextension --output-dir=src/locale
.. _Babel: http://babel.pocoo.org/ .. _Babel: https://babel.pocoo.org/

View File

@ -112,7 +112,7 @@ in which a Sphinx project is built: this works in several phases.
existing files are read, temporary nodes are created. existing files are read, temporary nodes are created.
There are nodes provided by docutils, which are documented `in the docutils There are nodes provided by docutils, which are documented `in the docutils
documentation <http://docutils.sourceforge.net/docs/ref/doctree.html>`__. documentation <https://docutils.sourceforge.io/docs/ref/doctree.html>`__.
Additional nodes are provided by Sphinx and :ref:`documented here <nodes>`. Additional nodes are provided by Sphinx and :ref:`documented here <nodes>`.
During reading, the build environment is updated with all meta- and cross During reading, the build environment is updated with all meta- and cross

View File

@ -149,4 +149,4 @@ return ``node.children`` from the Directive.
`Creating directives`_ HOWTO of the Docutils documentation `Creating directives`_ HOWTO of the Docutils documentation
.. _Creating directives: http://docutils.sourceforge.net/docs/howto/rst-directives.html .. _Creating directives: https://docutils.sourceforge.io/docs/howto/rst-directives.html

View File

@ -8,7 +8,7 @@ Parser API
The Parser analyzes the input document and creates a node tree The Parser analyzes the input document and creates a node tree
representation. representation.
__ http://docutils.sourceforge.net/docs/dev/hacking.html#parsing-the-document __ https://docutils.sourceforge.io/docs/dev/hacking.html#parsing-the-document
In Sphinx, the parser modules works as same as docutils. The parsers are In Sphinx, the parser modules works as same as docutils. The parsers are
registered to Sphinx by extensions using Application APIs; registered to Sphinx by extensions using Application APIs;

View File

@ -145,7 +145,7 @@ Google Search
.. _Getting Started: https://docs.readthedocs.io/en/stable/intro/getting-started-with-sphinx.html .. _Getting Started: https://docs.readthedocs.io/en/stable/intro/getting-started-with-sphinx.html
.. _api role: https://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py .. _api role: https://git.savannah.gnu.org/cgit/kenozooid.git/tree/doc/extapi.py
.. _xhtml to reST: http://docutils.sourceforge.net/sandbox/xhtml2rest/xhtml2rest.py .. _xhtml to reST: https://docutils.sourceforge.io/sandbox/xhtml2rest/xhtml2rest.py
Sphinx vs. Docutils Sphinx vs. Docutils
@ -179,10 +179,10 @@ of the *writers* provided by docutils. This allows Sphinx to provide many
features that would simply not be possible with docutils, such as those features that would simply not be possible with docutils, such as those
outlined above. outlined above.
__ http://docutils.sourceforge.io/ __ https://docutils.sourceforge.io/
__ http://docutils.sourceforge.io/docs/dev/hacking.html __ https://docutils.sourceforge.io/docs/dev/hacking.html
__ http://docutils.sourceforge.io/rst.html __ https://docutils.sourceforge.io/rst.html
__ http://docutils.sourceforge.net/docs/user/tools.html __ https://docutils.sourceforge.io/docs/user/tools.html
.. _epub-faq: .. _epub-faq:
@ -259,7 +259,9 @@ The following list gives some hints for the creation of epub files:
``parent.xhtml`` -> ``child.xhtml`` -> ``parent.xhtml`` ``parent.xhtml`` -> ``child.xhtml`` -> ``parent.xhtml``
If you get the following error, fix your document structure:: If you get the following error, fix your document structure:
.. code-block:: none
Error(prcgen):E24011: TOC section scope is not included in the parent chapter:(title) Error(prcgen):E24011: TOC section scope is not included in the parent chapter:(title)
Error(prcgen):E24001: The table of content could not be built. Error(prcgen):E24001: The table of content could not be built.

View File

@ -251,7 +251,7 @@ The parts of messages in Sphinx that go into builds are translated into several
locales. The translations are kept as gettext ``.po`` files translated from the locales. The translations are kept as gettext ``.po`` files translated from the
master template :file:`sphinx/locale/sphinx.pot`. master template :file:`sphinx/locale/sphinx.pot`.
Sphinx uses `Babel <http://babel.pocoo.org/en/latest/>`_ to extract messages 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. It is integrated in ``setup.py``:
* Use ``python setup.py extract_messages`` to update the ``.pot`` template. * Use ``python setup.py extract_messages`` to update the ``.pot`` template.
@ -297,7 +297,7 @@ Debugging tips
will complain about references without a known target. will complain about references without a known target.
* Set the debugging options in the `Docutils configuration file * Set the debugging options in the `Docutils configuration file
<http://docutils.sourceforge.net/docs/user/config.html>`_. <https://docutils.sourceforge.io/docs/user/config.html>`_.
* JavaScript stemming algorithms in ``sphinx/search/*.py`` (except ``en.py``) * JavaScript stemming algorithms in ``sphinx/search/*.py`` (except ``en.py``)
are generated by this `modified snowballcode generator are generated by this `modified snowballcode generator

View File

@ -19,7 +19,7 @@ if errorlevel 9009 (
echo.may add the Sphinx directory to PATH. echo.may add the Sphinx directory to PATH.
echo. echo.
echo.If you don't have Sphinx installed, grab it from echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/ echo.https://sphinx-doc.org/
exit /b 1 exit /b 1
) )

View File

@ -6,10 +6,11 @@
Templating Templating
========== ==========
Sphinx uses the `Jinja <http://jinja.pocoo.org>`_ templating engine for its HTML Sphinx uses the `Jinja <https://jinja.palletsprojects.com/>`_ templating engine
templates. Jinja is a text-based engine, inspired by Django templates, so for its HTML templates. Jinja is a text-based engine, inspired by Django
anyone having used Django will already be familiar with it. It also has templates, so anyone having used Django will already be familiar with it. It
excellent documentation for those who need to make themselves familiar with it. also has excellent documentation for those who need to make themselves familiar
with it.
Do I need to use Sphinx's templates to produce HTML? Do I need to use Sphinx's templates to produce HTML?

185
doc/tutorial/index.rst Normal file
View File

@ -0,0 +1,185 @@
.. _tutorial:
===============
Sphinx tutorial
===============
In this tutorial you will build a simple documentation project using Sphinx, and
view it in your browser as HTML. The project will include narrative,
handwritten documentation, as well as autogenerated API documentation.
The tutorial is aimed towards Sphinx newcomers willing to learn the fundamentals
of how projects are created and structured. You will create a fictional
software library to generate random food recipes that will serve as a guide
throughout the process, with the objective of properly documenting it.
To showcase Sphinx capabilities for code documentation you will use Python,
which also supports *automatic* documentation generation.
.. note::
Several other languages are natively supported in Sphinx for *manual* code
documentation, however they require extensions for *automatic* code
documentation, like `Breathe <https://breathe.readthedocs.io/>`_.
To follow the instructions you will need access to a Linux-like command line and
a basic understanding of how it works, as well as a working Python installation
for development, since you will use *Python virtual environments* to create the
project.
Getting started
---------------
Setting up your project and development environment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In a new directory, create a file called ``README.rst`` with the following
content.
.. code-block:: rest
Lumache
=======
**Lumache** (/luˈmake/) is a Python library for cooks and food lovers that
creates recipes mixing random ingredients.
It is a good moment to create a Python virtual environment and install the
required tools. For that, open a command line terminal, ``cd`` into the
directory you just created, and run the following commands:
.. code-block:: console
$ python -m venv .venv
$ source .venv/bin/activate
(.venv) $ python -m pip install sphinx
.. note::
The installation method used above is described in more detail in
:ref:`install-pypi`. For the rest of this tutorial, the instructions will
assume a Python virtual environment.
If you executed these instructions correctly, you should have the Sphinx command
line tools available. You can do a basic verification running this command:
.. code-block:: console
(.venv) $ sphinx-build --version
sphinx-build 4.0.2
If you see a similar output, you are on the right path!
Creating the documentation layout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Then from the command line, run the following command:
.. code-block:: console
(.venv) $ sphinx-quickstart docs
This will present to you a series of questions required to create the basic
directory and configuration layout for your project inside the ``docs`` folder.
To proceed, answer each question as follows:
- ``> Separate source and build directories (y/n) [n]``: Write "``y``" (without
quotes) and press :kbd:`Enter`. - ``> Project name``: Write "``Lumache``"
(without quotes) and press :kbd:`Enter`. - ``> Author name(s)``: Write
"``Graziella``" (without quotes) and press :kbd:`Enter`. - ``> Project
release []``: Write "``0.1``" (without quotes) and press :kbd:`Enter`. - ``>
Project language [en]``: Leave it empty (the default, English) and press
:kbd:`Enter`.
After the last question, you will see the new ``docs`` directory with the
following content.
.. code-block:: text
docs ├── build ├── make.bat ├── Makefile └── source ├── conf.py ├──
index.rst ├── _static └── _templates
The purpose of each of these files is:
``build/``
An empty directory (for now) that will hold the rendered documentation.
``make.bat`` and ``Makefile``
Convenience scripts to simplify some common Sphinx operations, such as
rendering the content.
``source/conf.py``
A Python script holding the configuration of the Sphinx project. It contains
the project name and release you specified to ``sphinx-quickstart``, as well
as some extra configuration keys.
``source/index.rst``
The :term:`master document` of the project, which serves as welcome page and
contains the root of the "table of contents tree" (or *toctree*).
Thanks to this bootstrapping step, you already have everything needed to render
the documentation as HTML for the first time. To do that, run this command:
.. code-block:: console
(.venv) $ sphinx-build -b html docs/source/ docs/build/html
And finally, open `docs/build/html/index.html` in your browser. You should see
something like this:
.. image:: /_static/tutorial/lumache-first-light.png
There we go! You created your first HTML documentation using Sphinx.
Making some tweaks to the index
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``index.rst`` file that ``sphinx-quickstart`` created has some content
already, and it gets rendered as the front page of our HTML documentation. It
is written in reStructuredText, a powerful markup language.
Modify the file as follows:
.. code-block:: rest
Welcome to Lumache's documentation!
===================================
**Lumache** (/luˈmake/) is a Python library for cooks and food lovers that
creates recipes mixing random ingredients. It pulls data from the `Open Food
Facts database <https://world.openfoodfacts.org/>`_ and offers a *simple* and
*intuitive* API.
.. note::
This project is under active development.
This showcases several features of the reStructuredText syntax, including:
- a **section header** using ``===`` for the underline, - two examples of
:ref:`rst-inline-markup`: ``**strong emphasis**`` (typically bold) and
``*emphasis*`` (typically italics), - an **inline external link**, - and a
``note`` **admonition** (one of the available :ref:`directives
<rst-directives>`)
Now to render it with the new content, you can use the ``sphinx-build`` command
as before, or leverage the convenience script as follows:
.. code-block:: console
(.venv) $ cd docs
(.venv) $ make html
After running this command, you will see that ``index.html`` reflects the new
changes!
Where to go from here
---------------------
This tutorial covered the very first steps to create a documentation project
with Sphinx. To continue learning more about Sphinx, check out the :ref:`rest
of the documentation <contents>`.

View File

@ -13,7 +13,7 @@ navigation bars, Sphinx provides mechanisms facilitating the translation of
:width: 100% :width: 100%
Workflow visualization of translations in Sphinx. (The figure is created by Workflow visualization of translations in Sphinx. (The figure is created by
`plantuml <http://plantuml.com>`_.) `plantuml <https://plantuml.com>`_.)
.. contents:: .. contents::
:local: :local:
@ -118,7 +118,7 @@ section describe an easy way to translate with *sphinx-intl*.
#. Translate po files. #. Translate po files.
AS noted above, these are located in the ``./locale/<lang>/LC_MESSAGES`` As noted above, these are located in the ``./locale/<lang>/LC_MESSAGES``
directory. An example of one such file, from Sphinx, ``builders.po``, is directory. An example of one such file, from Sphinx, ``builders.po``, is
given below. given below.
@ -193,7 +193,7 @@ pot file to the po file, use the :command:`sphinx-intl update` command.
.. code-block:: console .. code-block:: console
$ sphinx-intl update -p _build/locale $ sphinx-intl update -p _build/gettext
Using Transifex service for team translation Using Transifex service for team translation

View File

@ -61,7 +61,7 @@ This will return a dictionary containing the following items:
This dict can then be used as context for templates. The goal is to be easy to This dict can then be used as context for templates. The goal is to be easy to
integrate with your existing templating system. An example using `Jinja2 integrate with your existing templating system. An example using `Jinja2
<http://jinja.pocoo.org/>`_ is: <https://jinja.palletsprojects.com/>`_ is:
.. code-block:: html+jinja .. code-block:: html+jinja
@ -112,8 +112,8 @@ must update the websupport package's data::
should be a boolean representing whether the user has moderation privileges. should be a boolean representing whether the user has moderation privileges.
The default value for *moderator* is ``False``. The default value for *moderator* is ``False``.
An example `Flask <http://flask.pocoo.org/>`_ function that checks whether a An example `Flask <https://flask.palletsprojects.com/>`_ function that checks
user is logged in and then retrieves a document is:: whether a user is logged in and then retrieves a document is::
from sphinxcontrib.websupport.errors import * from sphinxcontrib.websupport.errors import *
@ -152,8 +152,8 @@ To use the search form built-in to the Sphinx sidebar, create a function to
handle requests to the URL 'search' relative to the documentation root. The handle requests to the URL 'search' relative to the documentation root. The
user's search query will be in the GET parameters, with the key `q`. Then use user's search query will be in the GET parameters, with the key `q`. Then use
the :meth:`~sphinxcontrib.websupport.WebSupport.get_search_results` method to the :meth:`~sphinxcontrib.websupport.WebSupport.get_search_results` method to
retrieve search results. In `Flask <http://flask.pocoo.org/>`_ that would be retrieve search results. In `Flask <https://flask.palletsprojects.com/>`_ that
like this:: would be like this::
@app.route('/search') @app.route('/search')
def search(): def search():

View File

@ -18,8 +18,8 @@ and output behavior.
directory to adjust `Docutils`_ configuration if not otherwise overridden or directory to adjust `Docutils`_ configuration if not otherwise overridden or
set by Sphinx. set by Sphinx.
.. _`docutils`: http://docutils.sourceforge.net/ .. _`docutils`: https://docutils.sourceforge.io/
.. _`docutils.conf`: http://docutils.sourceforge.net/docs/user/config.html .. _`docutils.conf`: https://docutils.sourceforge.io/docs/user/config.html
The configuration file is executed as Python code at build time (using The configuration file is executed as Python code at build time (using
:func:`execfile`, and with the current directory set to its containing :func:`execfile`, and with the current directory set to its containing
@ -484,7 +484,7 @@ General configuration
languages, will be used to convert quotes and dashes to typographically languages, will be used to convert quotes and dashes to typographically
correct entities. Default: ``True``. correct entities. Default: ``True``.
__ http://docutils.sourceforge.net/docs/user/smartquotes.html __ https://docutils.sourceforge.io/docs/user/smartquotes.html
__ https://daringfireball.net/projects/smartypants/ __ https://daringfireball.net/projects/smartypants/
.. versionadded:: 1.6.6 .. versionadded:: 1.6.6
@ -497,8 +497,8 @@ General configuration
*deactivates* smart quotes via the corresponding `Docutils option`__. But *deactivates* smart quotes via the corresponding `Docutils option`__. But
if it *activates* them, then :confval:`smartquotes` does prevail. if it *activates* them, then :confval:`smartquotes` does prevail.
__ http://docutils.sourceforge.net/docs/user/config.html __ https://docutils.sourceforge.io/docs/user/config.html
__ http://docutils.sourceforge.net/docs/user/config.html#smart-quotes __ https://docutils.sourceforge.io/docs/user/config.html#smart-quotes
.. confval:: smartquotes_action .. confval:: smartquotes_action
@ -591,17 +591,18 @@ General configuration
.. confval:: highlight_language .. confval:: highlight_language
The default language to highlight source code in. The default is The default language to highlight source code in. The default is
``'python3'``. The value should be a valid Pygments lexer name, see ``'default'``. It is similar to ``'python3'``; it is mostly a superset of
``'python'`` but it fallbacks to ``'none'`` without warning if failed.
``'python3'`` and other languages will emit warning if failed.
The value should be a valid Pygments lexer name, see
:ref:`code-examples` for more details. :ref:`code-examples` for more details.
.. versionadded:: 0.5 .. versionadded:: 0.5
.. versionchanged:: 1.4 .. versionchanged:: 1.4
The default is now ``'default'``. It is similar to ``'python3'``; The default is now ``'default'``. If you prefer Python 2 only
it is mostly a superset of ``'python'`` but it fallbacks to highlighting, you can set it back to ``'python'``.
``'none'`` without warning if failed. ``'python3'`` and other
languages will emit warning if failed. If you prefer Python 2
only highlighting, you can set it back to ``'python'``.
.. confval:: highlight_options .. confval:: highlight_options
@ -794,6 +795,10 @@ documentation on :ref:`intl` for details.
The default is ``['locales']``. The default is ``['locales']``.
.. note:: The :option:`-v option for sphinx-build command <sphinx-build -v>`
is useful to check the locale_dirs config works as expected. It
emits debug messages if message catalog directory not found.
.. versionchanged:: 1.5 .. versionchanged:: 1.5
Use ``locales`` directory as a default value Use ``locales`` directory as a default value
@ -1047,7 +1052,7 @@ that use Sphinx's HTMLWriter class.
A list of CSS files. The entry must be a *filename* string or a tuple A list of CSS files. The entry must be a *filename* string or a tuple
containing the *filename* string and the *attributes* dictionary. The containing the *filename* string and the *attributes* dictionary. The
*filename* must be relative to the :confval:`html_static_path`, or a full URI *filename* must be relative to the :confval:`html_static_path`, or a full URI
with scheme like ``http://example.org/style.css``. The *attributes* is used with scheme like ``https://example.org/style.css``. The *attributes* is used
for attributes of ``<link>`` tag. It defaults to an empty list. for attributes of ``<link>`` tag. It defaults to an empty list.
Example:: Example::
@ -1070,7 +1075,7 @@ that use Sphinx's HTMLWriter class.
A list of JavaScript *filename*. The entry must be a *filename* string or a A list of JavaScript *filename*. The entry must be a *filename* string or a
tuple containing the *filename* string and the *attributes* dictionary. The tuple containing the *filename* string and the *attributes* dictionary. The
*filename* must be relative to the :confval:`html_static_path`, or a full *filename* must be relative to the :confval:`html_static_path`, or a full
URI with scheme like ``http://example.org/script.js``. The *attributes* is URI with scheme like ``https://example.org/script.js``. The *attributes* is
used for attributes of ``<script>`` tag. It defaults to an empty list. used for attributes of ``<script>`` tag. It defaults to an empty list.
Example:: Example::
@ -1304,7 +1309,7 @@ that use Sphinx's HTMLWriter class.
.. confval:: html_use_opensearch .. confval:: html_use_opensearch
If nonempty, an `OpenSearch <http://www.opensearch.org/Home>`_ description If nonempty, an `OpenSearch <https://www.opensearch.org/>`_ description
file will be output, and all pages will contain a ``<link>`` tag referring file will be output, and all pages will contain a ``<link>`` tag referring
to it. Since OpenSearch doesn't support relative URLs for its search page to it. Since OpenSearch doesn't support relative URLs for its search page
location, the value of this option must be the base URL from which these location, the value of this option must be the base URL from which these
@ -1731,7 +1736,7 @@ Options for epub output
These options influence the epub output. As this builder derives from the HTML These options influence the epub output. As this builder derives from the HTML
builder, the HTML options also apply where appropriate. The actual values for builder, the HTML options also apply where appropriate. The actual values for
some of the options is not really important, they just have to be entered into some of the options is not really important, they just have to be entered into
the `Dublin Core metadata <http://dublincore.org/>`_. the `Dublin Core metadata <https://dublincore.org/>`_.
.. confval:: epub_basename .. confval:: epub_basename
@ -2353,6 +2358,10 @@ These options influence manual page output.
The default is changed to ``False`` from ``True``. The default is changed to ``False`` from ``True``.
.. versionchanged:: 4.0.2
The default is changed to ``True`` from ``False`` again.
.. _texinfo-options: .. _texinfo-options:
Options for Texinfo output Options for Texinfo output
@ -2588,7 +2597,7 @@ Options for the linkcheck builder
as follows:: as follows::
linkcheck_ignore = [ linkcheck_ignore = [
'http://www.sphinx-doc.org/en/1.7/intro.html#' 'https://www.sphinx-doc.org/en/1.7/intro.html#'
] ]
.. versionadded:: 1.5 .. versionadded:: 1.5

View File

@ -463,6 +463,20 @@ There are also config values that you can set:
.. versionadded:: 1.4 .. versionadded:: 1.4
.. confval:: autodoc_class_signature
This value selects how the signautre will be displayed for the class defined
by :rst:dir:`autoclass` directive. The possible values are:
``"mixed"``
Display the signature with the class name.
``"separated"``
Display the signature as a method.
The default is ``"mixed"``.
.. versionadded:: 4.1
.. confval:: autodoc_member_order .. confval:: autodoc_member_order
This value selects if automatically documented members are sorted This value selects if automatically documented members are sorted
@ -573,15 +587,27 @@ There are also config values that you can set:
This value controls how to represent typehints. The setting takes the This value controls how to represent typehints. The setting takes the
following values: following values:
* ``'signature'`` -- Show typehints as its signature (default) * ``'signature'`` -- Show typehints in the signature (default)
* ``'description'`` -- Show typehints as content of function or method * ``'description'`` -- Show typehints as content of the function or method
The typehints of overloaded functions or methods will still be represented
in the signature.
* ``'none'`` -- Do not show typehints * ``'none'`` -- Do not show typehints
* ``'both'`` -- Show typehints in the signature and as content of
the function or method
Overloaded functions or methods will not have typehints included in the
description because it is impossible to accurately represent all possible
overloads as a list of parameters.
.. versionadded:: 2.1 .. versionadded:: 2.1
.. versionadded:: 3.0 .. versionadded:: 3.0
New option ``'description'`` is added. New option ``'description'`` is added.
.. versionadded:: 4.1
New option ``'both'`` is added.
.. confval:: autodoc_typehints_description_target .. confval:: autodoc_typehints_description_target
This value controls whether the types of undocumented parameters and return This value controls whether the types of undocumented parameters and return
@ -737,6 +763,21 @@ needed docstring processing in event :event:`autodoc-process-docstring`:
.. autofunction:: cut_lines .. autofunction:: cut_lines
.. autofunction:: between .. autofunction:: between
.. event:: autodoc-process-bases (app, name, obj, options, bases)
.. versionadded:: 4.1
Emitted when autodoc has read and processed a class to determine the
base-classes. *bases* is a list of classes that the event handler can
modify **in place** to change what Sphinx puts into the output. It's
emitted only if ``show-inheritance`` option given.
:param app: the Sphinx application object
:param name: the fully qualified name of the object
:param obj: the object itself
:param options: the options given to the class directive
:param bases: the list of base classes signature. see above.
Skipping members Skipping members
---------------- ----------------

View File

@ -335,4 +335,4 @@ the title of a page.
You can use the :rst:dir:`autosummary` directive in the stub pages. You can use the :rst:dir:`autosummary` directive in the stub pages.
Stub pages are generated also based on these directives. Stub pages are generated also based on these directives.
.. _`escape filter`: http://jinja.pocoo.org/docs/2.9/templates/#escape .. _`escape filter`: https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-filters.escape

View File

@ -230,7 +230,7 @@ There are also these config values:
.. graphviz:: .. graphviz::
digraph example { digraph example {
a [label="sphinx", href="http://sphinx-doc.org", target="_top"]; a [label="sphinx", href="https://sphinx-doc.org", target="_top"];
b [label="other"]; b [label="other"];
a -> b; a -> b;
} }

View File

@ -220,7 +220,7 @@ Sphinx but is set to automatically include it from a third-party site.
The value is used as a parameter of ``MathJax.Hub.Config()``. The value is used as a parameter of ``MathJax.Hub.Config()``.
For more information, please read `Using in-line configuration options`__. For more information, please read `Using in-line configuration options`__.
__ http://docs.mathjax.org/en/v2.7-latest/ __ https://docs.mathjax.org/en/v2.7-latest/
configuration.html#using-in-line-configuration-options configuration.html#using-in-line-configuration-options
For example:: For example::

View File

@ -49,7 +49,7 @@ parse them. This happens in an intermediate step while Sphinx is processing
the documentation, so it doesn't modify any of the docstrings in your actual the documentation, so it doesn't modify any of the docstrings in your actual
source code files. source code files.
.. _ReStructuredText: http://docutils.sourceforge.net/rst.html .. _ReStructuredText: https://docutils.sourceforge.io/rst.html
.. _docstrings: https://www.python.org/dev/peps/pep-0287/ .. _docstrings: https://www.python.org/dev/peps/pep-0287/
.. _Google Python Style Guide: .. _Google Python Style Guide:
https://google.github.io/styleguide/pyguide.html https://google.github.io/styleguide/pyguide.html
@ -267,14 +267,9 @@ Google style with types in docstrings::
`Python 2/3 compatible annotations`_ aren't currently `Python 2/3 compatible annotations`_ aren't currently
supported by Sphinx and won't show up in the docs. supported by Sphinx and won't show up in the docs.
.. _PEP 484: .. _PEP 484: https://www.python.org/dev/peps/pep-0484/
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
.. _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
Configuration Configuration

View File

@ -185,30 +185,67 @@ the ``--pre`` flag.
$ pip install -U --pre sphinx $ pip install -U --pre sphinx
Using virtual environments
~~~~~~~~~~~~~~~~~~~~~~~~~~
When installing Sphinx using pip,
it is highly recommended to use *virtual environments*,
which isolate the installed packages from the system packages,
thus removing the need to use administrator privileges.
To create a virtual environment in the ``.venv`` directory,
use the following command.
::
$ python -m venv .venv
You can read more about them in the `Python Packaging User Guide`_.
.. _Python Packaging User Guide: https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment
.. warning::
Note that in some Linux distributions, such as Debian and Ubuntu,
this might require an extra installation step as follows.
.. code-block:: console
$ apt-get install python3-venv
Docker Docker
------ ------
Docker images for Sphinx are published on the `Docker Hub <https://hub.docker.com/>`_. There are two kind of images: Docker images for Sphinx are published on the `Docker Hub`_. There are two kind
of images:
- `sphinxdoc/sphinx <https://hub.docker.com/repository/docker/sphinxdoc/sphinx>`_ - `sphinxdoc/sphinx`_
- `sphinxdoc/sphinx-latexpdf <https://hub.docker.com/repository/docker/sphinxdoc/sphinx-latexpdf>`_ - `sphinxdoc/sphinx-latexpdf`_
Former one is used for standard usage of Sphinx, and latter one is mainly used for PDF builds using LaTeX. .. _Docker Hub: https://hub.docker.com/
Please choose one for your purpose. .. _sphinxdoc/sphinx: https://hub.docker.com/repository/docker/sphinxdoc/sphinx
.. _sphinxdoc/sphinx-latexpdf: https://hub.docker.com/repository/docker/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.
.. note:: .. note::
sphinxdoc/sphinx-latexpdf contains TeXLive packages. So the image is very large (over 2GB!). sphinxdoc/sphinx-latexpdf contains TeXLive packages. So the image is very large
(over 2GB!).
.. hint:: .. hint::
When using docker images, please use ``docker run`` command to invoke sphinx commands. For example, When using docker images, please use ``docker run`` command to invoke sphinx
you can use following command to create a Sphinx project:: commands. For example, you can use following command to create a Sphinx
project:
.. code-block:: bash
$ docker run -it --rm -v /path/to/document:/docs sphinxdoc/sphinx sphinx-quickstart $ 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 following command this to build HTML document:
.. code-block:: bash
$ docker run --rm -v /path/to/document:/docs sphinxdoc/sphinx make html $ docker run --rm -v /path/to/document:/docs sphinxdoc/sphinx make html

View File

@ -24,7 +24,7 @@ default markup format used by Sphinx, :doc:`reStucturedText
For a great "introduction" to writing docs in general -- the whys and hows, see For a great "introduction" to writing docs in general -- the whys and hows, see
also `Write the docs`__, written by Eric Holscher. also `Write the docs`__, written by Eric Holscher.
.. __: http://www.writethedocs.org/guide/writing/beginners-guide-to-docs/ .. __: https://www.writethedocs.org/guide/writing/beginners-guide-to-docs/
Setting up the documentation sources Setting up the documentation sources

View File

@ -15,7 +15,7 @@ language, this will not take too long.
.. seealso:: .. seealso::
The authoritative `reStructuredText User Documentation The authoritative `reStructuredText User Documentation
<http://docutils.sourceforge.net/rst.html>`_. The "ref" links in this <https://docutils.sourceforge.io/rst.html>`_. The "ref" links in this
document link to the description of the individual constructs in the reST document link to the description of the individual constructs in the reST
reference. reference.

View File

@ -424,7 +424,7 @@ code blocks using multiple varied syntaxes. Finally, the
in your documentation. in your documentation.
In all cases, Syntax highlighting is provided by `Pygments In all cases, Syntax highlighting is provided by `Pygments
<http://pygments.org>`_. When using literal blocks, this is configured using <https://pygments.org>`_. When using literal blocks, this is configured using
any :rst:dir:`highlight` directives in the source file. When a ``highlight`` any :rst:dir:`highlight` directives in the source file. When a ``highlight``
directive is encountered, it is used until the next ``highlight`` directive is directive is encountered, it is used until the next ``highlight`` directive is
encountered. If there is no ``highlight`` directive in the file, the global encountered. If there is no ``highlight`` directive in the file, the global
@ -452,7 +452,7 @@ If highlighting with the selected language fails (i.e. Pygments emits an
want to ensure consistent highlighting, you should fix your version of want to ensure consistent highlighting, you should fix your version of
Pygments. Pygments.
__ http://pygments.org/docs/lexers __ https://pygments.org/docs/lexers
.. rst:directive:: .. highlight:: language .. rst:directive:: .. highlight:: language

View File

@ -12,7 +12,7 @@ The below guides go through the most important aspects of reST. For the
authoritative reStructuredText reference, refer to the `docutils authoritative reStructuredText reference, refer to the `docutils
documentation`__. documentation`__.
__ http://docutils.sourceforge.net/rst.html __ https://docutils.sourceforge.io/rst.html
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2

View File

@ -248,7 +248,8 @@ These themes are:
**scrolls** **scrolls**
A more lightweight theme, based on `the Jinja documentation A more lightweight theme, based on `the Jinja documentation
<http://jinja.pocoo.org/>`_. The following color options are available: <https://jinja.palletsprojects.com/>`_. The following color options are
available:
- **headerbordercolor** - **headerbordercolor**
- **subheadlinecolor** - **subheadlinecolor**

12
package-lock.json generated
View File

@ -486,9 +486,9 @@
} }
}, },
"glob-parent": { "glob-parent": {
"version": "5.0.0", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true, "dev": true,
"requires": { "requires": {
"is-glob": "^4.0.1" "is-glob": "^4.0.1"
@ -704,9 +704,9 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.19", "version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true "dev": true
}, },
"log4js": { "log4js": {

View File

@ -44,8 +44,11 @@ extras_require = {
'lint': [ 'lint': [
'flake8>=3.5.0', 'flake8>=3.5.0',
'isort', 'isort',
'mypy>=0.800', 'mypy>=0.900',
'docutils-stubs', 'docutils-stubs',
"types-typed-ast",
"types-pkg_resources",
"types-requests",
], ],
'test': [ 'test': [
'pytest', 'pytest',
@ -173,7 +176,7 @@ else:
setup( setup(
name='Sphinx', name='Sphinx',
version=sphinx.__version__, version=sphinx.__version__,
url='http://sphinx-doc.org/', url='https://sphinx-doc.org/',
download_url='https://pypi.org/project/Sphinx/', download_url='https://pypi.org/project/Sphinx/',
license='BSD', license='BSD',
author='Georg Brandl', author='Georg Brandl',

View File

@ -14,6 +14,7 @@ import os
import pickle import pickle
import platform import platform
import sys import sys
import warnings
from collections import deque from collections import deque
from io import StringIO from io import StringIO
from os import path from os import path
@ -29,6 +30,7 @@ from pygments.lexer import Lexer
import sphinx import sphinx
from sphinx import locale, package_dir from sphinx import locale, package_dir
from sphinx.config import Config from sphinx.config import Config
from sphinx.deprecation import RemovedInSphinx60Warning
from sphinx.domains import Domain, Index from sphinx.domains import Domain, Index
from sphinx.environment import BuildEnvironment from sphinx.environment import BuildEnvironment
from sphinx.environment.collectors import EnvironmentCollector from sphinx.environment.collectors import EnvironmentCollector
@ -141,22 +143,15 @@ class Sphinx:
self.phase = BuildPhase.INITIALIZATION self.phase = BuildPhase.INITIALIZATION
self.verbosity = verbosity self.verbosity = verbosity
self.extensions: Dict[str, Extension] = {} self.extensions: Dict[str, Extension] = {}
self.builder: Builder = None self.builder: Optional[Builder] = None
self.env: BuildEnvironment = None self.env: Optional[BuildEnvironment] = None
self.project: Project = None self.project: Optional[Project] = None
self.registry = SphinxComponentRegistry() self.registry = SphinxComponentRegistry()
self.html_themes: Dict[str, str] = {}
# validate provided directories # validate provided directories
self.srcdir = abspath(srcdir) self.srcdir = abspath(srcdir)
self.outdir = abspath(outdir) self.outdir = abspath(outdir)
self.doctreedir = abspath(doctreedir) self.doctreedir = abspath(doctreedir)
self.confdir = confdir
if self.confdir: # confdir is optional
self.confdir = abspath(self.confdir)
if not path.isfile(path.join(self.confdir, 'conf.py')):
raise ApplicationError(__("config directory doesn't contain a "
"conf.py file (%s)") % confdir)
if not path.isdir(self.srcdir): if not path.isdir(self.srcdir):
raise ApplicationError(__('Cannot find source directory (%s)') % raise ApplicationError(__('Cannot find source directory (%s)') %
@ -174,7 +169,7 @@ class Sphinx:
if status is None: if status is None:
self._status: IO = StringIO() self._status: IO = StringIO()
self.quiet = True self.quiet: bool = True
else: else:
self._status = status self._status = status
self.quiet = False self.quiet = False
@ -211,9 +206,13 @@ class Sphinx:
# read config # read config
self.tags = Tags(tags) self.tags = Tags(tags)
if self.confdir is None: if confdir is None:
# set confdir to srcdir if -C given (!= no confdir); a few pieces
# of code expect a confdir to be set
self.confdir = self.srcdir
self.config = Config({}, confoverrides or {}) self.config = Config({}, confoverrides or {})
else: else:
self.confdir = abspath(confdir)
self.config = Config.read(self.confdir, confoverrides or {}, self.tags) self.config = Config.read(self.confdir, confoverrides or {}, self.tags)
# initialize some limited config variables before initialize i18n and loading # initialize some limited config variables before initialize i18n and loading
@ -229,11 +228,6 @@ class Sphinx:
__('This project needs at least Sphinx v%s and therefore cannot ' __('This project needs at least Sphinx v%s and therefore cannot '
'be built with this version.') % self.config.needs_sphinx) 'be built with this version.') % self.config.needs_sphinx)
# set confdir to srcdir if -C given (!= no confdir); a few pieces
# of code expect a confdir to be set
if self.confdir is None:
self.confdir = self.srcdir
# load all built-in extension modules # load all built-in extension modules
for extension in builtin_extensions: for extension in builtin_extensions:
self.setup_extension(extension) self.setup_extension(extension)
@ -306,8 +300,7 @@ class Sphinx:
def _init_env(self, freshenv: bool) -> None: def _init_env(self, freshenv: bool) -> None:
filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME) filename = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
if freshenv or not os.path.exists(filename): if freshenv or not os.path.exists(filename):
self.env = BuildEnvironment() self.env = BuildEnvironment(self)
self.env.setup(self)
self.env.find_files(self.config, self.builder) self.env.find_files(self.config, self.builder)
else: else:
try: try:
@ -662,10 +655,10 @@ class Sphinx:
... ...
def setup(app): def setup(app):
add_directive('my-directive', MyDirective) app.add_directive('my-directive', MyDirective)
For more details, see `the Docutils docs For more details, see `the Docutils docs
<http://docutils.sourceforge.net/docs/howto/rst-directives.html>`__ . <https://docutils.sourceforge.io/docs/howto/rst-directives.html>`__ .
.. versionchanged:: 0.6 .. versionchanged:: 0.6
Docutils 0.5-style directive classes are now supported. Docutils 0.5-style directive classes are now supported.
@ -690,7 +683,7 @@ class Sphinx:
installed as the same name installed as the same name
For more details about role functions, see `the Docutils docs For more details about role functions, see `the Docutils docs
<http://docutils.sourceforge.net/docs/howto/rst-roles.html>`__ . <https://docutils.sourceforge.io/docs/howto/rst-roles.html>`__ .
.. versionchanged:: 1.8 .. versionchanged:: 1.8
Add *override* keyword. Add *override* keyword.
@ -928,7 +921,7 @@ class Sphinx:
refs: `Transform Priority Range Categories`__ refs: `Transform Priority Range Categories`__
__ http://docutils.sourceforge.net/docs/ref/transforms.html#transform-priority-range-categories __ https://docutils.sourceforge.io/docs/ref/transforms.html#transform-priority-range-categories
""" # NOQA """ # NOQA
self.registry.add_transform(transform) self.registry.add_transform(transform)
@ -1184,13 +1177,13 @@ class Sphinx:
def add_html_theme(self, name: str, theme_path: str) -> None: def add_html_theme(self, name: str, theme_path: str) -> None:
"""Register a HTML Theme. """Register a HTML Theme.
The *name* is a name of theme, and *path* is a full path to the theme The *name* is a name of theme, and *theme_path* is a full path to the
(refs: :ref:`distribute-your-theme`). theme (refs: :ref:`distribute-your-theme`).
.. versionadded:: 1.6 .. versionadded:: 1.6
""" """
logger.debug('[app] adding HTML theme: %r, %r', name, theme_path) logger.debug('[app] adding HTML theme: %r, %r', name, theme_path)
self.html_themes[name] = theme_path self.registry.add_html_theme(name, theme_path)
def add_html_math_renderer(self, name: str, def add_html_math_renderer(self, name: str,
inline_renderers: Tuple[Callable, Callable] = None, inline_renderers: Tuple[Callable, Callable] = None,
@ -1269,6 +1262,12 @@ class Sphinx:
raise ValueError('policy %s is not supported' % policy) raise ValueError('policy %s is not supported' % policy)
self.registry.html_assets_policy = policy self.registry.html_assets_policy = policy
@property
def html_themes(self) -> Dict[str, str]:
warnings.warn('app.html_themes is deprecated.',
RemovedInSphinx60Warning)
return self.registry.html_themes
class TemplateBridge: class TemplateBridge:
""" """

View File

@ -11,7 +11,8 @@
import pickle import pickle
import time import time
from os import path from os import path
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Sequence, Set, Tuple, Type, Union from typing import (TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Sequence, Set, Tuple,
Type, Union)
from docutils import nodes from docutils import nodes
from docutils.nodes import Node from docutils.nodes import Node
@ -88,7 +89,7 @@ class Builder:
ensuredir(self.doctreedir) ensuredir(self.doctreedir)
self.app: Sphinx = app self.app: Sphinx = app
self.env: BuildEnvironment = None self.env: Optional[BuildEnvironment] = None
self.events: EventManager = app.events self.events: EventManager = app.events
self.config: Config = app.config self.config: Config = app.config
self.tags: Tags = app.tags self.tags: Tags = app.tags
@ -225,7 +226,7 @@ class Builder:
self.compile_catalogs(set(repo.catalogs), message) self.compile_catalogs(set(repo.catalogs), message)
def compile_specific_catalogs(self, specified_files: List[str]) -> None: def compile_specific_catalogs(self, specified_files: List[str]) -> None:
def to_domain(fpath: str) -> str: def to_domain(fpath: str) -> Optional[str]:
docname = self.env.path2doc(path.abspath(fpath)) docname = self.env.path2doc(path.abspath(fpath))
if docname: if docname:
return docname_to_domain(docname, self.config.gettext_compact) return docname_to_domain(docname, self.config.gettext_compact)

View File

@ -13,7 +13,6 @@ from typing import Any, Dict
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
from sphinx.util import logging from sphinx.util import logging
from sphinx.util.osutil import SEP, os_path from sphinx.util.osutil import SEP, os_path
@ -46,17 +45,6 @@ class DirectoryHTMLBuilder(StandaloneHTMLBuilder):
return outfilename return outfilename
# for compatibility
deprecated_alias('sphinx.builders.html',
{
'DirectoryHTMLBuilder': DirectoryHTMLBuilder,
},
RemovedInSphinx40Warning,
{
'DirectoryHTMLBuilder': 'sphinx.builders.dirhtml.DirectoryHTMLBuilder',
})
def setup(app: Sphinx) -> Dict[str, Any]: def setup(app: Sphinx) -> Dict[str, Any]:
app.setup_extension('sphinx.builders.html') app.setup_extension('sphinx.builders.html')

View File

@ -1000,16 +1000,6 @@ class StandaloneHTMLBuilder(Builder):
return uri return uri
ctx['pathto'] = pathto ctx['pathto'] = pathto
def css_tag(css: Stylesheet) -> str:
attrs = []
for key in sorted(css.attributes):
value = css.attributes[key]
if value is not None:
attrs.append('%s="%s"' % (key, html.escape(value, True)))
attrs.append('href="%s"' % pathto(css.filename, resource=True))
return '<link %s />' % ' '.join(attrs)
ctx['css_tag'] = css_tag
def hasdoc(name: str) -> bool: def hasdoc(name: str) -> bool:
if name in self.env.all_docs: if name in self.env.all_docs:
return True return True
@ -1026,7 +1016,7 @@ class StandaloneHTMLBuilder(Builder):
# revert script_files and css_files # revert script_files and css_files
self.script_files[:] = self._script_files self.script_files[:] = self._script_files
self.css_files[:] = self.css_files self.css_files[:] = self._css_files
self.update_page_context(pagename, templatename, ctx, event_arg) self.update_page_context(pagename, templatename, ctx, event_arg)
newtmpl = self.app.emit_firstresult('html-page-context', pagename, newtmpl = self.app.emit_firstresult('html-page-context', pagename,
@ -1140,6 +1130,26 @@ def convert_html_js_files(app: Sphinx, config: Config) -> None:
config.html_js_files = html_js_files # type: ignore config.html_js_files = html_js_files # type: ignore
def setup_css_tag_helper(app: Sphinx, pagename: str, templatename: str,
context: Dict, doctree: Node) -> None:
"""Set up css_tag() template helper.
.. note:: This set up function is added to keep compatibility with webhelper.
"""
pathto = context.get('pathto')
def css_tag(css: Stylesheet) -> str:
attrs = []
for key in sorted(css.attributes):
value = css.attributes[key]
if value is not None:
attrs.append('%s="%s"' % (key, html.escape(value, True)))
attrs.append('href="%s"' % pathto(css.filename, resource=True))
return '<link %s />' % ' '.join(attrs)
context['css_tag'] = css_tag
def setup_js_tag_helper(app: Sphinx, pagename: str, templatename: str, def setup_js_tag_helper(app: Sphinx, pagename: str, templatename: str,
context: Dict, doctree: Node) -> None: context: Dict, doctree: Node) -> None:
"""Set up js_tag() template helper. """Set up js_tag() template helper.
@ -1347,6 +1357,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.connect('config-inited', validate_html_logo, priority=800) app.connect('config-inited', validate_html_logo, priority=800)
app.connect('config-inited', validate_html_favicon, priority=800) app.connect('config-inited', validate_html_favicon, priority=800)
app.connect('builder-inited', validate_math_renderer) app.connect('builder-inited', validate_math_renderer)
app.connect('html-page-context', setup_css_tag_helper)
app.connect('html-page-context', setup_js_tag_helper) app.connect('html-page-context', setup_js_tag_helper)
app.connect('html-page-context', setup_resource_paths) app.connect('html-page-context', setup_resource_paths)

View File

@ -21,12 +21,12 @@ from queue import PriorityQueue, Queue
from threading import Thread from threading import Thread
from typing import (Any, Dict, Generator, List, NamedTuple, Optional, Pattern, Set, Tuple, from typing import (Any, Dict, Generator, List, NamedTuple, Optional, Pattern, Set, Tuple,
Union, cast) Union, cast)
from urllib.parse import unquote, urlparse from urllib.parse import unquote, urlparse, urlunparse
from docutils import nodes from docutils import nodes
from docutils.nodes import Element from docutils.nodes import Element
from requests import Response from requests import Response
from requests.exceptions import HTTPError, TooManyRedirects from requests.exceptions import ConnectionError, HTTPError, TooManyRedirects
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.builders.dummy import DummyBuilder from sphinx.builders.dummy import DummyBuilder
@ -456,7 +456,9 @@ class HyperlinkAvailabilityCheckWorker(Thread):
config=self.config, auth=auth_info, config=self.config, auth=auth_info,
**kwargs) **kwargs)
response.raise_for_status() response.raise_for_status()
except (HTTPError, TooManyRedirects) as err: # Servers drop the connection on HEAD requests, causing
# ConnectionError.
except (ConnectionError, HTTPError, TooManyRedirects) as err:
if isinstance(err, HTTPError) and err.response.status_code == 429: if isinstance(err, HTTPError) and err.response.status_code == 429:
raise raise
# retry with GET request if that fails, some servers # retry with GET request if that fails, some servers
@ -627,6 +629,10 @@ class HyperlinkCollector(SphinxPostTransform):
if 'refuri' not in refnode: if 'refuri' not in refnode:
continue continue
uri = refnode['refuri'] uri = refnode['refuri']
newuri = self.app.emit_firstresult('linkcheck-process-uri', uri)
if newuri:
uri = newuri
lineno = get_node_line(refnode) lineno = get_node_line(refnode)
uri_info = Hyperlink(uri, self.env.docname, lineno) uri_info = Hyperlink(uri, self.env.docname, lineno)
if uri not in hyperlinks: if uri not in hyperlinks:
@ -636,12 +642,31 @@ class HyperlinkCollector(SphinxPostTransform):
for imgnode in self.document.traverse(nodes.image): for imgnode in self.document.traverse(nodes.image):
uri = imgnode['candidates'].get('?') uri = imgnode['candidates'].get('?')
if uri and '://' in uri: if uri and '://' in uri:
newuri = self.app.emit_firstresult('linkcheck-process-uri', uri)
if newuri:
uri = newuri
lineno = get_node_line(imgnode) lineno = get_node_line(imgnode)
uri_info = Hyperlink(uri, self.env.docname, lineno) uri_info = Hyperlink(uri, self.env.docname, lineno)
if uri not in hyperlinks: if uri not in hyperlinks:
hyperlinks[uri] = uri_info hyperlinks[uri] = uri_info
def rewrite_github_anchor(app: Sphinx, uri: str) -> Optional[str]:
"""Rewrite anchor name of the hyperlink to github.com
The hyperlink anchors in github.com are dynamically generated. This rewrites
them before checking and makes them comparable.
"""
parsed = urlparse(uri)
if parsed.hostname == "github.com" and parsed.fragment:
prefixed = parsed.fragment.startswith('user-content-')
if not prefixed:
fragment = f'user-content-{parsed.fragment}'
return urlunparse(parsed._replace(fragment=fragment))
return None
def setup(app: Sphinx) -> Dict[str, Any]: def setup(app: Sphinx) -> Dict[str, Any]:
app.add_builder(CheckExternalLinksBuilder) app.add_builder(CheckExternalLinksBuilder)
app.add_post_transform(HyperlinkCollector) app.add_post_transform(HyperlinkCollector)
@ -658,6 +683,9 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value('linkcheck_anchors_ignore', ["^!"], None) app.add_config_value('linkcheck_anchors_ignore', ["^!"], None)
app.add_config_value('linkcheck_rate_limit_timeout', 300.0, None) app.add_config_value('linkcheck_rate_limit_timeout', 300.0, None)
app.add_event('linkcheck-process-uri')
app.connect('linkcheck-process-uri', rewrite_github_anchor)
return { return {
'version': 'builtin', 'version': 'builtin',
'parallel_read_safe': True, 'parallel_read_safe': True,

View File

@ -79,8 +79,9 @@ class ManualPageBuilder(Builder):
docsettings.section = section docsettings.section = section
if self.config.man_make_section_directory: if self.config.man_make_section_directory:
ensuredir(path.join(self.outdir, str(section))) dirname = 'man%s' % section
targetname = '%s/%s.%s' % (section, name, section) ensuredir(path.join(self.outdir, dirname))
targetname = '%s/%s.%s' % (dirname, name, section)
else: else:
targetname = '%s.%s' % (name, section) targetname = '%s.%s' % (name, section)
@ -118,7 +119,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value('man_pages', default_man_pages, None) app.add_config_value('man_pages', default_man_pages, None)
app.add_config_value('man_show_urls', False, None) app.add_config_value('man_show_urls', False, None)
app.add_config_value('man_make_section_directory', True, None) app.add_config_value('man_make_section_directory', False, None)
return { return {
'version': 'builtin', 'version': 'builtin',

View File

@ -16,7 +16,6 @@ from docutils.nodes import Node
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.builders.html import StandaloneHTMLBuilder from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.deprecation import RemovedInSphinx40Warning, deprecated_alias
from sphinx.environment.adapters.toctree import TocTree from sphinx.environment.adapters.toctree import TocTree
from sphinx.locale import __ from sphinx.locale import __
from sphinx.util import logging, progress_message from sphinx.util import logging, progress_message
@ -187,18 +186,6 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
self.handle_page('opensearch', {}, 'opensearch.xml', outfilename=fn) self.handle_page('opensearch', {}, 'opensearch.xml', outfilename=fn)
# for compatibility
deprecated_alias('sphinx.builders.html',
{
'SingleFileHTMLBuilder': SingleFileHTMLBuilder,
},
RemovedInSphinx40Warning,
{
'SingleFileHTMLBuilder':
'sphinx.builders.singlehtml.SingleFileHTMLBuilder',
})
def setup(app: Sphinx) -> Dict[str, Any]: def setup(app: Sphinx) -> Dict[str, Any]:
app.setup_extension('sphinx.builders.html') app.setup_extension('sphinx.builders.html')

View File

@ -166,6 +166,9 @@ class Config:
def read(cls, confdir: str, overrides: Dict = None, tags: Tags = None) -> "Config": def read(cls, confdir: str, overrides: Dict = None, tags: Tags = None) -> "Config":
"""Create a Config object from configuration file.""" """Create a Config object from configuration file."""
filename = path.join(confdir, CONFIG_FILENAME) filename = path.join(confdir, CONFIG_FILENAME)
if not path.isfile(filename):
raise ConfigError(__("config directory doesn't contain a conf.py file (%s)") %
confdir)
namespace = eval_config_file(filename, tags) namespace = eval_config_file(filename, tags)
return cls(namespace, overrides or {}) return cls(namespace, overrides or {})

View File

@ -14,10 +14,6 @@ from importlib import import_module
from typing import Any, Dict, Type from typing import Any, Dict, Type
class RemovedInSphinx40Warning(DeprecationWarning):
pass
class RemovedInSphinx50Warning(DeprecationWarning): class RemovedInSphinx50Warning(DeprecationWarning):
pass pass

View File

@ -11,8 +11,8 @@
import copy import copy
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, List, NamedTuple, Tuple, from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterable, List, NamedTuple, Optional,
Type, Union, cast) Tuple, Type, Union, cast)
from docutils import nodes from docutils import nodes
from docutils.nodes import Element, Node, system_message from docutils.nodes import Element, Node, system_message
@ -196,7 +196,7 @@ class Domain:
#: data value for a fresh environment #: data value for a fresh environment
initial_data: Dict = {} initial_data: Dict = {}
#: data value #: data value
data: Dict = None data: Dict
#: data version, bump this when the format of `self.data` changes #: data version, bump this when the format of `self.data` changes
data_version = 0 data_version = 0
@ -251,7 +251,7 @@ class Domain:
for role in objtype.roles: for role in objtype.roles:
self._role2type.setdefault(role, []).append(name) self._role2type.setdefault(role, []).append(name)
def role(self, name: str) -> RoleFunction: def role(self, name: str) -> Optional[RoleFunction]:
"""Return a role adapter function that always gives the registered """Return a role adapter function that always gives the registered
role its full name ('domain:name') as the first argument. role its full name ('domain:name') as the first argument.
""" """
@ -269,7 +269,7 @@ class Domain:
self._role_cache[name] = role_adapter self._role_cache[name] = role_adapter
return role_adapter return role_adapter
def directive(self, name: str) -> Callable: def directive(self, name: str) -> Optional[Callable]:
"""Return a directive adapter class that always gives the registered """Return a directive adapter class that always gives the registered
directive its full name ('domain:name') as ``self.name``. directive its full name ('domain:name') as ``self.name``.
""" """
@ -318,7 +318,7 @@ class Domain:
def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder", def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder",
typ: str, target: str, node: pending_xref, contnode: Element typ: str, target: str, node: pending_xref, contnode: Element
) -> Element: ) -> Optional[Element]:
"""Resolve the pending_xref *node* with the given *typ* and *target*. """Resolve the pending_xref *node* with the given *typ* and *target*.
This method should return a new node, to replace the xref node, This method should return a new node, to replace the xref node,
@ -393,11 +393,11 @@ class Domain:
return type.lname return type.lname
return _('%s %s') % (self.label, type.lname) return _('%s %s') % (self.label, type.lname)
def get_enumerable_node_type(self, node: Node) -> str: def get_enumerable_node_type(self, node: Node) -> Optional[str]:
"""Get type of enumerable nodes (experimental).""" """Get type of enumerable nodes (experimental)."""
enum_node_type, _ = self.enumerable_nodes.get(node.__class__, (None, None)) enum_node_type, _ = self.enumerable_nodes.get(node.__class__, (None, None))
return enum_node_type return enum_node_type
def get_full_qualified_name(self, node: Element) -> str: def get_full_qualified_name(self, node: Element) -> Optional[str]:
"""Return full qualified name for given node.""" """Return full qualified name for given node."""
return None return None

View File

@ -9,7 +9,8 @@
""" """
import re import re
from typing import Any, Callable, Dict, Generator, Iterator, List, Tuple, TypeVar, Union, cast from typing import (Any, Callable, Dict, Generator, Iterator, List, Optional, Tuple, TypeVar,
Union, cast)
from docutils import nodes from docutils import nodes
from docutils.nodes import Element, Node, TextElement, system_message from docutils.nodes import Element, Node, TextElement, system_message
@ -3114,7 +3115,7 @@ class CObject(ObjectDescription[ASTDeclaration]):
doc_field_types = [ doc_field_types = [
TypedField('parameter', label=_('Parameters'), TypedField('parameter', label=_('Parameters'),
names=('param', 'parameter', 'arg', 'argument'), names=('param', 'parameter', 'arg', 'argument'),
typerolename='type', typenames=('type',)), typerolename='expr', typenames=('type',)),
Field('returnvalue', label=_('Returns'), has_arg=False, Field('returnvalue', label=_('Returns'), has_arg=False,
names=('returns', 'return')), names=('returns', 'return')),
Field('returntype', label=_('Return type'), has_arg=False, Field('returntype', label=_('Return type'), has_arg=False,
@ -3807,7 +3808,7 @@ class CDomain(Domain):
def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder: Builder, def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
typ: str, target: str, node: pending_xref, typ: str, target: str, node: pending_xref,
contnode: Element) -> Tuple[Element, str]: contnode: Element) -> Tuple[Optional[Element], Optional[str]]:
parser = DefinitionParser(target, location=node, config=env.config) parser = DefinitionParser(target, location=node, config=env.config)
try: try:
name = parser.parse_xref_object() name = parser.parse_xref_object()
@ -3844,7 +3845,7 @@ class CDomain(Domain):
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
typ: str, target: str, node: pending_xref, typ: str, target: str, node: pending_xref,
contnode: Element) -> Element: contnode: Element) -> Optional[Element]:
return self._resolve_xref_inner(env, fromdocname, builder, typ, return self._resolve_xref_inner(env, fromdocname, builder, typ,
target, node, contnode)[0] target, node, contnode)[0]

View File

@ -8,7 +8,7 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from typing import TYPE_CHECKING, Any, Dict, List, Set, Tuple, cast from typing import TYPE_CHECKING, Any, Dict, List, Optional, Set, Tuple, cast
from docutils import nodes from docutils import nodes
from docutils.nodes import Element from docutils.nodes import Element
@ -88,7 +88,7 @@ class CitationDomain(Domain):
def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder", def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder",
typ: str, target: str, node: pending_xref, contnode: Element typ: str, target: str, node: pending_xref, contnode: Element
) -> Element: ) -> Optional[Element]:
docname, labelid, lineno = self.citations.get(target, ('', '', 0)) docname, labelid, lineno = self.citations.get(target, ('', '', 0))
if not docname: if not docname:
return None return None

View File

@ -6846,7 +6846,7 @@ class CPPObject(ObjectDescription[ASTDeclaration]):
GroupedField('template parameter', label=_('Template Parameters'), GroupedField('template parameter', label=_('Template Parameters'),
names=('tparam', 'template parameter'), names=('tparam', 'template parameter'),
can_collapse=True), can_collapse=True),
GroupedField('exceptions', label=_('Throws'), rolename='cpp:class', GroupedField('exceptions', label=_('Throws'), rolename='expr',
names=('throws', 'throw', 'exception'), names=('throws', 'throw', 'exception'),
can_collapse=True), can_collapse=True),
Field('returnvalue', label=_('Returns'), has_arg=False, Field('returnvalue', label=_('Returns'), has_arg=False,
@ -7594,7 +7594,7 @@ class CPPDomain(Domain):
def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder: Builder, def _resolve_xref_inner(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
typ: str, target: str, node: pending_xref, typ: str, target: str, node: pending_xref,
contnode: Element) -> Tuple[Element, str]: contnode: Element) -> Tuple[Optional[Element], Optional[str]]:
# add parens again for those that could be functions # add parens again for those that could be functions
if typ == 'any' or typ == 'func': if typ == 'any' or typ == 'func':
target += '()' target += '()'
@ -7743,7 +7743,7 @@ class CPPDomain(Domain):
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
typ: str, target: str, node: pending_xref, contnode: Element typ: str, target: str, node: pending_xref, contnode: Element
) -> Element: ) -> Optional[Element]:
return self._resolve_xref_inner(env, fromdocname, builder, typ, return self._resolve_xref_inner(env, fromdocname, builder, typ,
target, node, contnode)[0] target, node, contnode)[0]

View File

@ -8,7 +8,7 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from typing import Any, Dict, Iterator, List, Tuple, cast from typing import Any, Dict, Iterator, List, Optional, Tuple, cast
from docutils import nodes from docutils import nodes
from docutils.nodes import Element, Node from docutils.nodes import Element, Node
@ -215,7 +215,7 @@ class JSCallable(JSObject):
TypedField('arguments', label=_('Arguments'), TypedField('arguments', label=_('Arguments'),
names=('argument', 'arg', 'parameter', 'param'), names=('argument', 'arg', 'parameter', 'param'),
typerolename='func', typenames=('paramtype', 'type')), typerolename='func', typenames=('paramtype', 'type')),
GroupedField('errors', label=_('Throws'), rolename='err', GroupedField('errors', label=_('Throws'), rolename='func',
names=('throws', ), names=('throws', ),
can_collapse=True), can_collapse=True),
Field('returnvalue', label=_('Returns'), has_arg=False, Field('returnvalue', label=_('Returns'), has_arg=False,
@ -413,7 +413,7 @@ class JavaScriptDomain(Domain):
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
typ: str, target: str, node: pending_xref, contnode: Element typ: str, target: str, node: pending_xref, contnode: Element
) -> Element: ) -> Optional[Element]:
mod_name = node.get('js:module') mod_name = node.get('js:module')
prefix = node.get('js:object') prefix = node.get('js:object')
searchorder = 1 if node.hasattr('refspecific') else 0 searchorder = 1 if node.hasattr('refspecific') else 0

View File

@ -8,7 +8,7 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Tuple from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Optional, Tuple
from docutils import nodes from docutils import nodes
from docutils.nodes import Element, Node, make_id, system_message from docutils.nodes import Element, Node, make_id, system_message
@ -97,7 +97,7 @@ class MathDomain(Domain):
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: "Builder", def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: "Builder",
typ: str, target: str, node: pending_xref, contnode: Element typ: str, target: str, node: pending_xref, contnode: Element
) -> Element: ) -> Optional[Element]:
assert typ in ('eq', 'numref') assert typ in ('eq', 'numref')
docname, number = self.equations.get(target, (None, None)) docname, number = self.equations.get(target, (None, None))
if docname: if docname:

View File

@ -15,11 +15,12 @@ import sys
import typing import typing
import warnings import warnings
from inspect import Parameter from inspect import Parameter
from typing import Any, Dict, Iterable, Iterator, List, NamedTuple, Tuple, Type, cast from typing import Any, Dict, Iterable, Iterator, List, NamedTuple, Optional, Tuple, Type, cast
from docutils import nodes from docutils import nodes
from docutils.nodes import Element, Node from docutils.nodes import Element, Node
from docutils.parsers.rst import directives from docutils.parsers.rst import directives
from docutils.parsers.rst.states import Inliner
from sphinx import addnodes from sphinx import addnodes
from sphinx.addnodes import desc_signature, pending_xref, pending_xref_condition from sphinx.addnodes import desc_signature, pending_xref, pending_xref_condition
@ -284,9 +285,13 @@ def _pseudo_parse_arglist(signode: desc_signature, arglist: str) -> None:
class PyXrefMixin: class PyXrefMixin:
def make_xref(self, rolename: str, domain: str, target: str, def make_xref(self, rolename: str, domain: str, target: str,
innernode: Type[TextlikeNode] = nodes.emphasis, innernode: Type[TextlikeNode] = nodes.emphasis,
contnode: Node = None, env: BuildEnvironment = None) -> Node: contnode: Node = None, env: BuildEnvironment = None,
inliner: Inliner = None, location: Node = None) -> Node:
# we use inliner=None to make sure we get the old behaviour with a single
# pending_xref node
result = super().make_xref(rolename, domain, target, # type: ignore result = super().make_xref(rolename, domain, target, # type: ignore
innernode, contnode, env) innernode, contnode,
env, inliner=None, location=None)
result['refspecific'] = True result['refspecific'] = True
result['py:module'] = env.ref_context.get('py:module') result['py:module'] = env.ref_context.get('py:module')
result['py:class'] = env.ref_context.get('py:class') result['py:class'] = env.ref_context.get('py:class')
@ -299,12 +304,23 @@ class PyXrefMixin:
for node in result.traverse(nodes.Text): for node in result.traverse(nodes.Text):
node.parent[node.parent.index(node)] = nodes.Text(text) node.parent[node.parent.index(node)] = nodes.Text(text)
break break
elif isinstance(result, pending_xref) and env.config.python_use_unqualified_type_names:
children = result.children
result.clear()
shortname = target.split('.')[-1]
textnode = innernode('', shortname)
contnodes = [pending_xref_condition('', '', textnode, condition='resolved'),
pending_xref_condition('', '', *children, condition='*')]
result.extend(contnodes)
return result return result
def make_xrefs(self, rolename: str, domain: str, target: str, def make_xrefs(self, rolename: str, domain: str, target: str,
innernode: Type[TextlikeNode] = nodes.emphasis, innernode: Type[TextlikeNode] = nodes.emphasis,
contnode: Node = None, env: BuildEnvironment = None) -> List[Node]: contnode: Node = None, env: BuildEnvironment = None,
delims = r'(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+|\.\.\.)' inliner: Inliner = None, location: Node = None) -> List[Node]:
delims = r'(\s*[\[\]\(\),](?:\s*or\s)?\s*|\s+or\s+|\s*\|\s*|\.\.\.)'
delims_re = re.compile(delims) delims_re = re.compile(delims)
sub_targets = re.split(delims, target) sub_targets = re.split(delims, target)
@ -319,7 +335,7 @@ class PyXrefMixin:
results.append(contnode or innernode(sub_target, sub_target)) results.append(contnode or innernode(sub_target, sub_target))
else: else:
results.append(self.make_xref(rolename, domain, sub_target, results.append(self.make_xref(rolename, domain, sub_target,
innernode, contnode, env)) innernode, contnode, env, inliner, location))
return results return results
@ -327,12 +343,14 @@ class PyXrefMixin:
class PyField(PyXrefMixin, Field): class PyField(PyXrefMixin, Field):
def make_xref(self, rolename: str, domain: str, target: str, def make_xref(self, rolename: str, domain: str, target: str,
innernode: Type[TextlikeNode] = nodes.emphasis, innernode: Type[TextlikeNode] = nodes.emphasis,
contnode: Node = None, env: BuildEnvironment = None) -> Node: contnode: Node = None, env: BuildEnvironment = None,
inliner: Inliner = None, location: Node = None) -> Node:
if rolename == 'class' and target == 'None': if rolename == 'class' and target == 'None':
# None is not a type, so use obj role instead. # None is not a type, so use obj role instead.
rolename = 'obj' rolename = 'obj'
return super().make_xref(rolename, domain, target, innernode, contnode, env) return super().make_xref(rolename, domain, target, innernode, contnode,
env, inliner, location)
class PyGroupedField(PyXrefMixin, GroupedField): class PyGroupedField(PyXrefMixin, GroupedField):
@ -342,12 +360,14 @@ class PyGroupedField(PyXrefMixin, GroupedField):
class PyTypedField(PyXrefMixin, TypedField): class PyTypedField(PyXrefMixin, TypedField):
def make_xref(self, rolename: str, domain: str, target: str, def make_xref(self, rolename: str, domain: str, target: str,
innernode: Type[TextlikeNode] = nodes.emphasis, innernode: Type[TextlikeNode] = nodes.emphasis,
contnode: Node = None, env: BuildEnvironment = None) -> Node: contnode: Node = None, env: BuildEnvironment = None,
inliner: Inliner = None, location: Node = None) -> Node:
if rolename == 'class' and target == 'None': if rolename == 'class' and target == 'None':
# None is not a type, so use obj role instead. # None is not a type, so use obj role instead.
rolename = 'obj' rolename = 'obj'
return super().make_xref(rolename, domain, target, innernode, contnode, env) return super().make_xref(rolename, domain, target, innernode, contnode,
env, inliner, location)
class PyObject(ObjectDescription[Tuple[str, str]]): class PyObject(ObjectDescription[Tuple[str, str]]):
@ -448,10 +468,7 @@ class PyObject(ObjectDescription[Tuple[str, str]]):
if prefix: if prefix:
signode += addnodes.desc_addname(prefix, prefix) signode += addnodes.desc_addname(prefix, prefix)
elif add_module and self.env.config.add_module_names: elif modname and add_module and self.env.config.add_module_names:
if modname and modname != 'exceptions':
# exceptions are a special case, since they are documented in the
# 'exceptions' module.
nodetext = modname + '.' nodetext = modname + '.'
signode += addnodes.desc_addname(nodetext, nodetext) signode += addnodes.desc_addname(nodetext, nodetext)
@ -1246,7 +1263,7 @@ class PythonDomain(Domain):
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
type: str, target: str, node: pending_xref, contnode: Element type: str, target: str, node: pending_xref, contnode: Element
) -> Element: ) -> Optional[Element]:
modname = node.get('py:module') modname = node.get('py:module')
clsname = node.get('py:class') clsname = node.get('py:class')
searchmode = 1 if node.hasattr('refspecific') else 0 searchmode = 1 if node.hasattr('refspecific') else 0
@ -1269,6 +1286,10 @@ class PythonDomain(Domain):
if not matches: if not matches:
return None return None
elif len(matches) > 1: elif len(matches) > 1:
canonicals = [m for m in matches if not m[1].aliased]
if len(canonicals) == 1:
matches = canonicals
else:
logger.warning(__('more than one target found for cross-reference %r: %s'), logger.warning(__('more than one target found for cross-reference %r: %s'),
target, ', '.join(match[0] for match in matches), target, ', '.join(match[0] for match in matches),
type='ref', subtype='python', location=node) type='ref', subtype='python', location=node)
@ -1340,7 +1361,7 @@ class PythonDomain(Domain):
else: else:
yield (refname, refname, obj.objtype, obj.docname, obj.node_id, 1) yield (refname, refname, obj.objtype, obj.docname, obj.node_id, 1)
def get_full_qualified_name(self, node: Element) -> str: def get_full_qualified_name(self, node: Element) -> Optional[str]:
modname = node.get('py:module') modname = node.get('py:module')
clsname = node.get('py:class') clsname = node.get('py:class')
target = node.get('reftarget') target = node.get('reftarget')
@ -1359,10 +1380,6 @@ def builtin_resolver(app: Sphinx, env: BuildEnvironment,
return s in typing.__all__ # type: ignore return s in typing.__all__ # type: ignore
content = find_pending_xref_condition(node, 'resolved')
if content:
contnode = content.children[0] # type: ignore
if node.get('refdomain') != 'py': if node.get('refdomain') != 'py':
return None return None
elif node.get('reftype') in ('class', 'obj') and node.get('reftarget') == 'None': elif node.get('reftype') in ('class', 'obj') and node.get('reftarget') == 'None':

View File

@ -9,7 +9,7 @@
""" """
import re import re
from typing import Any, Dict, Iterator, List, Tuple, cast from typing import Any, Dict, Iterator, List, Optional, Tuple, cast
from docutils.nodes import Element from docutils.nodes import Element
from docutils.parsers.rst import directives from docutils.parsers.rst import directives
@ -247,7 +247,7 @@ class ReSTDomain(Domain):
def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder, def resolve_xref(self, env: BuildEnvironment, fromdocname: str, builder: Builder,
typ: str, target: str, node: pending_xref, contnode: Element typ: str, target: str, node: pending_xref, contnode: Element
) -> Element: ) -> Optional[Element]:
objtypes = self.objtypes_for_role(typ) objtypes = self.objtypes_for_role(typ)
for objtype in objtypes: for objtype in objtypes:
todocname, node_id = self.objects.get((objtype, target), (None, None)) todocname, node_id = self.objects.get((objtype, target), (None, None))

View File

@ -285,7 +285,7 @@ class OptionXRefRole(XRefRole):
def split_term_classifiers(line: str) -> List[Optional[str]]: def split_term_classifiers(line: str) -> List[Optional[str]]:
# split line into a term and classifiers. if no classifier, None is used.. # split line into a term and classifiers. if no classifier, None is used..
parts = re.split(' +: +', line) + [None] parts: List[Optional[str]] = re.split(' +: +', line) + [None]
return parts return parts
@ -621,7 +621,7 @@ class StandardDomain(Domain):
} }
# node_class -> (figtype, title_getter) # node_class -> (figtype, title_getter)
enumerable_nodes: Dict[Type[Node], Tuple[str, Callable]] = { enumerable_nodes: Dict[Type[Node], Tuple[str, Optional[Callable]]] = {
nodes.figure: ('figure', None), nodes.figure: ('figure', None),
nodes.table: ('table', None), nodes.table: ('table', None),
nodes.container: ('code-block', None), nodes.container: ('code-block', None),
@ -812,7 +812,8 @@ class StandardDomain(Domain):
return newnode return newnode
def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder", def resolve_xref(self, env: "BuildEnvironment", fromdocname: str, builder: "Builder",
typ: str, target: str, node: pending_xref, contnode: Element) -> Element: typ: str, target: str, node: pending_xref, contnode: Element
) -> Optional[Element]:
if typ == 'ref': if typ == 'ref':
resolver = self._resolve_ref_xref resolver = self._resolve_ref_xref
elif typ == 'numref': elif typ == 'numref':
@ -832,7 +833,7 @@ class StandardDomain(Domain):
def _resolve_ref_xref(self, env: "BuildEnvironment", fromdocname: str, def _resolve_ref_xref(self, env: "BuildEnvironment", fromdocname: str,
builder: "Builder", typ: str, target: str, node: pending_xref, builder: "Builder", typ: str, target: str, node: pending_xref,
contnode: Element) -> Element: contnode: Element) -> Optional[Element]:
if node['refexplicit']: if node['refexplicit']:
# reference to anonymous label; the reference uses # reference to anonymous label; the reference uses
# the supplied link caption # the supplied link caption
@ -850,7 +851,7 @@ class StandardDomain(Domain):
def _resolve_numref_xref(self, env: "BuildEnvironment", fromdocname: str, def _resolve_numref_xref(self, env: "BuildEnvironment", fromdocname: str,
builder: "Builder", typ: str, target: str, builder: "Builder", typ: str, target: str,
node: pending_xref, contnode: Element) -> Element: node: pending_xref, contnode: Element) -> Optional[Element]:
if target in self.labels: if target in self.labels:
docname, labelid, figname = self.labels.get(target, ('', '', '')) docname, labelid, figname = self.labels.get(target, ('', '', ''))
else: else:
@ -913,7 +914,7 @@ class StandardDomain(Domain):
def _resolve_keyword_xref(self, env: "BuildEnvironment", fromdocname: str, def _resolve_keyword_xref(self, env: "BuildEnvironment", fromdocname: str,
builder: "Builder", typ: str, target: str, builder: "Builder", typ: str, target: str,
node: pending_xref, contnode: Element) -> Element: node: pending_xref, contnode: Element) -> Optional[Element]:
# keywords are oddballs: they are referenced by named labels # keywords are oddballs: they are referenced by named labels
docname, labelid, _ = self.labels.get(target, ('', '', '')) docname, labelid, _ = self.labels.get(target, ('', '', ''))
if not docname: if not docname:
@ -923,7 +924,7 @@ class StandardDomain(Domain):
def _resolve_doc_xref(self, env: "BuildEnvironment", fromdocname: str, def _resolve_doc_xref(self, env: "BuildEnvironment", fromdocname: str,
builder: "Builder", typ: str, target: str, builder: "Builder", typ: str, target: str,
node: pending_xref, contnode: Element) -> Element: node: pending_xref, contnode: Element) -> Optional[Element]:
# directly reference to document by source name; can be absolute or relative # directly reference to document by source name; can be absolute or relative
refdoc = node.get('refdoc', fromdocname) refdoc = node.get('refdoc', fromdocname)
docname = docname_join(refdoc, node['reftarget']) docname = docname_join(refdoc, node['reftarget'])
@ -940,7 +941,7 @@ class StandardDomain(Domain):
def _resolve_option_xref(self, env: "BuildEnvironment", fromdocname: str, def _resolve_option_xref(self, env: "BuildEnvironment", fromdocname: str,
builder: "Builder", typ: str, target: str, builder: "Builder", typ: str, target: str,
node: pending_xref, contnode: Element) -> Element: node: pending_xref, contnode: Element) -> Optional[Element]:
progname = node.get('std:program') progname = node.get('std:program')
target = target.strip() target = target.strip()
docname, labelid = self.progoptions.get((progname, target), ('', '')) docname, labelid = self.progoptions.get((progname, target), ('', ''))
@ -977,7 +978,7 @@ class StandardDomain(Domain):
def _resolve_obj_xref(self, env: "BuildEnvironment", fromdocname: str, def _resolve_obj_xref(self, env: "BuildEnvironment", fromdocname: str,
builder: "Builder", typ: str, target: str, builder: "Builder", typ: str, target: str,
node: pending_xref, contnode: Element) -> Element: node: pending_xref, contnode: Element) -> Optional[Element]:
objtypes = self.objtypes_for_role(typ) or [] objtypes = self.objtypes_for_role(typ) or []
for objtype in objtypes: for objtype in objtypes:
if (objtype, target) in self.objects: if (objtype, target) in self.objects:
@ -1041,7 +1042,7 @@ class StandardDomain(Domain):
def is_enumerable_node(self, node: Node) -> bool: def is_enumerable_node(self, node: Node) -> bool:
return node.__class__ in self.enumerable_nodes return node.__class__ in self.enumerable_nodes
def get_numfig_title(self, node: Node) -> str: def get_numfig_title(self, node: Node) -> Optional[str]:
"""Get the title of enumerable nodes to refer them using its title""" """Get the title of enumerable nodes to refer them using its title"""
if self.is_enumerable_node(node): if self.is_enumerable_node(node):
elem = cast(Element, node) elem = cast(Element, node)
@ -1055,7 +1056,7 @@ class StandardDomain(Domain):
return None return None
def get_enumerable_node_type(self, node: Node) -> str: def get_enumerable_node_type(self, node: Node) -> Optional[str]:
"""Get type of enumerable nodes.""" """Get type of enumerable nodes."""
def has_child(node: Element, cls: Type) -> bool: def has_child(node: Element, cls: Type) -> bool:
return any(isinstance(child, cls) for child in node) return any(isinstance(child, cls) for child in node)
@ -1094,7 +1095,7 @@ class StandardDomain(Domain):
# Maybe it is defined in orphaned document. # Maybe it is defined in orphaned document.
raise ValueError from exc raise ValueError from exc
def get_full_qualified_name(self, node: Element) -> str: def get_full_qualified_name(self, node: Element) -> Optional[str]:
if node.get('reftype') == 'option': if node.get('reftype') == 'option':
progname = node.get('std:program') progname = node.get('std:program')
command = ws_re.split(node.get('reftarget')) command = ws_re.split(node.get('reftarget'))
@ -1109,7 +1110,8 @@ class StandardDomain(Domain):
return None return None
def warn_missing_reference(app: "Sphinx", domain: Domain, node: pending_xref) -> bool: def warn_missing_reference(app: "Sphinx", domain: Domain, node: pending_xref
) -> Optional[bool]:
if (domain and domain.name != 'std') or node['reftype'] != 'ref': if (domain and domain.name != 'std') or node['reftype'] != 'ref':
return None return None
else: else:

View File

@ -10,18 +10,20 @@
import os import os
import pickle import pickle
import warnings
from collections import defaultdict from collections import defaultdict
from copy import copy from copy import copy
from datetime import datetime from datetime import datetime
from os import path from os import path
from typing import (TYPE_CHECKING, Any, Callable, Dict, Generator, Iterator, List, Set, Tuple, from typing import (TYPE_CHECKING, Any, Callable, Dict, Generator, Iterator, List, Optional,
Union) Set, Tuple, Union)
from docutils import nodes from docutils import nodes
from docutils.nodes import Node from docutils.nodes import Node
from sphinx import addnodes from sphinx import addnodes
from sphinx.config import Config from sphinx.config import Config
from sphinx.deprecation import RemovedInSphinx60Warning
from sphinx.domains import Domain from sphinx.domains import Domain
from sphinx.environment.adapters.toctree import TocTree from sphinx.environment.adapters.toctree import TocTree
from sphinx.errors import BuildEnvironmentError, DocumentError, ExtensionError, SphinxError from sphinx.errors import BuildEnvironmentError, DocumentError, ExtensionError, SphinxError
@ -87,7 +89,7 @@ class BuildEnvironment:
transformations to resolve links to them. transformations to resolve links to them.
""" """
domains: Dict[str, Domain] = None domains: Dict[str, Domain]
# --------- ENVIRONMENT INITIALIZATION ------------------------------------- # --------- ENVIRONMENT INITIALIZATION -------------------------------------
@ -181,6 +183,9 @@ class BuildEnvironment:
# set up environment # set up environment
if app: if app:
self.setup(app) self.setup(app)
else:
warnings.warn("The 'app' argument for BuildEnvironment() becomes required now.",
RemovedInSphinx60Warning, stacklevel=2)
def __getstate__(self) -> Dict: def __getstate__(self) -> Dict:
"""Obtains serializable data for pickling.""" """Obtains serializable data for pickling."""
@ -266,7 +271,7 @@ class BuildEnvironment:
raise an exception if the user tries to use an environment with an raise an exception if the user tries to use an environment with an
incompatible versioning method. incompatible versioning method.
""" """
condition: Union[bool, Callable] = None condition: Union[bool, Callable]
if callable(method): if callable(method):
condition = method condition = method
else: else:
@ -309,7 +314,7 @@ class BuildEnvironment:
domain.merge_domaindata(docnames, other.domaindata[domainname]) domain.merge_domaindata(docnames, other.domaindata[domainname])
self.events.emit('env-merge-info', self, docnames, other) self.events.emit('env-merge-info', self, docnames, other)
def path2doc(self, filename: str) -> str: def path2doc(self, filename: str) -> Optional[str]:
"""Return the docname for the filename if the file is document. """Return the docname for the filename if the file is document.
*filename* should be absolute or relative to the source directory. *filename* should be absolute or relative to the source directory.
@ -577,7 +582,7 @@ class BuildEnvironment:
# allow custom references to be resolved # allow custom references to be resolved
self.events.emit('doctree-resolved', doctree, docname) self.events.emit('doctree-resolved', doctree, docname)
def collect_relations(self) -> Dict[str, List[str]]: def collect_relations(self) -> Dict[str, List[Optional[str]]]:
traversed = set() traversed = set()
def traverse_toctree(parent: str, docname: str) -> Iterator[Tuple[str, str]]: def traverse_toctree(parent: str, docname: str) -> Iterator[Tuple[str, str]]:

View File

@ -313,7 +313,7 @@ class TocTree:
return toc return toc
def get_toctree_for(self, docname: str, builder: "Builder", collapse: bool, def get_toctree_for(self, docname: str, builder: "Builder", collapse: bool,
**kwargs: Any) -> Element: **kwargs: Any) -> Optional[Element]:
"""Return the global TOC nodetree.""" """Return the global TOC nodetree."""
doctree = self.env.get_doctree(self.env.config.root_doc) doctree = self.env.get_doctree(self.env.config.root_doc)
toctrees: List[Element] = [] toctrees: List[Element] = []

View File

@ -8,7 +8,7 @@
:license: BSD, see LICENSE for details. :license: BSD, see LICENSE for details.
""" """
from typing import TYPE_CHECKING, Dict, List, Set from typing import TYPE_CHECKING, Dict, List, Optional, Set
from docutils import nodes from docutils import nodes
@ -27,7 +27,7 @@ class EnvironmentCollector:
entries and toctrees, etc. entries and toctrees, etc.
""" """
listener_ids: Dict[str, int] = None listener_ids: Optional[Dict[str, int]] = None
def enable(self, app: "Sphinx") -> None: def enable(self, app: "Sphinx") -> None:
assert self.listener_ids is None assert self.listener_ids is None

View File

@ -47,7 +47,7 @@ class MetadataCollector(EnvironmentCollector):
md[field_name.astext()] = field_body.astext() md[field_name.astext()] = field_body.astext()
elif isinstance(node, nodes.TextElement): elif isinstance(node, nodes.TextElement):
# other children must be TextElement # other children must be TextElement
# see: http://docutils.sourceforge.net/docs/ref/doctree.html#bibliographic-elements # NOQA # see: https://docutils.sourceforge.io/docs/ref/doctree.html#bibliographic-elements # NOQA
md[node.__class__.__name__] = node.astext() md[node.__class__.__name__] = node.astext()
for name, value in md.items(): for name, value in md.items():

View File

@ -70,6 +70,9 @@ class _All:
def __contains__(self, item: Any) -> bool: def __contains__(self, item: Any) -> bool:
return True return True
def append(self, item: Any) -> None:
pass # nothing
class _Empty: class _Empty:
"""A special value for :exclude-members: that never matches to any member.""" """A special value for :exclude-members: that never matches to any member."""
@ -389,8 +392,8 @@ class Documenter:
# functions can contain a signature which is then used instead of # functions can contain a signature which is then used instead of
# an autogenerated one # an autogenerated one
try: try:
explicit_modname, path, base, args, retann = \ matched = py_ext_sig_re.match(self.name)
py_ext_sig_re.match(self.name).groups() explicit_modname, path, base, args, retann = matched.groups()
except AttributeError: except AttributeError:
logger.warning(__('invalid signature for auto%s (%r)') % (self.objtype, self.name), logger.warning(__('invalid signature for auto%s (%r)') % (self.objtype, self.name),
type='autodoc') type='autodoc')
@ -412,8 +415,8 @@ class Documenter:
self.args = args self.args = args
self.retann = retann self.retann = retann
self.fullname = (self.modname or '') + \ self.fullname = ((self.modname or '') +
('.' + '.'.join(self.objpath) if self.objpath else '') ('.' + '.'.join(self.objpath) if self.objpath else ''))
return True return True
def import_object(self, raiseerror: bool = False) -> bool: def import_object(self, raiseerror: bool = False) -> bool:
@ -709,6 +712,8 @@ class Documenter:
# if isattr is True, the member is documented as an attribute # if isattr is True, the member is documented as an attribute
if member is INSTANCEATTR: if member is INSTANCEATTR:
isattr = True isattr = True
elif (namespace, membername) in attr_docs:
isattr = True
else: else:
isattr = False isattr = False
@ -769,7 +774,6 @@ class Documenter:
else: else:
# keep documented attributes # keep documented attributes
keep = True keep = True
isattr = True
elif want_all and isprivate: elif want_all and isprivate:
if has_doc or self.options.undoc_members: if has_doc or self.options.undoc_members:
if self.options.private_members is None: if self.options.private_members is None:
@ -824,8 +828,9 @@ class Documenter:
if self.objpath: if self.objpath:
self.env.temp_data['autodoc:class'] = self.objpath[0] self.env.temp_data['autodoc:class'] = self.objpath[0]
want_all = all_members or self.options.inherited_members or \ want_all = (all_members or
self.options.members is ALL self.options.inherited_members or
self.options.members is ALL)
# find out which members are documentable # find out which members are documentable
members_check_module, members = self.get_object_members(want_all) members_check_module, members = self.get_object_members(want_all)
@ -841,8 +846,7 @@ class Documenter:
classes.sort(key=lambda cls: cls.priority) classes.sort(key=lambda cls: cls.priority)
# give explicitly separated module name, so that members # give explicitly separated module name, so that members
# of inner classes can be documented # of inner classes can be documented
full_mname = self.modname + '::' + \ full_mname = self.modname + '::' + '.'.join(self.objpath + [mname])
'.'.join(self.objpath + [mname])
documenter = classes[-1](self.directive, full_mname, self.indent) documenter = classes[-1](self.directive, full_mname, self.indent)
memberdocumenters.append((documenter, isattr)) memberdocumenters.append((documenter, isattr))
@ -1314,7 +1318,7 @@ class FunctionDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # typ
sigs = [] sigs = []
if (self.analyzer and if (self.analyzer and
'.'.join(self.objpath) in self.analyzer.overloads and '.'.join(self.objpath) in self.analyzer.overloads and
self.config.autodoc_typehints == 'signature'): self.config.autodoc_typehints != 'none'):
# Use signatures for overloaded functions instead of the implementation function. # Use signatures for overloaded functions instead of the implementation function.
overloaded = True overloaded = True
else: else:
@ -1439,6 +1443,15 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
def __init__(self, *args: Any) -> None: def __init__(self, *args: Any) -> None:
super().__init__(*args) super().__init__(*args)
if self.config.autodoc_class_signature == 'separated':
# show __init__() method
if self.options.special_members is None:
self.options['special-members'] = {'__new__', '__init__'}
else:
self.options.special_members.append('__new__')
self.options.special_members.append('__init__')
merge_members_option(self.options) merge_members_option(self.options)
@classmethod @classmethod
@ -1555,12 +1568,15 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
def format_signature(self, **kwargs: Any) -> str: def format_signature(self, **kwargs: Any) -> str:
if self.doc_as_attr: if self.doc_as_attr:
return '' return ''
if self.config.autodoc_class_signature == 'separated':
# do not show signatures
return ''
sig = super().format_signature() sig = super().format_signature()
sigs = [] sigs = []
overloads = self.get_overloaded_signatures() overloads = self.get_overloaded_signatures()
if overloads and self.config.autodoc_typehints == 'signature': if overloads and self.config.autodoc_typehints != 'none':
# Use signatures for overloaded methods instead of the implementation method. # Use signatures for overloaded methods instead of the implementation method.
method = safe_getattr(self._signature_class, self._signature_method_name, None) method = safe_getattr(self._signature_class, self._signature_method_name, None)
__globals__ = safe_getattr(method, '__globals__', {}) __globals__ = safe_getattr(method, '__globals__', {})
@ -1625,18 +1641,23 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
# add inheritance info, if wanted # add inheritance info, if wanted
if not self.doc_as_attr and self.options.show_inheritance: if not self.doc_as_attr and self.options.show_inheritance:
sourcename = self.get_sourcename()
self.add_line('', sourcename)
if hasattr(self.object, '__orig_bases__') and len(self.object.__orig_bases__): if hasattr(self.object, '__orig_bases__') and len(self.object.__orig_bases__):
# A subclass of generic types # A subclass of generic types
# refs: PEP-560 <https://www.python.org/dev/peps/pep-0560/> # refs: PEP-560 <https://www.python.org/dev/peps/pep-0560/>
bases = [restify(cls) for cls in self.object.__orig_bases__] bases = list(self.object.__orig_bases__)
self.add_line(' ' + _('Bases: %s') % ', '.join(bases), sourcename)
elif hasattr(self.object, '__bases__') and len(self.object.__bases__): elif hasattr(self.object, '__bases__') and len(self.object.__bases__):
# A normal class # A normal class
bases = [restify(cls) for cls in self.object.__bases__] bases = list(self.object.__bases__)
self.add_line(' ' + _('Bases: %s') % ', '.join(bases), sourcename) else:
bases = []
self.env.events.emit('autodoc-process-bases',
self.fullname, self.object, self.options, bases)
base_classes = [restify(cls) for cls in bases]
sourcename = self.get_sourcename()
self.add_line('', sourcename)
self.add_line(' ' + _('Bases: %s') % ', '.join(base_classes), sourcename)
def get_object_members(self, want_all: bool) -> Tuple[bool, ObjectMembers]: def get_object_members(self, want_all: bool) -> Tuple[bool, ObjectMembers]:
members = get_class_members(self.object, self.objpath, self.get_attr) members = get_class_members(self.object, self.objpath, self.get_attr)
@ -1660,6 +1681,10 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
def get_doc(self, ignore: int = None) -> Optional[List[List[str]]]: def get_doc(self, ignore: int = None) -> Optional[List[List[str]]]:
if self.doc_as_attr: if self.doc_as_attr:
# Don't show the docstring of the class when it is an alias. # Don't show the docstring of the class when it is an alias.
comment = self.get_variable_comment()
if comment:
return []
else:
return None return None
lines = getattr(self, '_new_docstrings', None) lines = getattr(self, '_new_docstrings', None)
@ -1679,7 +1704,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
__init__ = self.get_attr(self.object, '__init__', None) __init__ = self.get_attr(self.object, '__init__', None)
initdocstring = getdoc(__init__, self.get_attr, initdocstring = getdoc(__init__, self.get_attr,
self.config.autodoc_inherit_docstrings, self.config.autodoc_inherit_docstrings,
self.parent, self.object_name) self.object, '__init__')
# for new-style classes, no __init__ means default __init__ # for new-style classes, no __init__ means default __init__
if (initdocstring is not None and if (initdocstring is not None and
(initdocstring == object.__init__.__doc__ or # for pypy (initdocstring == object.__init__.__doc__ or # for pypy
@ -1690,7 +1715,7 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
__new__ = self.get_attr(self.object, '__new__', None) __new__ = self.get_attr(self.object, '__new__', None)
initdocstring = getdoc(__new__, self.get_attr, initdocstring = getdoc(__new__, self.get_attr,
self.config.autodoc_inherit_docstrings, self.config.autodoc_inherit_docstrings,
self.parent, self.object_name) self.object, '__new__')
# for new-style classes, no __new__ means default __new__ # for new-style classes, no __new__ means default __new__
if (initdocstring is not None and if (initdocstring is not None and
(initdocstring == object.__new__.__doc__ or # for pypy (initdocstring == object.__new__.__doc__ or # for pypy
@ -1705,9 +1730,18 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
tab_width = self.directive.state.document.settings.tab_width tab_width = self.directive.state.document.settings.tab_width
return [prepare_docstring(docstring, ignore, tab_width) for docstring in docstrings] return [prepare_docstring(docstring, ignore, tab_width) for docstring in docstrings]
def get_variable_comment(self) -> Optional[List[str]]:
try:
key = ('', '.'.join(self.objpath))
analyzer = ModuleAnalyzer.for_module(self.get_real_modname())
analyzer.analyze()
return list(self.analyzer.attr_docs.get(key, []))
except PycodeError:
return None
def add_content(self, more_content: Optional[StringList], no_docstring: bool = False def add_content(self, more_content: Optional[StringList], no_docstring: bool = False
) -> None: ) -> None:
if self.doc_as_attr: if self.doc_as_attr and not self.get_variable_comment():
try: try:
more_content = StringList([_('alias of %s') % restify(self.object)], source='') more_content = StringList([_('alias of %s') % restify(self.object)], source='')
except AttributeError: except AttributeError:
@ -1967,8 +2001,8 @@ class DataDocumenter(GenericAliasMixin, NewTypeMixin, TypeVarMixin,
pass pass
def get_real_modname(self) -> str: def get_real_modname(self) -> str:
return self.get_attr(self.parent or self.object, '__module__', None) \ real_modname = self.get_attr(self.parent or self.object, '__module__', None)
or self.modname return real_modname or self.modname
def get_module_comment(self, attrname: str) -> Optional[List[str]]: def get_module_comment(self, attrname: str) -> Optional[List[str]]:
try: try:
@ -2033,8 +2067,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
@classmethod @classmethod
def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any def can_document_member(cls, member: Any, membername: str, isattr: bool, parent: Any
) -> bool: ) -> bool:
return inspect.isroutine(member) and \ return inspect.isroutine(member) and not isinstance(parent, ModuleDocumenter)
not isinstance(parent, ModuleDocumenter)
def import_object(self, raiseerror: bool = False) -> bool: def import_object(self, raiseerror: bool = False) -> bool:
ret = super().import_object(raiseerror) ret = super().import_object(raiseerror)
@ -2109,7 +2142,7 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
sigs = [] sigs = []
if (self.analyzer and if (self.analyzer and
'.'.join(self.objpath) in self.analyzer.overloads and '.'.join(self.objpath) in self.analyzer.overloads and
self.config.autodoc_typehints == 'signature'): self.config.autodoc_typehints != 'none'):
# Use signatures for overloaded methods instead of the implementation method. # Use signatures for overloaded methods instead of the implementation method.
overloaded = True overloaded = True
else: else:
@ -2193,6 +2226,38 @@ class MethodDocumenter(DocstringSignatureMixin, ClassLevelDocumenter): # type:
else: else:
return None return None
def get_doc(self, ignore: int = None) -> Optional[List[List[str]]]:
if self.objpath[-1] == '__init__':
docstring = getdoc(self.object, self.get_attr,
self.config.autodoc_inherit_docstrings,
self.parent, self.object_name)
if (docstring is not None and
(docstring == object.__init__.__doc__ or # for pypy
docstring.strip() == object.__init__.__doc__)): # for !pypy
docstring = None
if docstring:
tab_width = self.directive.state.document.settings.tab_width
return [prepare_docstring(docstring, tabsize=tab_width)]
else:
return []
elif self.objpath[-1] == '__new__':
__new__ = self.get_attr(self.object, '__new__', None)
if __new__:
docstring = getdoc(__new__, self.get_attr,
self.config.autodoc_inherit_docstrings,
self.parent, self.object_name)
if (docstring is not None and
(docstring == object.__new__.__doc__ or # for pypy
docstring.strip() == object.__new__.__doc__)): # for !pypy
docstring = None
if docstring:
tab_width = self.directive.state.document.settings.tab_width
return [prepare_docstring(docstring, tabsize=tab_width)]
else:
return []
else:
return super().get_doc()
class NonDataDescriptorMixin(DataDocumenterMixinBase): class NonDataDescriptorMixin(DataDocumenterMixinBase):
""" """
@ -2291,9 +2356,29 @@ class RuntimeInstanceAttributeMixin(DataDocumenterMixinBase):
# An instance variable defined in __init__(). # An instance variable defined in __init__().
if self.get_attribute_comment(parent, self.objpath[-1]): # type: ignore if self.get_attribute_comment(parent, self.objpath[-1]): # type: ignore
return True return True
elif self.is_runtime_instance_attribute_not_commented(parent):
return True
else: else:
return False return False
def is_runtime_instance_attribute_not_commented(self, parent: Any) -> bool:
"""Check the subject is an attribute defined in __init__() without comment."""
for cls in inspect.getmro(parent):
try:
module = safe_getattr(cls, '__module__')
qualname = safe_getattr(cls, '__qualname__')
analyzer = ModuleAnalyzer.for_module(module)
analyzer.analyze()
if qualname and self.objpath:
key = '.'.join([qualname, self.objpath[-1]])
if key in analyzer.tagorder:
return True
except (AttributeError, PycodeError):
pass
return None
def import_object(self, raiseerror: bool = False) -> bool: def import_object(self, raiseerror: bool = False) -> bool:
"""Check the existence of runtime instance attribute when failed to import the """Check the existence of runtime instance attribute when failed to import the
attribute.""" attribute."""
@ -2324,6 +2409,13 @@ class RuntimeInstanceAttributeMixin(DataDocumenterMixinBase):
return (self.object is self.RUNTIME_INSTANCE_ATTRIBUTE or return (self.object is self.RUNTIME_INSTANCE_ATTRIBUTE or
super().should_suppress_value_header()) super().should_suppress_value_header())
def get_doc(self, ignore: int = None) -> Optional[List[List[str]]]:
if (self.object is self.RUNTIME_INSTANCE_ATTRIBUTE and
self.is_runtime_instance_attribute_not_commented(self.parent)):
return None
else:
return super().get_doc(ignore) # type: ignore
class UninitializedInstanceAttributeMixin(DataDocumenterMixinBase): class UninitializedInstanceAttributeMixin(DataDocumenterMixinBase):
""" """
@ -2469,8 +2561,8 @@ class AttributeDocumenter(GenericAliasMixin, NewTypeMixin, SlotsMixin, # type:
return ret return ret
def get_real_modname(self) -> str: def get_real_modname(self) -> str:
return self.get_attr(self.parent or self.object, '__module__', None) \ real_modname = self.get_attr(self.parent or self.object, '__module__', None)
or self.modname return real_modname or self.modname
def should_suppress_value_header(self) -> bool: def should_suppress_value_header(self) -> bool:
if super().should_suppress_value_header(): if super().should_suppress_value_header():
@ -2571,8 +2663,8 @@ class PropertyDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): #
pass pass
def get_real_modname(self) -> str: def get_real_modname(self) -> str:
return self.get_attr(self.parent or self.object, '__module__', None) \ real_modname = self.get_attr(self.parent or self.object, '__module__', None)
or self.modname return real_modname or self.modname
def add_directive_header(self, sig: str) -> None: def add_directive_header(self, sig: str) -> None:
super().add_directive_header(sig) super().add_directive_header(sig)
@ -2592,7 +2684,7 @@ class PropertyDocumenter(DocstringStripSignatureMixin, ClassLevelDocumenter): #
self.fullname, exc) self.fullname, exc)
return None return None
except ValueError: except ValueError:
raise return None
class NewTypeAttributeDocumenter(AttributeDocumenter): class NewTypeAttributeDocumenter(AttributeDocumenter):
@ -2662,11 +2754,12 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_config_value('autoclass_content', 'class', True, ENUM('both', 'class', 'init')) app.add_config_value('autoclass_content', 'class', True, ENUM('both', 'class', 'init'))
app.add_config_value('autodoc_member_order', 'alphabetical', True, app.add_config_value('autodoc_member_order', 'alphabetical', True,
ENUM('alphabetic', 'alphabetical', 'bysource', 'groupwise')) ENUM('alphabetic', 'alphabetical', 'bysource', 'groupwise'))
app.add_config_value('autodoc_class_signature', 'mixed', True, ENUM('mixed', 'separated'))
app.add_config_value('autodoc_default_options', {}, True) app.add_config_value('autodoc_default_options', {}, True)
app.add_config_value('autodoc_docstring_signature', True, True) app.add_config_value('autodoc_docstring_signature', True, True)
app.add_config_value('autodoc_mock_imports', [], True) app.add_config_value('autodoc_mock_imports', [], True)
app.add_config_value('autodoc_typehints', "signature", True, app.add_config_value('autodoc_typehints', "signature", True,
ENUM("signature", "description", "none")) ENUM("signature", "description", "none", "both"))
app.add_config_value('autodoc_typehints_description_target', 'all', True, app.add_config_value('autodoc_typehints_description_target', 'all', True,
ENUM('all', 'documented')) ENUM('all', 'documented'))
app.add_config_value('autodoc_type_aliases', {}, True) app.add_config_value('autodoc_type_aliases', {}, True)
@ -2676,6 +2769,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.add_event('autodoc-process-docstring') app.add_event('autodoc-process-docstring')
app.add_event('autodoc-process-signature') app.add_event('autodoc-process-signature')
app.add_event('autodoc-skip-member') app.add_event('autodoc-skip-member')
app.add_event('autodoc-process-bases')
app.connect('config-inited', migrate_autodoc_member_order, priority=800) app.connect('config-inited', migrate_autodoc_member_order, priority=800)

View File

@ -40,7 +40,7 @@ def record_typehints(app: Sphinx, objtype: str, name: str, obj: Any,
def merge_typehints(app: Sphinx, domain: str, objtype: str, contentnode: Element) -> None: def merge_typehints(app: Sphinx, domain: str, objtype: str, contentnode: Element) -> None:
if domain != 'py': if domain != 'py':
return return
if app.config.autodoc_typehints != 'description': if app.config.autodoc_typehints not in ('both', 'description'):
return return
try: try:

View File

@ -72,7 +72,8 @@ import sphinx
from sphinx import addnodes from sphinx import addnodes
from sphinx.application import Sphinx from sphinx.application import Sphinx
from sphinx.config import Config from sphinx.config import Config
from sphinx.deprecation import RemovedInSphinx50Warning from sphinx.deprecation import (RemovedInSphinx50Warning, RemovedInSphinx60Warning,
deprecated_alias)
from sphinx.environment import BuildEnvironment from sphinx.environment import BuildEnvironment
from sphinx.environment.adapters.toctree import TocTree from sphinx.environment.adapters.toctree import TocTree
from sphinx.ext.autodoc import INSTANCEATTR, Documenter from sphinx.ext.autodoc import INSTANCEATTR, Documenter
@ -80,7 +81,9 @@ from sphinx.ext.autodoc.directive import DocumenterBridge, Options
from sphinx.ext.autodoc.importer import import_module from sphinx.ext.autodoc.importer import import_module
from sphinx.ext.autodoc.mock import mock from sphinx.ext.autodoc.mock import mock
from sphinx.locale import __ from sphinx.locale import __
from sphinx.project import Project
from sphinx.pycode import ModuleAnalyzer, PycodeError from sphinx.pycode import ModuleAnalyzer, PycodeError
from sphinx.registry import SphinxComponentRegistry
from sphinx.util import logging, rst from sphinx.util import logging, rst
from sphinx.util.docutils import (NullReporter, SphinxDirective, SphinxRole, new_document, from sphinx.util.docutils import (NullReporter, SphinxDirective, SphinxRole, new_document,
switch_source_input) switch_source_input)
@ -163,17 +166,33 @@ def autosummary_table_visit_html(self: HTMLTranslator, node: autosummary_table)
# -- autodoc integration ------------------------------------------------------- # -- autodoc integration -------------------------------------------------------
deprecated_alias('sphinx.ext.autosummary',
{
'_app': None,
},
RemovedInSphinx60Warning,
{
})
# current application object (used in `get_documenter()`).
_app: Sphinx = None class FakeApplication:
def __init__(self):
self.doctreedir = None
self.events = None
self.extensions = {}
self.srcdir = None
self.config = Config()
self.project = Project(None, None)
self.registry = SphinxComponentRegistry()
class FakeDirective(DocumenterBridge): class FakeDirective(DocumenterBridge):
def __init__(self) -> None: def __init__(self) -> None:
settings = Struct(tab_width=8) settings = Struct(tab_width=8)
document = Struct(settings=settings) document = Struct(settings=settings)
env = BuildEnvironment() app = FakeApplication()
env.config = Config() app.config.add('autodoc_class_signature', 'mixed', True, None)
env = BuildEnvironment(app) # type: ignore
state = Struct(document=document) state = Struct(document=document)
super().__init__(env, None, Options(), 0, state) super().__init__(env, None, Options(), 0, state)
@ -775,7 +794,7 @@ def setup(app: Sphinx) -> Dict[str, Any]:
app.connect('builder-inited', process_generate_options) app.connect('builder-inited', process_generate_options)
app.add_config_value('autosummary_context', {}, True) app.add_config_value('autosummary_context', {}, True)
app.add_config_value('autosummary_filename_map', {}, 'html') app.add_config_value('autosummary_filename_map', {}, 'html')
app.add_config_value('autosummary_generate', True, True, [bool]) app.add_config_value('autosummary_generate', True, True, [bool, list])
app.add_config_value('autosummary_generate_overwrite', True, False) app.add_config_value('autosummary_generate_overwrite', True, False)
app.add_config_value('autosummary_mock_imports', app.add_config_value('autosummary_mock_imports',
lambda config: config.autodoc_mock_imports, 'env') lambda config: config.autodoc_mock_imports, 'env')

View File

@ -45,7 +45,6 @@ from sphinx.environment import BuildEnvironment
from sphinx.locale import _, __ from sphinx.locale import _, __
from sphinx.util import logging, requests from sphinx.util import logging, requests
from sphinx.util.inventory import InventoryFile from sphinx.util.inventory import InventoryFile
from sphinx.util.nodes import find_pending_xref_condition
from sphinx.util.typing import Inventory from sphinx.util.typing import Inventory
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -287,16 +286,6 @@ def missing_reference(app: Sphinx, env: BuildEnvironment, node: pending_xref,
# Since Sphinx-2.1, properties are stored as py:method # Since Sphinx-2.1, properties are stored as py:method
objtypes.append('py:method') objtypes.append('py:method')
# determine the contnode by pending_xref_condition
content = find_pending_xref_condition(node, 'resolved')
if content:
# resolved condition found.
contnodes = content.children
contnode = content.children[0] # type: ignore
else:
# not resolved. Use the given contnode
contnodes = [contnode]
to_try = [(inventories.main_inventory, target)] to_try = [(inventories.main_inventory, target)]
if domain: if domain:
full_qualified_name = env.get_domain(domain).get_full_qualified_name(node) full_qualified_name = env.get_domain(domain).get_full_qualified_name(node)
@ -329,7 +318,7 @@ def missing_reference(app: Sphinx, env: BuildEnvironment, node: pending_xref,
newnode = nodes.reference('', '', internal=False, refuri=uri, reftitle=reftitle) newnode = nodes.reference('', '', internal=False, refuri=uri, reftitle=reftitle)
if node.get('refexplicit'): if node.get('refexplicit'):
# use whatever title was given # use whatever title was given
newnode.extend(contnodes) newnode.append(contnode)
elif dispname == '-' or \ elif dispname == '-' or \
(domain == 'std' and node['reftype'] == 'keyword'): (domain == 'std' and node['reftype'] == 'keyword'):
# use whatever title was given, but strip prefix # use whatever title was given, but strip prefix
@ -338,7 +327,7 @@ def missing_reference(app: Sphinx, env: BuildEnvironment, node: pending_xref,
newnode.append(contnode.__class__(title[len(in_set) + 1:], newnode.append(contnode.__class__(title[len(in_set) + 1:],
title[len(in_set) + 1:])) title[len(in_set) + 1:]))
else: else:
newnode.extend(contnodes) newnode.append(contnode)
else: else:
# else use the given display name (used for :ref:) # else use the given display name (used for :ref:)
newnode.append(contnode.__class__(dispname, dispname)) newnode.append(contnode.__class__(dispname, dispname))

View File

@ -150,6 +150,7 @@ def env_merge_info(app: Sphinx, env: BuildEnvironment, docnames: Iterable[str],
if modname not in env._viewcode_modules: # type: ignore if modname not in env._viewcode_modules: # type: ignore
env._viewcode_modules[modname] = entry # type: ignore env._viewcode_modules[modname] = entry # type: ignore
else: else:
if env._viewcode_modules[modname]: # type: ignore
used = env._viewcode_modules[modname][2] # type: ignore used = env._viewcode_modules[modname][2] # type: ignore
for fullname, docname in entry[2].items(): for fullname, docname in entry[2].items():
if fullname not in used: if fullname not in used:

View File

@ -23,7 +23,7 @@ from sphinx.util import logging
from sphinx.util.osutil import mtimes_of_files from sphinx.util.osutil import mtimes_of_files
try: try:
from jinja2.utils import pass_context # type: ignore # jinja2-3.0 or above from jinja2.utils import pass_context
except ImportError: except ImportError:
from jinja2 import contextfunction as pass_context from jinja2 import contextfunction as pass_context

View File

@ -11,12 +11,12 @@ Documentation.addTranslations({
"Changes in Version %(version)s &#8212; %(docstitle)s": "", "Changes in Version %(version)s &#8212; %(docstitle)s": "",
"Collapse sidebar": "", "Collapse sidebar": "",
"Complete Table of Contents": "", "Complete Table of Contents": "",
"Contents": "", "Contents": "\u0627\u0644\u0645\u062d\u062a\u0648\u0649",
"Copyright": "", "Copyright": "\u0627\u0644\u062d\u0642\u0648\u0642",
"Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "", "Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "", "Expand sidebar": "",
"Full index on one page": "", "Full index on one page": "",
"General Index": "", "General Index": "\u0627\u0644\u0641\u0647\u0631\u0633 \u0627\u0644\u0639\u0627\u0645",
"Global Module Index": "", "Global Module Index": "",
"Go": "", "Go": "",
"Hide Search Matches": "", "Hide Search Matches": "",
@ -25,7 +25,7 @@ Documentation.addTranslations({
"Index pages by letter": "", "Index pages by letter": "",
"Indices and tables:": "", "Indices and tables:": "",
"Last updated on %(last_updated)s.": "", "Last updated on %(last_updated)s.": "",
"Library changes": "", "Library changes": "\u062a\u062c\u0647\u064a\u0632 \u0627\u0644\u0628\u062d\u062b",
"Navigation": "", "Navigation": "",
"Next topic": "\u0627\u0644\u0645\u0648\u0636\u0648\u0639 \u0627\u0644\u062a\u0627\u0644\u064a", "Next topic": "\u0627\u0644\u0645\u0648\u0636\u0648\u0639 \u0627\u0644\u062a\u0627\u0644\u064a",
"Other changes": "", "Other changes": "",
@ -35,29 +35,29 @@ Documentation.addTranslations({
"Please activate JavaScript to enable the search\n functionality.": "", "Please activate JavaScript to enable the search\n functionality.": "",
"Preparing search...": "", "Preparing search...": "",
"Previous topic": "\u0627\u0644\u0645\u0648\u0636\u0648\u0639 \u0627\u0644\u0633\u0627\u0628\u0642", "Previous topic": "\u0627\u0644\u0645\u0648\u0636\u0648\u0639 \u0627\u0644\u0633\u0627\u0628\u0642",
"Quick search": "", "Quick search": "\u0627\u0644\u0628\u062d\u062b \u0627\u0644\u0633\u0631\u064a\u0639",
"Search": "", "Search": "\u0628\u062d\u062b",
"Search Page": "", "Search Page": "\u0635\u0641\u062d\u0629 \u0627\u0644\u0628\u062d\u062b",
"Search Results": "", "Search Results": "\u0646\u062a\u0627\u0626\u062c \u0627\u0644\u0628\u062d\u062b",
"Search finished, found %s page(s) matching the search query.": "", "Search finished, found %s page(s) matching the search query.": "",
"Search within %(docstitle)s": "\u0627\u0644\u0628\u062d\u062b \u0636\u0645\u0646 %(docstitle)s", "Search within %(docstitle)s": "\u0627\u0644\u0628\u062d\u062b \u0636\u0645\u0646 %(docstitle)s",
"Searching": "", "Searching": "",
"Searching for multiple words only shows matches that contain\n all words.": "", "Searching for multiple words only shows matches that contain\n all words.": "",
"Show Source": "", "Show Source": "\u0625\u0638\u0647\u0627\u0631 \u0627\u0644\u0645\u0635\u062f\u0631",
"Table of Contents": "", "Table of Contents": "\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u0645\u062d\u062a\u0648\u064a\u0627\u062a",
"This Page": "", "This Page": "\u0647\u0630\u0647 \u0627\u0644\u0635\u0641\u062d\u0629",
"Welcome! This is": "", "Welcome! This is": "\u0623\u0647\u0644\u0627 \u0648\u0633\u0647\u0644\u0627 \u0647\u0630\u0627",
"Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "", "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories.": "",
"all functions, classes, terms": "", "all functions, classes, terms": "",
"can be huge": "", "can be huge": "",
"last updated": "", "last updated": "",
"lists all sections and subsections": "", "lists all sections and subsections": "",
"next chapter": "\u0627\u0644\u0641\u0635\u0644 \u0627\u0644\u062a\u0627\u0644\u064a", "next chapter": "\u0627\u0644\u0641\u0635\u0644 \u0627\u0644\u062a\u0627\u0644\u064a",
"previous chapter": "", "previous chapter": "\u0627\u0644\u0642\u0633\u0645 \u0627\u0644\u0633\u0627\u0628\u0642",
"quick access to all modules": "", "quick access to all modules": "",
"search": "", "search": "\u0628\u062d\u062b",
"search this documentation": "", "search this documentation": "",
"the documentation for": "" "the documentation for": "\u0627\u0644\u062a\u0648\u062b\u064a\u0642 \u0644"
}, },
"plural_expr": "n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5" "plural_expr": "n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5"
}); });

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ Documentation.addTranslations({
"Complete Table of Contents": "", "Complete Table of Contents": "",
"Contents": "", "Contents": "",
"Copyright": "", "Copyright": "",
"Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "", "Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "", "Expand sidebar": "",
"Full index on one page": "", "Full index on one page": "",
"General Index": "", "General Index": "",

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ Documentation.addTranslations({
"Complete Table of Contents": "\u09aa\u09c2\u09b0\u09cd\u09a3\u09be\u0999\u09cd\u0997 \u09b8\u09c2\u099a\u09c0\u09aa\u09a4\u09cd\u09b0", "Complete Table of Contents": "\u09aa\u09c2\u09b0\u09cd\u09a3\u09be\u0999\u09cd\u0997 \u09b8\u09c2\u099a\u09c0\u09aa\u09a4\u09cd\u09b0",
"Contents": "", "Contents": "",
"Copyright": "\u0995\u09aa\u09bf\u09b0\u09be\u0987\u099f", "Copyright": "\u0995\u09aa\u09bf\u09b0\u09be\u0987\u099f",
"Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "<a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s \u09a6\u09bf\u09df\u09c7 \u09a4\u09c8\u09b0\u09c0\u0964", "Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "", "Expand sidebar": "",
"Full index on one page": "\u098f\u0995 \u09aa\u09be\u09a4\u09be\u09df \u09b8\u09ae\u09cd\u09aa\u09c2\u09b0\u09cd\u09a3 \u0987\u09a8\u09a1\u09c7\u0995\u09cd\u09b8", "Full index on one page": "\u098f\u0995 \u09aa\u09be\u09a4\u09be\u09df \u09b8\u09ae\u09cd\u09aa\u09c2\u09b0\u09cd\u09a3 \u0987\u09a8\u09a1\u09c7\u0995\u09cd\u09b8",
"General Index": "\u09b8\u09be\u09a7\u09be\u09b0\u09a3 \u0987\u09a8\u09a1\u09c7\u0995\u09cd\u09b8", "General Index": "\u09b8\u09be\u09a7\u09be\u09b0\u09a3 \u0987\u09a8\u09a1\u09c7\u0995\u09cd\u09b8",

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ Documentation.addTranslations({
"Complete Table of Contents": "Taula de Contingut Completa", "Complete Table of Contents": "Taula de Contingut Completa",
"Contents": "", "Contents": "",
"Copyright": "Copyright", "Copyright": "Copyright",
"Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "Creat amb <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.", "Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "", "Expand sidebar": "",
"Full index on one page": "\u00cdndex complet en una p\u00e0gina", "Full index on one page": "\u00cdndex complet en una p\u00e0gina",
"General Index": "\u00cdndex General", "General Index": "\u00cdndex General",

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ Documentation.addTranslations({
"Complete Table of Contents": "", "Complete Table of Contents": "",
"Contents": "", "Contents": "",
"Copyright": "", "Copyright": "",
"Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "", "Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "", "Expand sidebar": "",
"Full index on one page": "", "Full index on one page": "",
"General Index": "Konojel cholwuj", "General Index": "Konojel cholwuj",

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ Documentation.addTranslations({
"Complete Table of Contents": "Celkov\u00fd obsah", "Complete Table of Contents": "Celkov\u00fd obsah",
"Contents": "Obsah", "Contents": "Obsah",
"Copyright": "Ve\u0161ker\u00e1 pr\u00e1va vyhrazena", "Copyright": "Ve\u0161ker\u00e1 pr\u00e1va vyhrazena",
"Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "Vytvo\u0159eno pomoc\u00ed <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.", "Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "Rozbalit bo\u010dn\u00ed li\u0161tu", "Expand sidebar": "Rozbalit bo\u010dn\u00ed li\u0161tu",
"Full index on one page": "Cel\u00fd rejst\u0159\u00edk na jedn\u00e9 str\u00e1nce", "Full index on one page": "Cel\u00fd rejst\u0159\u00edk na jedn\u00e9 str\u00e1nce",
"General Index": "Obecn\u00fd rejst\u0159\u00edk", "General Index": "Obecn\u00fd rejst\u0159\u00edk",

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ Documentation.addTranslations({
"Complete Table of Contents": "Tabl Cynnwys Llawn", "Complete Table of Contents": "Tabl Cynnwys Llawn",
"Contents": "Cynnwys", "Contents": "Cynnwys",
"Copyright": "Hawlfraint", "Copyright": "Hawlfraint",
"Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "Cr\u8c37wyd gan ddefnyddio <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s", "Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "Ehangu'r bar ochr", "Expand sidebar": "Ehangu'r bar ochr",
"Full index on one page": "Indecs llawn ar un tudalen", "Full index on one page": "Indecs llawn ar un tudalen",
"General Index": "Indecs cyffredinol", "General Index": "Indecs cyffredinol",

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ Documentation.addTranslations({
"Complete Table of Contents": "Fuldst\u00e6ndig indholdsfortegnelse", "Complete Table of Contents": "Fuldst\u00e6ndig indholdsfortegnelse",
"Contents": "Indhold", "Contents": "Indhold",
"Copyright": "Ophavsret", "Copyright": "Ophavsret",
"Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "Bygget med <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.", "Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "Udfold sidebj\u00e6lke", "Expand sidebar": "Udfold sidebj\u00e6lke",
"Full index on one page": "Fuldt indeks p\u00e5 \u00e9n side", "Full index on one page": "Fuldt indeks p\u00e5 \u00e9n side",
"General Index": "Generelt indeks", "General Index": "Generelt indeks",
@ -42,7 +42,7 @@ Documentation.addTranslations({
"Search finished, found %s page(s) matching the search query.": "S\u00f8gning f\u00e6rdig, fandt %s sider der matcher s\u00f8geforesp\u00f8rgslen.", "Search finished, found %s page(s) matching the search query.": "S\u00f8gning f\u00e6rdig, fandt %s sider der matcher s\u00f8geforesp\u00f8rgslen.",
"Search within %(docstitle)s": "S\u00f8g i %(docstitle)s", "Search within %(docstitle)s": "S\u00f8g i %(docstitle)s",
"Searching": "S\u00f8ger", "Searching": "S\u00f8ger",
"Searching for multiple words only shows matches that contain\n all words.": "", "Searching for multiple words only shows matches that contain\n all words.": "Bem\u00e6rk: Hvis du s\u00f8ger efter flere ord, vises kun resultater der indeholder alle ordene.",
"Show Source": "Vis kilde", "Show Source": "Vis kilde",
"Table of Contents": "", "Table of Contents": "",
"This Page": "Denne side", "This Page": "Denne side",

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ Documentation.addTranslations({
"Complete Table of Contents": "Vollst\u00e4ndiges Inhaltsverzeichnis", "Complete Table of Contents": "Vollst\u00e4ndiges Inhaltsverzeichnis",
"Contents": "Inhalt", "Contents": "Inhalt",
"Copyright": "Copyright", "Copyright": "Copyright",
"Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "Mit <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s erstellt.", "Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "Seitenleiste ausklappen", "Expand sidebar": "Seitenleiste ausklappen",
"Full index on one page": "Gesamtes Stichwortverzeichnis auf einer Seite", "Full index on one page": "Gesamtes Stichwortverzeichnis auf einer Seite",
"General Index": "Stichwortverzeichnis", "General Index": "Stichwortverzeichnis",

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ Documentation.addTranslations({
"Complete Table of Contents": "\u03a0\u03bb\u03ae\u03c1\u03b7\u03c2 \u03a0\u03af\u03bd\u03b1\u03ba\u03b1\u03c2 \u03a0\u03b5\u03c1\u03b9\u03b5\u03c7\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd", "Complete Table of Contents": "\u03a0\u03bb\u03ae\u03c1\u03b7\u03c2 \u03a0\u03af\u03bd\u03b1\u03ba\u03b1\u03c2 \u03a0\u03b5\u03c1\u03b9\u03b5\u03c7\u03bf\u03bc\u03ad\u03bd\u03c9\u03bd",
"Contents": "\u03a0\u03b5\u03c1\u03b9\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03b1", "Contents": "\u03a0\u03b5\u03c1\u03b9\u03b5\u03c7\u03cc\u03bc\u03b5\u03bd\u03b1",
"Copyright": "Copyright", "Copyright": "Copyright",
"Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03b8\u03b7\u03ba\u03b5 \u03bc\u03b5 \u03c4\u03bf <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.", "Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1 \u03c0\u03bb\u03b1\u03ca\u03bd\u03ae\u03c2 \u03bc\u03c0\u03ac\u03c1\u03b1\u03c2", "Expand sidebar": "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1 \u03c0\u03bb\u03b1\u03ca\u03bd\u03ae\u03c2 \u03bc\u03c0\u03ac\u03c1\u03b1\u03c2",
"Full index on one page": "\u03a0\u03bb\u03ae\u03c1\u03b5\u03c2 \u03b5\u03c5\u03c1\u03b5\u03c4\u03ae\u03c1\u03b9\u03bf \u03c3\u03b5 \u03bc\u03af\u03b1 \u03c3\u03b5\u03bb\u03af\u03b4\u03b1", "Full index on one page": "\u03a0\u03bb\u03ae\u03c1\u03b5\u03c2 \u03b5\u03c5\u03c1\u03b5\u03c4\u03ae\u03c1\u03b9\u03bf \u03c3\u03b5 \u03bc\u03af\u03b1 \u03c3\u03b5\u03bb\u03af\u03b4\u03b1",
"General Index": "\u039a\u03b5\u03bd\u03c4\u03c1\u03b9\u03ba\u03cc \u0395\u03c5\u03c1\u03b5\u03c4\u03ae\u03c1\u03b9\u03bf\u03bf", "General Index": "\u039a\u03b5\u03bd\u03c4\u03c1\u03b9\u03ba\u03cc \u0395\u03c5\u03c1\u03b5\u03c4\u03ae\u03c1\u03b9\u03bf\u03bf",

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@ Documentation.addTranslations({
"Complete Table of Contents": "", "Complete Table of Contents": "",
"Contents": "", "Contents": "",
"Copyright": "A\u016dtora rajto", "Copyright": "A\u016dtora rajto",
"Created using <a href=\"http://sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "", "Created using <a href=\"https://www.sphinx-doc.org/\">Sphinx</a> %(sphinx_version)s.": "",
"Expand sidebar": "", "Expand sidebar": "",
"Full index on one page": "", "Full index on one page": "",
"General Index": "Indico universala", "General Index": "Indico universala",

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