Merge branch 'master' into feature-text-secnumbers

This commit is contained in:
Takeshi KOMIYA 2018-01-15 00:21:50 +09:00 committed by GitHub
commit b688941b09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
382 changed files with 5516 additions and 3381 deletions

View File

@ -6,19 +6,12 @@ environment:
matrix:
- PYTHON: 27
DOCUTILS: 0.13.1
TEST_IGNORE: --ignore py35
- PYTHON: 27
DOCUTILS: 0.14
TEST_IGNORE: --ignore py35
- PYTHON: 36
DOCUTILS: 0.14
- PYTHON: 36-x64
DOCUTILS: 0.14
install:
- C:\Python%PYTHON%\python.exe -m pip install -U pip setuptools
- C:\Python%PYTHON%\python.exe -m pip install docutils==%DOCUTILS% mock
- C:\Python%PYTHON%\python.exe -m pip install .[test,websupport]
# No automatic build, just run python tests
@ -39,7 +32,7 @@ test_script:
if (-not $test_ignore) { $test_ignore = '' }
$tests = $env:TEST
if (-not $tests) { $tests = '' }
& "C:\Python$($env:PYTHON)\python.exe" run.py $test_ignore.Split(' ') --junitxml .junit.xml $tests.Split(' ')
& "C:\Python$($env:PYTHON)\python.exe" -m pytest $test_ignore.Split(' ') --junitxml .junit.xml $tests.Split(' ')
Pop-Location
if ($LastExitCode -eq 1) { Write-Host "Test Failures Occurred, leaving for test result parsing" }
elseif ($LastExitCode -ne 0) { Write-Host "Other Error Occurred, aborting"; exit $LastExitCode }

View File

@ -6,4 +6,6 @@ jobs:
working_directory: /sphinx
steps:
- checkout
- run: /python3.4/bin/pip install -U pip setuptools
- run: /python3.4/bin/pip install -U .[test,websupport]
- run: make test PYTHON=/python3.4/bin/python

1
.gitignore vendored
View File

@ -13,6 +13,7 @@ TAGS
.tox
.venv
.coverage
htmlcov
.DS_Store
sphinx/pycode/Grammar*pickle
distribute-*

View File

@ -2,46 +2,48 @@ language: python
sudo: false
dist: trusty
cache: pip
python:
- "pypy-5.4.1"
- "3.6"
- "3.5"
- "3.4"
- "2.7"
- "nightly"
env:
global:
- TEST='-v --durations 25'
- PYTHONFAULTHANDLER=x
- PYTHONWARNINGS=all
- SKIP_LATEX_BUILD=1
matrix:
- DOCUTILS=0.13.1
- DOCUTILS=0.14
matrix:
exclude:
- python: "3.4"
env: DOCUTILS=0.13.1
- python: "3.5"
env: DOCUTILS=0.13.1
- python: "3.6"
env: DOCUTILS=0.13.1
- python: nightly
env: DOCUTILS=0.13.1
- python: "pypy-5.4.1"
env: DOCUTILS=0.13.1
include:
- python: 'pypy'
env: TOXENV=pypy
- python: '2.7'
env:
- TOXENV=du13
- PYTEST_ADDOPTS = --cov sphinx --cov-append --cov-config setup.cfg
- python: '3.4'
env: TOXENV=py34
- python: '3.5'
env: TOXENV=py35
- python: '3.6'
env:
- TOXENV=py36
- PYTEST_ADDOPTS = --cov sphinx --cov-append --cov-config setup.cfg
- python: 'nightly'
env: TOXENV=py37
- python: '3.6'
env: TOXENV=docs
- python: '3.6'
env: TOXENV=mypy
- python: '2.7'
env: TOXENV=flake8
addons:
apt:
packages:
- graphviz
- imagemagick
install:
- pip install -U pip setuptools
- pip install docutils==$DOCUTILS
- pip install .[test,websupport]
- pip install flake8
- if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then python3.6 -m pip install mypy typed-ast; fi
- pip install -U tox codecov
script:
- flake8
- if [[ $TRAVIS_PYTHON_VERSION == '3.6' ]]; then make type-check test-async; fi
- if [[ $TRAVIS_PYTHON_VERSION != '3.6' ]]; then make test; fi
- tox -- -v
after_success:
- codecov

View File

@ -18,6 +18,7 @@ Other co-maintainers:
Other contributors, listed alphabetically, are:
* Alastair Houghton -- Apple Help builder
* Alexander Todorov -- inheritance_diagram tests and improvements
* Andi Albrecht -- agogo theme
* Jakob Lykke Andersen -- Rewritten C++ domain
* Henrique Bastos -- SVG support for graphviz extension

108
CHANGES
View File

@ -1,6 +1,11 @@
Release 1.7 (in development)
============================
Dependencies
------------
* Add ``packaging`` package
Incompatible changes
--------------------
@ -11,12 +16,31 @@ Incompatible changes
package when ``--implicit-namespaces`` option given, not subdirectories of
given directory.
* #3929: apidoc: Move sphinx.apidoc to sphinx.ext.apidoc
* #4226: apidoc: Generate new style makefile (make-mode)
* #4274: sphinx-build returns 2 as an exit code on argument error
* #4389: output directory will be created after loading extensions
* autodoc does not generate warnings messages to the generated document even if
:confval:`keep_warnings` is True. They are only emitted to stderr.
* shebang line is removed from generated conf.py
* #2557: autodoc: :confval:`autodoc_mock_imports` only mocks specified modules
with their descendants. It does not mock their ancestors. If you want to
mock them, please specify the name of ancestors implicitly.
* #3620: html theme: move DOCUMENTATION_OPTIONS to independent JavaScript file
(refs: #4295)
Deprecated
----------
* using a string value for :confval:`html_sidebars` is deprecated and only list
values will be accepted at 2.0.
* ``format_annotation()`` and ``formatargspec()`` is deprecated. Please use
``sphinx.util.inspect.Signature`` instead.
* ``sphinx.ext.autodoc.AutodocReporter`` is replaced by ``sphinx.util.docutils.
switch_source_input()`` and now deprecated. It will be removed in Sphinx-2.0.
* ``sphinx.ext.autodoc.add_documenter()`` and ``AutoDirective._register`` is now
deprecated. Please use ``app.add_autodocumenter()`` instead.
* ``AutoDirective._special_attrgetters`` is now deprecated. Please use
``app.add_autodoc_attrgetter()`` instead.
Features added
--------------
@ -24,7 +48,8 @@ Features added
* C++, handle ``decltype(auto)``.
* #2406: C++, add proper parsing of expressions, including linking of identifiers.
* C++, add a ``cpp:expr`` role for inserting inline C++ expressions or types.
* #4094: C++, allow empty template argument lists.
* C++, support explicit member instantiations with shorthand ``template`` prefix.
* C++, make function parameters linkable, like template params.
* #3638: Allow to change a label of reference to equation using
``math_eqref_format``
@ -43,10 +68,29 @@ Features added
* #4168: improve zh search with jieba
* HTML themes can set up default sidebars through ``theme.conf``
* #3160: html: Use ``<kdb>`` to represent ``:kbd:`` role
* #4212: autosummary: catch all exceptions when importing modules
* #4166: Add :confval:`math_numfig` for equation numbering by section (refs:
#3991, #4080). Thanks to Oliver Jahn.
* #4311: Let LaTeX obey :confval:`numfig_secnum_depth` for figures, tables, and
code-blocks
* #947: autodoc now supports ignore-module-all to ignore a module's ``__all__``
* #4332: Let LaTeX obey :confval:`math_numfig` for equation numbering
* #4093: sphinx-build creates empty directories for unknown targets/builders
* Add ``top-classes`` option for the ``sphinx.ext.inheritance_diagram``
extension to limit the scope of inheritance graphs.
* #4183: doctest: ``:pyversion:`` option also follows PEP-440 specification
* #4235: html: Add :confval:`manpages_url` to make manpage roles to hyperlinks
* #3570: autodoc: Do not display 'typing.' module for type hints
* #4354: sphinx-build now emits finish message. Builders can modify it through
``Builder.epilog`` attribute
* #4245: html themes: Add ``language`` to javascript vars list
* #4079: html: Add ``notranslate`` class to each code-blocks, literals and maths
to let Google Translate know they are not translatable
* #4137: doctest: doctest block is always highlighted as python console (pycon)
* #4137: doctest: testcode block is always highlighted as python
* #3998: text: Add new config values :confval:`text_add_secnumbers` and
:confval:`text_secnumber_suffix`
Features removed
----------------
@ -75,19 +119,36 @@ Features removed
* ``sphinx.util.nodes.process_only_nodes()``
* LaTeX environment ``notice``, use ``sphinxadmonition`` instead
* LaTeX ``\sphinxstylethead``, use ``\sphinxstyletheadfamily``
* C++, support of function concepts. Thanks to mickk-on-cpp.
* Not used and previously not documented LaTeX macros ``\shortversion``
and ``\setshortversion``
Bugs fixed
----------
* #3882: Update the order of files for HTMLHelp and QTHelp
* #3962: sphinx-apidoc does not recognize implicit namespace packages correctly
* #4094: C++, allow empty template argument lists.
* C++, also hyperlink types in the name of declarations with qualified names.
* C++, do not add index entries for declarations inside concepts.
* C++, support the template disambiguator for dependent names.
* #4314: For PDF 'howto' documents, numbering of code-blocks differs from the
one of figures and tables
* #4330: PDF 'howto' documents have an incoherent default LaTeX tocdepth counter
setting
* #4198: autosummary emits multiple 'autodoc-process-docstring' event. Thanks
to Joel Nothman.
* #4081: Warnings and errors colored the same when building
* latex: Do not display 'Release' label if :confval:`release` is not set
Testing
--------
* Add support for docutils 0.14
* Add tests for the ``sphinx.ext.inheritance_diagram`` extension.
Release 1.6.6 (in development)
Release 1.6.7 (in development)
==============================
Dependencies
@ -102,15 +163,50 @@ Deprecated
Features added
--------------
Bugs fixed
----------
Testing
--------
Release 1.6.6 (released Jan 08, 2018)
=====================================
Features added
--------------
* #4181: autodoc: Sort dictionary keys when possible
* ``VerbatimHighlightColor`` is a new
:ref:`LaTeX 'sphinxsetup' <latexsphinxsetup>` key (refs: #4285)
* Easier customizability of LaTeX macros involved in rendering of code-blocks
* Show traceback if conf.py raises an exception (refs: #4369)
* Add :confval:`smartquotes` to disable smart quotes through ``conf.py``
(refs: #3967)
* Add :confval:`smartquotes_action` and :confval:`smartquotes_excludes`
(refs: #4142, #4357)
Bugs fixed
----------
* #4334: sphinx-apidoc: Don't generate references to non-existing files in TOC
* #4206: latex: reST label between paragraphs loses paragraph break
Testing
--------
* #4231: html: Apply fixFirefoxAnchorBug only under Firefox
* #4221: napoleon depends on autodoc, but users need to load it manually
* #2298: automodule fails to document a class attribute
* #4099: C++: properly link class reference to class from inside constructor
* #4267: PDF build broken by Unicode U+2116 NUMERO SIGN character
* #4249: PDF output: Pygments error highlighting increases line spacing in
code blocks
* #1238: Support ``:emphasize-lines:`` in PDF output
* #4279: Sphinx crashes with pickling error when run with multiple processes and
remote image
* #1421: Respect the quiet flag in sphinx-quickstart
* #4281: Race conditions when creating output directory
* #4315: For PDF 'howto' documents, ``latex_toplevel_sectioning='part'`` generates
``\chapter`` commands
* #4214: Two todolist directives break sphinx-1.6.5
* Fix links to external option docs with intersphinx (refs: #3769)
* #4091: Private members not documented without :undoc-members:
Release 1.6.5 (released Oct 23, 2017)
=====================================

View File

@ -33,10 +33,10 @@ Bug Reports and Feature Requests
If you have encountered a problem with Sphinx or have an idea for a new
feature, please submit it to the `issue tracker`_ on GitHub or discuss it
on the sphinx-dev mailing list.
on the `sphinx-dev`_ mailing list.
For bug reports, please include the output produced during the build process
and also the log file Sphinx creates after it encounters an un-handled
and also the log file Sphinx creates after it encounters an unhandled
exception. The location of this file should be shown towards the end of the
error message.
@ -45,6 +45,7 @@ issue. If possible, try to create a minimal project that produces the error
and post that instead.
.. _`issue tracker`: https://github.com/sphinx-doc/sphinx/issues
.. _`sphinx-dev`: mailto:sphinx-dev@googlegroups.com
Contributing to Sphinx
@ -58,7 +59,7 @@ of the core developers before it is merged into the main repository.
#. Check for open issues or open a fresh issue to start a discussion around a
feature idea or a bug.
#. If you feel uncomfortable or uncertain about an issue or your changes, feel
free to email sphinx-dev@googlegroups.com.
free to email the *sphinx-dev* mailing list.
#. Fork `the repository`_ on GitHub to start making your changes to the
**master** branch for next major version, or **stable** branch for next
minor version.
@ -98,10 +99,14 @@ These are the basic steps needed to start developing on Sphinx.
For new features or other substantial changes that should wait until the
next major release, use the ``master`` branch.
#. Optional: setup a virtual environment. ::
#. Setup a virtual environment.
virtualenv ~/sphinxenv
. ~/sphinxenv/bin/activate
This is not necessary for unit testing, thanks to ``tox``, but it is
necessary if you wish to run ``sphinx-build`` locally or run unit tests
without the help of ``tox``. ::
virtualenv ~/.venv
. ~/.venv/bin/activate
pip install -e .
#. Create a new working branch. Choose any name you like. ::
@ -112,44 +117,53 @@ These are the basic steps needed to start developing on Sphinx.
For tips on working with the code, see the `Coding Guide`_.
#. Test, test, test. Possible steps:
#. Test, test, test.
* Run the unit tests::
Testing is best done through ``tox``, which provides a number of targets and
allows testing against multiple different Python environments:
pip install .[test,websupport]
make test
* To list all possible targets::
* Again, it's useful to turn on deprecation warnings on so they're shown in
the test output::
tox -av
PYTHONWARNINGS=all make test
* To run unit tests for a specific Python version, such as 3.6::
* Arguments to pytest can be passed via tox, e.g. in order to run a
tox -e py36
* To run unit tests for a specific Python version and turn on deprecation
warnings on so they're shown in the test output::
PYTHONWARNINGS=all tox -e py36
* To run code style and type checks::
tox -e mypy
tox -e flake8
* Arguments to ``pytest`` can be passed via ``tox``, e.g. in order to run a
particular test::
tox -e py27 tests/test_module.py::test_new_feature
tox -e py36 tests/test_module.py::test_new_feature
* Build the documentation and check the output for different builders::
* To build the documentation::
make docs target="clean html latexpdf"
tox -e docs
* Run code style checks and type checks (type checks require mypy)::
* To build the documentation in multiple formats::
make style-check
make type-check
tox -e docs -- -b html,latexpdf
* Run the unit tests under different Python environments using
:program:`tox`::
You can also test by installing dependencies in your local environment. ::
pip install tox
tox -v
pip install .[test]
* Add a new unit test in the ``tests`` directory if you can.
New unit tests should be included in the ``tests`` directory where
necessary:
* For bug fixes, first add a test that fails without your changes and passes
after they are applied.
* Tests that need a sphinx-build run should be integrated in one of the
* Tests that need a ``sphinx-build`` run should be integrated in one of the
existing test modules if possible. New tests that to ``@with_app`` and
then ``build_all`` for a few assertions are not good since *the test suite
should not take more than a minute to run*.
@ -266,7 +280,7 @@ Debugging Tips
code by running the command ``make clean`` or using the
:option:`sphinx-build -E` option.
* Use the :option:`sphinx-build -P` option to run Pdb on exceptions.
* Use the :option:`sphinx-build -P` option to run ``pdb`` on exceptions.
* Use ``node.pformat()`` and ``node.asdom().toxml()`` to generate a printable
representation of the document structure.
@ -303,14 +317,17 @@ There are a couple reasons that code in Sphinx might be deprecated:
no longer needs to support the older version of Python that doesn't include
the library, the library will be deprecated in Sphinx.
As the :ref:`deprecation-policy` describes,
the first release of Sphinx that deprecates a feature (``A.B``) should raise a
``RemovedInSphinxXXWarning`` (where XX is the Sphinx version where the feature
will be removed) when the deprecated feature is invoked. Assuming we have good
test coverage, these warnings are converted to errors when running the test
suite with warnings enabled: ``python -Wall tests/run.py``. Thus, when adding
a ``RemovedInSphinxXXWarning`` you need to eliminate or silence any warnings
generated when running the tests.
As the :ref:`deprecation-policy` describes, the first release of Sphinx that
deprecates a feature (``A.B``) should raise a ``RemovedInSphinxXXWarning``
(where ``XX`` is the Sphinx version where the feature will be removed) when the
deprecated feature is invoked. Assuming we have good test coverage, these
warnings are converted to errors when running the test suite with warnings
enabled::
pytest -Wall
Thus, when adding a ``RemovedInSphinxXXWarning`` you need to eliminate or
silence any warnings generated when running the tests.
.. _deprecation-policy:

View File

@ -34,6 +34,8 @@ Documentation using the alabaster theme
* pytest: https://docs.pytest.org/ (customized)
* python-apt: https://apt.alioth.debian.org/python-apt-doc/
* PyVisfile: https://documen.tician.de/pyvisfile/
* Requests: http://www.python-requests.org/
* searx: https://asciimoo.github.io/searx/
* Tablib: http://docs.python-tablib.org/
* urllib3: https://urllib3.readthedocs.io/ (customized)
* Werkzeug: http://werkzeug.pocoo.org/docs/ (customized)
@ -46,6 +48,7 @@ Documentation using the classic theme
* APSW: https://rogerbinns.github.io/apsw/
* Arb: http://arblib.org/
* Bazaar: http://doc.bazaar.canonical.com/ (customized)
* Beautiful Soup: https://www.crummy.com/software/BeautifulSoup/bs4/doc/
* Blender: https://docs.blender.org/api/current/
* Bugzilla: https://bugzilla.readthedocs.io/
* Buildbot: https://docs.buildbot.net/latest/
@ -79,6 +82,8 @@ Documentation using the classic theme
* Pyevolve: http://pyevolve.sourceforge.net/
* Pygame: https://www.pygame.org/docs/ (customized)
* PyMQI: https://pythonhosted.org/pymqi/
* PyQt4: http://pyqt.sourceforge.net/Docs/PyQt4/ (customized)
* PyQt5: http://pyqt.sourceforge.net/Docs/PyQt5/ (customized)
* Python 2: https://docs.python.org/2/
* Python 3: https://docs.python.org/3/ (customized)
* Python Packaging Authority: https://www.pypa.io/ (customized)
@ -88,7 +93,7 @@ Documentation using the classic theme
* simuPOP: http://simupop.sourceforge.net/manual_release/build/userGuide.html (customized)
* Sprox: http://sprox.org/ (customized)
* SymPy: http://docs.sympy.org/
* TurboGears: https://turbogears.readthedocs.org/ (customized)
* TurboGears: https://turbogears.readthedocs.io/ (customized)
* tvtk: http://docs.enthought.com/mayavi/tvtk/
* Varnish: https://www.varnish-cache.org/docs/ (customized, alabaster for index)
* Waf: https://waf.io/apidocs/
@ -121,18 +126,25 @@ Documentation using the nature theme
* Alembic: http://alembic.zzzcomputing.com/
* Cython: http://docs.cython.org/
* easybuild: https://easybuild.readthedocs.io/
* jsFiddle: http://doc.jsfiddle.net/
* libLAS: https://www.liblas.org/ (customized)
* Lmod: https://lmod.readthedocs.io/
* MapServer: http://mapserver.org/ (customized)
* Pandas: https://pandas.pydata.org/pandas-docs/stable/
* pyglet: https://pyglet.readthedocs.io/ (customized)
* Setuptools: https://setuptools.readthedocs.io/
* Spring Python: https://docs.spring.io/spring-python/1.2.x/sphinx/html/
* StatsModels: http://www.statsmodels.org/ (customized)
* Sylli: http://sylli.sourceforge.net/
Documentation using another builtin theme
-----------------------------------------
* Arcade: http://arcade.academy/ (sphinx_rtd_theme)
* Breathe: https://breathe.readthedocs.io/ (haiku)
* MPipe: https://vmlaker.github.io/mpipe/ (sphinx13)
* NLTK: http://www.nltk.org/ (agogo)
* Programmieren mit PyGTK und Glade (German):
http://www.florian-diesch.de/doc/python-und-glade/online/ (agogo, customized)
* PyPubSub: https://pypubsub.readthedocs.io/ (bizstyle)
@ -150,8 +162,10 @@ Documentation using sphinx_rtd_theme
* ASE: https://wiki.fysik.dtu.dk/ase/
* Autofac: http://docs.autofac.org/
* BigchainDB: https://docs.bigchaindb.com/
* Blocks: https://blocks.readthedocs.io/
* bootstrap-datepicker: https://bootstrap-datepicker.readthedocs.io/
* Certbot: https://letsencrypt.readthedocs.io/
* Chainer: https://docs.chainer.org/ (customized)
* CherryPy: http://docs.cherrypy.org/
* Chainer: https://docs.chainer.org/
* CodeIgniter: https://www.codeigniter.com/user_guide/
@ -178,14 +192,18 @@ Documentation using sphinx_rtd_theme
* Idris: http://docs.idris-lang.org/
* javasphinx: https://bronto-javasphinx.readthedocs.io/
* Julia: https://julia.readthedocs.io/
* Jupyter Notebook: https://jupyter-notebook.readthedocs.io/
* Lasagne: https://lasagne.readthedocs.io/
* Linguistica: https://linguistica-uchicago.github.io/lxa5/
* Linux kernel: https://www.kernel.org/doc/html/latest/index.html
* MathJax: https://docs.mathjax.org/
* MDTraj: http://mdtraj.org/latest/ (customized)
* MICrobial Community Analysis (micca): http://micca.org/docs/latest/
* MicroPython: https://docs.micropython.org/
* Minds: https://www.minds.org/docs/ (customized)
* Mink: http://mink.behat.org/
* Mockery: http://docs.mockery.io/
* mod_wsgi: https://modwsgi.readthedocs.io/
* MoinMoin: https://moin-20.readthedocs.io/
* Mopidy: https://docs.mopidy.com/
* MyHDL: http://docs.myhdl.org/
@ -224,13 +242,16 @@ Documentation using sphinx_rtd_theme
* Sylius: http://docs.sylius.org/
* Tango Controls: https://tango-controls.readthedocs.io/ (customized)
* Topshelf: http://docs.topshelf-project.com/
* Theano: http://www.deeplearning.net/software/theano/
* ThreatConnect: https://docs.threatconnect.com/
* Tuleap: https://tuleap.net/doc/en/
* TYPO3: https://docs.typo3.org/ (customized)
* uWSGI: https://uwsgi-docs.readthedocs.io/
* Wagtail: http://docs.wagtail.io/
* Web Application Attack and Audit Framework (w3af): http://docs.w3af.org/
* Weblate: https://docs.weblate.org/
* x265: https://x265.readthedocs.io/
* ZeroNet: https://zeronet.readthedocs.io/
Documentation using sphinx_bootstrap_theme
------------------------------------------
@ -238,19 +259,21 @@ Documentation using sphinx_bootstrap_theme
* Bootstrap Theme: https://ryan-roemer.github.io/sphinx-bootstrap-theme/
* C/C++ Software Development with Eclipse: http://eclipsebook.in/
* Dataverse: http://guides.dataverse.org/
* e-cidadania: http://e-cidadania.readthedocs.org/
* e-cidadania: https://e-cidadania.readthedocs.io/
* Hangfire: http://docs.hangfire.io/
* Hedge: https://documen.tician.de/hedge/
* ObsPy: https://docs.obspy.org/
* Open Dylan: https://opendylan.org/documentation/
* Pootle: http://docs.translatehouse.org/projects/pootle/
* PyUblas: https://documen.tician.de/pyublas/
* seaborn: https://seaborn.pydata.org/
Documentation using a custom theme or integrated in a website
-------------------------------------------------------------
* Apache Cassandra: https://cassandra.apache.org/doc/
* Astropy: http://docs.astropy.org/
* Bokeh: https://bokeh.pydata.org/
* Boto 3: https://boto3.readthedocs.io/
* CakePHP: https://book.cakephp.org/
* CasperJS: http://docs.casperjs.org/
@ -263,6 +286,7 @@ Documentation using a custom theme or integrated in a website
* Enterprise Toolkit for Acrobat products:
https://www.adobe.com/devnet-docs/acrobatetk/
* Gameduino: http://excamera.com/sphinx/gameduino/
* gensim: https://radimrehurek.com/gensim/
* GeoServer: http://docs.geoserver.org/
* gevent: http://www.gevent.org/
* GHC - Glasgow Haskell Compiler: http://downloads.haskell.org/~ghc/master/users-guide/
@ -307,6 +331,7 @@ Documentation using a custom theme or integrated in a website
* Sulu: http://docs.sulu.io/
* SQLAlchemy: https://docs.sqlalchemy.org/
* tinyTiM: http://tinytim.sourceforge.net/docs/2.0/
* Twisted: http://twistedmatrix.com/documents/current/
* Ubuntu Packaging Guide: http://packaging.ubuntu.com/html/
* WebFaction: https://docs.webfaction.com/
* WTForms: https://wtforms.readthedocs.io/
@ -320,8 +345,10 @@ Homepages and other non-documentation sites
* Benoit Boissinot: https://bboissin.appspot.com/ (classic, customized)
* Computer Networks, Parallelization, and Simulation Laboratory (CNPSLab):
https://lab.miletic.net/ (sphinx_rtd_theme)
* Deep Learning Tutorials: http://www.deeplearning.net/tutorial/ (sphinxdoc)
* Loyola University Chicago COMP 339-439 Distributed Systems course:
http://books.cs.luc.edu/distributedsystems/ (sphinx_bootstrap_theme)
* Pylearn2: http://www.deeplearning.net/software/pylearn2/ (sphinxdoc, customized)
* SciPy Cookbook: https://scipy-cookbook.readthedocs.io/ (sphinx_rtd_theme)
* The Wine Cellar Book: https://www.thewinecellarbook.com/doc/en/ (sphinxdoc)
* Thomas Cokelaer's Python, Sphinx and reStructuredText tutorials:

View File

@ -1,7 +1,7 @@
License for Sphinx
==================
Copyright (c) 2007-2017 by the Sphinx team (see AUTHORS file).
Copyright (c) 2007-2018 by the Sphinx team (see AUTHORS file).
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -69,15 +69,15 @@ reindent:
.PHONY: test
test:
@cd tests; $(PYTHON) run.py --ignore py35 -v $(TEST)
@$(PYTHON) -m pytest -v $(TEST)
.PHONY: test-async
test-async:
@cd tests; $(PYTHON) run.py -v $(TEST)
@echo "This target no longer does anything and will be removed imminently"
.PHONY: covertest
covertest:
@cd tests; $(PYTHON) run.py -v --cov=sphinx --junitxml=.junit.xml $(TEST)
@$(PYTHON) -m pytest -v --cov=sphinx --junitxml=.junit.xml $(TEST)
.PHONY: build
build:

View File

@ -1,45 +1,106 @@
========
Sphinx
========
.. image:: https://img.shields.io/pypi/v/sphinx.svg
:target: https://pypi.python.org/pypi/Sphinx
:alt: Package on PyPi
.. image:: https://readthedocs.org/projects/sphinx/badge/
:target: http://www.sphinx-doc.org/
: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)
=================
README for Sphinx
=================
.. image:: https://ci.appveyor.com/api/projects/status/github/sphinx-doc/sphinx?branch=master&svg=true
:target: https://ci.appveyor.com/project/sphinxdoc/sphinx
:alt: Build Status (AppVeyor)
This is the Sphinx documentation generator, see http://www.sphinx-doc.org/.
.. image:: https://circleci.com/gh/sphinx-doc/sphinx.svg?style=shield
:target: https://circleci.com/gh/sphinx-doc/sphinx
:alt: Build Status (CircleCI)
.. image:: https://codecov.io/gh/sphinx-doc/sphinx/branch/master/graph/badge.svg
:target: https://codecov.io/gh/sphinx-doc/sphinx
:alt: Code Coverage Status (Codecov)
Installing
==========
Sphinx is a tool that makes it easy to create intelligent and beautiful
documentation for Python projects (or other documents consisting of multiple
reStructuredText sources), written by Georg Brandl. It was originally created
for the new Python documentation, and has excellent facilities for Python
project documentation, but C/C++ is supported as well, and more languages are
planned.
Install from PyPI to use stable version::
Sphinx uses reStructuredText as its markup language, and many of its strengths
come from the power and straightforwardness of reStructuredText and its parsing
and translating suite, the Docutils.
Among its features are the following:
* Output formats: HTML (including derivative formats such as HTML Help, Epub
and Qt Help), plain text, manual pages and LaTeX or direct PDF output
using rst2pdf
* Extensive cross-references: semantic markup and automatic links
for functions, classes, glossary terms and similar pieces of information
* Hierarchical structure: easy definition of a document tree, with automatic
links to siblings, parents and children
* Automatic indices: general index as well as a module index
* Code handling: automatic highlighting using the Pygments highlighter
* Flexible HTML output using the Jinja 2 templating engine
* Various extensions are available, e.g. for automatic testing of snippets
and inclusion of appropriately formatted docstrings
* Setuptools integration
For more information, refer to the `the documentation`__.
.. __: http://www.sphinx-doc.org/
Installation
============
Sphinx is published on `PyPI`__ and can be installed from there::
pip install -U sphinx
Install from PyPI to use beta version::
We also publish beta releases::
pip install -U --pre sphinx
Install from newest dev version in stable branch::
If you wish to install `Sphinx` for development purposes, refer to `the
contributors guide`__.
pip install git+https://github.com/sphinx-doc/sphinx@stable
__ https://pypi.python.org/pypi/Sphinx
__ CONTRIBUTING.rst
Install from newest dev version in master branch::
Documentation
=============
pip install git+https://github.com/sphinx-doc/sphinx
Documentation is available from `sphinx-doc.org`__.
Install from cloned source::
__ http://www.sphinx-doc.org/
pip install .
Testing
=======
Install from cloned source as editable::
Continuous testing is provided by `Travis`__ (for unit tests and style checks
on Linux), `AppVeyor`__ (for unit tests on Windows), and `CircleCI`__ (for
large processes like TeX compilation).
pip install -e .
For information on running tests locally, refer to `the contributors guide`__.
__ https://travis-ci.org/sphinx-doc/sphinx
__ https://ci.appveyor.com/project/sphinxdoc/sphinx
__ https://circleci.com/gh/sphinx-doc/sphinx
__ CONTRIBUTING.rst
Contributing
============
Refer to `the contributors guide`__.
__ CONTRIBUTING.rst
Release signatures
==================
@ -48,37 +109,3 @@ Releases are signed with following keys:
* `498D6B9E <https://pgp.mit.edu/pks/lookup?op=vindex&search=0x102C2C17498D6B9E>`_
* `5EBA0E07 <https://pgp.mit.edu/pks/lookup?op=vindex&search=0x1425F8CE5EBA0E07>`_
Reading the docs
================
You can read them online at <http://www.sphinx-doc.org/>.
Or, after installing::
cd doc
make html
Then, direct your browser to ``_build/html/index.html``.
Testing
=======
To run the tests with the interpreter available as ``python``, use::
make test
If you want to use a different interpreter, e.g. ``python3``, use::
PYTHON=python3 make test
Continuous testing runs on travis: https://travis-ci.org/sphinx-doc/sphinx
Contributing
============
See `CONTRIBUTING.rst`__
.. __: CONTRIBUTING.rst

View File

@ -74,9 +74,9 @@
<p>{%trans%}
You can also download PDF/EPUB versions of the Sphinx documentation:
a <a href="http://readthedocs.org/projects/sphinx/downloads/pdf/stable/">PDF version</a> generated from
a <a href="https://media.readthedocs.org/pdf/sphinx/stable/sphinx.pdf">PDF version</a> generated from
the LaTeX Sphinx produces, and
a <a href="http://readthedocs.org/projects/sphinx/downloads/epub/stable/">EPUB version</a>.
a <a href="https://media.readthedocs.org/epub/sphinx/stable/sphinx.epub">EPUB version</a>.
{%endtrans%}
</p>
@ -106,7 +106,7 @@
<h2>{%trans%}Hosting{%endtrans%}</h2>
<p>{%trans%}Need a place to host your Sphinx docs?
<a href="http://readthedocs.org">readthedocs.org</a> hosts a lot of Sphinx docs
<a href="https://readthedocs.org/">readthedocs.org</a> hosts a lot of Sphinx docs
already, and integrates well with projects' source control. It also features a
powerful built-in search that exceeds the possibilities of Sphinx' JavaScript-based
offline search.{%endtrans%}</p>

View File

@ -20,12 +20,14 @@ Index</a>, or install it with:{%endtrans%}</p>
<h3>{%trans%}Questions? Suggestions?{%endtrans%}</h3>
<p>{%trans%}Join the <a href="http://groups.google.com/group/sphinx-users">sphinx-users</a> mailing list on Google Groups:{%endtrans%}</p>
<div class="subscribeformwrapper">
<form action="http://groups.google.com/group/sphinx-users/boxsubscribe"
style="padding-left: 0.5em">
<input type="text" name="email" value="your@email" style="font-size: 90%; width: 120px"
class="subscribeform">
<input type="text" name="email" value="your@email"
onfocus="$(this).val('');" />
<input type="submit" name="sub" value="Subscribe" style="font-size: 90%; width: 70px"/>
<input type="submit" name="sub" value="Subscribe" />
</form>
</div>
<p>{%trans%}or come to the <tt>#sphinx-doc</tt> channel on FreeNode.{%endtrans%}</p>
<p>{%trans%}You can also open an issue at the
<a href="https://github.com/sphinx-doc/sphinx/issues">tracker</a>.{%endtrans%}</p>

View File

@ -4,7 +4,7 @@
Sphinx layout template for the sphinxdoc theme.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
#}
{%- extends "basic/layout.html" %}

View File

@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- sphinx13 theme.
*
* :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
* :copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
* :license: BSD, see LICENSE for details.
*
*/
@ -140,11 +140,37 @@ div.sphinxsidebar .logo img {
vertical-align: middle;
}
div.subscribeformwrapper {
display: block;
overflow: auto;
margin-bottom: 1.2em;
}
div.sphinxsidebar input {
border: 1px solid #aaa;
font-family: 'Open Sans', 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
'Verdana', sans-serif;
font-size: 1em;
}
div.sphinxsidebar .subscribeform {
margin-top: 0;
}
div.sphinxsidebar .subscribeform input {
border: 1px solid #aaa;
font-size: 0.9em;
float: left;
padding: 0.25em 0.5em;
box-sizing: border-box;
}
div.sphinxsidebar .subscribeform input[type="text"] {
width: 60%;
}
div.sphinxsidebar .subscribeform input[type="submit"] {
width: 40%;
border-left: none;
}
div.sphinxsidebar h3 {
@ -281,7 +307,7 @@ tt {
border: 1px solid #ddd;
border-radius: 2px;
color: #333;
padding: 1px;
padding: 1px 0.2em;
}
tt.descname, tt.descclassname, tt.xref {

View File

@ -15,7 +15,7 @@ templates_path = ['_templates']
exclude_patterns = ['_build']
project = 'Sphinx'
copyright = '2007-2017, Georg Brandl and the Sphinx team'
copyright = '2007-2018, Georg Brandl and the Sphinx team'
version = sphinx.__display_version__
release = version
show_authors = True

View File

@ -138,12 +138,10 @@ General configuration
- ``'library/xml.rst'`` -- ignores the ``library/xml.rst`` file (replaces
entry in :confval:`unused_docs`)
- ``'library/xml'`` -- ignores the ``library/xml`` directory (replaces entry
in :confval:`exclude_trees`)
- ``'library/xml'`` -- ignores the ``library/xml`` directory
- ``'library/xml*'`` -- ignores all files and directories starting with
``library/xml``
- ``'**/.svn'`` -- ignores all ``.svn`` directories (replaces entry in
:confval:`exclude_dirnames`)
- ``'**/.svn'`` -- ignores all ``.svn`` directories
:confval:`exclude_patterns` is also consulted when looking for static files
in :confval:`html_static_path` and :confval:`html_extra_path`.
@ -295,6 +293,24 @@ General configuration
.. versionadded:: 1.3
.. confval:: manpages_url
A URL to cross-reference :rst:role:`manpage` directives. If this is
defined to ``https://manpages.debian.org/{path}``, the
:literal:`:manpage:`man(1)`` role will like to
<https://manpages.debian.org/man(1)>. The patterns available are:
* ``page`` - the manual page (``man``)
* ``section`` - the manual section (``1``)
* ``path`` - the original manual page and section specified (``man(1)``)
This also supports manpages specified as ``man.1``.
.. note:: This currently affects only HTML writers but could be
expanded in the future.
.. versionadded:: 1.7
.. confval:: nitpicky
If true, Sphinx will warn about *all* references where the target cannot be
@ -315,8 +331,8 @@ General configuration
.. confval:: numfig
If true, figures, tables and code-blocks are automatically numbered if they
have a caption. At same time, the `numref` role is enabled. For now, it
works only with the HTML builder and LaTeX builder. Default is ``False``.
have a caption. The :rst:role:`numref` role is enabled.
Obeyed so far only by HTML and LaTeX builders. Default is ``False``.
.. note::
@ -339,13 +355,80 @@ General configuration
.. confval:: numfig_secnum_depth
The scope of figure numbers, that is, the numfig feature numbers figures
in which scope. ``0`` means "whole document". ``1`` means "in a section".
Sphinx numbers like x.1, x.2, x.3... ``2`` means "in a subsection". Sphinx
numbers like x.x.1, x.x.2, x.x.3..., and so on. Default is ``1``.
- if set to ``0``, figures, tables and code-blocks are continuously numbered
starting at ``1``.
- if ``1`` (default) numbers will be ``x.1``, ``x.2``, ... with ``x``
the section number (top level sectioning; no ``x.`` if no section).
This naturally applies only if section numbering has been activated via
the ``:numbered:`` option of the :rst:dir:`toctree` directive.
- ``2`` means that numbers will be ``x.y.1``, ``x.y.2``, ... if located in
a sub-section (but still ``x.1``, ``x.2``, ... if located directly under a
section and ``1``, ``2``, ... if not in any top level section.)
- etc...
.. versionadded:: 1.3
.. versionchanged:: 1.7
The LaTeX builder obeys this setting (if :confval:`numfig` is set to
``True``).
.. confval:: smartquotes
If true, the `Docutils Smart Quotes transform`__, originally based on
`SmartyPants`__ (limited to English) and currently applying to many
languages, will be used to convert quotes and dashes to typographically
correct entities. Default: ``True``.
__ http://docutils.sourceforge.net/docs/user/smartquotes.html
__ https://daringfireball.net/projects/smartypants/
.. versionadded:: 1.6.6
It replaces deprecated :confval:`html_use_smartypants`.
It applies by default to all builders except ``man`` and ``text``
(see :confval:`smartquotes_excludes`.)
A `docutils.conf`__ file located in the configuration directory (or a
global :file:`~/.docutils` file) is obeyed unconditionally if it
*deactivates* smart quotes via the corresponding `Docutils option`__. But
if it *activates* them, then :confval:`smartquotes` does prevail.
__ http://docutils.sourceforge.net/docs/user/config.html
__ http://docutils.sourceforge.net/docs/user/config.html#smart-quotes
.. confval:: smartquotes_action
This string, for use with Docutils ``0.14`` or later, customizes the Smart
Quotes transform. See the file :file:`smartquotes.py` at the `Docutils
repository`__ for details. The default ``'qDe'`` educates normal **q**\
uote characters ``"``, ``'``, em- and en-**D**\ ashes ``---``, ``--``, and
**e**\ llipses ``...``.
.. versionadded:: 1.6.6
__ https://sourceforge.net/p/docutils/code/HEAD/tree/trunk/docutils/
.. confval:: smartquotes_excludes
This is a ``dict`` whose default is::
{'languages': ['ja'], 'builders': ['man', 'text']}
Each entry gives a sufficient condition to ignore the
:confval:`smartquotes` setting and deactivate the Smart Quotes transform.
Accepted keys are as above ``'builders'`` or ``'languages'``.
The values are lists.
.. note:: Currently, in case of invocation of :program:`make` with multiple
targets, the first target name is the only one which is tested against
the ``'builders'`` entry and it decides for all. Also, a ``make text``
following ``make html`` needs to be issued in the form ``make text
O="-E"`` to force re-parsing of source files, as the cached ones are
already transformed. On the other hand the issue does not arise with
direct usage of :program:`sphinx-build` as it caches
(in its default usage) the parsed source files in per builder locations.
.. versionadded:: 1.6.6
.. confval:: tls_verify
If true, Sphinx verifies server certifications. Default is ``True``.
@ -777,15 +860,11 @@ that use Sphinx's HTMLWriter class.
.. confval:: html_use_smartypants
If true, `SmartyPants <https://daringfireball.net/projects/smartypants/>`_
will be used to convert quotes and dashes to typographically correct
If true, quotes and dashes are converted to typographically correct
entities. Default: ``True``.
.. deprecated:: 1.6
To disable or customize smart quotes, use the Docutils configuration file
(``docutils.conf``) instead to set there its `smart_quotes option`_.
.. _`smart_quotes option`: http://docutils.sourceforge.net/docs/user/config.html#smart-quotes
To disable smart quotes, use rather :confval:`smartquotes`.
.. confval:: html_add_permalinks
@ -1450,10 +1529,6 @@ the `Dublin Core metadata <http://dublincore.org/>`_.
a chapter, but can be confusing because it mixes entries of different
depth in one list. The default value is ``True``.
.. note::
``epub3`` builder ignores ``epub_tocdup`` option(always ``False``)
.. confval:: epub_tocscope
This setting control the scope of the epub table of contents. The setting
@ -1615,10 +1690,15 @@ These options influence LaTeX output. See further :doc:`latex`.
.. confval:: latex_toplevel_sectioning
This value determines the topmost sectioning unit. It should be chosen from
``part``, ``chapter`` or ``section``. The default is ``None``; the topmost
sectioning unit is switched by documentclass. ``section`` is used if
``'part'``, ``'chapter'`` or ``'section'``. The default is ``None``;
the topmost
sectioning unit is switched by documentclass: ``section`` is used if
documentclass will be ``howto``, otherwise ``chapter`` will be used.
Note that if LaTeX uses ``\part`` command, then the numbering of sectioning
units one level deep gets off-sync with HTML numbering, because LaTeX
numbers continuously ``\chapter`` (or ``\section`` for ``howto``.)
.. versionadded:: 1.4
.. confval:: latex_appendices

View File

@ -138,7 +138,7 @@ own extensions.
.. _cmakedomain: https://bitbucket.org/klorenz/sphinxcontrib-cmakedomain
.. _GNU Make: http://www.gnu.org/software/make/
.. _makedomain: https://bitbucket.org/klorenz/sphinxcontrib-makedomain
.. _inlinesyntaxhighlight: http://sphinxcontrib-inlinesyntaxhighlight.readthedocs.org
.. _inlinesyntaxhighlight: https://sphinxcontrib-inlinesyntaxhighlight.readthedocs.io/
.. _CMake: https://cmake.org
.. _domaintools: https://bitbucket.org/klorenz/sphinxcontrib-domaintools
.. _restbuilder: https://pypi.python.org/pypi/sphinxcontrib-restbuilder

View File

@ -720,13 +720,13 @@ a visibility statement (``public``, ``private`` or ``protected``).
.. rst:directive:: .. cpp:concept:: template-parameter-list name
.. cpp:concept:: template-parameter-list name()
.. warning:: The support for concepts is experimental. It is based on the
Concepts Technical Specification, and the features may change as the TS evolves.
current draft standard and the Concepts Technical Specification.
The features may change as they evolve.
Describe a variable concept or a function concept. Both must have exactly 1
template parameter list. The name may be a nested name. Examples::
Describe a concept. It must have exactly 1 template parameter list. The name may be a
nested name. Example::
.. cpp:concept:: template<typename It> std::Iterator
@ -744,12 +744,7 @@ a visibility statement (``public``, ``private`` or ``protected``).
- :cpp:expr:`*r`, when :cpp:expr:`r` is dereferenceable.
- :cpp:expr:`++r`, with return type :cpp:expr:`It&`, when :cpp:expr:`r` is incrementable.
.. cpp:concept:: template<typename Cont> std::Container()
Holder of elements, to which it can provide access via
:cpp:concept:`Iterator` s.
They will render as follows:
This will render as follows:
.. cpp:concept:: template<typename It> std::Iterator
@ -767,11 +762,6 @@ a visibility statement (``public``, ``private`` or ``protected``).
- :cpp:expr:`*r`, when :cpp:expr:`r` is dereferenceable.
- :cpp:expr:`++r`, with return type :cpp:expr:`It&`, when :cpp:expr:`r` is incrementable.
.. cpp:concept:: template<typename Cont> std::Container()
Holder of elements, to which it can provide access via
:cpp:concept:`Iterator` s.
Options
.......
@ -785,8 +775,9 @@ Some directives support options:
Constrained Templates
~~~~~~~~~~~~~~~~~~~~~
.. warning:: The support for constrained templates is experimental. It is based on the
Concepts Technical Specification, and the features may change as the TS evolves.
.. warning:: The support for concepts is experimental. It is based on the
current draft standard and the Concepts Technical Specification.
The features may change as they evolve.
.. note:: Sphinx does not currently support ``requires`` clauses.

View File

@ -103,8 +103,10 @@ inserting them into the page source under a suitable :rst:dir:`py:module`,
will document all non-private member functions and properties (that is,
those whose name doesn't start with ``_``).
For modules, ``__all__`` will be respected when looking for members; the
order of the members will also be the order in ``__all__``.
For modules, ``__all__`` will be respected when looking for members unless
you give the ``ignore-module-all`` flag option. Without
``ignore-module-all``, the order of the members will also be the order in
``__all__``.
You can also give an explicit list of members; only these will then be
documented::
@ -339,7 +341,7 @@ There are also new config values that you can set:
This value is a list of autodoc directive flags that should be automatically
applied to all autodoc directives. The supported flags are ``'members'``,
``'undoc-members'``, ``'private-members'``, ``'special-members'``,
``'inherited-members'`` and ``'show-inheritance'``.
``'inherited-members'``, ``'show-inheritance'`` and ``'ignore-module-all'``.
If you set one of these flags in this config value, you can use a negated
form, :samp:`'no-{flag}'`, in an autodoc directive, to disable it once.

View File

@ -80,12 +80,24 @@ a comma-separated list of group names.
.. doctest::
:pyversion: > 3.3
The supported operands are ``<``, ``<=``, ``==``, ``>=``, ``>``, and
comparison is performed by `distutils.version.LooseVersion
<https://www.python.org/dev/peps/pep-0386/#distutils>`__.
The following operands are supported:
* ``~=``: Compatible release clause
* ``==``: Version matching clause
* ``!=``: Version exclusion clause
* ``<=``, ``>=``: Inclusive ordered comparison clause
* ``<``, ``>``: Exclusive ordered comparison clause
* ``===``: Arbitrary equality clause.
``pyversion`` option is followed `PEP-440: Version Specifiers
<https://www.python.org/dev/peps/pep-0440/#version-specifiers>`__.
.. versionadded:: 1.6
.. versionchanged:: 1.7
Supported PEP-440 operands and notations
Note that like with standard doctests, you have to use ``<BLANKLINE>`` to
signal a blank line in the expected output. The ``<BLANKLINE>`` is removed
when building presentation output (HTML, LaTeX etc.).

View File

@ -42,6 +42,54 @@ It adds this directive:
.. versionchanged:: 1.5
Added ``caption`` option
It also supports a ``top-classes`` option which requires one or more class
names separated by comma. If specified inheritance traversal will stop at the
specified class names. Given the following Python module::
"""
A
/ \
B C
/ \ / \
E D F
"""
class A(object):
pass
class B(A):
pass
class C(A):
pass
class D(B, C):
pass
class E(B):
pass
class F(C):
pass
If you have specified a module in the inheritance diagram like this::
.. inheritance-diagram:: dummy.test
:top-classes: dummy.test.B, dummy.test.C
any base classes which are ancestors to ``top-classes`` and are also defined
in the same module will be rendered as stand alone nodes. In this example
class A will be rendered as stand alone node in the graph. This is a known
issue due to how this extension works internally.
If you don't want class A (or any other ancestors) to be visible then specify
only the classes you would like to generate the diagram for like this::
.. inheritance-diagram:: dummy.test.D dummy.test.E dummy.test.F
:top-classes: dummy.test.B, dummy.test.C
.. versionchanged:: 1.7
Added ``top-classes`` option to limit the scope of inheritance graphs.
New config values are:

View File

@ -44,6 +44,15 @@ or use Python raw strings (``r"raw"``).
Example: ``'Eq.{number}'`` is rendered as ``Eq.10``
.. confval:: math_numfig
If ``True``, displayed math equations are numbered across pages when
:confval:`numfig` is enabled. The :confval:`numfig_secnum_depth` setting
is respected. The :rst:role:`eq`, not :rst:role:`numref`, role
must be used to reference equation numbers. Default is ``True``.
.. versionadded:: 1.7
:mod:`.mathbase` defines these new markup elements:
.. rst:role:: math
@ -85,7 +94,7 @@ or use Python raw strings (``r"raw"``).
Normally, equations are not numbered. If you want your equation to get a
number, use the ``label`` option. When given, it selects an internal label
for the equation, by which it can be cross-referenced, and causes an equation
number to be issued. See :rst:role:`eqref` for an example. The numbering
number to be issued. See :rst:role:`eq` for an example. The numbering
style depends on the output format.
There is also an option ``nowrap`` that prevents any wrapping of the given
@ -102,8 +111,7 @@ or use Python raw strings (``r"raw"``).
.. rst:role:: eq
Role for cross-referencing equations via their label. This currently works
only within the same document. Example::
Role for cross-referencing equations via their label. Example::
.. math:: e^{i\pi} + 1 = 0
:label: euler

View File

@ -68,8 +68,8 @@ Getting Started
# conf.py
# Add autodoc and napoleon to the extensions list
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']
# Add napoleon to the extensions list
extensions = ['sphinx.ext.napoleon']
2. Use `sphinx-apidoc` to build your API documentation::
@ -246,13 +246,12 @@ Configuration
Listed below are all the settings used by napoleon and their default
values. These settings can be changed in the Sphinx `conf.py` file. Make
sure that both "sphinx.ext.autodoc" and "sphinx.ext.napoleon" are
enabled in `conf.py`::
sure that "sphinx.ext.napoleon" is enabled in `conf.py`::
# conf.py
# Add any Sphinx extension module names here, as strings
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']
extensions = ['sphinx.ext.napoleon']
# Napoleon settings
napoleon_google_docstring = True

View File

@ -6,7 +6,7 @@ repository. It is open for anyone who wants to maintain an extension
publicly; just send a short message asking for write permissions.
There are also several extensions hosted elsewhere. The `Sphinx extension
survey <http://sphinxext-survey.readthedocs.org/en/latest/>`__ contains a
survey <https://sphinxext-survey.readthedocs.io/>`__ contains a
comprehensive list.
If you write an extension that you think others will find useful or you think

View File

@ -15,6 +15,7 @@ Builder API
.. autoattribute:: name
.. autoattribute:: format
.. autoattribute:: epilog
.. autoattribute:: supported_image_types
These methods are predefined and will be called from the application:

View File

@ -117,12 +117,30 @@ Both APIs parse the content into a given node. They are used like this::
node = docutils.nodes.paragraph()
# either
from sphinx.ext.autodoc import AutodocReporter
self.state.memo.reporter = AutodocReporter(self.result, self.state.memo.reporter) # override reporter to avoid errors from "include" directive
nested_parse_with_titles(self.state, self.result, node)
# or
self.state.nested_parse(self.result, 0, node)
.. note::
``sphinx.util.docutils.switch_source_input()`` allows to change a target file
during nested_parse. It is useful to mixed contents. For example, ``sphinx.
ext.autodoc`` uses it to parse docstrings::
from sphinx.util.docutils import switch_source_input
# Switch source_input between parsing content.
# Inside this context, all parsing errors and warnings are reported as
# happened in new source_input (in this case, ``self.result``).
with switch_source_input(self.state, self.result):
node = docutils.nodes.paragraph()
self.state.nested_parse(self.result, 0, node)
.. deprecated:: 1.7
Until Sphinx-1.6, ``sphinx.ext.autodoc.AutodocReporter`` is used for this purpose.
For now, it is replaced by ``switch_source_input()``.
If you don't need the wrapping node, you can use any concrete node type and
return ``node.children`` from the Directive.

View File

@ -58,7 +58,7 @@ Read the Docs
Sphinx. They will host sphinx documentation, along with supporting a number
of other features including version support, PDF generation, and more. The
`Getting Started
<http://read-the-docs.readthedocs.org/en/latest/getting_started.html>`_
<https://read-the-docs.readthedocs.io/en/latest/getting_started.html>`_
guide is a good place to start.
Epydoc

View File

@ -3,7 +3,7 @@ Introduction
This is the documentation for the Sphinx documentation builder. Sphinx is a
tool that translates a set of reStructuredText_ source files into various output
formats, automatically producing cross-references, indices etc. That is, if
formats, automatically producing cross-references, indices, etc. That is, if
you have a directory containing a bunch of reST-formatted documents (and
possibly subdirectories of docs in there as well), Sphinx can generate a
nicely-organized arrangement of HTML files (in some other directory) for easy
@ -17,7 +17,7 @@ docs have a look at `Epydoc <http://epydoc.sourceforge.net/>`_, which also
understands reST.
For a great "introduction" to writing docs in general -- the whys and hows, see
also `Write the docs <http://write-the-docs.readthedocs.org/>`_, written by Eric
also `Write the docs <https://write-the-docs.readthedocs.io/>`_, written by Eric
Holscher.
.. _rinohtype: https://github.com/brechtm/rinohtype
@ -38,7 +38,7 @@ to reStructuredText/Sphinx from other documentation systems.
code to convert Python-doc-style LaTeX markup to Sphinx reST.
* Marcin Wojdyr has written a script to convert Docbook to reST with Sphinx
markup; it is at `Google Code <https://github.com/wojdyr/db2rst>`_.
markup; it is at `GitHub <https://github.com/wojdyr/db2rst>`_.
* Christophe de Vienne wrote a tool to convert from Open/LibreOffice documents
to Sphinx: `odt2sphinx <https://pypi.python.org/pypi/odt2sphinx/>`_.

View File

@ -267,6 +267,16 @@ The available styling options
``VerbatimBorderColor``
default ``{rgb}{0,0,0}``. The frame color, defaults to black.
``VerbatimHighlightColor``
default ``{rgb}{0.878,1,1}``. The color for highlighted lines.
.. versionadded:: 1.6.6
.. note::
Starting with this colour key, and for all others coming next, the actual
names declared to "color" or "xcolor" are prefixed with "sphinx".
``verbatimsep``
default ``\fboxsep``. The separation between code lines and the frame.
@ -288,11 +298,6 @@ The available styling options
default ``{rgb}{0,0,0}`` (black). The colour for the two horizontal rules
used by Sphinx in LaTeX for styling a :dudir:`note` type admonition.
.. note::
The actual colour names declared to "color" or "xcolor" are prefixed with
"sphinx".
``noteborder``, ``hintborder``, ``importantborder``, ``tipborder``
default ``0.5pt``. The width of the two horizontal rules.
@ -441,6 +446,11 @@ Environments
.. versionadded:: 1.5
options ``verbatimwithframe``, ``verbatimwrapslines``,
``verbatimsep``, ``verbatimborder``.
.. versionadded:: 1.6.6
support for ``:emphasize-lines:`` option
.. versionadded:: 1.6.6
easier customizability of the formatting via exposed to user LaTeX macros
such as ``\sphinxVerbatimHighlightLine``.
- the bibliography uses ``sphinxthebibliography`` and the Python Module index
as well as the general index both use ``sphinxtheindex``; these environments
are wrappers of the ``thebibliography`` and respectively ``theindex``

View File

@ -91,7 +91,7 @@ Options
Interpret paths recursively according to PEP-0420.
.. option:: -M
.. option:: -M, --module-first
Put module documentation before submodule documentation.
@ -118,6 +118,14 @@ These options are used when :option:`--full` is specified:
Sets the project release to put in generated files (see :confval:`release`).
Environment
-----------
.. envvar:: SPHINX_APIDOC_OPTIONS
A comma-separated list of option to append to generated ``automodule``
directives. Defaults to ``members,undoc-members,show-inheritance``.
See also
--------

View File

@ -99,11 +99,10 @@ Options
:ref:`builders <builders>`, the following build pipelines are available:
**latexpdf**
Build LaTeX files and run them through :program:`pdflatex`.
**latexpdfja**
Build LaTeX files and run them through :program:`platex/dvipdfmx`.
We recommend using ``latexpdf`` instead.
Build LaTeX files and run them through :program:`pdflatex`, or as per
:confval:`latex_engine` setting.
If :confval:`language` is set to ``'ja'``, will use automatically
the :program:`platex/dvipdfmx` latex to PDF pipeline.
**info**
Build Texinfo files and run them through :program:`makeinfo`.

View File

@ -121,6 +121,8 @@ emphasize particular lines::
.. versionchanged:: 1.3
``lineno-start`` has been added.
.. versionchanged:: 1.6.6
LaTeX supports the ``emphasize-lines`` option.
Includes
^^^^^^^^
@ -188,8 +190,8 @@ Includes
``lines``, the first allowed line having by convention the line number ``1``.
When lines have been selected in any of the ways described above, the
line numbers in ``emphasize-lines`` also refer to the selection, with the
first selected line having number ``1``.
line numbers in ``emphasize-lines`` refer to those selected lines, counted
consecutively starting at ``1``.
When specifying particular parts of a file to display, it can be useful to
display the original line numbers. This can be done using the

View File

@ -63,7 +63,7 @@ Cross-referencing anything
by :rst:role:`doc`, :rst:role:`ref` or :rst:role:`option`.
Custom objects added to the standard domain by extensions (see
:meth:`.add_object_type`) are also searched.
:meth:`Sphinx.add_object_type`) are also searched.
* Then, it looks for objects (targets) in all loaded domains. It is up to
the domains how specific a match must be. For example, in the Python
@ -227,15 +227,15 @@ Cross-referencing figures by figure number
reST labels are used. When you use this role, it will insert a reference to
the figure with link text by its figure number like "Fig. 1.1".
If an explicit link text is given (like usual: ``:numref:`Image of Sphinx (Fig.
%s) <my-figure>```), the link caption will be the title of the reference.
As a special character, `%s` and `{number}` will be replaced to figure
number. `{name}` will be replaced to figure caption.
If no explicit link text is given, the value of :confval:`numfig_format` is
used to default value of link text.
If an explicit link text is given (as usual: ``:numref:`Image of Sphinx (Fig.
%s) <my-figure>```), the link caption will serve as title of the reference.
As placeholders, `%s` and `{number}` get replaced by the figure
number and `{name}` by the figure caption.
If no explicit link text is given, the :confval:`numfig_format` setting is
used as fall-back default.
If :confval:`numfig` is ``False``, figures are not numbered.
so this role inserts not a reference but labels or link text.
If :confval:`numfig` is ``False``, figures are not numbered,
so this role inserts not a reference but the label or the link text.
Cross-referencing other items of interest
-----------------------------------------
@ -355,7 +355,8 @@ in a different style:
.. rst:role:: manpage
A reference to a Unix manual page including the section,
e.g. ``:manpage:`ls(1)```.
e.g. ``:manpage:`ls(1)```. Creates a hyperlink to an external site
rendering the manpage if :confval:`manpages_url` is defined.
.. rst:role:: menuselection

View File

@ -323,6 +323,11 @@ following directive exists:
Sphinx's merged cells interact well with ``p{width}``, ``\X{a}{b}``, ``Y{f}``
and tabulary's columns.
.. note::
:rst:dir:`tabularcolumns` conflicts with ``:widths:`` option of table
directives. If both are specified, ``:widths:`` option will be ignored.
Math
----

View File

@ -1,11 +1,20 @@
[metadata]
license_file = LICENSE
[egg_info]
tag_build = .dev
tag_date = true
[bdist_wheel]
universal = 1
[aliases]
release = egg_info -Db ''
upload = upload --sign --identity=36580288
[build_sphinx]
warning-is-error = 1
[extract_messages]
mapping_file = babel.cfg
output_file = sphinx/locale/sphinx.pot
@ -20,12 +29,6 @@ output_dir = sphinx/locale/
domain = sphinx
directory = sphinx/locale/
[bdist_wheel]
universal = 1
[metadata]
license_file = LICENSE
[flake8]
max-line-length = 95
ignore = E116,E241,E251,E741
@ -41,5 +44,20 @@ incremental = True
check_untyped_defs = True
warn_unused_ignores = True
[build_sphinx]
warning-is-error = 1
[tool:pytest]
filterwarnings =
ignore::DeprecationWarning:docutils.io
[coverage:run]
branch = True
source = sphinx
[coverage:report]
exclude_lines =
# Have to re-enable the standard pragma
pragma: no cover
# Don't complain if tests don't hit defensive assertion code:
raise NotImplementedError
# Don't complain if non-runnable code isn't run:
if __name__ == .__main__.:
ignore_errors = True

View File

@ -8,34 +8,8 @@ from distutils.cmd import Command
import sphinx
long_desc = '''
Sphinx is a tool that makes it easy to create intelligent and beautiful
documentation for Python projects (or other documents consisting of multiple
reStructuredText sources), written by Georg Brandl. It was originally created
for the new Python documentation, and has excellent facilities for Python
project documentation, but C/C++ is supported as well, and more languages are
planned.
Sphinx uses reStructuredText as its markup language, and many of its strengths
come from the power and straightforwardness of reStructuredText and its parsing
and translating suite, the Docutils.
Among its features are the following:
* Output formats: HTML (including derivative formats such as HTML Help, Epub
and Qt Help), plain text, manual pages and LaTeX or direct PDF output
using rst2pdf
* Extensive cross-references: semantic markup and automatic links
for functions, classes, glossary terms and similar pieces of information
* Hierarchical structure: easy definition of a document tree, with automatic
links to siblings, parents and children
* Automatic indices: general index as well as a module index
* Code handling: automatic highlighting using the Pygments highlighter
* Flexible HTML output using the Jinja 2 templating engine
* Various extensions are available, e.g. for automatic testing of snippets
and inclusion of appropriately formatted docstrings
* Setuptools integration
'''
with open('README.rst') as f:
long_desc = f.read()
if sys.version_info < (2, 7) or (3, 0) <= sys.version_info < (3, 4):
print('ERROR: Sphinx requires at least Python 2.7 or 3.4 to run.')
@ -52,6 +26,7 @@ requires = [
'imagesize',
'requests>=2.0.0',
'setuptools',
'packaging',
'sphinxcontrib-websupport',
]
@ -68,13 +43,14 @@ extras_require = {
'whoosh>=2.0',
],
'test': [
'mock',
'pytest',
'pytest-cov',
'html5lib',
'flake8',
],
'test:python_version<"3"': [
'enum34',
'mock',
],
'test:python_version>="3"': [
'mypy',

View File

@ -5,7 +5,7 @@
The Sphinx documentation toolchain.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
The Sphinx documentation toolchain.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import sys

View File

@ -5,7 +5,7 @@
Additional docutils nodes.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
This file has moved to :py:mod:`sphinx.ext.apidoc`.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -7,7 +7,7 @@
Gracefully adapted from the TextPress system by Armin.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
@ -19,7 +19,7 @@ import posixpath
from os import path
from collections import deque
from six import iteritems
from six import iteritems, itervalues
from six.moves import cStringIO
from docutils import nodes
@ -33,14 +33,13 @@ from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.environment import BuildEnvironment
from sphinx.events import EventManager
from sphinx.extension import verify_required_extensions
from sphinx.io import SphinxStandaloneReader
from sphinx.locale import __
from sphinx.registry import SphinxComponentRegistry
from sphinx.util import pycompat # noqa: F401
from sphinx.util import import_object
from sphinx.util import logging
from sphinx.util.tags import Tags
from sphinx.util.osutil import ENOENT
from sphinx.util.osutil import ENOENT, ensuredir
from sphinx.util.console import bold # type: ignore
from sphinx.util.docutils import is_html5_writer_available, directive_helper
from sphinx.util.i18n import find_catalog_source_files
@ -54,7 +53,9 @@ if False:
from sphinx.domains import Domain, Index # NOQA
from sphinx.environment.collectors import EnvironmentCollector # NOQA
from sphinx.extension import Extension # NOQA
from sphinx.roles import XRefRole # NOQA
from sphinx.theming import Theme # NOQA
from sphinx.util.typing import RoleFunction # NOQA
builtin_extensions = (
'sphinx.builders.applehelp',
@ -83,6 +84,7 @@ builtin_extensions = (
'sphinx.directives.code',
'sphinx.directives.other',
'sphinx.directives.patches',
'sphinx.io',
'sphinx.parsers',
'sphinx.roles',
'sphinx.transforms.post_transforms',
@ -119,7 +121,6 @@ class Sphinx(object):
self.env = None # type: BuildEnvironment
self.registry = SphinxComponentRegistry()
self.enumerable_nodes = {} # type: Dict[nodes.Node, Tuple[unicode, Callable]] # NOQA
self.post_transforms = [] # type: List[Transform]
self.html_themes = {} # type: Dict[unicode, unicode]
self.srcdir = srcdir
@ -156,10 +157,6 @@ class Sphinx(object):
# status code for command-line application
self.statuscode = 0
if not path.isdir(outdir):
logger.info('making output directory...')
os.makedirs(outdir)
# read config
self.tags = Tags(tags)
self.config = Config(confdir, CONFIG_FILENAME,
@ -196,6 +193,10 @@ class Sphinx(object):
# preload builder module (before init config values)
self.preload_builder(buildername)
if not path.isdir(outdir):
logger.info('making output directory...')
ensuredir(outdir)
# the config file itself can be an extension
if self.config.setup:
self._setting_up_extension = ['conf.py']
@ -337,6 +338,13 @@ class Sphinx(object):
(status, self._warncount)))
else:
logger.info(bold(__('build %s.') % status))
if self.statuscode == 0 and self.builder.epilog:
logger.info('')
logger.info(self.builder.epilog % {
'outdir': path.relpath(self.outdir),
'project': self.config.project
})
except Exception as err:
# delete the saved env to force a fresh build next time
envfile = path.join(self.doctreedir, ENV_PICKLE_FILENAME)
@ -443,7 +451,6 @@ class Sphinx(object):
def add_builder(self, builder):
# type: (Type[Builder]) -> None
logger.debug('[app] adding builder: %r', builder)
self.registry.add_builder(builder)
def add_config_value(self, name, default, rebuild, types=()):
@ -463,7 +470,6 @@ class Sphinx(object):
def set_translator(self, name, translator_class):
# type: (unicode, Type[nodes.NodeVisitor]) -> None
logger.info(bold(__('Change of translator for the %s builder.') % name))
self.registry.add_translator(name, translator_class)
def add_node(self, node, **kwds):
@ -552,39 +558,30 @@ class Sphinx(object):
def add_domain(self, domain):
# type: (Type[Domain]) -> None
logger.debug('[app] adding domain: %r', domain)
self.registry.add_domain(domain)
def override_domain(self, domain):
# type: (Type[Domain]) -> None
logger.debug('[app] overriding domain: %r', domain)
self.registry.override_domain(domain)
def add_directive_to_domain(self, domain, name, obj,
has_content=None, argument_spec=None, **option_spec):
# type: (unicode, unicode, Any, bool, Any, Any) -> None
logger.debug('[app] adding directive to domain: %r',
(domain, name, obj, has_content, argument_spec, option_spec))
self.registry.add_directive_to_domain(domain, name, obj,
has_content, argument_spec, **option_spec)
def add_role_to_domain(self, domain, name, role):
# type: (unicode, unicode, Any) -> None
logger.debug('[app] adding role to domain: %r', (domain, name, role))
# type: (unicode, unicode, Union[RoleFunction, XRefRole]) -> None
self.registry.add_role_to_domain(domain, name, role)
def add_index_to_domain(self, domain, index):
# type: (unicode, Type[Index]) -> None
logger.debug('[app] adding index to domain: %r', (domain, index))
self.registry.add_index_to_domain(domain, index)
def add_object_type(self, directivename, rolename, indextemplate='',
parse_node=None, ref_nodeclass=None, objname='',
doc_field_types=[]):
# type: (unicode, unicode, unicode, Callable, nodes.Node, unicode, List) -> None
logger.debug('[app] adding object type: %r',
(directivename, rolename, indextemplate, parse_node,
ref_nodeclass, objname, doc_field_types))
self.registry.add_object_type(directivename, rolename, indextemplate, parse_node,
ref_nodeclass, objname, doc_field_types)
@ -601,21 +598,16 @@ class Sphinx(object):
def add_crossref_type(self, directivename, rolename, indextemplate='',
ref_nodeclass=None, objname=''):
# type: (unicode, unicode, unicode, nodes.Node, unicode) -> None
logger.debug('[app] adding crossref type: %r',
(directivename, rolename, indextemplate, ref_nodeclass,
objname))
self.registry.add_crossref_type(directivename, rolename,
indextemplate, ref_nodeclass, objname)
def add_transform(self, transform):
# type: (Type[Transform]) -> None
logger.debug('[app] adding transform: %r', transform)
SphinxStandaloneReader.transforms.append(transform)
self.registry.add_transform(transform)
def add_post_transform(self, transform):
# type: (Type[Transform]) -> None
logger.debug('[app] adding post transform: %r', transform)
self.post_transforms.append(transform)
self.registry.add_post_transform(transform)
def add_javascript(self, filename):
# type: (unicode) -> None
@ -657,15 +649,14 @@ class Sphinx(object):
def add_autodocumenter(self, cls):
# type: (Any) -> None
logger.debug('[app] adding autodocumenter: %r', cls)
from sphinx.ext import autodoc
autodoc.add_documenter(cls)
self.add_directive('auto' + cls.objtype, autodoc.AutoDirective)
from sphinx.ext.autodoc.directive import AutodocDirective
self.registry.add_documenter(cls.objtype, cls)
self.add_directive('auto' + cls.objtype, AutodocDirective)
def add_autodoc_attrgetter(self, type, getter):
# type: (Any, Callable) -> None
logger.debug('[app] adding autodoc attrgetter: %r', (type, getter))
from sphinx.ext import autodoc
autodoc.AutoDirective._special_attrgetters[type] = getter
def add_autodoc_attrgetter(self, typ, getter):
# type: (Type, Callable[[Any, unicode, Any], Any]) -> None
logger.debug('[app] adding autodoc attrgetter: %r', (typ, getter))
self.registry.add_autodoc_attrgetter(typ, getter)
def add_search_language(self, cls):
# type: (Any) -> None
@ -676,7 +667,6 @@ class Sphinx(object):
def add_source_parser(self, suffix, parser):
# type: (unicode, Parser) -> None
logger.debug('[app] adding search source_parser: %r, %r', suffix, parser)
self.registry.add_source_parser(suffix, parser)
def add_env_collector(self, collector):
@ -689,6 +679,34 @@ class Sphinx(object):
logger.debug('[app] adding HTML theme: %r, %r', name, theme_path)
self.html_themes[name] = theme_path
# ---- other methods -------------------------------------------------
def is_parallel_allowed(self, typ):
# type: (unicode) -> bool
"""Check parallel processing is allowed or not.
``typ`` is a type of processing; ``'read'`` or ``'write'``.
"""
if typ == 'read':
attrname = 'parallel_read_safe'
elif typ == 'write':
attrname = 'parallel_write_safe'
else:
raise ValueError('parallel type %s is not supported' % typ)
for ext in itervalues(self.extensions):
allowed = getattr(ext, attrname, None)
if allowed is None:
logger.warning(__("the %s extension does not declare if it is safe "
"for parallel %sing, assuming it isn't - please "
"ask the extension author to check and make it "
"explicit"), ext.name, typ)
logger.warning('doing serial %s', typ)
return False
elif not allowed:
return False
return True
class TemplateBridge(object):
"""

View File

@ -5,11 +5,10 @@
Builder superclass for all builders.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
from os import path
import warnings
@ -18,13 +17,12 @@ try:
except ImportError:
multiprocessing = None
from six import itervalues
from docutils import nodes
from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.environment.adapters.asset import ImageAdapter
from sphinx.util import i18n, path_stabilize, logging, status_iterator
from sphinx.util.osutil import SEP, relative_uri
from sphinx.util.osutil import SEP, ensuredir, relative_uri
from sphinx.util.i18n import find_catalog
from sphinx.util.console import bold # type: ignore
from sphinx.util.parallel import ParallelTasks, SerialTasks, make_chunks, \
@ -56,6 +54,11 @@ class Builder(object):
name = '' # type: unicode
#: The builder's output format, or '' if no document output is produced.
format = '' # type: unicode
#: The message emitted upon successful build completion. This can be a
#: printf-style template string with the following keys: ``outdir``,
#: ``project``
epilog = '' # type: unicode
# default translator class for the builder. This will be overrided by
# ``app.set_translator()``.
default_translator_class = None # type: nodes.NodeVisitor
@ -79,8 +82,7 @@ class Builder(object):
self.confdir = app.confdir
self.outdir = app.outdir
self.doctreedir = app.doctreedir
if not path.isdir(self.doctreedir):
os.makedirs(self.doctreedir)
ensuredir(self.doctreedir)
self.app = app # type: Sphinx
self.env = None # type: BuildEnvironment
@ -373,15 +375,10 @@ class Builder(object):
docnames = set(docnames) & self.env.found_docs
# determine if we can write in parallel
self.parallel_ok = False
if parallel_available and self.app.parallel > 1 and self.allow_parallel:
self.parallel_ok = True
for extension in itervalues(self.app.extensions):
if not extension.parallel_write_safe:
logger.warning('the %s extension is not safe for parallel '
'writing, doing serial write', extension.name)
self.parallel_ok = self.app.is_parallel_allowed('write')
else:
self.parallel_ok = False
break
# create a task executor to use for misc. "finish-up" tasks
# if self.parallel_ok:

View File

@ -5,7 +5,7 @@
Base class of epub2/epub3 builders.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Build Apple help books.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
@ -75,6 +75,10 @@ class AppleHelpBuilder(StandaloneHTMLBuilder):
on the ``hiutil`` command line tool.
"""
name = 'applehelp'
epilog = ('The help book is in %(outdir)s.\n'
'Note that won\'t be able to view it unless you put it in '
'~/Library/Documentation/Help or install it in your application '
'bundle.')
# don't copy the reST source
copysource = False

View File

@ -5,7 +5,7 @@
Changelog builder.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -38,6 +38,7 @@ class ChangesBuilder(Builder):
Write a summary with all versionadded/changed directives.
"""
name = 'changes'
epilog = 'The overview file is in %(outdir)s.'
def init(self):
# type: () -> None

View File

@ -7,7 +7,7 @@
.. _Devhelp: http://live.gnome.org/devhelp
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import absolute_import
@ -43,6 +43,10 @@ class DevhelpBuilder(StandaloneHTMLBuilder):
Builder that also outputs GNOME Devhelp file.
"""
name = 'devhelp'
epilog = ('To view the help file:\n'
'$ mkdir -p $HOME/.local/share/devhelp/%(project)s\n'
'$ ln -s %(outdir)s $HOME/.local/share/devhelp/%(project)s\n'
'$ devhelp')
# don't copy the reST source
copysource = False

View File

@ -21,6 +21,8 @@ if False:
class DummyBuilder(Builder):
name = 'dummy'
epilog = 'The dummy builder generates no files.'
allow_parallel = True
def init(self):

View File

@ -63,6 +63,7 @@ class Epub3Builder(_epub_base.EpubBuilder):
an epub file.
"""
name = 'epub'
epilog = 'The ePub file is in %(outdir)s.'
supported_remote_images = False
template_dir = path.join(package_dir, 'templates', 'epub3')

View File

@ -5,7 +5,7 @@
The MessageCatalogBuilder class.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -214,6 +214,7 @@ class MessageCatalogBuilder(I18nBuilder):
Builds gettext-style message catalogs (.pot files).
"""
name = 'gettext'
epilog = 'The message catalogs are in %(outdir)s.'
def init(self):
# type: () -> None

View File

@ -5,7 +5,7 @@
Several HTML builders.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -153,6 +153,8 @@ class StandaloneHTMLBuilder(Builder):
"""
name = 'html'
format = 'html'
epilog = 'The HTML pages are in %(outdir)s.'
copysource = True
allow_parallel = True
out_suffix = '.html'
@ -274,7 +276,7 @@ class StandaloneHTMLBuilder(Builder):
# type: () -> Iterator[unicode]
cfgdict = dict((confval.name, confval.value) for confval in self.config.filter('html'))
self.config_hash = get_stable_hash(cfgdict)
self.tags_hash = get_stable_hash(sorted(self.tags)) # type: ignore
self.tags_hash = get_stable_hash(sorted(self.tags))
old_config_hash = old_tags_hash = ''
try:
with open(path.join(self.outdir, '.buildinfo')) as fp:
@ -1066,6 +1068,8 @@ class SingleFileHTMLBuilder(StandaloneHTMLBuilder):
HTML page.
"""
name = 'singlehtml'
epilog = 'The HTML page is in %(outdir)s.'
copysource = False
def get_outdated_docs(self): # type: ignore
@ -1328,12 +1332,14 @@ class PickleHTMLBuilder(SerializingHTMLBuilder):
"""
A Builder that dumps the generated HTML into pickle files.
"""
name = 'pickle'
epilog = 'You can now process the pickle files in %(outdir)s.'
implementation = pickle
implementation_dumps_unicode = False
additional_dump_args = (pickle.HIGHEST_PROTOCOL,)
indexer_format = pickle
indexer_dumps_unicode = False
name = 'pickle'
out_suffix = '.fpickle'
globalcontext_filename = 'globalcontext.pickle'
searchindex_filename = 'searchindex.pickle'
@ -1347,11 +1353,13 @@ class JSONHTMLBuilder(SerializingHTMLBuilder):
"""
A builder that dumps the generated HTML into JSON files.
"""
name = 'json'
epilog = 'You can now process the JSON files in %(outdir)s.'
implementation = jsonimpl
implementation_dumps_unicode = True
indexer_format = jsonimpl
indexer_dumps_unicode = True
name = 'json'
out_suffix = '.fjson'
globalcontext_filename = 'globalcontext.json'
searchindex_filename = 'searchindex.json'

View File

@ -6,7 +6,7 @@
Build HTML help support files.
Parts adapted from Python's Doc/tools/prechm.py.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
@ -174,6 +174,8 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
index files. Adapted from the original Doc/tools/prechm.py.
"""
name = 'htmlhelp'
epilog = ('You can now run HTML Help Workshop with the .htp file in '
'%(outdir)s.')
# don't copy the reST source
copysource = False

View File

@ -5,7 +5,7 @@
LaTeX builder.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -49,6 +49,12 @@ class LaTeXBuilder(Builder):
"""
name = 'latex'
format = 'latex'
epilog = 'The LaTeX files are in %(outdir)s.'
if os.name == 'posix':
epilog += ("\nRun 'make' in that directory to run these through "
"(pdf)latex\n"
"(use `make latexpdf' here to do that automatically).")
supported_image_types = ['application/pdf', 'image/png', 'image/jpeg']
supported_remote_images = False
default_translator_class = LaTeXTranslator

View File

@ -5,7 +5,7 @@
The CheckExternalLinksBuilder class.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -90,6 +90,8 @@ class CheckExternalLinksBuilder(Builder):
Checks for broken external links.
"""
name = 'linkcheck'
epilog = ('Look for any errors in the above output or in '
'%(outdir)s/output.txt')
def init(self):
# type: () -> None

View File

@ -5,7 +5,7 @@
Manual pages builder.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -40,6 +40,8 @@ class ManualPageBuilder(Builder):
"""
name = 'man'
format = 'man'
epilog = 'The manual pages are in %(outdir)s.'
default_translator_class = ManualPageTranslator
supported_image_types = [] # type: List[unicode]

View File

@ -5,7 +5,7 @@
Build input files for the Qt collection generator.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -108,6 +108,11 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
Builder that also outputs Qt help project, contents and index files.
"""
name = 'qthelp'
epilog = ('You can now run "qcollectiongenerator" with the .qhcp '
'project file in %(outdir)s, like this:\n'
'$ qcollectiongenerator %(outdir)s/%(project)s.qhcp\n'
'To view the help file:\n'
'$ assistant -collectionFile %(outdir)s/%(project)s.qhc')
# don't copy the reST source
copysource = False
@ -269,7 +274,7 @@ class QtHelpBuilder(StandaloneHTMLBuilder):
link = node['refuri']
title = htmlescape(node.astext()).replace('"', '&quot;')
item = section_template % {'title': title, 'ref': link}
item = u' ' * 4 * indentlevel + item # type: ignore
item = u' ' * 4 * indentlevel + item
parts.append(item.encode('ascii', 'xmlcharrefreplace'))
elif isinstance(node, nodes.bullet_list):
for subnode in node:

View File

@ -5,10 +5,11 @@
Texinfo builder.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import os
from os import path
from docutils import nodes
@ -97,6 +98,12 @@ class TexinfoBuilder(Builder):
"""
name = 'texinfo'
format = 'texinfo'
epilog = 'The Texinfo files are in %(outdir)s.'
if os.name == 'posix':
epilog += ("\nRun 'make' in that directory to run these through "
"makeinfo\n"
"(use 'make info' here to do that automatically).")
supported_image_types = ['image/png', 'image/jpeg',
'image/gif']
default_translator_class = TexinfoTranslator

View File

@ -5,7 +5,7 @@
Plain-text Sphinx builder.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -31,6 +31,8 @@ logger = logging.getLogger(__name__)
class TextBuilder(Builder):
name = 'text'
format = 'text'
epilog = 'The text files are in %(outdir)s.'
out_suffix = '.txt'
allow_parallel = True
default_translator_class = TextTranslator

View File

@ -5,7 +5,7 @@
Builder for the web support package.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Docutils-native XML and pseudo-XML builders.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -35,6 +35,8 @@ class XMLBuilder(Builder):
"""
name = 'xml'
format = 'xml'
epilog = 'The XML files are in %(outdir)s.'
out_suffix = '.xml'
allow_parallel = True
@ -108,6 +110,8 @@ class PseudoXMLBuilder(XMLBuilder):
"""
name = 'pseudoxml'
format = 'pseudoxml'
epilog = 'The pseudo-XML files are in %(outdir)s.'
out_suffix = '.pseudoxml'
_writer_class = PseudoXMLWriter

View File

@ -5,6 +5,6 @@
Modules for command line executables.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Build documentation from a provided source.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Quickly setup documentation source to work with Sphinx.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
@ -16,6 +16,7 @@ import os
import re
import sys
import time
from collections import OrderedDict
from io import open
from os import path
@ -35,7 +36,7 @@ from six.moves.urllib.parse import quote as urlquote
from docutils.utils import column_width
from sphinx import __display_version__, package_dir
from sphinx.util.osutil import make_filename
from sphinx.util.osutil import ensuredir, make_filename
from sphinx.util.console import ( # type: ignore
purple, bold, red, turquoise, nocolor, color_terminal
)
@ -48,7 +49,22 @@ if False:
TERM_ENCODING = getattr(sys.stdin, 'encoding', None)
DEFAULT_VALUE = {
EXTENSIONS = OrderedDict([
('autodoc', 'automatically insert docstrings from modules'),
('doctest', 'automatically test code snippets in doctest blocks'),
('intersphinx', 'link between Sphinx documentation of different projects'),
('todo', 'write "todo" entries that can be shown or hidden on build'),
('coverage', 'checks for documentation coverage'),
('imgmath', 'include math, rendered as PNG or SVG images'),
('mathjax', 'include math, rendered in the browser by MathJax'),
('ifconfig', 'conditional inclusion of content based on config values'),
('viewcode',
'include links to the source code of documented Python objects'),
('githubpages',
'create .nojekyll file to publish the document on GitHub pages'),
])
DEFAULTS = {
'path': '.',
'sep': False,
'dot': '_',
@ -56,26 +72,13 @@ DEFAULT_VALUE = {
'suffix': '.rst',
'master': 'index',
'epub': False,
'ext_autodoc': False,
'ext_doctest': False,
'ext_todo': False,
'makefile': True,
'batchfile': True,
}
EXTENSIONS = ('autodoc', 'doctest', 'intersphinx', 'todo', 'coverage',
'imgmath', 'mathjax', 'ifconfig', 'viewcode', 'githubpages')
PROMPT_PREFIX = '> '
def mkdir_p(dir):
# type: (unicode) -> None
if path.isdir(dir):
return
os.makedirs(dir)
# function to get input from terminal -- overridden by the test suite
def term_input(prompt):
# type: (unicode) -> unicode
@ -159,8 +162,8 @@ def term_decode(text):
return text.decode('latin1')
def do_prompt(d, key, text, default=None, validator=nonempty):
# type: (Dict, unicode, unicode, unicode, Callable[[unicode], Any]) -> None
def do_prompt(text, default=None, validator=nonempty):
# type: (unicode, unicode, Callable[[unicode], Any]) -> Union[unicode, bool]
while True:
if default is not None:
prompt = PROMPT_PREFIX + '%s [%s]: ' % (text, default) # type: unicode
@ -191,7 +194,7 @@ def do_prompt(d, key, text, default=None, validator=nonempty):
print(red('* ' + str(err)))
continue
break
d[key] = x
return x
def convert_python_source(source, rex=re.compile(r"[uU]('.*?')")):
@ -235,7 +238,7 @@ def ask_user(d):
* suffix: source file suffix
* master: master document name
* epub: use epub (bool)
* ext_*: extensions to use (bools)
* extensions: extensions to use (list)
* makefile: make Makefile
* batchfile: make command file
"""
@ -251,7 +254,7 @@ Selected root path: %s''' % d['path']))
else:
print('''
Enter the root path for documentation.''')
do_prompt(d, 'path', 'Root path for the documentation', '.', is_path)
d['path'] = do_prompt('Root path for the documentation', '.', is_path)
while path.isfile(path.join(d['path'], 'conf.py')) or \
path.isfile(path.join(d['path'], 'source', 'conf.py')):
@ -260,7 +263,7 @@ Enter the root path for documentation.''')
'selected root path.'))
print('sphinx-quickstart will not overwrite existing Sphinx projects.')
print()
do_prompt(d, 'path', 'Please enter a new root path (or just Enter '
d['path'] = do_prompt('Please enter a new root path (or just Enter '
'to exit)', '', is_path)
if not d['path']:
sys.exit(1)
@ -270,22 +273,22 @@ Enter the root path for documentation.''')
You have two options for placing the build directory for Sphinx output.
Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.''')
do_prompt(d, 'sep', 'Separate source and build directories (y/n)', 'n',
boolean)
d['sep'] = do_prompt('Separate source and build directories (y/n)',
'n', boolean)
if 'dot' not in d:
print('''
Inside the root directory, two more directories will be created; "_templates"
for custom HTML templates and "_static" for custom stylesheets and other static
files. You can enter another prefix (such as ".") to replace the underscore.''')
do_prompt(d, 'dot', 'Name prefix for templates and static dir', '_', ok)
d['dot'] = do_prompt('Name prefix for templates and static dir', '_', ok)
if 'project' not in d:
print('''
The project name will occur in several places in the built documentation.''')
do_prompt(d, 'project', 'Project name')
d['project'] = do_prompt('Project name')
if 'author' not in d:
do_prompt(d, 'author', 'Author name(s)')
d['author'] = do_prompt('Author name(s)')
if 'version' not in d:
print('''
@ -294,9 +297,9 @@ software. Each version can have multiple releases. For example, for
Python the version is something like 2.5 or 3.0, while the release is
something like 2.5.1 or 3.0a1. If you don't need this dual structure,
just set both to the same value.''')
do_prompt(d, 'version', 'Project version', '', allow_empty)
d['version'] = do_prompt('Project version', '', allow_empty)
if 'release' not in d:
do_prompt(d, 'release', 'Project release', d['version'], allow_empty)
d['release'] = do_prompt('Project release', d['version'], allow_empty)
if 'language' not in d:
print('''
@ -306,7 +309,7 @@ translate text that it generates into that language.
For a list of supported codes, see
http://sphinx-doc.org/config.html#confval-language.''')
do_prompt(d, 'language', 'Project language', 'en')
d['language'] = do_prompt('Project language', 'en')
if d['language'] == 'en':
d['language'] = None
@ -314,7 +317,7 @@ http://sphinx-doc.org/config.html#confval-language.''')
print('''
The file name suffix for source files. Commonly, this is either ".txt"
or ".rst". Only files with this suffix are considered documents.''')
do_prompt(d, 'suffix', 'Source file suffix', '.rst', suffix)
d['suffix'] = do_prompt('Source file suffix', '.rst', suffix)
if 'master' not in d:
print('''
@ -322,7 +325,7 @@ One document is special in that it is considered the top node of the
"contents tree", that is, it is the root of the hierarchical structure
of the documents. Normally, this is "index", but if your "index"
document is a custom template, you can also set this to another filename.''')
do_prompt(d, 'master', 'Name of your master document (without suffix)',
d['master'] = do_prompt('Name of your master document (without suffix)',
'index')
while path.isfile(path.join(d['path'], d['master'] + d['suffix'])) or \
@ -332,64 +335,39 @@ document is a custom template, you can also set this to another filename.''')
'selected root path.' % (d['master'] + d['suffix'])))
print('sphinx-quickstart will not overwrite the existing file.')
print()
do_prompt(d, 'master', 'Please enter a new file name, or rename the '
d['master'] = do_prompt('Please enter a new file name, or rename the '
'existing file and press Enter', d['master'])
if 'epub' not in d:
print('''
Sphinx can also add configuration for epub output:''')
do_prompt(d, 'epub', 'Do you want to use the epub builder (y/n)',
d['epub'] = do_prompt('Do you want to use the epub builder (y/n)',
'n', boolean)
if 'ext_autodoc' not in d:
print('''
Please indicate if you want to use one of the following Sphinx extensions:''')
do_prompt(d, 'ext_autodoc', 'autodoc: automatically insert docstrings '
'from modules (y/n)', 'n', boolean)
if 'ext_doctest' not in d:
do_prompt(d, 'ext_doctest', 'doctest: automatically test code snippets '
'in doctest blocks (y/n)', 'n', boolean)
if 'ext_intersphinx' not in d:
do_prompt(d, 'ext_intersphinx', 'intersphinx: link between Sphinx '
'documentation of different projects (y/n)', 'n', boolean)
if 'ext_todo' not in d:
do_prompt(d, 'ext_todo', 'todo: write "todo" entries '
'that can be shown or hidden on build (y/n)', 'n', boolean)
if 'ext_coverage' not in d:
do_prompt(d, 'ext_coverage', 'coverage: checks for documentation '
'coverage (y/n)', 'n', boolean)
if 'ext_imgmath' not in d:
do_prompt(d, 'ext_imgmath', 'imgmath: include math, rendered '
'as PNG or SVG images (y/n)', 'n', boolean)
if 'ext_mathjax' not in d:
do_prompt(d, 'ext_mathjax', 'mathjax: include math, rendered in the '
'browser by MathJax (y/n)', 'n', boolean)
if d['ext_imgmath'] and d['ext_mathjax']:
print('''Note: imgmath and mathjax cannot be enabled at the same time.
imgmath has been deselected.''')
d['ext_imgmath'] = False
if 'ext_ifconfig' not in d:
do_prompt(d, 'ext_ifconfig', 'ifconfig: conditional inclusion of '
'content based on config values (y/n)', 'n', boolean)
if 'ext_viewcode' not in d:
do_prompt(d, 'ext_viewcode', 'viewcode: include links to the source '
'code of documented Python objects (y/n)', 'n', boolean)
if 'ext_githubpages' not in d:
do_prompt(d, 'ext_githubpages', 'githubpages: create .nojekyll file '
'to publish the document on GitHub pages (y/n)', 'n', boolean)
if 'extensions' not in d:
print('Indicate which of the following Sphinx extensions should be '
'enabled:')
d['extensions'] = []
for name, description in EXTENSIONS.items():
if do_prompt('%s: %s (y/n)' % (name, description), 'n', boolean):
d['extensions'].append('sphinx.ext.%s' % name)
if 'no_makefile' in d:
d['makefile'] = False
elif 'makefile' not in d:
# Handle conflicting options
if set(['sphinx.ext.imgmath', 'sphinx.ext.mathjax']).issubset(
d['extensions']):
print('Note: imgmath and mathjax cannot be enabled at the same '
'time. imgmath has been deselected.')
d['extensions'].remove('sphinx.ext.imgmath')
if 'makefile' not in d:
print('''
A Makefile and a Windows command file can be generated for you so that you
only have to run e.g. `make html' instead of invoking sphinx-build
directly.''')
do_prompt(d, 'makefile', 'Create Makefile? (y/n)', 'y', boolean)
if 'no_batchfile' in d:
d['batchfile'] = False
elif 'batchfile' not in d:
do_prompt(d, 'batchfile', 'Create Windows command file? (y/n)',
d['makefile'] = do_prompt('Create Makefile? (y/n)', 'y', boolean)
if 'batchfile' not in d:
d['batchfile'] = do_prompt('Create Windows command file? (y/n)',
'y', boolean)
print()
@ -400,7 +378,6 @@ def generate(d, overwrite=True, silent=False, templatedir=None):
template = QuickstartRenderer(templatedir=templatedir)
texescape.init()
indent = ' ' * 4
if 'mastertoctree' not in d:
d['mastertoctree'] = ''
@ -414,10 +391,6 @@ def generate(d, overwrite=True, silent=False, templatedir=None):
d['now'] = time.asctime()
d['project_underline'] = column_width(d['project']) * '='
d.setdefault('extensions', [])
for name in EXTENSIONS:
if d.get('ext_' + name):
d['extensions'].append('sphinx.ext.' + name)
d['extensions'] = (',\n' + indent).join(repr(name) for name in d['extensions'])
d['copyright'] = time.strftime('%Y') + ', ' + d['author']
d['author_texescaped'] = text_type(d['author']).\
translate(texescape.tex_escape_map)
@ -433,11 +406,11 @@ def generate(d, overwrite=True, silent=False, templatedir=None):
d[key + '_str'] = d[key].replace('\\', '\\\\').replace("'", "\\'")
if not path.isdir(d['path']):
mkdir_p(d['path'])
ensuredir(d['path'])
srcdir = d['sep'] and path.join(d['path'], 'source') or d['path']
mkdir_p(srcdir)
ensuredir(srcdir)
if d['sep']:
builddir = path.join(d['path'], 'build')
d['exclude_patterns'] = ''
@ -448,17 +421,19 @@ def generate(d, overwrite=True, silent=False, templatedir=None):
'Thumbs.db', '.DS_Store',
])
d['exclude_patterns'] = ', '.join(exclude_patterns)
mkdir_p(builddir)
mkdir_p(path.join(srcdir, d['dot'] + 'templates'))
mkdir_p(path.join(srcdir, d['dot'] + 'static'))
ensuredir(builddir)
ensuredir(path.join(srcdir, d['dot'] + 'templates'))
ensuredir(path.join(srcdir, d['dot'] + 'static'))
def write_file(fpath, content, newline=None):
# type: (unicode, unicode, unicode) -> None
if overwrite or not path.isfile(fpath):
if 'quiet' not in d:
print('Creating file %s.' % fpath)
with open(fpath, 'wt', encoding='utf-8', newline=newline) as f:
f.write(content)
else:
if 'quiet' not in d:
print('File %s already exists, skipping.' % fpath)
conf_path = os.path.join(templatedir, 'conf.py_t') if templatedir else None
@ -587,28 +562,28 @@ Makefile to be used with sphinx-build.
group = parser.add_argument_group('Extension options')
for ext in EXTENSIONS:
group.add_argument('--ext-' + ext, action='store_true',
dest='ext_' + ext, default=False,
group.add_argument('--ext-%s' % ext, action='append_const',
const='sphinx.ext.%s' % ext, dest='extensions',
help='enable %s extension' % ext)
group.add_argument('--extensions', metavar='EXTENSIONS', dest='extensions',
action='append', help='enable extensions')
action='append', help='enable arbitrary extensions')
# TODO(stephenfin): Consider using mutually exclusive groups here
group = parser.add_argument_group('Makefile and Batchfile creation')
group.add_argument('--makefile', action='store_true', default=False,
group.add_argument('--makefile', action='store_true', dest='makefile',
help='create makefile')
group.add_argument('--no-makefile', action='store_true', default=False,
help='not create makefile')
group.add_argument('--batchfile', action='store_true', default=False,
group.add_argument('--no-makefile', action='store_false', dest='makefile',
help='do not create makefile')
group.add_argument('--batchfile', action='store_true', dest='batchfile',
help='create batchfile')
group.add_argument('--no-batchfile', action='store_true', default=False,
help='not create batchfile')
group.add_argument('-M', '--no-use-make-mode', action='store_false',
dest='make_mode', default=False,
help='not use make-mode for Makefile/make.bat')
group.add_argument('--no-batchfile', action='store_false',
dest='batchfile',
help='do not create batchfile')
group.add_argument('-m', '--use-make-mode', action='store_true',
dest='make_mode', default=True,
help='use make-mode for Makefile/make.bat')
group.add_argument('-M', '--no-use-make-mode', action='store_false',
dest='make_mode',
help='do not use make-mode for Makefile/make.bat')
group = parser.add_argument_group('Project templating')
group.add_argument('-t', '--templatedir', metavar='TEMPLATEDIR',
@ -648,14 +623,9 @@ def main(argv=sys.argv[1:]):
# quiet mode with all required params satisfied, use default
d.setdefault('version', '')
d.setdefault('release', d['version'])
d2 = DEFAULT_VALUE.copy()
d2.update(dict(("ext_" + ext, False) for ext in EXTENSIONS))
d2 = DEFAULTS.copy()
d2.update(d)
d = d2
if 'no_makefile' in d:
d['makefile'] = False
if 'no_batchfile' in d:
d['batchfile'] = False
if not valid_dir(d):
print()
@ -676,13 +646,12 @@ def main(argv=sys.argv[1:]):
if isinstance(value, binary_type):
d[key] = term_decode(value)
# parse extensions list
# handle use of CSV-style extension values
d.setdefault('extensions', [])
for ext in d['extensions'][:]:
if ',' in ext:
d['extensions'].remove(ext)
for modname in ext.split(','):
d['extensions'].append(modname)
d['extensions'].extend(ext.split(','))
for variable in d.get('variables', []):
try:

View File

@ -5,7 +5,7 @@
sphinx-build command-line handling.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
@ -182,11 +182,7 @@ def main(argv=sys.argv[1:]): # type: ignore
# type: (List[unicode]) -> int
parser = get_parser()
# parse options
try:
args = parser.parse_args(argv)
except SystemExit as err:
return err.code
# get paths (first and second positional argument)
try:
@ -194,34 +190,28 @@ def main(argv=sys.argv[1:]): # type: ignore
confdir = abspath(args.confdir or srcdir)
if args.noconfig:
confdir = None
if not path.isdir(srcdir):
print('Error: Cannot find source directory `%s\'.' % srcdir,
file=sys.stderr)
return 1
parser.error('cannot find source directory (%s)' % srcdir)
if not args.noconfig and not path.isfile(path.join(confdir, 'conf.py')):
print('Error: Config directory doesn\'t contain a conf.py file.',
file=sys.stderr)
return 1
parser.error("config directory doesn't contain a conf.py file "
"(%s)" % confdir)
outdir = abspath(args.outputdir)
if srcdir == outdir:
print('Error: source directory and destination directory are same.',
file=sys.stderr)
return 1
parser.error('source directory and destination directory are same')
except UnicodeError:
print(
'Error: Multibyte filename not supported on this filesystem '
'encoding (%r).' % fs_encoding, file=sys.stderr)
return 1
parser.error('multibyte filename not supported on this filesystem '
'encoding (%r)' % fs_encoding)
# handle remaining filename arguments
filenames = args.filenames
errored = False
missing_files = []
for filename in filenames:
if not path.isfile(filename):
print('Error: Cannot find file %r.' % filename, file=sys.stderr)
errored = True
if errored:
return 1
missing_files.append(filename)
if missing_files:
parser.error('cannot find files %r' % missing_files)
# likely encoding used for command-line arguments
try:
@ -231,8 +221,7 @@ def main(argv=sys.argv[1:]): # type: ignore
likely_encoding = None
if args.force_all and filenames:
print('Error: Cannot combine -a option and filenames.', file=sys.stderr)
return 1
parser.error('cannot combine -a option and filenames')
if args.color == 'no' or (args.color == 'auto' and not color_terminal()):
nocolor()
@ -245,15 +234,16 @@ def main(argv=sys.argv[1:]): # type: ignore
if args.quiet:
status = None
if args.really_quiet:
status = warning = None
if warning and args.warnfile:
try:
warnfp = open(args.warnfile, 'w')
except Exception as exc:
print('Error: Cannot open warning file %r: %s' %
(args.warnfile, exc), file=sys.stderr)
sys.exit(1)
parser.error('cannot open warning file %r: %s' % (
args.warnfile, exc))
warning = Tee(warning, warnfp) # type: ignore
error = warning
@ -262,9 +252,7 @@ def main(argv=sys.argv[1:]): # type: ignore
try:
key, val = val.split('=', 1)
except ValueError:
print('Error: -D option argument must be in the form name=value.',
file=sys.stderr)
return 1
parser.error('-D option argument must be in the form name=value')
if likely_encoding and isinstance(val, binary_type):
try:
val = val.decode(likely_encoding)
@ -276,9 +264,7 @@ def main(argv=sys.argv[1:]): # type: ignore
try:
key, val = val.split('=')
except ValueError:
print('Error: -A option argument must be in the form name=value.',
file=sys.stderr)
return 1
parser.error('-A option argument must be in the form name=value')
try:
val = int(val)
except ValueError:
@ -302,4 +288,4 @@ def main(argv=sys.argv[1:]): # type: ignore
return app.statuscode
except (Exception, KeyboardInterrupt) as exc:
handle_exception(app, args, exc, error)
return 1
return 2

View File

@ -5,11 +5,12 @@
Build configuration file handling.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
import traceback
from os import path, getenv
from six import PY2, PY3, iteritems, string_types, binary_type, text_type, integer_types
@ -35,6 +36,7 @@ copyright_year_re = re.compile(r'^((\d{4}-)?)(\d{4})(?=[ ,])')
CONFIG_SYNTAX_ERROR = "There is a syntax error in your configuration file: %s"
if PY3:
CONFIG_SYNTAX_ERROR += "\nDid you change the syntax from 2.x to 3.x?"
CONFIG_ERROR = "There is a programable error in your configuration file:\n\n%s"
CONFIG_EXIT_ERROR = "The configuration file (or one of the modules it imports) " \
"called sys.exit()"
CONFIG_ENUM_WARNING = "The config value `{name}` has to be a one of {candidates}, " \
@ -123,6 +125,7 @@ class Config(object):
primary_domain = ('py', 'env', [NoneType]),
needs_sphinx = (None, None, string_classes),
needs_extensions = ({}, None),
manpages_url = (None, 'env'),
nitpicky = (False, None),
nitpick_ignore = ([], None),
numfig = (False, 'env'),
@ -135,6 +138,11 @@ class Config(object):
tls_verify = (True, 'env'),
tls_cacerts = (None, 'env'),
smartquotes = (True, 'env'),
smartquotes_action = ('qDe', 'env'),
smartquotes_excludes = ({'languages': ['ja'],
'builders': ['man', 'text']},
'env'),
) # type: Dict[unicode, Tuple]
def __init__(self, dirname, filename, overrides, tags):
@ -155,6 +163,8 @@ class Config(object):
raise ConfigError(CONFIG_SYNTAX_ERROR % err)
except SystemExit:
raise ConfigError(CONFIG_EXIT_ERROR)
except Exception:
raise ConfigError(CONFIG_ERROR % traceback.format_exc())
self._raw_config = config
# these two must be preinitialized because extensions can add their
@ -291,7 +301,7 @@ class Config(object):
logger.warning("%s", exc)
for name in config:
if name in self.values:
self.__dict__[name] = config[name]
self.__dict__[name] = config[name] # type: ignore
if isinstance(self.source_suffix, string_types): # type: ignore
self.source_suffix = [self.source_suffix] # type: ignore

View File

@ -5,7 +5,7 @@
Sphinx deprecation classes and utilities.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Handlers for additional ReST directives.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -3,7 +3,7 @@
sphinx.directives.code
~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -3,7 +3,7 @@
sphinx.directives.other
~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -3,7 +3,7 @@
sphinx.directives.patches
~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -6,7 +6,7 @@
Support for domains, which are groupings of description directives
and roles describing e.g. constructs of one programming language.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -141,7 +141,7 @@ class Domain(object):
#: domain label: longer, more descriptive (used in messages)
label = ''
#: type (usually directive) name -> ObjType instance
object_types = {} # type: Dict[unicode, Any]
object_types = {} # type: Dict[unicode, ObjType]
#: directive name -> directive class
directives = {} # type: Dict[unicode, Any]
#: role name -> role callable
@ -161,6 +161,17 @@ class Domain(object):
def __init__(self, env):
# type: (BuildEnvironment) -> None
self.env = env # type: BuildEnvironment
self._role_cache = {} # type: Dict[unicode, Callable]
self._directive_cache = {} # type: Dict[unicode, Callable]
self._role2type = {} # type: Dict[unicode, List[unicode]]
self._type2role = {} # type: Dict[unicode, unicode]
# convert class variables to instance one (to enhance through API)
self.object_types = dict(self.object_types)
self.directives = dict(self.directives)
self.roles = dict(self.roles)
self.indices = list(self.indices)
if self.name not in env.domaindata:
assert isinstance(self.initial_data, dict)
new_data = copy.deepcopy(self.initial_data)
@ -170,10 +181,6 @@ class Domain(object):
self.data = env.domaindata[self.name]
if self.data['version'] != self.data_version:
raise IOError('data of %r domain out of date' % self.label)
self._role_cache = {} # type: Dict[unicode, Callable]
self._directive_cache = {} # type: Dict[unicode, Callable]
self._role2type = {} # type: Dict[unicode, List[unicode]]
self._type2role = {} # type: Dict[unicode, unicode]
for name, obj in iteritems(self.object_types):
for rolename in obj.roles:
self._role2type.setdefault(rolename, []).append(name)
@ -181,6 +188,18 @@ class Domain(object):
self.objtypes_for_role = self._role2type.get # type: Callable[[unicode], List[unicode]] # NOQA
self.role_for_objtype = self._type2role.get # type: Callable[[unicode], unicode]
def add_object_type(self, name, objtype):
# type: (unicode, ObjType) -> None
"""Add an object type."""
self.object_types[name] = objtype
if objtype.roles:
self._type2role[name] = objtype.roles[0]
else:
self._type2role[name] = ''
for role in objtype.roles:
self._role2type.setdefault(role, []).append(name)
def role(self, name):
# type: (unicode) -> Callable
"""Return a role adapter function that always gives the registered

View File

@ -5,7 +5,7 @@
The C language domain.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
The JavaScript domain.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
The Python domain.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
The reStructuredText domain.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
The standard domain.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -959,12 +959,18 @@ class StandardDomain(Domain):
def get_full_qualified_name(self, node):
# type: (nodes.Node) -> unicode
if node.get('reftype') == 'option':
progname = node.get('std:program')
target = node.get('reftarget')
if progname is None or target is None:
command = ws_re.split(node.get('reftarget'))
if progname:
command.insert(0, progname)
option = command.pop()
if command:
return '.'.join(['-'.join(command), option])
else:
return None
else:
return '.'.join([progname, target])
return None
def setup(app):

View File

@ -5,7 +5,7 @@
Global creation environment.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -14,27 +14,23 @@ import os
import sys
import time
import types
import codecs
import fnmatch
import warnings
from os import path
from copy import copy
from collections import defaultdict
from contextlib import contextmanager
from six import BytesIO, itervalues, class_types, next
from six import BytesIO, itervalues, class_types, next, iteritems
from six.moves import cPickle as pickle
from docutils.io import NullOutput
from docutils.core import Publisher
from docutils.utils import Reporter, get_source_line, normalize_language_tag
from docutils.utils.smartquotes import smartchars
from docutils.parsers.rst import roles
from docutils.parsers.rst.languages import en as english
from docutils.frontend import OptionParser
from sphinx import addnodes
from sphinx.io import SphinxStandaloneReader, SphinxDummyWriter, SphinxFileInput
from sphinx.util import logging
from sphinx import addnodes, versioning
from sphinx.io import read_doc
from sphinx.util import logging, rst
from sphinx.util import get_matching_docs, FilenameUniqDict, status_iterator
from sphinx.util.nodes import is_translatable
from sphinx.util.osutil import SEP, ensuredir
@ -45,16 +41,14 @@ from sphinx.util.matching import compile_matchers
from sphinx.util.parallel import ParallelTasks, parallel_available, make_chunks
from sphinx.util.websupport import is_commentable
from sphinx.errors import SphinxError, ExtensionError
from sphinx.locale import __
from sphinx.transforms import SphinxTransformer
from sphinx.versioning import add_uids, merge_doctrees
from sphinx.transforms import SphinxTransformer, SphinxSmartQuotes
from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.environment.adapters.indexentries import IndexEntries
from sphinx.environment.adapters.toctree import TocTree
if False:
# For type annotation
from typing import Any, Callable, Dict, IO, Iterator, List, Pattern, Set, Tuple, Type, Union # NOQA
from typing import Any, Callable, Dict, IO, Iterator, List, Pattern, Set, Tuple, Type, Union, Generator # NOQA
from docutils import nodes # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.builders import Builder # NOQA
@ -73,6 +67,7 @@ default_settings = {
'sectsubtitle_xform': False,
'halt_level': 5,
'file_insertion_enabled': True,
'smartquotes_locales': [],
}
# This is increased every time an environment attribute is added
@ -82,8 +77,6 @@ default_settings = {
ENV_VERSION = 52 + (sys.version_info[0] - 2)
dummy_reporter = Reporter('', 4, 4)
versioning_conditions = {
'none': False,
'text': is_translatable,
@ -91,6 +84,22 @@ versioning_conditions = {
} # type: Dict[unicode, Union[bool, Callable]]
@contextmanager
def sphinx_smartquotes_action(env):
# type: (BuildEnvironment) -> Generator
if not hasattr(SphinxSmartQuotes, 'smartquotes_action'):
# less than docutils-0.14
yield
else:
# docutils-0.14 or above
try:
original = SphinxSmartQuotes.smartquotes_action
SphinxSmartQuotes.smartquotes_action = env.config.smartquotes_action
yield
finally:
SphinxSmartQuotes.smartquotes_action = original
class NoUri(Exception):
"""Raised by get_relative_uri if there is no URI available."""
pass
@ -566,21 +575,10 @@ class BuildEnvironment(object):
self.app.emit('env-before-read-docs', self, docnames)
# check if we should do parallel or serial read
par_ok = False
if parallel_available and len(docnames) > 5 and self.app.parallel > 1:
for ext in itervalues(self.app.extensions):
if ext.parallel_read_safe is None:
logger.warning(__('the %s extension does not declare if it is safe '
'for parallel reading, assuming it isn\'t - please '
'ask the extension author to check and make it '
'explicit'), ext.name)
logger.warning('doing serial read')
break
elif ext.parallel_read_safe is False:
break
par_ok = self.app.is_parallel_allowed('read')
else:
# all extensions support parallel-read
par_ok = True
par_ok = False
if par_ok:
self._read_parallel(docnames, self.app, nproc=self.app.parallel)
@ -604,6 +602,7 @@ class BuildEnvironment(object):
# remove all inventory entries for that file
app.emit('env-purge-doc', self, docname)
self.clear_doc(docname)
with sphinx_smartquotes_action(self):
self.read_doc(docname, app)
def _read_parallel(self, docnames, app, nproc):
@ -616,6 +615,7 @@ class BuildEnvironment(object):
def read_process(docs):
# type: (List[unicode]) -> unicode
self.app = app
with sphinx_smartquotes_action(self):
for docname in docs:
self.read_doc(docname, app)
# allow pickling self to send it back
@ -648,25 +648,9 @@ class BuildEnvironment(object):
# --------- SINGLE FILE READING --------------------------------------------
def warn_and_replace(self, error):
# type: (Any) -> Tuple
"""Custom decoding error handler that warns and replaces."""
linestart = error.object.rfind(b'\n', 0, error.start)
lineend = error.object.find(b'\n', error.start)
if lineend == -1:
lineend = len(error.object)
lineno = error.object.count(b'\n', 0, error.start) + 1
logger.warning('undecodable source characters, replacing with "?": %r',
(error.object[linestart + 1:error.start] + b'>>>' +
error.object[error.start:error.end] + b'<<<' +
error.object[error.end:lineend]),
location=(self.docname, lineno))
return (u'?', error.end)
def read_doc(self, docname, app=None):
# type: (unicode, Sphinx) -> None
"""Parse a file and add/update inventory entries for the doctree."""
def prepare_settings(self, docname):
# type: (unicode) -> None
"""Prepare to set up environment for reading."""
self.temp_data['docname'] = docname
# defaults to the global default, but can be re-set in a document
self.temp_data['default_role'] = self.config.default_role
@ -681,7 +665,19 @@ class BuildEnvironment(object):
language = self.config.language or 'en'
self.settings['language_code'] = language
if 'smart_quotes' not in self.settings:
self.settings['smart_quotes'] = True
self.settings['smart_quotes'] = self.config.smartquotes
# some conditions exclude smart quotes, overriding smart_quotes
for valname, vallist in iteritems(self.config.smartquotes_excludes):
if valname == 'builders':
# this will work only for checking first build target
if self.app.builder.name in vallist:
self.settings['smart_quotes'] = False
break
elif valname == 'languages':
if self.config.language in vallist:
self.settings['smart_quotes'] = False
break
# confirm selected language supports smart_quotes or not
for tag in normalize_language_tag(language):
@ -690,40 +686,19 @@ class BuildEnvironment(object):
else:
self.settings['smart_quotes'] = False
def read_doc(self, docname, app=None):
# type: (unicode, Sphinx) -> None
"""Parse a file and add/update inventory entries for the doctree."""
self.prepare_settings(docname)
docutilsconf = path.join(self.srcdir, 'docutils.conf')
# read docutils.conf from source dir, not from current dir
OptionParser.standard_config_files[1] = docutilsconf
if path.isfile(docutilsconf):
self.note_dependency(docutilsconf)
with sphinx_domains(self):
if self.config.default_role:
role_fn, messages = roles.role(self.config.default_role, english,
0, dummy_reporter)
if role_fn:
roles._roles[''] = role_fn
else:
logger.warning('default role %s not found', self.config.default_role,
location=docname)
codecs.register_error('sphinx', self.warn_and_replace) # type: ignore
# publish manually
reader = SphinxStandaloneReader(self.app,
parsers=self.app.registry.get_source_parsers())
pub = Publisher(reader=reader,
writer=SphinxDummyWriter(),
destination_class=NullOutput)
pub.set_components(None, 'restructuredtext', None)
pub.process_programmatic_settings(None, self.settings, None)
src_path = self.doc2path(docname)
source = SphinxFileInput(app, self, source=None, source_path=src_path,
encoding=self.config.source_encoding)
pub.source = source
pub.settings._source = src_path
pub.set_destination(None, None)
pub.publish()
doctree = pub.document
with sphinx_domains(self), rst.default_role(docname, self.config.default_role):
doctree = read_doc(self.app, self, self.doc2path(docname))
# post-processing
for domain in itervalues(self.domains):
@ -741,41 +716,14 @@ class BuildEnvironment(object):
time.time(), path.getmtime(self.doc2path(docname)))
if self.versioning_condition:
old_doctree = None
if self.versioning_compare:
# get old doctree
try:
with open(self.doc2path(docname,
self.doctreedir, '.doctree'), 'rb') as f:
old_doctree = pickle.load(f)
except EnvironmentError:
pass
# add uids for versioning
if not self.versioning_compare or old_doctree is None:
list(add_uids(doctree, self.versioning_condition))
else:
list(merge_doctrees(
old_doctree, doctree, self.versioning_condition))
# make it picklable
doctree.reporter = None
doctree.transformer = None
doctree.settings.warning_stream = None
doctree.settings.env = None
doctree.settings.record_dependencies = None
versioning.prepare(doctree)
# cleanup
self.temp_data.clear()
self.ref_context.clear()
roles._roles.pop('', None) # if a document has set a local default role
# save the parsed doctree
doctree_filename = self.doc2path(docname, self.doctreedir,
'.doctree')
ensuredir(path.dirname(doctree_filename))
with open(doctree_filename, 'wb') as f:
pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL)
self.write_doctree(docname, doctree)
# utilities to use while reading a document
@ -879,6 +827,21 @@ class BuildEnvironment(object):
doctree.reporter = Reporter(self.doc2path(docname), 2, 5, stream=WarningStream())
return doctree
def write_doctree(self, docname, doctree):
# type: (unicode, nodes.Node) -> None
"""Write the doctree to a file."""
# make it picklable
doctree.reporter = None
doctree.transformer = None
doctree.settings.warning_stream = None
doctree.settings.env = None
doctree.settings.record_dependencies = None
doctree_filename = self.doc2path(docname, self.doctreedir, '.doctree')
ensuredir(path.dirname(doctree_filename))
with open(doctree_filename, 'wb') as f:
pickle.dump(doctree, f, pickle.HIGHEST_PROTOCOL)
def get_and_resolve_doctree(self, docname, builder, doctree=None,
prune_toctrees=True, includehidden=False):
# type: (unicode, Builder, nodes.Node, bool, bool) -> nodes.Node
@ -935,7 +898,7 @@ class BuildEnvironment(object):
transformer = SphinxTransformer(doctree)
transformer.set_environment(self)
transformer.add_transforms(self.app.post_transforms)
transformer.add_transforms(self.app.registry.get_post_transforms())
transformer.apply_transforms()
finally:
self.temp_data = backup

View File

@ -5,6 +5,6 @@
Sphinx environment adapters
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Assets adapter for sphinx.environment.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Index entries adapters for sphinx.environment.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re

View File

@ -5,7 +5,7 @@
Toctree adapter for sphinx.environment.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
The data collector components for sphinx.environment.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
The image collector for sphinx.environment.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
The dependencies collector components for sphinx.environment.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Index entries collector for sphinx.environment.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
The metadata collector components for sphinx.environment.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
The title collector components for sphinx.environment.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -5,7 +5,7 @@
Toctree collector for sphinx.environment.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -262,7 +262,7 @@ class TocTreeCollector(EnvironmentCollector):
continue
figtype = env.get_domain('std').get_figtype(subnode) # type: ignore
figtype = env.get_domain('std').get_figtype(subnode)
if figtype and subnode['ids']:
register_fignumber(docname, secnum, figtype, subnode)

View File

@ -6,7 +6,7 @@
Contains SphinxError and a few subclasses (in an extra module to avoid
circular import problems).
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -7,7 +7,7 @@
Gracefully adapted from the TextPress system by Armin.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function

View File

@ -5,6 +5,6 @@
Contains Sphinx features not activated by default.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -11,7 +11,7 @@
Copyright 2008 Société des arts technologiques (SAT),
http://www.sat.qc.ca/
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -27,7 +27,7 @@ from fnmatch import fnmatch
from sphinx import __display_version__
from sphinx.cmd.quickstart import EXTENSIONS
from sphinx.util import rst
from sphinx.util.osutil import FileAvoidWrite, walk
from sphinx.util.osutil import FileAvoidWrite, ensuredir, walk
if False:
# For type annotation
@ -117,7 +117,11 @@ def create_package_file(root, master_package, subroot, py_files, opts, subs, is_
text += '\n'
# build a list of directories that are szvpackages (contain an INITPY file)
subs = [sub for sub in subs if path.isfile(path.join(root, sub, INITPY))]
# and also checks the INITPY file is not empty, or there are other python
# source files in that folder.
# (depending on settings - but shall_skip() takes care of that)
subs = [sub for sub in subs if not
shall_skip(path.join(root, sub, INITPY), opts)]
# if there are some package directories, add a TOC for theses subpackages
if subs:
text += format_heading(2, 'Subpackages')
@ -358,8 +362,8 @@ Note: By default this script will not overwrite already created files.""")
group = parser.add_argument_group('extension options')
for ext in EXTENSIONS:
group.add_argument('--ext-' + ext, action='store_true',
dest='ext_' + ext, default=False,
group.add_argument('--ext-%s' % ext, action='append_const',
const='sphinx.ext.%s' % ext, dest='extensions',
help='enable %s extension' % ext)
return parser
@ -382,8 +386,8 @@ def main(argv=sys.argv[1:]):
if not path.isdir(rootpath):
print('%s is not a directory.' % rootpath, file=sys.stderr)
sys.exit(1)
if not path.isdir(args.destdir) and not args.dryrun:
os.makedirs(args.destdir)
if not args.dryrun:
ensuredir(args.destdir)
excludes = [path.abspath(exclude) for exclude in args.exclude_pattern]
modules = recurse_tree(rootpath, excludes, args)
@ -408,20 +412,19 @@ def main(argv=sys.argv[1:]):
suffix = '.' + args.suffix,
master = 'index',
epub = True,
ext_autodoc = True,
ext_viewcode = True,
ext_todo = True,
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode',
'sphinx.ext.todo'],
makefile = True,
batchfile = True,
make_mode = True,
mastertocmaxdepth = args.maxdepth,
mastertoctree = text,
language = 'en',
module_path = rootpath,
append_syspath = args.append_syspath,
)
enabled_exts = {'ext_' + ext: getattr(args, 'ext_' + ext)
for ext in EXTENSIONS if getattr(args, 'ext_' + ext)}
d.update(enabled_exts)
if args.extensions:
d['extensions'].extend(args.extensions)
if isinstance(args.header, binary_type):
d['project'] = d['project'].decode('utf-8')

View File

@ -7,46 +7,46 @@
the doctree, thus avoiding duplication between docstrings and documentation
for those who like elaborate docstrings.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import re
import sys
import inspect
import traceback
import warnings
from six import PY2, iterkeys, iteritems, itervalues, text_type, class_types, string_types
from six import iteritems, itervalues, text_type, class_types, string_types
from docutils import nodes
from docutils.utils import assemble_option_dict
from docutils.parsers.rst import Directive
from docutils.statemachine import ViewList
import sphinx
from sphinx.ext.autodoc.importer import _MockImporter
from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.ext.autodoc.importer import mock, import_object, get_object_members
from sphinx.ext.autodoc.importer import _MockImporter # to keep compatibility # NOQA
from sphinx.ext.autodoc.inspector import format_annotation, formatargspec # to keep compatibility # NOQA
from sphinx.util import rpartition, force_decode
from sphinx.locale import _
from sphinx.pycode import ModuleAnalyzer, PycodeError
from sphinx.application import ExtensionError
from sphinx.util import logging
from sphinx.util.nodes import nested_parse_with_titles
from sphinx.util.inspect import Signature, isdescriptor, safe_getmembers, \
safe_getattr, object_description, is_builtin_class_method, \
isenumclass, isenumattribute, getdoc
isenumattribute, getdoc
from sphinx.util.docstrings import prepare_docstring
if False:
# For type annotation
from types import ModuleType # NOQA
from typing import Any, Callable, Dict, Iterator, List, Sequence, Set, Tuple, Type, Union # NOQA
from docutils import nodes # NOQA
from docutils.utils import Reporter # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.ext.autodoc.directive import DocumenterBridge # NOQA
logger = logging.getLogger(__name__)
# This type isn't exposed directly in any modules, but can be found
# here in most Python versions
MethodDescriptorType = type(type.__subclasses__)
@ -63,42 +63,11 @@ py_ext_sig_re = re.compile(
''', re.VERBOSE)
class DefDict(dict):
"""A dict that returns a default on nonexisting keys."""
def __init__(self, default):
# type: (Any) -> None
dict.__init__(self)
self.default = default
def __getitem__(self, key):
# type: (Any) -> Any
try:
return dict.__getitem__(self, key)
except KeyError:
return self.default
def __bool__(self):
# type: () -> bool
# docutils check "if option_spec"
return True
__nonzero__ = __bool__ # for python2 compatibility
def identity(x):
# type: (Any) -> Any
return x
class Options(dict):
"""A dict/attribute hybrid that returns None on nonexisting keys."""
def __getattr__(self, name):
# type: (unicode) -> Any
try:
return self[name.replace('_', '-')]
except KeyError:
return None
ALL = object()
INSTANCEATTR = object()
@ -146,6 +115,9 @@ class AutodocReporter(object):
"""
def __init__(self, viewlist, reporter):
# type: (ViewList, Reporter) -> None
warnings.warn('AutodocReporter is now deprecated. '
'Use sphinx.util.docutils.switch_source_input() instead.',
RemovedInSphinx20Warning)
self.viewlist = viewlist
self.reporter = reporter
@ -284,14 +256,10 @@ class Documenter(object):
option_spec = {'noindex': bool_option} # type: Dict[unicode, Callable]
@staticmethod
def get_attr(obj, name, *defargs):
def get_attr(self, obj, name, *defargs):
# type: (Any, unicode, Any) -> Any
"""getattr() override for types such as Zope interfaces."""
for typ, func in iteritems(AutoDirective._special_attrgetters):
if isinstance(obj, typ):
return func(obj, name, *defargs)
return safe_getattr(obj, name, *defargs)
return autodoc_attrgetter(self.env.app, obj, name, *defargs)
@classmethod
def can_document_member(cls, member, membername, isattr, parent):
@ -300,7 +268,7 @@ class Documenter(object):
raise NotImplementedError('must be implemented in subclasses')
def __init__(self, directive, name, indent=u''):
# type: (Directive, unicode, unicode) -> None
# type: (DocumenterBridge, unicode, unicode) -> None
self.directive = directive
self.env = directive.env
self.options = directive.genopt
@ -324,6 +292,12 @@ class Documenter(object):
# the module analyzer to get at attribute docs, or None
self.analyzer = None # type: Any
@property
def documenters(self):
# type: () -> Dict[unicode, Type[Documenter]]
"""Returns registered Documenter classes"""
return get_documenters(self.env.app)
def add_line(self, line, source, *lineno):
# type: (unicode, unicode, int) -> None
"""Append one line of generated reST to the output."""
@ -354,8 +328,7 @@ class Documenter(object):
explicit_modname, path, base, args, retann = \
py_ext_sig_re.match(self.name).groups() # type: ignore
except AttributeError:
self.directive.warn('invalid signature for auto%s (%r)' %
(self.objtype, self.name))
logger.warning('invalid signature for auto%s (%r)' % (self.objtype, self.name))
return False
# support explicit module and class name separation via ::
@ -384,53 +357,17 @@ class Documenter(object):
Returns True if successful, False if an error occurred.
"""
if self.objpath:
logger.debug('[autodoc] from %s import %s',
self.modname, '.'.join(self.objpath))
# always enable mock import hook
# it will do nothing if autodoc_mock_imports is empty
import_hook = _MockImporter(self.env.config.autodoc_mock_imports)
with mock(self.env.config.autodoc_mock_imports):
try:
logger.debug('[autodoc] import %s', self.modname)
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=ImportWarning)
with logging.skip_warningiserror(not self.env.config.autodoc_warningiserror):
__import__(self.modname)
parent = None
obj = self.module = sys.modules[self.modname]
logger.debug('[autodoc] => %r', obj)
for part in self.objpath:
parent = obj
logger.debug('[autodoc] getattr(_, %r)', part)
obj = self.get_attr(obj, part)
logger.debug('[autodoc] => %r', obj)
self.object_name = part
self.parent = parent
self.object = obj
ret = import_object(self.modname, self.objpath, self.objtype,
attrgetter=self.get_attr,
warningiserror=self.env.config.autodoc_warningiserror)
self.module, self.parent, self.object_name, self.object = ret
return True
# this used to only catch SyntaxError, ImportError and AttributeError,
# but importing modules with side effects can raise all kinds of errors
except (Exception, SystemExit) as e:
if self.objpath:
errmsg = 'autodoc: failed to import %s %r from module %r' % \
(self.objtype, '.'.join(self.objpath), self.modname)
else:
errmsg = 'autodoc: failed to import %s %r' % \
(self.objtype, self.fullname)
if isinstance(e, SystemExit):
errmsg += ('; the module executes module level statement ' +
'and it might call sys.exit().')
else:
errmsg += '; the following exception was raised:\n%s' % \
traceback.format_exc()
if PY2:
errmsg = errmsg.decode('utf-8') # type: ignore
logger.debug(errmsg)
self.directive.warn(errmsg)
except ImportError as exc:
logger.warning(exc.args[0])
self.env.note_reread()
return False
finally:
import_hook.disable()
def get_real_modname(self):
# type: () -> str
@ -488,8 +425,8 @@ class Documenter(object):
try:
args = self.format_args()
except Exception as err:
self.directive.warn('error while formatting arguments for '
'%s: %s' % (self.fullname, err))
logger.warning('error while formatting arguments for %s: %s' %
(self.fullname, err))
args = None
retann = self.retann
@ -601,57 +538,24 @@ class Documenter(object):
If *want_all* is True, return all members. Else, only return those
members given by *self.options.members* (which may also be none).
"""
analyzed_member_names = set()
if self.analyzer:
attr_docs = self.analyzer.find_attr_docs()
namespace = '.'.join(self.objpath)
for item in iteritems(attr_docs):
if item[0][0] == namespace:
analyzed_member_names.add(item[0][1])
members = get_object_members(self.object, self.objpath, self.get_attr, self.analyzer)
if not want_all:
if not self.options.members:
return False, []
# specific members given
members = []
for mname in self.options.members:
try:
members.append((mname, self.get_attr(self.object, mname)))
except AttributeError:
if mname not in analyzed_member_names:
self.directive.warn('missing attribute %s in object %s'
% (mname, self.fullname))
selected = []
for name in self.options.members:
if name in members:
selected.append((name, members[name].value))
else:
logger.warning('missing attribute %s in object %s' %
(name, self.fullname))
return False, sorted(selected)
elif self.options.inherited_members:
# safe_getmembers() uses dir() which pulls in members from all
# base classes
members = safe_getmembers(self.object, attr_getter=self.get_attr)
return False, sorted((m.name, m.value) for m in itervalues(members))
else:
# __dict__ contains only the members directly defined in
# the class (but get them via getattr anyway, to e.g. get
# unbound method objects instead of function objects);
# using list(iterkeys()) because apparently there are objects for which
# __dict__ changes while getting attributes
try:
obj_dict = self.get_attr(self.object, '__dict__')
except AttributeError:
members = []
else:
members = [(mname, self.get_attr(self.object, mname, None))
for mname in list(iterkeys(obj_dict))]
# Py34 doesn't have enum members in __dict__.
if isenumclass(self.object):
members.extend(
item for item in self.object.__members__.items()
if item not in members
)
membernames = set(m[0] for m in members)
# add instance attributes from the analyzer
for aname in analyzed_member_names:
if aname not in membernames and \
(want_all or aname in self.options.members):
members.append((aname, INSTANCEATTR))
return False, sorted(members)
return False, sorted((m.name, m.value) for m in itervalues(members)
if m.directly_defined)
def filter_members(self, members, want_all):
# type: (List[Tuple[unicode, Any]], bool) -> List[Tuple[unicode, Any, bool]]
@ -710,8 +614,7 @@ class Documenter(object):
elif (namespace, membername) in attr_docs:
if want_all and membername.startswith('_'):
# ignore members whose name starts with _ by default
keep = self.options.private_members and \
(has_doc or self.options.undoc_members)
keep = self.options.private_members
else:
# keep documented attributes
keep = True
@ -764,7 +667,7 @@ class Documenter(object):
# document non-skipped members
memberdocumenters = [] # type: List[Tuple[Documenter, bool]]
for (mname, member, isattr) in self.filter_members(members, want_all):
classes = [cls for cls in itervalues(AutoDirective._registry)
classes = [cls for cls in itervalues(self.documenters)
if cls.can_document_member(member, mname, isattr, self)]
if not classes:
# don't know how to document this member
@ -815,11 +718,11 @@ class Documenter(object):
"""
if not self.parse_name():
# need a module to import
self.directive.warn(
logger.warning(
'don\'t know which module to import for autodocumenting '
'%r (try placing a "module" or "currentmodule" directive '
'in the document, or giving an explicit module name)'
% self.name)
'in the document, or giving an explicit module name)' %
self.name)
return
# now, import the module and get object to document
@ -893,7 +796,7 @@ class ModuleDocumenter(Documenter):
'platform': identity, 'deprecated': bool_option,
'member-order': identity, 'exclude-members': members_set_option,
'private-members': bool_option, 'special-members': members_option,
'imported-members': bool_option,
'imported-members': bool_option, 'ignore-module-all': bool_option
} # type: Dict[unicode, Callable]
@classmethod
@ -905,14 +808,14 @@ class ModuleDocumenter(Documenter):
def resolve_name(self, modname, parents, path, base):
# type: (str, Any, str, Any) -> Tuple[str, List[unicode]]
if modname is not None:
self.directive.warn('"::" in automodule name doesn\'t make sense')
logger.warning('"::" in automodule name doesn\'t make sense')
return (path or '') + base, []
def parse_name(self):
# type: () -> bool
ret = Documenter.parse_name(self)
if self.args or self.retann:
self.directive.warn('signature arguments or return annotation '
logger.warning('signature arguments or return annotation '
'given for automodule %s' % self.fullname)
return ret
@ -935,7 +838,8 @@ class ModuleDocumenter(Documenter):
def get_object_members(self, want_all):
# type: (bool) -> Tuple[bool, List[Tuple[unicode, object]]]
if want_all:
if not hasattr(self.object, '__all__'):
if (self.options.ignore_module_all or not
hasattr(self.object, '__all__')):
# for implicit module members, check __module__ to avoid
# documenting imported objects
return True, safe_getmembers(self.object)
@ -944,7 +848,7 @@ class ModuleDocumenter(Documenter):
# Sometimes __all__ is broken...
if not isinstance(memberlist, (list, tuple)) or not \
all(isinstance(entry, string_types) for entry in memberlist):
self.directive.warn(
logger.warning(
'__all__ should be a list of strings, not %r '
'(in module %s) -- ignoring __all__' %
(memberlist, self.fullname))
@ -957,10 +861,10 @@ class ModuleDocumenter(Documenter):
try:
ret.append((mname, safe_getattr(self.object, mname)))
except AttributeError:
self.directive.warn(
logger.warning(
'missing attribute mentioned in :members: or __all__: '
'module %s, attribute %s' % (
safe_getattr(self.object, '__name__', '???'), mname))
'module %s, attribute %s' %
(safe_getattr(self.object, '__name__', '???'), mname))
return False, ret
@ -1269,6 +1173,17 @@ class ClassDocumenter(DocstringSignatureMixin, ModuleLevelDocumenter): # type:
return
ModuleLevelDocumenter.document_members(self, all_members)
def generate(self, more_content=None, real_modname=None,
check_module=False, all_members=False):
# Do not pass real_modname and use the name from the __module__
# attribute of the class.
# If a class gets imported into the module real_modname
# the analyzer won't find the source of the class, if
# it looks in real_modname.
return super(ClassDocumenter, self).generate(more_content=more_content,
check_module=check_module,
all_members=all_members)
class ExceptionDocumenter(ClassDocumenter):
"""
@ -1488,118 +1403,56 @@ class InstanceAttributeDocumenter(AttributeDocumenter):
AttributeDocumenter.add_content(self, more_content, no_docstring=True)
class AutoDirective(Directive):
"""
The AutoDirective class is used for all autodoc directives. It dispatches
most of the work to one of the Documenters, which it selects through its
*_registry* dictionary.
class DeprecatedDict(dict):
def __init__(self, message):
self.message = message
super(DeprecatedDict, self).__init__()
The *_special_attrgetters* attribute is used to customize ``getattr()``
calls that the Documenters make; its entries are of the form ``type:
getattr_function``.
def __setitem__(self, key, value):
warnings.warn(self.message, RemovedInSphinx20Warning)
super(DeprecatedDict, self).__setitem__(key, value)
def setdefault(self, key, default=None):
warnings.warn(self.message, RemovedInSphinx20Warning)
super(DeprecatedDict, self).setdefault(key, default)
def update(self, other=None):
warnings.warn(self.message, RemovedInSphinx20Warning)
super(DeprecatedDict, self).update(other)
class AutodocRegistry(object):
"""
A registry of Documenters and attrgetters.
Note: When importing an object, all items along the import chain are
accessed using the descendant's *_special_attrgetters*, thus this
dictionary should include all necessary functions for accessing
attributes of the parents.
"""
# a registry of objtype -> documenter class
_registry = {} # type: Dict[unicode, Type[Documenter]]
# a registry of objtype -> documenter class (Deprecated)
_registry = DeprecatedDict(
'AutoDirective._registry has been deprecated. '
'Please use app.add_autodocumenter() instead.'
) # type: Dict[unicode, Type[Documenter]]
# a registry of type -> getattr function
_special_attrgetters = {} # type: Dict[Type, Callable]
_special_attrgetters = DeprecatedDict(
'AutoDirective._special_attrgetters has been deprecated. '
'Please use app.add_autodoc_attrgetter() instead.'
) # type: Dict[Type, Callable]
# flags that can be given in autodoc_default_flags
_default_flags = set([
'members', 'undoc-members', 'inherited-members', 'show-inheritance',
'private-members', 'special-members',
])
# standard docutils directive settings
has_content = True
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
# allow any options to be passed; the options are parsed further
# by the selected Documenter
option_spec = DefDict(identity)
def warn(self, msg):
# type: (unicode) -> None
self.warnings.append(self.reporter.warning(msg, line=self.lineno))
def run(self):
# type: () -> List[nodes.Node]
self.filename_set = set() # type: Set[unicode]
# a set of dependent filenames
self.reporter = self.state.document.reporter
self.env = self.state.document.settings.env
self.warnings = [] # type: List[unicode]
self.result = ViewList()
try:
source, lineno = self.reporter.get_source_and_line(self.lineno)
except AttributeError:
source = lineno = None
logger.debug('[autodoc] %s:%s: input:\n%s',
source, lineno, self.block_text)
# find out what documenter to call
objtype = self.name[4:]
doc_class = self._registry[objtype]
# add default flags
for flag in self._default_flags:
if flag not in doc_class.option_spec:
continue
negated = self.options.pop('no-' + flag, 'not given') is None
if flag in self.env.config.autodoc_default_flags and \
not negated:
self.options[flag] = None
# process the options with the selected documenter's option_spec
try:
self.genopt = Options(assemble_option_dict(
self.options.items(), doc_class.option_spec))
except (KeyError, ValueError, TypeError) as err:
# an option is either unknown or has a wrong type
msg = self.reporter.error('An option to %s is either unknown or '
'has an invalid value: %s' % (self.name, err),
line=self.lineno)
return [msg]
# generate the output
documenter = doc_class(self, self.arguments[0])
documenter.generate(more_content=self.content)
if not self.result:
return self.warnings
logger.debug('[autodoc] output:\n%s', '\n'.join(self.result))
# record all filenames as dependencies -- this will at least
# partially make automatic invalidation possible
for fn in self.filename_set:
self.state.document.settings.record_dependencies.add(fn)
# use a custom reporter that correctly assigns lines to source
# filename/description and lineno
old_reporter = self.state.memo.reporter
self.state.memo.reporter = AutodocReporter(self.result,
self.state.memo.reporter)
if documenter.titles_allowed:
node = nodes.section()
# necessary so that the child nodes get the right source/line set
node.document = self.state.document
nested_parse_with_titles(self.state, self.result, node)
else:
node = nodes.paragraph()
node.document = self.state.document
self.state.nested_parse(self.result, 0, node)
self.state.memo.reporter = old_reporter
return self.warnings + node.children
AutoDirective = AutodocRegistry # for backward compatibility
def add_documenter(cls):
# type: (Type[Documenter]) -> None
"""Register a new Documenter."""
warnings.warn('sphinx.ext.autodoc.add_documenter() has been deprecated. '
'Please use app.add_autodocumenter() instead.',
RemovedInSphinx20Warning)
if not issubclass(cls, Documenter):
raise ExtensionError('autodoc documenter %r must be a subclass '
'of Documenter' % cls)
@ -1610,6 +1463,29 @@ def add_documenter(cls):
AutoDirective._registry[cls.objtype] = cls
def get_documenters(app):
# type: (Sphinx) -> Dict[unicode, Type[Documenter]]
"""Returns registered Documenter classes"""
classes = dict(AutoDirective._registry) # registered directly
if app:
classes.update(app.registry.documenters) # registered by API
return classes
def autodoc_attrgetter(app, obj, name, *defargs):
# type: (Sphinx, Any, unicode, Any) -> Any
"""Alternative getattr() for types"""
candidates = dict(AutoDirective._special_attrgetters)
if app:
candidates.update(app.registry.autodoc_attrgettrs)
for typ, func in iteritems(candidates):
if isinstance(obj, typ):
return func(obj, name, *defargs)
return safe_getattr(obj, name, *defargs)
def setup(app):
# type: (Sphinx) -> Dict[unicode, Any]
app.add_autodocumenter(ModuleDocumenter)

View File

@ -0,0 +1,155 @@
# -*- coding: utf-8 -*-
"""
sphinx.ext.autodoc.directive
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from docutils import nodes
from docutils.parsers.rst import Directive
from docutils.statemachine import ViewList
from docutils.utils import assemble_option_dict
from sphinx.ext.autodoc import get_documenters
from sphinx.util import logging
from sphinx.util.docutils import switch_source_input
from sphinx.util.nodes import nested_parse_with_titles
if False:
# For type annotation
from typing import Any, Dict, List, Set, Type # NOQA
from docutils.statemachine import State, StateMachine, StringList # NOQA
from docutils.utils import Reporter # NOQA
from sphinx.config import Config # NOQA
from sphinx.environment import BuildEnvironment # NOQA
from sphinx.ext.autodoc import Documenter # NOQA
logger = logging.getLogger(__name__)
# common option names for autodoc directives
AUTODOC_DEFAULT_OPTIONS = ['members', 'undoc-members', 'inherited-members',
'show-inheritance', 'private-members', 'special-members',
'ignore-module-all']
class DummyOptionSpec(object):
"""An option_spec allows any options."""
def __getitem__(self, key):
# type: (Any) -> Any
return lambda x: x
class Options(dict):
"""A dict/attribute hybrid that returns None on nonexisting keys."""
def __getattr__(self, name):
# type: (unicode) -> Any
try:
return self[name.replace('_', '-')]
except KeyError:
return None
class DocumenterBridge(object):
"""A parameters container for Documenters."""
def __init__(self, env, reporter, options, lineno):
# type: (BuildEnvironment, Reporter, Options, int) -> None
self.env = env
self.reporter = reporter
self.genopt = options
self.lineno = lineno
self.filename_set = set() # type: Set[unicode]
self.result = ViewList()
def warn(self, msg):
# type: (unicode) -> None
logger.warning(msg, line=self.lineno)
def process_documenter_options(documenter, config, options):
# type: (Type[Documenter], Config, Dict) -> Options
"""Recognize options of Documenter from user input."""
for name in AUTODOC_DEFAULT_OPTIONS:
if name not in documenter.option_spec:
continue
else:
negated = options.pop('no-' + name, True) is None
if name in config.autodoc_default_flags and not negated:
options[name] = None
return Options(assemble_option_dict(options.items(), documenter.option_spec))
def parse_generated_content(state, content, documenter):
# type: (State, StringList, Documenter) -> List[nodes.Node]
"""Parse a generated content by Documenter."""
with switch_source_input(state, content):
if documenter.titles_allowed:
node = nodes.section()
# necessary so that the child nodes get the right source/line set
node.document = state.document
nested_parse_with_titles(state, content, node)
else:
node = nodes.paragraph()
node.document = state.document
state.nested_parse(content, 0, node)
return node.children
class AutodocDirective(Directive):
"""A directive class for all autodoc directives. It works as a dispatcher of Documenters.
It invokes a Documenter on running. After the processing, it parses and returns
the generated content by Documenter.
"""
option_spec = DummyOptionSpec()
has_content = True
required_arguments = 1
optional_arguments = 0
final_argument_whitespace = True
def run(self):
# type: () -> List[nodes.Node]
env = self.state.document.settings.env
reporter = self.state.document.reporter
try:
source, lineno = reporter.get_source_and_line(self.lineno)
except AttributeError:
source, lineno = (None, None)
logger.debug('[autodoc] %s:%s: input:\n%s', source, lineno, self.block_text)
# look up target Documenter
objtype = self.name[4:] # strip prefix (auto-).
doccls = get_documenters(env.app)[objtype]
# process the options with the selected documenter's option_spec
try:
documenter_options = process_documenter_options(doccls, env.config, self.options)
except (KeyError, ValueError, TypeError) as exc:
# an option is either unknown or has a wrong type
logger.error('An option to %s is either unknown or has an invalid value: %s' %
(self.name, exc), line=lineno)
return []
# generate the output
params = DocumenterBridge(env, reporter, documenter_options, lineno)
documenter = doccls(params, self.arguments[0])
documenter.generate(more_content=self.content)
if not params.result:
return []
logger.debug('[autodoc] output:\n%s', '\n'.join(params.result))
# record all filenames as dependencies -- this will at least
# partially make automatic invalidation possible
for fn in params.filename_set:
self.state.document.settings.record_dependencies.add(fn)
result = parse_generated_content(self.state, params.result, documenter)
return result

View File

@ -5,18 +5,25 @@
Importer utilities for autodoc
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import sys
import warnings
import traceback
import contextlib
from collections import namedtuple
from types import FunctionType, MethodType, ModuleType
from six import PY2
from sphinx.util import logging
from sphinx.util.inspect import isenumclass, safe_getattr
if False:
# For type annotation
from typing import Any, List, Set # NOQA
from typing import Any, Callable, Dict, Generator, List, Optional # NOQA
logger = logging.getLogger(__name__)
@ -75,16 +82,9 @@ class _MockModule(ModuleType):
class _MockImporter(object):
def __init__(self, names):
# type: (List[str]) -> None
self.base_packages = set() # type: Set[str]
for n in names:
# Convert module names:
# ['a.b.c', 'd.e']
# to a set of base packages:
# set(['a', 'd'])
self.base_packages.add(n.split('.')[0])
self.names = names
self.mocked_modules = [] # type: List[str]
# enable hook by adding itself to meta_path
sys.meta_path = sys.meta_path + [self]
@ -100,8 +100,9 @@ class _MockImporter(object):
def find_module(self, name, path=None):
# type: (str, str) -> Any
base_package = name.split('.')[0]
if base_package in self.base_packages:
# check if name is (or is a descendant of) one of our base_packages
for n in self.names:
if n == name or name.startswith(n + '.'):
return self
return None
@ -116,3 +117,112 @@ class _MockImporter(object):
sys.modules[name] = module
self.mocked_modules.append(name)
return module
@contextlib.contextmanager
def mock(names):
# type: (List[str]) -> Generator
try:
importer = _MockImporter(names)
yield
finally:
importer.disable()
def import_module(modname, warningiserror=False):
"""
Call __import__(modname), convert exceptions to ImportError
"""
try:
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=ImportWarning)
with logging.skip_warningiserror(not warningiserror):
__import__(modname)
return sys.modules[modname]
except BaseException as exc:
# Importing modules may cause any side effects, including
# SystemExit, so we need to catch all errors.
raise ImportError(exc, traceback.format_exc())
def import_object(modname, objpath, objtype='', attrgetter=safe_getattr, warningiserror=False):
# type: (str, List[unicode], str, Callable[[Any, unicode], Any], bool) -> Any
if objpath:
logger.debug('[autodoc] from %s import %s', modname, '.'.join(objpath))
else:
logger.debug('[autodoc] import %s', modname)
try:
module = import_module(modname, warningiserror=warningiserror)
logger.debug('[autodoc] => %r', module)
obj = module
parent = None
object_name = None
for attrname in objpath:
parent = obj
logger.debug('[autodoc] getattr(_, %r)', attrname)
obj = attrgetter(obj, attrname)
logger.debug('[autodoc] => %r', obj)
object_name = attrname
return [module, parent, object_name, obj]
except (AttributeError, ImportError) as exc:
if objpath:
errmsg = ('autodoc: failed to import %s %r from module %r' %
(objtype, '.'.join(objpath), modname))
else:
errmsg = 'autodoc: failed to import %s %r' % (objtype, modname)
if isinstance(exc, ImportError):
# import_module() raises ImportError having real exception obj and
# traceback
real_exc, traceback_msg = exc.args
if isinstance(real_exc, SystemExit):
errmsg += ('; the module executes module level statement '
'and it might call sys.exit().')
elif isinstance(real_exc, ImportError):
errmsg += '; the following exception was raised:\n%s' % real_exc.args[0]
else:
errmsg += '; the following exception was raised:\n%s' % traceback_msg
else:
errmsg += '; the following exception was raised:\n%s' % traceback.format_exc()
if PY2:
errmsg = errmsg.decode('utf-8') # type: ignore
logger.debug(errmsg)
raise ImportError(errmsg)
Attribute = namedtuple('Attribute', ['name', 'directly_defined', 'value'])
def get_object_members(subject, objpath, attrgetter, analyzer=None):
# type: (Any, List[unicode], Callable, Any) -> Dict[str, Attribute] # NOQA
"""Get members and attributes of target object."""
# the members directly defined in the class
obj_dict = attrgetter(subject, '__dict__', {})
# Py34 doesn't have enum members in __dict__.
if sys.version_info[:2] == (3, 4) and isenumclass(subject):
obj_dict = dict(obj_dict)
for name, value in subject.__members__.items():
obj_dict[name] = value
members = {}
for name in dir(subject):
try:
value = attrgetter(subject, name)
directly_defined = name in obj_dict
members[name] = Attribute(name, directly_defined, value)
except AttributeError:
continue
if analyzer:
# append instance attributes (cf. self.attr1) if analyzer knows
from sphinx.ext.autodoc import INSTANCEATTR
namespace = '.'.join(objpath)
for (ns, name) in analyzer.find_attr_docs():
if namespace == ns and name not in members:
members[name] = Attribute(name, True, INSTANCEATTR)
return members

View File

@ -5,14 +5,16 @@
Inspect utilities for autodoc
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
import typing
import warnings
from six import StringIO, string_types
from sphinx.deprecation import RemovedInSphinx20Warning
from sphinx.util.inspect import object_description
if False:
@ -29,6 +31,9 @@ def format_annotation(annotation):
Displaying complex types from ``typing`` relies on its private API.
"""
warnings.warn('format_annotation() is now deprecated. '
'Please use sphinx.util.inspect.Signature instead.',
RemovedInSphinx20Warning)
if isinstance(annotation, typing.TypeVar): # type: ignore
return annotation.__name__
if annotation == Ellipsis:
@ -65,7 +70,7 @@ def format_annotation(annotation):
elif (hasattr(typing, 'UnionMeta') and
isinstance(annotation, typing.UnionMeta) and # type: ignore
hasattr(annotation, '__union_params__')):
params = annotation.__union_params__ # type: ignore
params = annotation.__union_params__
if params is not None:
param_str = ', '.join(format_annotation(p) for p in params)
return '%s[%s]' % (qualified_name, param_str)
@ -74,7 +79,7 @@ def format_annotation(annotation):
getattr(annotation, '__args__', None) is not None and
hasattr(annotation, '__result__')):
# Skipped in the case of plain typing.Callable
args = annotation.__args__ # type: ignore
args = annotation.__args__
if args is None:
return qualified_name
elif args is Ellipsis:
@ -84,15 +89,15 @@ def format_annotation(annotation):
args_str = '[%s]' % ', '.join(formatted_args)
return '%s[%s, %s]' % (qualified_name,
args_str,
format_annotation(annotation.__result__)) # type: ignore
format_annotation(annotation.__result__))
elif (hasattr(typing, 'TupleMeta') and
isinstance(annotation, typing.TupleMeta) and # type: ignore
hasattr(annotation, '__tuple_params__') and
hasattr(annotation, '__tuple_use_ellipsis__')):
params = annotation.__tuple_params__ # type: ignore
params = annotation.__tuple_params__
if params is not None:
param_strings = [format_annotation(p) for p in params]
if annotation.__tuple_use_ellipsis__: # type: ignore
if annotation.__tuple_use_ellipsis__:
param_strings.append('...')
return '%s[%s]' % (qualified_name,
', '.join(param_strings))
@ -107,6 +112,9 @@ def formatargspec(function, args, varargs=None, varkw=None, defaults=None,
An enhanced version of ``inspect.formatargspec()`` that handles typing
annotations better.
"""
warnings.warn('formatargspec() is now deprecated. '
'Please use sphinx.util.inspect.Signature instead.',
RemovedInSphinx20Warning)
def format_arg_with_annotation(name):
# type: (str) -> str

View File

@ -5,7 +5,7 @@
Allow reference sections by :ref: role using its title.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

View File

@ -49,7 +49,7 @@
resolved to a Python object, and otherwise it becomes simple emphasis.
This can be used as the default role to make links 'smart'.
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@ -72,7 +72,9 @@ from sphinx import addnodes
from sphinx.environment.adapters.toctree import TocTree
from sphinx.util import import_object, rst, logging
from sphinx.pycode import ModuleAnalyzer, PycodeError
from sphinx.ext.autodoc import Options
from sphinx.ext.autodoc import get_documenters
from sphinx.ext.autodoc.directive import DocumenterBridge, Options
from sphinx.ext.autodoc.importer import import_module
if False:
# For type annotation
@ -152,13 +154,13 @@ def autosummary_table_visit_html(self, node):
# -- autodoc integration -------------------------------------------------------
class FakeDirective(object):
env = {} # type: Dict
genopt = Options()
class FakeDirective(DocumenterBridge):
def __init__(self):
super(FakeDirective, self).__init__({}, None, Options(), 0) # type: ignore
def get_documenter(obj, parent):
# type: (Any, Any) -> Type[Documenter]
def get_documenter(app, obj, parent):
# type: (Sphinx, Any, Any) -> Type[Documenter]
"""Get an autodoc.Documenter class suitable for documenting the given
object.
@ -166,8 +168,7 @@ def get_documenter(obj, parent):
another Python object (e.g. a module or a class) to which *obj*
belongs to.
"""
from sphinx.ext.autodoc import AutoDirective, DataDocumenter, \
ModuleDocumenter
from sphinx.ext.autodoc import DataDocumenter, ModuleDocumenter
if inspect.ismodule(obj):
# ModuleDocumenter.can_document_member always returns False
@ -175,7 +176,7 @@ def get_documenter(obj, parent):
# Construct a fake documenter for *parent*
if parent is not None:
parent_doc_cls = get_documenter(parent, None)
parent_doc_cls = get_documenter(app, parent, None)
else:
parent_doc_cls = ModuleDocumenter
@ -185,7 +186,7 @@ def get_documenter(obj, parent):
parent_doc = parent_doc_cls(FakeDirective(), "")
# Get the corrent documenter class for *obj*
classes = [cls for cls in AutoDirective._registry.values()
classes = [cls for cls in get_documenters(app).values()
if cls.can_document_member(obj, '', False, parent_doc)]
if classes:
classes.sort(key=lambda cls: cls.priority)
@ -288,7 +289,7 @@ class Autosummary(Directive):
full_name = modname + '::' + full_name[len(modname) + 1:]
# NB. using full_name here is important, since Documenters
# handle module prefixes slightly differently
documenter = get_documenter(obj, parent)(self, full_name)
documenter = get_documenter(self.env.app, obj, parent)(self, full_name)
if not documenter.parse_name():
self.warn('failed to parse name %s' % real_name)
items.append((display_name, '', '', real_name))
@ -324,7 +325,7 @@ class Autosummary(Directive):
# -- Grab the summary
documenter.add_content(None)
doc = list(documenter.process_doc([self.result.data]))
doc = self.result.data
while doc and not doc[0].strip():
doc.pop(0)
@ -512,8 +513,7 @@ def _import_by_name(name):
modname = '.'.join(name_parts[:-1])
if modname:
try:
__import__(modname)
mod = sys.modules[modname]
mod = import_module(modname)
return getattr(mod, name_parts[-1]), mod, modname
except (ImportError, IndexError, AttributeError):
pass
@ -525,9 +525,10 @@ def _import_by_name(name):
last_j = j
modname = '.'.join(name_parts[:j])
try:
__import__(modname)
import_module(modname)
except ImportError:
continue
if modname in sys.modules:
break
@ -614,7 +615,8 @@ def process_generate_options(app):
generate_autosummary_docs(genfiles, builder=app.builder,
warn=logger.warning, info=logger.info,
suffix=suffix, base_path=app.srcdir)
suffix=suffix, base_path=app.srcdir,
app=app)
def setup(app):

View File

@ -14,7 +14,7 @@
generate:
sphinx-autogen -o source/generated source/*.rst
:copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
:copyright: Copyright 2007-2018 by the Sphinx team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
from __future__ import print_function
@ -33,24 +33,11 @@ from sphinx import __display_version__
from sphinx import package_dir
from sphinx.ext.autosummary import import_by_name, get_documenter
from sphinx.jinja2glue import BuiltinTemplateLoader
from sphinx.registry import SphinxComponentRegistry
from sphinx.util.osutil import ensuredir
from sphinx.util.inspect import safe_getattr
from sphinx.util.rst import escape as rst_escape
# Add documenters to AutoDirective registry
from sphinx.ext.autodoc import add_documenter, \
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter, \
FunctionDocumenter, MethodDocumenter, AttributeDocumenter, \
InstanceAttributeDocumenter
add_documenter(ModuleDocumenter)
add_documenter(ClassDocumenter)
add_documenter(ExceptionDocumenter)
add_documenter(DataDocumenter)
add_documenter(FunctionDocumenter)
add_documenter(MethodDocumenter)
add_documenter(AttributeDocumenter)
add_documenter(InstanceAttributeDocumenter)
if False:
# For type annotation
from typing import Any, Callable, Dict, Tuple, List # NOQA
@ -60,6 +47,30 @@ if False:
from sphinx.environment import BuildEnvironment # NOQA
class DummyApplication(object):
"""Dummy Application class for sphinx-autogen command."""
def __init__(self):
# type: () -> None
self.registry = SphinxComponentRegistry()
def setup_documenters(app):
# type: (Any) -> None
from sphinx.ext.autodoc import (
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
FunctionDocumenter, MethodDocumenter, AttributeDocumenter,
InstanceAttributeDocumenter
)
documenters = [
ModuleDocumenter, ClassDocumenter, ExceptionDocumenter, DataDocumenter,
FunctionDocumenter, MethodDocumenter, AttributeDocumenter,
InstanceAttributeDocumenter
]
for documenter in documenters:
app.registry.add_documenter(documenter.objtype, documenter)
def _simple_info(msg):
# type: (unicode) -> None
print(msg)
@ -81,8 +92,8 @@ def _underline(title, line='='):
def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
warn=_simple_warn, info=_simple_info,
base_path=None, builder=None, template_dir=None,
imported_members=False):
# type: (List[unicode], unicode, unicode, Callable, Callable, unicode, Builder, unicode, bool) -> None # NOQA
imported_members=False, app=None):
# type: (List[unicode], unicode, unicode, Callable, Callable, unicode, Builder, unicode, bool, Any) -> None # NOQA
showed_sources = list(sorted(sources))
if len(showed_sources) > 20:
@ -148,7 +159,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
new_files.append(fn)
with open(fn, 'w') as f:
doc = get_documenter(obj, parent)
doc = get_documenter(app, obj, parent)
if template_name is not None:
template = template_env.get_template(template_name)
@ -167,7 +178,7 @@ def generate_autosummary_docs(sources, output_dir=None, suffix='.rst',
value = safe_getattr(obj, name)
except AttributeError:
continue
documenter = get_documenter(value, obj)
documenter = get_documenter(app, value, obj)
if documenter.objtype == typ:
if typ == 'method':
items.append(name)
@ -392,11 +403,14 @@ The format of the autosummary directive is documented in the
def main(argv=sys.argv[1:]):
# type: (List[str]) -> None
app = DummyApplication()
setup_documenters(app)
args = get_parser().parse_args(argv)
generate_autosummary_docs(args.source_file, args.output_dir,
'.' + args.suffix,
template_dir=args.templates,
imported_members=args.imported_members)
imported_members=args.imported_members,
app=app)
if __name__ == '__main__':

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