Merge branch 'master' of github.com:sphinx-doc/sphinx

This commit is contained in:
Jakob Lykke Andersen 2017-12-20 09:06:22 +01:00
commit 42f557d4b0
54 changed files with 395 additions and 405 deletions

View File

@ -2,46 +2,40 @@ 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
- python: '3.4'
env: TOXENV=py34
- python: '3.5'
env: TOXENV=py35
- python: '3.6'
env: TOXENV=py36
- python: 'nightly'
env: TOXENV=py37
- 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
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

View File

@ -19,6 +19,8 @@ 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.
Features added
--------------
@ -129,6 +131,7 @@ Bugs fixed
* #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
Testing
--------

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.

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)
@ -121,11 +126,16 @@ 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
@ -133,6 +143,7 @@ Documentation using another builtin 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 +161,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 +191,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 +241,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
------------------------------------------
@ -245,12 +265,14 @@ Documentation using sphinx_bootstrap_theme
* 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 +285,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 +330,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 +344,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

@ -69,11 +69,11 @@ reindent:
.PHONY: test
test:
@cd tests; $(PYTHON) run.py --ignore py35 -v $(TEST)
@cd tests; $(PYTHON) run.py -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:

View File

@ -1,45 +1,102 @@
========
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)
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.
Installing
==========
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.
Install from PyPI to use stable version::
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 +105,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

@ -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`.
@ -315,8 +313,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,10 +337,21 @@ 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...
.. note::
The LaTeX builder currently ignores this configuration setting. It will
obey it at Sphinx 1.7.
.. versionadded:: 1.3

View File

@ -85,7 +85,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 +102,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

@ -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
-----------------------------------------

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
@ -40,6 +43,3 @@ follow_imports = skip
incremental = True
check_untyped_defs = True
warn_unused_ignores = True
[build_sphinx]
warning-is-error = 1

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.')
@ -72,6 +46,7 @@ extras_require = {
'pytest',
'pytest-cov',
'html5lib',
'flake8',
],
'test:python_version<"3"': [
'enum34',

View File

@ -40,7 +40,7 @@ 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
@ -159,7 +159,7 @@ class Sphinx(object):
if not path.isdir(outdir):
logger.info('making output directory...')
os.makedirs(outdir)
ensuredir(outdir)
# read config
self.tags = Tags(tags)

View File

@ -9,7 +9,6 @@
:license: BSD, see LICENSE for details.
"""
import os
from os import path
import warnings
@ -24,7 +23,7 @@ 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, \
@ -79,8 +78,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

View File

@ -274,7 +274,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:

View File

@ -269,7 +269,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

@ -36,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
)
@ -79,13 +79,6 @@ DEFAULTS = {
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
@ -413,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'] = ''
@ -428,9 +421,9 @@ 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
@ -586,7 +579,7 @@ Makefile to be used with sphinx-build.
dest='batchfile',
help='do not create batchfile')
group.add_argument('-m', '--use-make-mode', action='store_true',
dest='make_mode',
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',

View File

@ -291,7 +291,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

@ -573,7 +573,7 @@ class ASTBase(UnicodeMixin):
if type(self) is not type(other):
return False
try:
for key, value in iteritems(self.__dict__): # type: ignore
for key, value in iteritems(self.__dict__):
if value != getattr(other, key):
return False
except AttributeError:

View File

@ -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

@ -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
@ -382,8 +382,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)

View File

@ -10,9 +10,11 @@
"""
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

@ -194,7 +194,7 @@ class GoogleDocstring(UnicodeMixin):
line = self._line_iter.peek()
while(not self._is_section_break() and
(not line or self._is_indented(line, indent))):
lines.append(next(self._line_iter)) # type: ignore
lines.append(next(self._line_iter))
line = self._line_iter.peek()
return lines
@ -204,7 +204,7 @@ class GoogleDocstring(UnicodeMixin):
while (self._line_iter.has_next() and
self._line_iter.peek() and
not self._is_section_header()):
lines.append(next(self._line_iter)) # type: ignore
lines.append(next(self._line_iter))
return lines
def _consume_empty(self):
@ -212,13 +212,13 @@ class GoogleDocstring(UnicodeMixin):
lines = []
line = self._line_iter.peek()
while self._line_iter.has_next() and not line:
lines.append(next(self._line_iter)) # type: ignore
lines.append(next(self._line_iter))
line = self._line_iter.peek()
return lines
def _consume_field(self, parse_type=True, prefer_type=False):
# type: (bool, bool) -> Tuple[unicode, unicode, List[unicode]]
line = next(self._line_iter) # type: ignore
line = next(self._line_iter)
before, colon, after = self._partition_field_on_colon(line)
_name, _type, _desc = before, '', after # type: unicode, unicode, unicode
@ -250,7 +250,7 @@ class GoogleDocstring(UnicodeMixin):
def _consume_inline_attribute(self):
# type: () -> Tuple[unicode, List[unicode]]
line = next(self._line_iter) # type: ignore
line = next(self._line_iter)
_type, colon, _desc = self._partition_field_on_colon(line)
if not colon:
_type, _desc = _desc, _type
@ -285,7 +285,7 @@ class GoogleDocstring(UnicodeMixin):
def _consume_section_header(self):
# type: () -> unicode
section = next(self._line_iter) # type: ignore
section = next(self._line_iter)
stripped_section = section.strip(':')
if stripped_section.lower() in self._sections:
section = stripped_section
@ -295,7 +295,7 @@ class GoogleDocstring(UnicodeMixin):
# type: () -> List[unicode]
lines = []
while self._line_iter.has_next():
lines.append(next(self._line_iter)) # type: ignore
lines.append(next(self._line_iter))
return lines
def _consume_to_next_section(self):
@ -303,7 +303,7 @@ class GoogleDocstring(UnicodeMixin):
self._consume_empty()
lines = []
while not self._is_section_break():
lines.append(next(self._line_iter)) # type: ignore
lines.append(next(self._line_iter))
return lines + self._consume_empty()
def _dedent(self, lines, full=False):
@ -886,7 +886,7 @@ class NumpyDocstring(GoogleDocstring):
def _consume_field(self, parse_type=True, prefer_type=False):
# type: (bool, bool) -> Tuple[unicode, unicode, List[unicode]]
line = next(self._line_iter) # type: ignore
line = next(self._line_iter)
if parse_type:
_name, _, _type = self._partition_field_on_colon(line)
else:
@ -907,10 +907,10 @@ class NumpyDocstring(GoogleDocstring):
def _consume_section_header(self):
# type: () -> unicode
section = next(self._line_iter) # type: ignore
section = next(self._line_iter)
if not _directive_regex.match(section):
# Consume the header underline
next(self._line_iter) # type: ignore
next(self._line_iter)
return section
def _is_section_break(self):

View File

@ -36,11 +36,11 @@ class ModuleAnalyzer(object):
if ('file', filename) in cls.cache:
return cls.cache['file', filename]
try:
fileobj = open(filename, 'rb')
with open(filename, 'rb') as f:
obj = cls(f, modname, filename)
cls.cache['file', filename] = obj
except Exception as err:
raise PycodeError('error opening %r' % filename, err)
obj = cls(fileobj, modname, filename)
cls.cache['file', filename] = obj
return obj
@classmethod

View File

@ -136,8 +136,8 @@ class BuildDoc(Command):
# type: () -> None
if self.source_dir is None:
self.source_dir = self._guess_source_dir()
self.announce('Using source directory %s' % self.source_dir) # type: ignore
self.ensure_dirname('source_dir') # type: ignore
self.announce('Using source directory %s' % self.source_dir)
self.ensure_dirname('source_dir')
if self.source_dir is None:
self.source_dir = os.curdir
self.source_dir = abspath(self.source_dir)
@ -145,10 +145,10 @@ class BuildDoc(Command):
self.config_dir = self.source_dir
self.config_dir = abspath(self.config_dir)
self.ensure_string_list('builder') # type: ignore
self.ensure_string_list('builder')
if self.build_dir is None:
build = self.get_finalized_command('build') # type: ignore
self.build_dir = os.path.join(abspath(build.build_base), 'sphinx')
build = self.get_finalized_command('build')
self.build_dir = os.path.join(abspath(build.build_base), 'sphinx') # type: ignore
self.mkpath(self.build_dir) # type: ignore
self.build_dir = abspath(self.build_dir)
self.doctree_dir = os.path.join(self.build_dir, 'doctrees')

View File

@ -14,6 +14,10 @@ from docutils import nodes
from sphinx import addnodes
from sphinx.transforms import SphinxTransform
if False:
# For type annotation
from typing import List # NOQA
class RefOnlyListChecker(nodes.GenericNodeVisitor):
"""Raise `nodes.NodeFound` if non-simple list item is encountered.
@ -32,7 +36,7 @@ class RefOnlyListChecker(nodes.GenericNodeVisitor):
def visit_list_item(self, node):
# type: (nodes.Node) -> None
children = []
children = [] # type: List[nodes.Node]
for child in node.children:
if not isinstance(child, nodes.Invisible):
children.append(child)

View File

@ -398,10 +398,8 @@ def parselinenos(spec, total):
elif len(begend) == 1:
items.append(int(begend[0]) - 1)
elif len(begend) == 2:
start = int(begend[0] or 1) # type: ignore
# left half open (cf. -10)
end = int(begend[1] or max(start, total)) # type: ignore
# right half open (cf. 10-)
start = int(begend[0] or 1) # left half open (cf. -10)
end = int(begend[1] or max(start, total)) # right half open (cf. 10-)
if start > end: # invalid range (cf. 10-1)
raise ValueError
items.extend(range(start - 1, end))
@ -528,7 +526,7 @@ class PeekableIterator(object):
def peek(self):
# type: () -> Any
"""Return the next item without changing the state of the iterator."""
item = next(self) # type: ignore
item = next(self)
self.push(item)
return item

View File

@ -434,7 +434,7 @@ class Signature(object):
elif (hasattr(typing, 'UnionMeta') and # for py35 or below
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(self.format_annotation(p) for p in params)
return '%s[%s]' % (qualified_name, param_str)
@ -442,7 +442,7 @@ class Signature(object):
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:
@ -452,14 +452,14 @@ class Signature(object):
args_str = '[%s]' % ', '.join(formatted_args)
return '%s[%s, %s]' % (qualified_name,
args_str,
self.format_annotation(annotation.__result__)) # type: ignore # NOQA
self.format_annotation(annotation.__result__))
elif (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 = [self.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))

View File

@ -156,8 +156,8 @@ class NewLineStreamHandlerPY2(logging.StreamHandler):
# remove return code forcely when nonl=True
self.stream = StringIO()
super(NewLineStreamHandlerPY2, self).emit(record)
stream.write(self.stream.getvalue()[:-1]) # type: ignore
stream.flush() # type: ignore
stream.write(self.stream.getvalue()[:-1])
stream.flush()
else:
super(NewLineStreamHandlerPY2, self).emit(record)
finally:

View File

@ -8,12 +8,20 @@
"""
import os
import sys
import pytest
from sphinx.testing.path import path
pytest_plugins = 'sphinx.testing.fixtures'
# Exclude 'roots' dirs for pytest test collector
collect_ignore = ['roots']
# Disable Python version-specific
if sys.version_info < (3, 5):
collect_ignore += ['py35']
@pytest.fixture(scope='session')
def rootdir():

View File

@ -0,0 +1,5 @@
File with UTF-8 BOM
===================
This file has a UTF-8 "BOM".

View File

@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-
master_doc = 'index'
latex_documents = [
(master_doc, 'test.tex', 'The basic Sphinx documentation for testing', 'Sphinx', 'report')
]

View File

@ -0,0 +1,6 @@
The basic Sphinx documentation for testing
==========================================
.. toctree::
bom

View File

@ -1 +0,0 @@
This whole directory is there to test html_static_path.

View File

@ -1 +0,0 @@
/* This file should be excluded from being copied over */

View File

@ -1 +0,0 @@
/* Stub file */

View File

@ -29,16 +29,11 @@ numfig = True
rst_epilog = '.. |subst| replace:: global substitution'
html_theme = 'testtheme'
html_theme_path = ['.']
html_theme_options = {'testopt': 'testoverride'}
html_sidebars = {'**': ['localtoc.html', 'relations.html', 'sourcelink.html',
'customsb.html', 'searchbox.html'],
'contents': ['contentssb.html', 'localtoc.html',
'globaltoc.html']}
html_style = 'default.css'
html_static_path = ['_static', 'templated.css_t']
html_extra_path = ['robots.txt']
html_last_updated_fmt = '%b %d, %Y'
html_context = {'hckey': 'hcval', 'hckey_co': 'wrong_hcval_co'}

View File

@ -1,2 +0,0 @@
User-agent: *
Disallow: /cgi-bin/

View File

@ -1,9 +0,0 @@
#, fuzzy
msgid ""
msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "Including in subdir"
msgstr "translation"

View File

@ -1,2 +0,0 @@
/* Stub file, templated */
{{ sphinx_version }}

View File

Before

Width:  |  Height:  |  Size: 120 B

After

Width:  |  Height:  |  Size: 120 B

View File

@ -55,14 +55,5 @@ os.makedirs(tempdir)
print('Running Sphinx test suite (with Python %s)...' % sys.version.split()[0])
sys.stdout.flush()
# exclude 'roots' dirs for pytest test collector
ignore_paths = [
os.path.relpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), sub))
for sub in ('roots',)
]
args = sys.argv[1:]
for ignore_path in ignore_paths:
args.extend(['--ignore', ignore_path])
import pytest # NOQA
sys.exit(pytest.main(args))
sys.exit(pytest.main(sys.argv[1:]))

View File

@ -1108,53 +1108,3 @@ class EnumCls(enum.Enum):
val2 = 23 #: doc for val2
val3 = 34
"""doc for val3"""
def test_type_hints():
from sphinx.ext.autodoc import formatargspec
from sphinx.util.inspect import getargspec
try:
from typing_test_data import f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11
except (ImportError, SyntaxError):
pytest.skip('Cannot import Python code with function annotations')
def verify_arg_spec(f, expected):
assert formatargspec(f, *getargspec(f)) == expected
# Class annotations
verify_arg_spec(f0, '(x: int, y: numbers.Integral) -> None')
# Generic types with concrete parameters
verify_arg_spec(f1, '(x: typing.List[int]) -> typing.List[int]')
# TypeVars and generic types with TypeVars
verify_arg_spec(f2, '(x: typing.List[T],'
' y: typing.List[T_co],'
' z: T) -> typing.List[T_contra]')
# Union types
verify_arg_spec(f3, '(x: typing.Union[str, numbers.Integral]) -> None')
# Quoted annotations
verify_arg_spec(f4, '(x: str, y: str) -> None')
# Keyword-only arguments
verify_arg_spec(f5, '(x: int, *, y: str, z: str) -> None')
# Keyword-only arguments with varargs
verify_arg_spec(f6, '(x: int, *args, y: str, z: str) -> None')
# Space around '=' for defaults
verify_arg_spec(f7, '(x: int = None, y: dict = {}) -> None')
# Callable types
verify_arg_spec(f8, '(x: typing.Callable[[int, str], int]) -> None')
verify_arg_spec(f9, '(x: typing.Callable) -> None')
# Tuple types
verify_arg_spec(f10, '(x: typing.Tuple[int, str],'
' y: typing.Tuple[int, ...]) -> None')
# Instance annotations
verify_arg_spec(f11, '(x: CustomAnnotation, y: 123) -> None')

View File

@ -59,13 +59,14 @@ def nonascii_srcdir(request, rootdir, sphinx_test_tempdir):
return srcdir
# note: this test skips building docs for some builders because they have independent testcase.
# (html, latex, texinfo and manpage)
@pytest.mark.parametrize(
"buildername",
[
# note: no 'html' - if it's ok with dirhtml it's ok with html
'dirhtml', 'singlehtml', 'latex', 'texinfo', 'pickle', 'json', 'text',
'htmlhelp', 'qthelp', 'epub', 'applehelp', 'changes', 'xml',
'pseudoxml', 'man', 'linkcheck',
'dirhtml', 'singlehtml', 'pickle', 'json', 'text', 'htmlhelp', 'qthelp',
'epub', 'applehelp', 'changes', 'xml', 'pseudoxml', 'linkcheck',
],
)
@mock.patch('sphinx.builders.linkcheck.requests.head',

View File

@ -126,24 +126,6 @@ def check_xpath(etree, fname, path, check, be_found=True):
[node.text for node in nodes]))
def check_static_entries(outdir):
staticdir = outdir / '_static'
assert staticdir.isdir()
# a file from a directory entry in html_static_path
assert (staticdir / 'README').isfile()
# a directory from a directory entry in html_static_path
assert (staticdir / 'subdir' / 'foo.css').isfile()
# a file from a file entry in html_static_path
assert (staticdir / 'templated.css').isfile()
assert (staticdir / 'templated.css').text().splitlines()[1] == __display_version__
# a file from _static, but matches exclude_patterns
assert not (staticdir / 'excluded.css').exists()
def check_extra_entries(outdir):
assert (outdir / 'robots.txt').isfile()
@pytest.mark.sphinx('html', testroot='warnings')
def test_html_warnings(app, warning):
app.build()
@ -156,15 +138,6 @@ def test_html_warnings(app, warning):
'--- Got:\n' + html_warnings
@pytest.mark.sphinx('html', tags=['testtag'], confoverrides={
'html_context.hckey_co': 'hcval_co'})
@pytest.mark.test_params(shared_result='test_build_html_output')
def test_static_output(app):
app.build()
check_static_entries(app.builder.outdir)
check_extra_entries(app.builder.outdir)
@pytest.mark.parametrize("fname,expect", flat_dict({
'images.html': [
(".//img[@src='_images/img.png']", ''),
@ -377,7 +350,6 @@ def test_static_output(app):
'contents.html': [
(".//meta[@name='hc'][@content='hcval']", ''),
(".//meta[@name='hc_co'][@content='hcval_co']", ''),
(".//meta[@name='testopt'][@content='testoverride']", ''),
(".//td[@class='label']", r'\[Ref1\]'),
(".//td[@class='label']", ''),
(".//li[@class='toctree-l1']/a", 'Testing various markup'),
@ -410,9 +382,6 @@ def test_static_output(app):
(".//a[@href='http://bugs.python.org/issue1000']", "issue 1000"),
(".//a[@href='http://bugs.python.org/issue1042']", "explicit caption"),
],
'_static/statictmpl.html': [
(".//project", 'Sphinx <Tests>'),
],
'genindex.html': [
# index entries
(".//a/strong", "Main"),
@ -1145,16 +1114,28 @@ def test_html_assets(app):
assert not (app.outdir / 'subdir' / '.htpasswd').exists()
@pytest.mark.sphinx('html', confoverrides={'html_sourcelink_suffix': ''})
@pytest.mark.sphinx('html', testroot='basic', confoverrides={'html_copy_source': False})
def test_html_copy_source(app):
app.builder.build_all()
assert not (app.outdir / '_sources' / 'index.rst.txt').exists()
@pytest.mark.sphinx('html', testroot='basic', confoverrides={'html_sourcelink_suffix': '.txt'})
def test_html_sourcelink_suffix(app):
app.builder.build_all()
content_otherext = (app.outdir / 'otherext.html').text()
content_images = (app.outdir / 'images.html').text()
assert (app.outdir / '_sources' / 'index.rst.txt').exists()
assert '<a href="_sources/otherext.foo"' in content_otherext
assert '<a href="_sources/images.txt"' in content_images
assert (app.outdir / '_sources' / 'otherext.foo').exists()
assert (app.outdir / '_sources' / 'images.txt').exists()
@pytest.mark.sphinx('html', testroot='basic', confoverrides={'html_sourcelink_suffix': '.rst'})
def test_html_sourcelink_suffix_same(app):
app.builder.build_all()
assert (app.outdir / '_sources' / 'index.rst').exists()
@pytest.mark.sphinx('html', testroot='basic', confoverrides={'html_sourcelink_suffix': ''})
def test_html_sourcelink_suffix_empty(app):
app.builder.build_all()
assert (app.outdir / '_sources' / 'index.rst').exists()
@pytest.mark.sphinx('html', testroot='html_entity')

View File

@ -251,7 +251,6 @@ def cached_etree_parse():
'contents.html': [
(".//meta[@name='hc'][@content='hcval']", ''),
(".//meta[@name='hc_co'][@content='hcval_co']", ''),
(".//meta[@name='testopt'][@content='testoverride']", ''),
(".//dt[@class='label']/span[@class='brackets']", r'Ref1'),
(".//dt[@class='label']", ''),
(".//li[@class='toctree-l1']/a", 'Testing various markup'),
@ -284,9 +283,6 @@ def cached_etree_parse():
(".//a[@href='http://bugs.python.org/issue1000']", "issue 1000"),
(".//a[@href='http://bugs.python.org/issue1042']", "explicit caption"),
],
'_static/statictmpl.html': [
(".//project", 'Sphinx <Tests>'),
],
'genindex.html': [
# index entries
(".//a/strong", "Main"),

View File

@ -9,11 +9,25 @@
:license: BSD, see LICENSE for details.
"""
import os
import re
import subprocess
import pytest
def has_binary(binary):
try:
subprocess.check_output([binary])
except OSError as e:
if e.errno == os.errno.ENOENT:
# handle file not found error.
return False
else:
return True
return True
@pytest.mark.sphinx(
'html', testroot='ext-math',
confoverrides = {'extensions': ['sphinx.ext.jsmath'], 'jsmath_path': 'dummy.js'})
@ -34,6 +48,8 @@ def test_jsmath(app, status, warning):
assert '<div class="math">\na + 1 &lt; b</div>' in content
@pytest.mark.skipif(not has_binary('dvipng'),
reason='Requires dvipng" binary')
@pytest.mark.sphinx('html', testroot='ext-math-simple',
confoverrides = {'extensions': ['sphinx.ext.imgmath']})
def test_imgmath_png(app, status, warning):
@ -49,6 +65,8 @@ def test_imgmath_png(app, status, warning):
assert re.search(html, content, re.S)
@pytest.mark.skipif(not has_binary('dvisvgm'),
reason='Requires dvisvgm" binary')
@pytest.mark.sphinx('html', testroot='ext-math-simple',
confoverrides={'extensions': ['sphinx.ext.imgmath'],
'imgmath_image_format': 'svg'})

View File

@ -520,7 +520,7 @@ def test_gettext_buildr_ignores_only_directive(app):
@sphinx_intl
# use individual shared_result directory to avoid "incompatible doctree" error
@pytest.mark.test_params(shared_result='test_gettext_dont_rebuild_mo')
@pytest.mark.sphinx(testroot='builder-gettext-dont-rebuild-mo')
def test_gettext_dont_rebuild_mo(make_app, app_params, build_mo):
# --- don't rebuild by .mo mtime
def get_number_of_update_targets(app_):
@ -533,7 +533,7 @@ def test_gettext_dont_rebuild_mo(make_app, app_params, build_mo):
app0 = make_app('dummy', *args, **kwargs)
build_mo(app0.srcdir)
app0.build()
assert (app0.srcdir / 'bom.mo')
assert (app0.srcdir / 'xx' / 'LC_MESSAGES' / 'bom.mo').exists()
# Since it is after the build, the number of documents to be updated is 0
assert get_number_of_update_targets(app0) == 0
# When rewriting the timestamp of mo file, the number of documents to be

View File

@ -17,6 +17,7 @@ from sphinx.theming import ThemeError
@pytest.mark.sphinx(
testroot='theming',
confoverrides={'html_theme': 'ziptheme',
'html_theme_options.testopt': 'foo'})
def test_theme_api(app, status, warning):
@ -25,10 +26,11 @@ def test_theme_api(app, status, warning):
# test Theme class API
assert set(app.html_themes.keys()) == \
set(['basic', 'default', 'scrolls', 'agogo', 'sphinxdoc', 'haiku',
'traditional', 'testtheme', 'ziptheme', 'epub', 'nature',
'pyramid', 'bizstyle', 'classic', 'nonav'])
assert app.html_themes['testtheme'] == app.srcdir / 'testtheme'
'traditional', 'epub', 'nature', 'pyramid', 'bizstyle', 'classic', 'nonav',
'test-theme', 'ziptheme', 'staticfiles', 'parent', 'child'])
assert app.html_themes['test-theme'] == app.srcdir / 'test_theme' / 'test-theme'
assert app.html_themes['ziptheme'] == app.srcdir / 'ziptheme.zip'
assert app.html_themes['staticfiles'] == app.srcdir / 'test_theme' / 'staticfiles'
# test Theme instance API
theme = app.builder.theme
@ -97,6 +99,21 @@ def test_nested_zipped_theme(app, status, warning):
app.build() # => not raises TemplateNotFound
@pytest.mark.sphinx(testroot='theming',
confoverrides={'html_theme': 'staticfiles'})
def test_staticfiles(app, status, warning):
app.build()
assert (app.outdir / '_static' / 'staticimg.png').exists()
assert (app.outdir / '_static' / 'statictmpl.html').exists()
assert (app.outdir / '_static' / 'statictmpl.html').text() == (
'<!-- testing static templates -->\n'
'<html><project>Python</project></html>'
)
result = (app.outdir / 'index.html').text()
assert '<meta name="testopt" content="optdefault" />' in result
@pytest.mark.sphinx(testroot='theming')
def test_theme_sidebars(app, status, warning):
app.build()

71
tox.ini
View File

@ -1,69 +1,56 @@
[tox]
minversion=2.0
envlist=flake8,mypy,py{27,34,35,36},pypy,du{11,12,13,14}
minversion = 2.0
envlist = docs,flake8,mypy,coverage,py{27,34,35,36,py},du{11,12,13,14}
[testenv]
passenv = https_proxy http_proxy no_proxy
passenv =
https_proxy http_proxy no_proxy
description =
py{27,34,35,36,py}: Run unit tests against {envname}.
du{11,12,13,14}: Run unit tests with the given version of docutils.
coverage: Run code coverage checks.
# TODO(stephenfin) Replace this with the 'extras' config option when tox 2.4 is
# widely available, likely some time after the Ubuntu 18.04 release
#
# https://tox.readthedocs.io/en/latest/config.html#confval-extras=MULTI-LINE-LIST
deps =
.[test,websupport]
du11: docutils==0.11
du12: docutils==0.12
du13: docutils==0.13.1
du14: docutils==0.14
setenv =
SPHINX_TEST_TEMPDIR = {envdir}/testbuild
coverage: PYTEST_ADDOPTS = --cov sphinx
commands=
{envpython} -Wall tests/run.py --ignore tests/py35 --cov=sphinx \
--durations 25 {posargs}
sphinx-build -q -W -b html -d {envtmpdir}/doctrees doc {envtmpdir}/html
[testenv:du11]
deps=
docutils==0.11
{[testenv]deps}
[testenv:du12]
deps=
docutils==0.12
{[testenv]deps}
[testenv:du13]
deps=
docutils==0.13.1
{[testenv]deps}
[testenv:du14]
deps=
docutils==0.14
{[testenv]deps}
{envpython} -Wall tests/run.py --durations 25 {posargs}
[testenv:flake8]
deps=flake8
commands=flake8
description =
Run style checks.
commands =
flake8
[testenv:pylint]
deps=
description =
Run source code analyzer.
deps =
pylint
{[testenv]deps}
commands=
commands =
pylint --rcfile utils/pylintrc sphinx
[testenv:py27]
deps=
{[testenv]deps}
[testenv:py35]
commands=
{envpython} -Wall tests/run.py --cov=sphinx --durations 25 {posargs}
sphinx-build -q -W -b html -d {envtmpdir}/doctrees doc {envtmpdir}/html
[testenv:mypy]
basepython=python3
deps=
description =
Run type checks.
deps =
mypy
commands=
mypy sphinx/
[testenv:docs]
commands=
description =
Build documentation.
commands =
python setup.py build_sphinx {posargs}