summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2018-01-08 20:19:36 +0900
committerTakeshi KOMIYA <i.tkomiya@gmail.com>2018-01-08 20:19:36 +0900
commit326d7e64cedb5280a9cf51a90c00266e1dab9e7b (patch)
tree0ce4e7845e09aa822da027fbe6401174458c47d9
parent7a194f52960fe5ace04ef7daa72563e6d3bf094f (diff)
parent3965b1f023bbac932d0dfbf414386f0667ec002a (diff)
downloadsphinx-git-326d7e64cedb5280a9cf51a90c00266e1dab9e7b.tar.gz
Merge branch 'master' into dont_emit_system_message_on_autodoc_warning
-rw-r--r--.appveyor.yml9
-rw-r--r--.circleci/config.yml2
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml64
-rw-r--r--CHANGES31
-rw-r--r--CONTRIBUTING.rst87
-rw-r--r--EXAMPLES5
-rw-r--r--LICENSE2
-rw-r--r--Makefile6
-rw-r--r--README.rst133
-rw-r--r--doc/_templates/index.html6
-rw-r--r--doc/_templates/indexsidebar.html10
-rw-r--r--doc/_themes/sphinx13/layout.html2
-rw-r--r--doc/_themes/sphinx13/static/sphinx13.css32
-rw-r--r--doc/conf.py2
-rw-r--r--doc/config.rst41
-rw-r--r--doc/develop.rst2
-rw-r--r--doc/ext/autodoc.rst8
-rw-r--r--doc/ext/math.rst12
-rw-r--r--doc/ext/thirdparty.rst2
-rw-r--r--doc/extdev/markupapi.rst22
-rw-r--r--doc/faq.rst2
-rw-r--r--doc/intro.rst2
-rw-r--r--doc/man/sphinx-apidoc.rst10
-rw-r--r--doc/markup/inline.rst18
-rw-r--r--setup.cfg34
-rw-r--r--setup.py31
-rw-r--r--sphinx/__init__.py2
-rw-r--r--sphinx/__main__.py2
-rw-r--r--sphinx/addnodes.py2
-rw-r--r--sphinx/apidoc.py2
-rw-r--r--sphinx/application.py84
-rw-r--r--sphinx/builders/__init__.py20
-rw-r--r--sphinx/builders/_epub_base.py2
-rw-r--r--sphinx/builders/applehelp.py2
-rw-r--r--sphinx/builders/changes.py2
-rw-r--r--sphinx/builders/devhelp.py2
-rw-r--r--sphinx/builders/gettext.py2
-rw-r--r--sphinx/builders/html.py2
-rw-r--r--sphinx/builders/htmlhelp.py2
-rw-r--r--sphinx/builders/latex.py2
-rw-r--r--sphinx/builders/linkcheck.py2
-rw-r--r--sphinx/builders/manpage.py2
-rw-r--r--sphinx/builders/qthelp.py2
-rw-r--r--sphinx/builders/texinfo.py2
-rw-r--r--sphinx/builders/text.py2
-rw-r--r--sphinx/builders/websupport.py2
-rw-r--r--sphinx/builders/xml.py2
-rw-r--r--sphinx/cmd/__init__.py2
-rw-r--r--sphinx/cmd/build.py2
-rw-r--r--sphinx/cmd/quickstart.py21
-rw-r--r--sphinx/cmdline.py2
-rw-r--r--sphinx/config.py6
-rw-r--r--sphinx/deprecation.py2
-rw-r--r--sphinx/directives/__init__.py2
-rw-r--r--sphinx/directives/code.py2
-rw-r--r--sphinx/directives/other.py2
-rw-r--r--sphinx/directives/patches.py2
-rw-r--r--sphinx/domains/__init__.py31
-rw-r--r--sphinx/domains/c.py2
-rw-r--r--sphinx/domains/cpp.py373
-rw-r--r--sphinx/domains/javascript.py2
-rw-r--r--sphinx/domains/python.py2
-rw-r--r--sphinx/domains/rst.py2
-rw-r--r--sphinx/domains/std.py18
-rw-r--r--sphinx/environment/__init__.py22
-rw-r--r--sphinx/environment/adapters/__init__.py2
-rw-r--r--sphinx/environment/adapters/asset.py2
-rw-r--r--sphinx/environment/adapters/indexentries.py2
-rw-r--r--sphinx/environment/adapters/toctree.py2
-rw-r--r--sphinx/environment/collectors/__init__.py2
-rw-r--r--sphinx/environment/collectors/asset.py2
-rw-r--r--sphinx/environment/collectors/dependencies.py2
-rw-r--r--sphinx/environment/collectors/indexentries.py2
-rw-r--r--sphinx/environment/collectors/metadata.py2
-rw-r--r--sphinx/environment/collectors/title.py2
-rw-r--r--sphinx/environment/collectors/toctree.py2
-rw-r--r--sphinx/errors.py2
-rw-r--r--sphinx/events.py2
-rw-r--r--sphinx/ext/__init__.py2
-rw-r--r--sphinx/ext/apidoc.py14
-rw-r--r--sphinx/ext/autodoc/__init__.py339
-rw-r--r--sphinx/ext/autodoc/directive.py155
-rw-r--r--sphinx/ext/autodoc/importer.py91
-rw-r--r--sphinx/ext/autodoc/inspector.py2
-rw-r--r--sphinx/ext/autosectionlabel.py2
-rw-r--r--sphinx/ext/autosummary/__init__.py29
-rw-r--r--sphinx/ext/autosummary/generate.py54
-rw-r--r--sphinx/ext/coverage.py2
-rw-r--r--sphinx/ext/doctest.py2
-rw-r--r--sphinx/ext/extlinks.py2
-rw-r--r--sphinx/ext/githubpages.py2
-rw-r--r--sphinx/ext/graphviz.py2
-rw-r--r--sphinx/ext/ifconfig.py2
-rw-r--r--sphinx/ext/imgconverter.py2
-rw-r--r--sphinx/ext/imgmath.py6
-rw-r--r--sphinx/ext/inheritance_diagram.py2
-rw-r--r--sphinx/ext/intersphinx.py3
-rw-r--r--sphinx/ext/jsmath.py6
-rw-r--r--sphinx/ext/linkcode.py2
-rw-r--r--sphinx/ext/mathbase.py39
-rw-r--r--sphinx/ext/mathjax.py6
-rw-r--r--sphinx/ext/napoleon/__init__.py2
-rw-r--r--sphinx/ext/napoleon/docstring.py2
-rw-r--r--sphinx/ext/napoleon/iterators.py2
-rw-r--r--sphinx/ext/pngmath.py6
-rw-r--r--sphinx/ext/todo.py5
-rw-r--r--sphinx/ext/viewcode.py2
-rw-r--r--sphinx/extension.py4
-rw-r--r--sphinx/highlighting.py2
-rw-r--r--sphinx/io.py18
-rw-r--r--sphinx/jinja2glue.py2
-rw-r--r--sphinx/make_mode.py2
-rw-r--r--sphinx/parsers.py2
-rw-r--r--sphinx/pycode/__init__.py2
-rw-r--r--sphinx/pycode/parser.py2
-rw-r--r--sphinx/pygments_styles.py2
-rw-r--r--sphinx/quickstart.py2
-rw-r--r--sphinx/registry.py107
-rw-r--r--sphinx/roles.py2
-rw-r--r--sphinx/search/__init__.py2
-rw-r--r--sphinx/search/en.py2
-rw-r--r--sphinx/search/ja.py2
-rw-r--r--sphinx/search/jssplitter.py2
-rw-r--r--sphinx/search/zh.py2
-rw-r--r--sphinx/setup_command.py2
-rw-r--r--sphinx/templates/epub2/container.xml6
-rw-r--r--sphinx/templates/epub2/content.opf_t37
-rw-r--r--sphinx/templates/epub2/mimetype1
-rw-r--r--sphinx/templates/epub2/toc.ncx_t15
-rw-r--r--sphinx/templates/quickstart/Makefile_t7
-rw-r--r--sphinx/templates/quickstart/make.bat_t9
-rw-r--r--sphinx/testing/__init__.py2
-rw-r--r--sphinx/testing/fixtures.py2
-rw-r--r--sphinx/testing/path.py2
-rw-r--r--sphinx/testing/util.py2
-rw-r--r--sphinx/texinputs/sphinx.sty160
-rw-r--r--sphinx/texinputs/sphinxhowto.cls1
-rw-r--r--sphinx/themes/agogo/layout.html2
-rw-r--r--sphinx/themes/agogo/static/agogo.css_t2
-rw-r--r--sphinx/themes/basic/defindex.html2
-rw-r--r--sphinx/themes/basic/domainindex.html2
-rw-r--r--sphinx/themes/basic/genindex-single.html2
-rw-r--r--sphinx/themes/basic/genindex-split.html2
-rw-r--r--sphinx/themes/basic/genindex.html2
-rw-r--r--sphinx/themes/basic/globaltoc.html2
-rw-r--r--sphinx/themes/basic/layout.html2
-rw-r--r--sphinx/themes/basic/localtoc.html2
-rw-r--r--sphinx/themes/basic/page.html2
-rw-r--r--sphinx/themes/basic/relations.html2
-rw-r--r--sphinx/themes/basic/search.html2
-rw-r--r--sphinx/themes/basic/searchbox.html8
-rw-r--r--sphinx/themes/basic/searchresults.html2
-rw-r--r--sphinx/themes/basic/sourcelink.html2
-rw-r--r--sphinx/themes/basic/static/basic.css_t16
-rw-r--r--sphinx/themes/basic/static/doctools.js_t2
-rw-r--r--sphinx/themes/basic/static/searchtools.js_t2
-rw-r--r--sphinx/themes/basic/static/websupport.js2
-rw-r--r--sphinx/themes/classic/layout.html2
-rw-r--r--sphinx/themes/classic/static/classic.css_t2
-rw-r--r--sphinx/themes/classic/static/sidebar.js_t2
-rw-r--r--sphinx/themes/epub/epub-cover.html2
-rw-r--r--sphinx/themes/epub/layout.html2
-rw-r--r--sphinx/themes/epub/static/epub.css_t2
-rw-r--r--sphinx/themes/haiku/layout.html2
-rw-r--r--sphinx/themes/haiku/static/haiku.css_t2
-rw-r--r--sphinx/themes/nature/static/nature.css_t9
-rw-r--r--sphinx/themes/nonav/layout.html2
-rw-r--r--sphinx/themes/nonav/static/nonav.css2
-rw-r--r--sphinx/themes/pyramid/static/epub.css2
-rw-r--r--sphinx/themes/pyramid/static/pyramid.css_t9
-rw-r--r--sphinx/themes/scrolls/layout.html2
-rw-r--r--sphinx/themes/scrolls/static/scrolls.css_t2
-rw-r--r--sphinx/themes/sphinxdoc/layout.html2
-rw-r--r--sphinx/themes/sphinxdoc/static/sphinxdoc.css_t2
-rw-r--r--sphinx/themes/traditional/static/traditional.css_t2
-rw-r--r--sphinx/theming.py2
-rw-r--r--sphinx/transforms/__init__.py6
-rw-r--r--sphinx/transforms/compact_bullet_list.py2
-rw-r--r--sphinx/transforms/i18n.py2
-rw-r--r--sphinx/transforms/post_transforms/__init__.py2
-rw-r--r--sphinx/transforms/post_transforms/images.py2
-rw-r--r--sphinx/util/__init__.py2
-rw-r--r--sphinx/util/console.py2
-rw-r--r--sphinx/util/docfields.py2
-rw-r--r--sphinx/util/docstrings.py2
-rw-r--r--sphinx/util/docutils.py26
-rw-r--r--sphinx/util/fileutil.py2
-rw-r--r--sphinx/util/i18n.py2
-rw-r--r--sphinx/util/images.py2
-rw-r--r--sphinx/util/inspect.py2
-rw-r--r--sphinx/util/inventory.py2
-rw-r--r--sphinx/util/jsdump.py2
-rw-r--r--sphinx/util/jsonimpl.py2
-rw-r--r--sphinx/util/logging.py4
-rw-r--r--sphinx/util/matching.py2
-rw-r--r--sphinx/util/nodes.py2
-rw-r--r--sphinx/util/osutil.py2
-rw-r--r--sphinx/util/parallel.py2
-rw-r--r--sphinx/util/png.py2
-rw-r--r--sphinx/util/pycompat.py2
-rw-r--r--sphinx/util/requests.py2
-rw-r--r--sphinx/util/rst.py2
-rw-r--r--sphinx/util/stemmer/__init__.py2
-rw-r--r--sphinx/util/tags.py2
-rw-r--r--sphinx/util/template.py2
-rw-r--r--sphinx/util/texescape.py2
-rw-r--r--sphinx/util/typing.py2
-rw-r--r--sphinx/util/websupport.py2
-rw-r--r--sphinx/versioning.py2
-rw-r--r--sphinx/websupport/__init__.py2
-rw-r--r--sphinx/websupport/errors.py2
-rw-r--r--sphinx/websupport/search/__init__.py2
-rw-r--r--sphinx/websupport/search/nullsearch.py2
-rw-r--r--sphinx/websupport/search/whooshsearch.py2
-rw-r--r--sphinx/websupport/search/xapiansearch.py2
-rw-r--r--sphinx/websupport/storage/__init__.py2
-rw-r--r--sphinx/websupport/storage/differ.py2
-rw-r--r--sphinx/websupport/storage/sqlalchemy_db.py2
-rw-r--r--sphinx/websupport/storage/sqlalchemystorage.py2
-rw-r--r--sphinx/writers/__init__.py2
-rw-r--r--sphinx/writers/html.py2
-rw-r--r--sphinx/writers/html5.py2
-rw-r--r--sphinx/writers/latex.py112
-rw-r--r--sphinx/writers/manpage.py2
-rw-r--r--sphinx/writers/texinfo.py2
-rw-r--r--sphinx/writers/text.py2
-rw-r--r--sphinx/writers/websupport.py2
-rw-r--r--sphinx/writers/xml.py2
-rw-r--r--tests/conftest.py35
-rw-r--r--tests/py35/test_autodoc_py35.py10
-rw-r--r--tests/roots/test-apidoc-toc/mypackage/__init__.py0
-rwxr-xr-xtests/roots/test-apidoc-toc/mypackage/main.py16
-rw-r--r--tests/roots/test-apidoc-toc/mypackage/no_init/foo.py1
-rw-r--r--tests/roots/test-apidoc-toc/mypackage/resource/__init__.py0
-rw-r--r--tests/roots/test-apidoc-toc/mypackage/resource/resource.txt1
-rw-r--r--tests/roots/test-apidoc-toc/mypackage/something/__init__.py1
-rw-r--r--tests/roots/test-domain-cpp/index.rst6
-rw-r--r--tests/roots/test-ext-autodoc/target/__init__.py225
-rw-r--r--tests/roots/test-ext-math/index.rst2
-rw-r--r--tests/roots/test-ext-math/page.rst9
-rw-r--r--tests/roots/test-ext-todo/index.rst2
-rw-r--r--tests/roots/test-extensions/conf.py4
-rw-r--r--tests/roots/test-extensions/read_parallel.py4
-rw-r--r--tests/roots/test-extensions/read_serial.py4
-rw-r--r--tests/roots/test-extensions/write_parallel.py4
-rw-r--r--tests/roots/test-extensions/write_serial.py4
-rw-r--r--tests/roots/test-latex-numfig/conf.py12
-rw-r--r--tests/roots/test-latex-numfig/index.rst9
-rw-r--r--tests/roots/test-latex-numfig/indexhowto.rst10
-rw-r--r--tests/roots/test-latex-numfig/indexmanual.rst13
-rw-r--r--tests/roots/test-root/autodoc.txt4
-rw-r--r--tests/roots/test-root/autodoc_target.py225
-rwxr-xr-xtests/run.py68
-rw-r--r--tests/test_api_translator.py2
-rw-r--r--tests/test_application.py38
-rw-r--r--tests/test_autodoc.py431
-rw-r--r--tests/test_build.py6
-rw-r--r--tests/test_build_applehelp.py2
-rw-r--r--tests/test_build_epub.py2
-rw-r--r--tests/test_build_gettext.py2
-rw-r--r--tests/test_build_html.py7
-rw-r--r--tests/test_build_html5.py6
-rw-r--r--tests/test_build_latex.py99
-rw-r--r--tests/test_build_linkcheck.py2
-rw-r--r--tests/test_build_manpage.py2
-rw-r--r--tests/test_build_qthelp.py2
-rw-r--r--tests/test_build_texinfo.py2
-rw-r--r--tests/test_build_text.py2
-rw-r--r--tests/test_catalogs.py2
-rw-r--r--tests/test_config.py2
-rw-r--r--tests/test_correct_year.py2
-rw-r--r--tests/test_directive_code.py2
-rw-r--r--tests/test_directive_only.py2
-rw-r--r--tests/test_docutilsconf.py4
-rw-r--r--tests/test_domain_cpp.py451
-rw-r--r--tests/test_domain_js.py2
-rw-r--r--tests/test_domain_py.py2
-rw-r--r--tests/test_domain_rst.py2
-rw-r--r--tests/test_domain_std.py2
-rw-r--r--tests/test_environment.py4
-rw-r--r--tests/test_environment_indexentries.py2
-rw-r--r--tests/test_environment_toctree.py2
-rw-r--r--tests/test_ext_apidoc.py79
-rw-r--r--tests/test_ext_autodoc.py2
-rw-r--r--tests/test_ext_autosectionlabel.py2
-rw-r--r--tests/test_ext_autosummary.py19
-rw-r--r--tests/test_ext_coverage.py18
-rw-r--r--tests/test_ext_doctest.py2
-rw-r--r--tests/test_ext_githubpages.py2
-rw-r--r--tests/test_ext_graphviz.py4
-rw-r--r--tests/test_ext_ifconfig.py2
-rw-r--r--tests/test_ext_imgconverter.py2
-rw-r--r--tests/test_ext_inheritance_diagram.py2
-rw-r--r--tests/test_ext_intersphinx.py11
-rw-r--r--tests/test_ext_math.py69
-rw-r--r--tests/test_ext_napoleon.py2
-rw-r--r--tests/test_ext_napoleon_docstring.py2
-rw-r--r--tests/test_ext_napoleon_iterators.py2
-rw-r--r--tests/test_ext_todo.py14
-rw-r--r--tests/test_ext_viewcode.py2
-rw-r--r--tests/test_highlighting.py2
-rw-r--r--tests/test_intl.py3
-rw-r--r--tests/test_io.py2
-rw-r--r--tests/test_markup.py14
-rw-r--r--tests/test_metadata.py2
-rw-r--r--tests/test_pycode.py3
-rw-r--r--tests/test_quickstart.py3
-rw-r--r--tests/test_search.py2
-rw-r--r--tests/test_setup_command.py2
-rw-r--r--tests/test_templating.py13
-rw-r--r--tests/test_theming.py2
-rw-r--r--tests/test_toctree.py2
-rw-r--r--tests/test_util.py3
-rw-r--r--tests/test_util_fileutil.py2
-rw-r--r--tests/test_util_i18n.py2
-rw-r--r--tests/test_util_images.py18
-rw-r--r--tests/test_util_inspect.py3
-rw-r--r--tests/test_util_logging.py8
-rw-r--r--tests/test_util_matching.py2
-rw-r--r--tests/test_util_nodes.py2
-rw-r--r--tests/test_util_rst.py2
-rw-r--r--tests/test_versioning.py4
-rw-r--r--tests/test_websupport.py2
-rw-r--r--tests/test_writer_latex.py2
-rw-r--r--tox.ini78
-rw-r--r--utils/checks.py2
-rw-r--r--utils/jssplitter_generator.py2
328 files changed, 3048 insertions, 1908 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index a3f83394f..600a51419 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -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 }
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 1bbcb4884..f4d4415f1 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -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
diff --git a/.gitignore b/.gitignore
index f1dc3167c..5d1026c5e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@ TAGS
.tox
.venv
.coverage
+htmlcov
.DS_Store
sphinx/pycode/Grammar*pickle
distribute-*
diff --git a/.travis.yml b/.travis.yml
index 1d065b178..e51523c19 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -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
diff --git a/CHANGES b/CHANGES
index cb43a26ae..3de25c0ee 100644
--- a/CHANGES
+++ b/CHANGES
@@ -13,6 +13,7 @@ Incompatible changes
* #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.
@@ -23,6 +24,12 @@ Deprecated
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
--------------
@@ -51,7 +58,13 @@ Features added
* 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
Features removed
----------------
@@ -92,6 +105,14 @@ Bugs fixed
* #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
Testing
--------
@@ -117,10 +138,12 @@ Features added
* ``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)
Bugs fixed
----------
+* #4334: sphinx-apidoc: Don't generate references to non-existing files in TOC
* #4206: latex: reST label between paragraphs loses paragraph break
* #4231: html: Apply fixFirefoxAnchorBug only under Firefox
* #4221: napoleon depends on autodoc, but users need to load it manually
@@ -133,6 +156,12 @@ 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
+* #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:
Testing
--------
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 7c8a90c6b..03d26c001 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -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.
+
+ Testing is best done through ``tox``, which provides a number of targets and
+ allows testing against multiple different Python environments:
+
+ * To list all possible targets::
+
+ tox -av
- * Run the unit tests::
+ * To run unit tests for a specific Python version, such as 3.6::
- pip install .[test,websupport]
- make test
+ tox -e py36
- * Again, it's useful to turn on deprecation warnings on so they're shown in
- the test output::
+ * 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 make test
+ PYTHONWARNINGS=all tox -e py36
- * Arguments to pytest can be passed via tox, e.g. in order to run a
+ * 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:
diff --git a/EXAMPLES b/EXAMPLES
index 0b2de95d9..edbf48903 100644
--- a/EXAMPLES
+++ b/EXAMPLES
@@ -93,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/
@@ -141,6 +141,7 @@ Documentation using the nature theme
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)
@@ -258,7 +259,7 @@ 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/
diff --git a/LICENSE b/LICENSE
index a2783ab3f..19f1090fd 100644
--- a/LICENSE
+++ b/LICENSE
@@ -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
diff --git a/Makefile b/Makefile
index 5b3d5aad4..67699363f 100644
--- a/Makefile
+++ b/Makefile
@@ -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:
diff --git a/README.rst b/README.rst
index 1e027ec8e..2d841f78e 100644
--- a/README.rst
+++ b/README.rst
@@ -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)
+
+.. 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)
+
+.. 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)
+
+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
+
+For more information, refer to the `the documentation`__.
+
+.. __: http://www.sphinx-doc.org/
+
+Installation
+============
-=================
-README for Sphinx
-=================
-
-This is the Sphinx documentation generator, see http://www.sphinx-doc.org/.
+Sphinx is published on `PyPI`__ and can be installed from there::
+ pip install -U sphinx
-Installing
-==========
+We also publish beta releases::
-Install from PyPI to use stable version::
+ pip install -U --pre sphinx
- pip install -U sphinx
+If you wish to install `Sphinx` for development purposes, refer to `the
+contributors guide`__.
-Install from PyPI to use beta version::
+__ https://pypi.python.org/pypi/Sphinx
+__ CONTRIBUTING.rst
- pip install -U --pre sphinx
+Documentation
+=============
-Install from newest dev version in stable branch::
+Documentation is available from `sphinx-doc.org`__.
- pip install git+https://github.com/sphinx-doc/sphinx@stable
+__ http://www.sphinx-doc.org/
-Install from newest dev version in master branch::
+Testing
+=======
- pip install git+https://github.com/sphinx-doc/sphinx
+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).
-Install from cloned source::
+For information on running tests locally, refer to `the contributors guide`__.
- pip install .
+__ https://travis-ci.org/sphinx-doc/sphinx
+__ https://ci.appveyor.com/project/sphinxdoc/sphinx
+__ https://circleci.com/gh/sphinx-doc/sphinx
+__ CONTRIBUTING.rst
-Install from cloned source as editable::
+Contributing
+============
- pip install -e .
+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
-
diff --git a/doc/_templates/index.html b/doc/_templates/index.html
index b4bdb5985..5a8a2f025 100644
--- a/doc/_templates/index.html
+++ b/doc/_templates/index.html
@@ -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>
diff --git a/doc/_templates/indexsidebar.html b/doc/_templates/indexsidebar.html
index 6359921a5..b07ef2033 100644
--- a/doc/_templates/indexsidebar.html
+++ b/doc/_templates/indexsidebar.html
@@ -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"
- onfocus="$(this).val('');"/>
- <input type="submit" name="sub" value="Subscribe" style="font-size: 90%; width: 70px"/>
+ class="subscribeform">
+ <input type="text" name="email" value="your@email"
+ onfocus="$(this).val('');" />
+ <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>
diff --git a/doc/_themes/sphinx13/layout.html b/doc/_themes/sphinx13/layout.html
index 911d1287c..ce6f08daa 100644
--- a/doc/_themes/sphinx13/layout.html
+++ b/doc/_themes/sphinx13/layout.html
@@ -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" %}
diff --git a/doc/_themes/sphinx13/static/sphinx13.css b/doc/_themes/sphinx13/static/sphinx13.css
index d15fbaea4..24a33fba7 100644
--- a/doc/_themes/sphinx13/static/sphinx13.css
+++ b/doc/_themes/sphinx13/static/sphinx13.css
@@ -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 {
diff --git a/doc/conf.py b/doc/conf.py
index db2846186..fa82cbfb7 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -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
diff --git a/doc/config.rst b/doc/config.rst
index 415a2298a..1ef455803 100644
--- a/doc/config.rst
+++ b/doc/config.rst
@@ -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,13 +337,23 @@ 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:: tls_verify
If true, Sphinx verifies server certifications. Default is ``True``.
@@ -1450,10 +1458,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 +1619,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
diff --git a/doc/develop.rst b/doc/develop.rst
index 4fc7792f7..19ca81ef9 100644
--- a/doc/develop.rst
+++ b/doc/develop.rst
@@ -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
diff --git a/doc/ext/autodoc.rst b/doc/ext/autodoc.rst
index bfd55c81a..09098f39c 100644
--- a/doc/ext/autodoc.rst
+++ b/doc/ext/autodoc.rst
@@ -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.
diff --git a/doc/ext/math.rst b/doc/ext/math.rst
index 2aad7853f..4097bb29e 100644
--- a/doc/ext/math.rst
+++ b/doc/ext/math.rst
@@ -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
@@ -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
diff --git a/doc/ext/thirdparty.rst b/doc/ext/thirdparty.rst
index 6304e4af3..40c24246a 100644
--- a/doc/ext/thirdparty.rst
+++ b/doc/ext/thirdparty.rst
@@ -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
diff --git a/doc/extdev/markupapi.rst b/doc/extdev/markupapi.rst
index df23f164d..ffa08cae7 100644
--- a/doc/extdev/markupapi.rst
+++ b/doc/extdev/markupapi.rst
@@ -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.
diff --git a/doc/faq.rst b/doc/faq.rst
index 1ae9a7792..fe3173749 100644
--- a/doc/faq.rst
+++ b/doc/faq.rst
@@ -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
diff --git a/doc/intro.rst b/doc/intro.rst
index d3328a5ea..d3b191700 100644
--- a/doc/intro.rst
+++ b/doc/intro.rst
@@ -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
diff --git a/doc/man/sphinx-apidoc.rst b/doc/man/sphinx-apidoc.rst
index 803466040..9a13f1401 100644
--- a/doc/man/sphinx-apidoc.rst
+++ b/doc/man/sphinx-apidoc.rst
@@ -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
--------
diff --git a/doc/markup/inline.rst b/doc/markup/inline.rst
index 32360baf7..4d14a653d 100644
--- a/doc/markup/inline.rst
+++ b/doc/markup/inline.rst
@@ -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
-----------------------------------------
diff --git a/setup.cfg b/setup.cfg
index cb6887fc3..c19d0d518 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -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
diff --git a/setup.py b/setup.py
index 10a513166..6b7de9129 100644
--- a/setup.py
+++ b/setup.py
@@ -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',
diff --git a/sphinx/__init__.py b/sphinx/__init__.py
index 68844b8a7..c84e2672f 100644
--- a/sphinx/__init__.py
+++ b/sphinx/__init__.py
@@ -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.
"""
diff --git a/sphinx/__main__.py b/sphinx/__main__.py
index 0022d1b0b..fbac1c4f7 100644
--- a/sphinx/__main__.py
+++ b/sphinx/__main__.py
@@ -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
diff --git a/sphinx/addnodes.py b/sphinx/addnodes.py
index 762dc9bbb..e6999bd16 100644
--- a/sphinx/addnodes.py
+++ b/sphinx/addnodes.py
@@ -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.
"""
diff --git a/sphinx/apidoc.py b/sphinx/apidoc.py
index 0a924b31d..4e20fb7e4 100644
--- a/sphinx/apidoc.py
+++ b/sphinx/apidoc.py
@@ -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.
"""
diff --git a/sphinx/application.py b/sphinx/application.py
index 05d302c81..e76f101a3 100644
--- a/sphinx/application.py
+++ b/sphinx/application.py
@@ -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',
@@ -120,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
@@ -157,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,
@@ -197,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']
@@ -444,7 +444,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=()):
@@ -464,7 +463,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):
@@ -553,39 +551,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)
@@ -602,21 +591,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
@@ -658,15 +642,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
@@ -677,7 +660,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):
@@ -690,6 +672,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):
"""
diff --git a/sphinx/builders/__init__.py b/sphinx/builders/__init__.py
index 496028268..a1e360d2f 100644
--- a/sphinx/builders/__init__.py
+++ b/sphinx/builders/__init__.py
@@ -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, \
@@ -79,8 +77,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 +370,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 = False
- break
+ self.parallel_ok = self.app.is_parallel_allowed('write')
+ else:
+ self.parallel_ok = False
# create a task executor to use for misc. "finish-up" tasks
# if self.parallel_ok:
diff --git a/sphinx/builders/_epub_base.py b/sphinx/builders/_epub_base.py
index a2530b1b1..f4cb8afa0 100644
--- a/sphinx/builders/_epub_base.py
+++ b/sphinx/builders/_epub_base.py
@@ -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.
"""
diff --git a/sphinx/builders/applehelp.py b/sphinx/builders/applehelp.py
index f8df9310c..52ba2ce5c 100644
--- a/sphinx/builders/applehelp.py
+++ b/sphinx/builders/applehelp.py
@@ -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
diff --git a/sphinx/builders/changes.py b/sphinx/builders/changes.py
index a73125e30..5309649c6 100644
--- a/sphinx/builders/changes.py
+++ b/sphinx/builders/changes.py
@@ -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.
"""
diff --git a/sphinx/builders/devhelp.py b/sphinx/builders/devhelp.py
index 9dbbf3c17..88a9be219 100644
--- a/sphinx/builders/devhelp.py
+++ b/sphinx/builders/devhelp.py
@@ -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
diff --git a/sphinx/builders/gettext.py b/sphinx/builders/gettext.py
index b684104c1..464d574cc 100644
--- a/sphinx/builders/gettext.py
+++ b/sphinx/builders/gettext.py
@@ -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.
"""
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index 1c51f07fa..f9c9420c2 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -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.
"""
diff --git a/sphinx/builders/htmlhelp.py b/sphinx/builders/htmlhelp.py
index c2e3bbe2c..0b45601e3 100644
--- a/sphinx/builders/htmlhelp.py
+++ b/sphinx/builders/htmlhelp.py
@@ -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
diff --git a/sphinx/builders/latex.py b/sphinx/builders/latex.py
index 8b987e658..8fdb2fa49 100644
--- a/sphinx/builders/latex.py
+++ b/sphinx/builders/latex.py
@@ -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.
"""
diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py
index c52b808cd..ca62b9fe1 100644
--- a/sphinx/builders/linkcheck.py
+++ b/sphinx/builders/linkcheck.py
@@ -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.
"""
diff --git a/sphinx/builders/manpage.py b/sphinx/builders/manpage.py
index 83e354601..b57a756ee 100644
--- a/sphinx/builders/manpage.py
+++ b/sphinx/builders/manpage.py
@@ -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.
"""
diff --git a/sphinx/builders/qthelp.py b/sphinx/builders/qthelp.py
index 9bcfe9811..2f56792a9 100644
--- a/sphinx/builders/qthelp.py
+++ b/sphinx/builders/qthelp.py
@@ -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.
"""
diff --git a/sphinx/builders/texinfo.py b/sphinx/builders/texinfo.py
index 3e6816507..82c6f1b9d 100644
--- a/sphinx/builders/texinfo.py
+++ b/sphinx/builders/texinfo.py
@@ -5,7 +5,7 @@
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.
"""
diff --git a/sphinx/builders/text.py b/sphinx/builders/text.py
index 29ceaa855..7b977b1b9 100644
--- a/sphinx/builders/text.py
+++ b/sphinx/builders/text.py
@@ -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.
"""
diff --git a/sphinx/builders/websupport.py b/sphinx/builders/websupport.py
index 2e416b287..1fe9e2001 100644
--- a/sphinx/builders/websupport.py
+++ b/sphinx/builders/websupport.py
@@ -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.
"""
diff --git a/sphinx/builders/xml.py b/sphinx/builders/xml.py
index d4ebb47ef..599530ac1 100644
--- a/sphinx/builders/xml.py
+++ b/sphinx/builders/xml.py
@@ -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.
"""
diff --git a/sphinx/cmd/__init__.py b/sphinx/cmd/__init__.py
index 9ffb9e612..a559306d6 100644
--- a/sphinx/cmd/__init__.py
+++ b/sphinx/cmd/__init__.py
@@ -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.
"""
diff --git a/sphinx/cmd/build.py b/sphinx/cmd/build.py
index 6c9d6e3e9..c0c31ae67 100644
--- a/sphinx/cmd/build.py
+++ b/sphinx/cmd/build.py
@@ -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.
"""
diff --git a/sphinx/cmd/quickstart.py b/sphinx/cmd/quickstart.py
index 80e9e3dd4..fd9b15649 100644
--- a/sphinx/cmd/quickstart.py
+++ b/sphinx/cmd/quickstart.py
@@ -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
@@ -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
diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py
index f18bbb286..779ba142d 100644
--- a/sphinx/cmdline.py
+++ b/sphinx/cmdline.py
@@ -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
diff --git a/sphinx/config.py b/sphinx/config.py
index 509af31e6..55b73a7cc 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -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}, " \
@@ -155,6 +157,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
diff --git a/sphinx/deprecation.py b/sphinx/deprecation.py
index bb63df330..e28e0f916 100644
--- a/sphinx/deprecation.py
+++ b/sphinx/deprecation.py
@@ -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.
"""
diff --git a/sphinx/directives/__init__.py b/sphinx/directives/__init__.py
index dc0cc4f6c..dc51810d3 100644
--- a/sphinx/directives/__init__.py
+++ b/sphinx/directives/__init__.py
@@ -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.
"""
diff --git a/sphinx/directives/code.py b/sphinx/directives/code.py
index 4d7e7a48d..b951e704d 100644
--- a/sphinx/directives/code.py
+++ b/sphinx/directives/code.py
@@ -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.
"""
diff --git a/sphinx/directives/other.py b/sphinx/directives/other.py
index 626218ca2..4ce709a63 100644
--- a/sphinx/directives/other.py
+++ b/sphinx/directives/other.py
@@ -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.
"""
diff --git a/sphinx/directives/patches.py b/sphinx/directives/patches.py
index 880377ff7..c97340a81 100644
--- a/sphinx/directives/patches.py
+++ b/sphinx/directives/patches.py
@@ -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.
"""
diff --git a/sphinx/domains/__init__.py b/sphinx/domains/__init__.py
index 6edc3cdb0..c68d37472 100644
--- a/sphinx/domains/__init__.py
+++ b/sphinx/domains/__init__.py
@@ -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
diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py
index b9afd10c2..3030cff8a 100644
--- a/sphinx/domains/c.py
+++ b/sphinx/domains/c.py
@@ -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.
"""
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index 0ed987384..39955d4f4 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -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.
"""
@@ -1285,7 +1285,7 @@ class ASTTemplateParamType(ASTBase):
def name(self):
# type: () -> ASTNestedName
id = self.get_identifier()
- return ASTNestedName([ASTNestedNameElement(id, None)], rooted=False)
+ return ASTNestedName([ASTNestedNameElement(id, None)], [False], rooted=False)
@property
def isPack(self):
@@ -1314,6 +1314,44 @@ class ASTTemplateParamType(ASTBase):
self.data.describe_signature(signode, mode, env, symbol)
+class ASTTemplateParamConstrainedTypeWithInit(ASTBase):
+ def __init__(self, type, init):
+ # type: (Any, Any) -> None
+ assert type
+ self.type = type
+ self.init = init
+
+ @property
+ def name(self):
+ # type: () -> ASTNestedName
+ return self.type.name
+
+ def get_id(self, version, objectType=None, symbol=None):
+ # type: (int, unicode, Symbol) -> unicode
+ # this is not part of the normal name mangling in C++
+ assert version >= 2
+ if symbol:
+ # the anchor will be our parent
+ return symbol.parent.declaration.get_id(version, prefixed=False)
+ else:
+ return self.type.get_id(version)
+
+ def __unicode__(self):
+ # type: () -> unicode
+ res = text_type(self.type)
+ if self.init:
+ res += " = "
+ res += text_type(self.init)
+ return res
+
+ def describe_signature(self, signode, mode, env, symbol):
+ # type: (addnodes.desc_signature, unicode, BuildEnvironment, Symbol) -> None
+ self.type.describe_signature(signode, mode, env, symbol)
+ if self.init:
+ signode += nodes.Text(" = ")
+ self.init.describe_signature(signode, mode, env, symbol)
+
+
class ASTTemplateParamTemplateType(ASTBase):
def __init__(self, nestedParams, data):
# type: (Any, Any) -> None
@@ -1326,7 +1364,7 @@ class ASTTemplateParamTemplateType(ASTBase):
def name(self):
# type: () -> ASTNestedName
id = self.get_identifier()
- return ASTNestedName([ASTNestedNameElement(id, None)], rooted=False)
+ return ASTNestedName([ASTNestedNameElement(id, None)], [False], rooted=False)
def get_identifier(self):
# type: () -> unicode
@@ -1363,16 +1401,16 @@ class ASTTemplateParamNonType(ASTBase):
def name(self):
# type: () -> ASTNestedName
id = self.get_identifier()
- return ASTNestedName([ASTNestedNameElement(id, None)], rooted=False)
+ return ASTNestedName([ASTNestedNameElement(id, None)], [False], rooted=False)
def get_identifier(self):
# type: () -> unicode
name = self.param.name
if name:
assert len(name.names) == 1
- assert name.names[0].identifier
+ assert name.names[0].identOrOp
assert not name.names[0].templateArgs
- return name.names[0].identifier
+ return name.names[0].identOrOp
else:
return None
@@ -1456,7 +1494,7 @@ class ASTTemplateIntroductionParameter(ASTBase):
def name(self):
# type: () -> ASTNestedName
id = self.get_identifier()
- return ASTNestedName([ASTNestedNameElement(id, None)], rooted=False)
+ return ASTNestedName([ASTNestedNameElement(id, None)], [False], rooted=False)
@property
def isPack(self):
@@ -1612,8 +1650,8 @@ class ASTOperatorBuildIn(ASTBase):
else:
return u'operator' + self.op
- def describe_signature(self, signode, mode, env, prefix, symbol):
- # type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None
+ def describe_signature(self, signode, mode, env, prefix, templateArgs, symbol):
+ # type: (addnodes.desc_signature, unicode, Any, unicode, unicode, Symbol) -> None
_verify_description_mode(mode)
identifier = text_type(self)
if mode == 'lastIsName':
@@ -1646,8 +1684,8 @@ class ASTOperatorType(ASTBase):
# type: () -> unicode
return text_type(self)
- def describe_signature(self, signode, mode, env, prefix, symbol):
- # type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None
+ def describe_signature(self, signode, mode, env, prefix, templateArgs, symbol):
+ # type: (addnodes.desc_signature, unicode, Any, unicode, unicode, Symbol) -> None
_verify_description_mode(mode)
identifier = text_type(self)
if mode == 'lastIsName':
@@ -1676,8 +1714,8 @@ class ASTOperatorLiteral(ASTBase):
# type: () -> unicode
return u'operator""' + text_type(self.identifier)
- def describe_signature(self, signode, mode, env, prefix, symbol):
- # type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None
+ def describe_signature(self, signode, mode, env, prefix, templateArgs, symbol):
+ # type: (addnodes.desc_signature, unicode, Any, unicode, unicode, Symbol) -> None
_verify_description_mode(mode)
identifier = text_type(self)
if mode == 'lastIsName':
@@ -1750,9 +1788,9 @@ class ASTTemplateArgs(ASTBase):
class ASTNestedNameElement(ASTBase):
- def __init__(self, identifier, templateArgs):
+ def __init__(self, identOrOp, templateArgs):
# type: (Any, Any) -> None
- self.identifier = identifier
+ self.identOrOp = identOrOp
self.templateArgs = templateArgs
def is_operator(self):
@@ -1761,14 +1799,14 @@ class ASTNestedNameElement(ASTBase):
def get_id(self, version):
# type: (int) -> unicode
- res = self.identifier.get_id(version)
+ res = self.identOrOp.get_id(version)
if self.templateArgs:
res += self.templateArgs.get_id(version)
return res
def __unicode__(self):
# type: () -> unicode
- res = text_type(self.identifier)
+ res = text_type(self.identOrOp)
if self.templateArgs:
res += text_type(self.templateArgs)
return res
@@ -1776,16 +1814,18 @@ class ASTNestedNameElement(ASTBase):
def describe_signature(self, signode, mode, env, prefix, symbol):
# type: (addnodes.desc_signature, unicode, BuildEnvironment, unicode, Symbol) -> None
tArgs = text_type(self.templateArgs) if self.templateArgs is not None else ''
- self.identifier.describe_signature(signode, mode, env, prefix, tArgs, symbol)
+ self.identOrOp.describe_signature(signode, mode, env, prefix, tArgs, symbol)
if self.templateArgs is not None:
self.templateArgs.describe_signature(signode, mode, env, symbol)
class ASTNestedName(ASTBase):
- def __init__(self, names, rooted):
- # type: (List[Any], bool) -> None
+ def __init__(self, names, templates, rooted):
+ # type: (List[Any], List[bool], bool) -> None
assert len(names) > 0
self.names = names
+ self.templates = templates
+ assert len(self.names) == len(self.templates)
self.rooted = rooted
@property
@@ -1826,8 +1866,13 @@ class ASTNestedName(ASTBase):
res = [] # type: List[unicode]
if self.rooted:
res.append('')
- for n in self.names:
- res.append(text_type(n))
+ for i in range(len(self.names)):
+ n = self.names[i]
+ t = self.templates[i]
+ if t:
+ res.append("template " + text_type(n))
+ else:
+ res.append(text_type(n))
return '::'.join(res)
def describe_signature(self, signode, mode, env, symbol):
@@ -1854,10 +1899,14 @@ class ASTNestedName(ASTBase):
prefix = '' # type: unicode
first = True
names = self.names[:-1] if mode == 'lastIsName' else self.names
- for name in names:
+ for i in range(len(names)):
+ name = names[i]
+ template = self.templates[i]
if not first:
signode += nodes.Text('::')
prefix += '::'
+ if template:
+ signode += nodes.Text("template ")
first = False
if name != '':
if (name.templateArgs and # type: ignore
@@ -1870,6 +1919,8 @@ class ASTNestedName(ASTBase):
if mode == 'lastIsName':
if len(self.names) > 1:
signode += addnodes.desc_addname('::', '::')
+ if self.templates[-1]:
+ signode += nodes.Text("template ")
self.names[-1].describe_signature(signode, mode, env, '', symbol)
else:
raise Exception('Unknown description mode: %s' % mode)
@@ -3259,23 +3310,20 @@ class Symbol(object):
# type: () -> None
if not self.parent:
# parent == None means global scope, so declaration means a parent
- assert not self.identifier
+ assert not self.identOrOp
assert not self.templateParams
assert not self.templateArgs
assert not self.declaration
assert not self.docname
else:
- if not self.identifier:
- # in case it's an operator
- assert self.declaration
if self.declaration:
assert self.docname
- def __init__(self, parent, identifier,
+ def __init__(self, parent, identOrOp,
templateParams, templateArgs, declaration, docname):
# type: (Any, Any, Any, Any, Any, unicode) -> None
self.parent = parent
- self.identifier = identifier
+ self.identOrOp = identOrOp
self.templateParams = templateParams # template<templateParams>
self.templateArgs = templateArgs # identifier<templateArgs>
self.declaration = declaration
@@ -3300,7 +3348,7 @@ class Symbol(object):
else:
decl = None
nne = ASTNestedNameElement(p.get_identifier(), None)
- nn = ASTNestedName([nne], rooted=False)
+ nn = ASTNestedName([nne], [False], rooted=False)
self._add_symbols(nn, [], decl, docname)
# add symbols for function parameters, if any
if declaration is not None and declaration.function_params is not None:
@@ -3314,8 +3362,8 @@ class Symbol(object):
decl = ASTDeclaration('functionParam', None, None, p)
assert not nn.rooted
assert len(nn.names) == 1
- identifier = nn.names[0].identifier
- Symbol(parent=self, identifier=identifier,
+ identOrOp = nn.names[0].identOrOp
+ Symbol(parent=self, identOrOp=identOrOp,
templateParams=None, templateArgs=None,
declaration=decl, docname=docname)
@@ -3339,12 +3387,7 @@ class Symbol(object):
if sChild.declaration and sChild.docname == docname:
sChild.declaration = None
sChild.docname = None
- # Just remove operators, because there is no identification if
- # they got removed.
- # Don't remove other symbols because they may be used in namespace
- # directives.
- if sChild.identifier or sChild.declaration:
- newChildren.append(sChild)
+ newChildren.append(sChild)
self.children = newChildren
def get_all_symbols(self):
@@ -3364,26 +3407,22 @@ class Symbol(object):
symbols.reverse()
key = []
for s in symbols:
- if s.identifier:
- nne = ASTNestedNameElement(s.identifier, s.templateArgs)
- else:
- assert s.declaration
- nne = s.declaration.name.names[-1]
+ nne = ASTNestedNameElement(s.identOrOp, s.templateArgs)
key.append((nne, s.templateParams))
return key
def get_full_nested_name(self):
# type: () -> ASTNestedName
names = []
+ templates = []
for nne, templateParams in self.get_lookup_key():
names.append(nne)
- return ASTNestedName(names, rooted=False)
+ templates.append(False)
+ return ASTNestedName(names, templates, rooted=False)
- def _find_named_symbol(self, identifier, templateParams,
- templateArgs, operator,
+ def _find_named_symbol(self, identOrOp, templateParams, templateArgs,
templateShorthand, matchSelf):
- # type: (Any, Any, Any, Any, Any, bool) -> Symbol
- assert (identifier is None) != (operator is None)
+ # type: (Any, Any, Any, Any, bool) -> Symbol
def isSpecialization():
# the names of the template parameters must be given exactly as args
@@ -3411,17 +3450,8 @@ class Symbol(object):
templateArgs = None
def matches(s):
- if s.identifier != identifier:
+ if s.identOrOp != identOrOp:
return False
- if not s.identifier:
- if not s.declaration:
- return False
- assert operator
- name = s.declaration.name.names[-1]
- if not name.is_operator():
- return False
- if text_type(name) != text_type(operator):
- return False
if (s.templateParams is None) != (templateParams is None):
if templateParams is not None:
# we query with params, they must match params
@@ -3462,10 +3492,7 @@ class Symbol(object):
names = nestedName.names
iTemplateDecl = 0
for name in names[:-1]:
- # there shouldn't be anything inside an operator
- # (other than template parameters, which are not added this way, right?)
- assert not name.is_operator()
- identifier = name.identifier
+ identOrOp = name.identOrOp
templateArgs = name.templateArgs
if templateArgs:
assert iTemplateDecl < len(templateDecls)
@@ -3473,27 +3500,20 @@ class Symbol(object):
iTemplateDecl += 1
else:
templateParams = None
- symbol = parentSymbol._find_named_symbol(identifier,
+ symbol = parentSymbol._find_named_symbol(identOrOp,
templateParams,
templateArgs,
- operator=None,
templateShorthand=False,
matchSelf=False)
if symbol is None:
- symbol = Symbol(parent=parentSymbol, identifier=identifier,
+ symbol = Symbol(parent=parentSymbol, identOrOp=identOrOp,
templateParams=templateParams,
templateArgs=templateArgs, declaration=None,
docname=None)
parentSymbol = symbol
name = names[-1]
- if name.is_operator():
- identifier = None
- templateArgs = None
- operator = name
- else:
- identifier = name.identifier
- templateArgs = name.templateArgs
- operator = None
+ identOrOp = name.identOrOp
+ templateArgs = name.templateArgs
if iTemplateDecl < len(templateDecls):
if iTemplateDecl + 1 != len(templateDecls):
print(text_type(templateDecls))
@@ -3503,10 +3523,9 @@ class Symbol(object):
else:
assert iTemplateDecl == len(templateDecls)
templateParams = None
- symbol = parentSymbol._find_named_symbol(identifier,
+ symbol = parentSymbol._find_named_symbol(identOrOp,
templateParams,
templateArgs,
- operator,
templateShorthand=False,
matchSelf=False)
if symbol:
@@ -3523,7 +3542,7 @@ class Symbol(object):
return symbol
# It may simply be a function overload, so let's compare ids.
isRedeclaration = True
- candSymbol = Symbol(parent=parentSymbol, identifier=identifier,
+ candSymbol = Symbol(parent=parentSymbol, identOrOp=identOrOp,
templateParams=templateParams,
templateArgs=templateArgs,
declaration=declaration,
@@ -3543,7 +3562,7 @@ class Symbol(object):
candSymbol.isRedeclaration = True
raise _DuplicateSymbolError(symbol, declaration)
else:
- symbol = Symbol(parent=parentSymbol, identifier=identifier,
+ symbol = Symbol(parent=parentSymbol, identOrOp=identOrOp,
templateParams=templateParams,
templateArgs=templateArgs,
declaration=declaration,
@@ -3554,22 +3573,9 @@ class Symbol(object):
# type: (Any, List[unicode], BuildEnvironment) -> None
assert other is not None
for otherChild in other.children:
- if not otherChild.identifier:
- if not otherChild.declaration:
- print("Problem in symbol tree merging")
- print("OtherChild.dump:")
- print(otherChild.dump(0))
- print("Other.dump:")
- print(other.dump(0))
- assert otherChild.declaration
- operator = otherChild.declaration.name.names[-1]
- assert operator.is_operator()
- else:
- operator = None
- ourChild = self._find_named_symbol(otherChild.identifier,
+ ourChild = self._find_named_symbol(otherChild.identOrOp,
otherChild.templateParams,
otherChild.templateArgs,
- operator,
templateShorthand=False,
matchSelf=False)
if ourChild is None:
@@ -3614,12 +3620,12 @@ class Symbol(object):
templateDecls = []
return self._add_symbols(nestedName, templateDecls, declaration, docname)
- def find_identifier(self, identifier, matchSelf):
+ def find_identifier(self, identOrOp, matchSelf):
# type: (Any, bool) -> Symbol
- if matchSelf and self.identifier and self.identifier == identifier:
+ if matchSelf and self.identOrOp == identOrOp:
return self
for s in self.children:
- if s.identifier and s.identifier == identifier:
+ if s.identOrOp == identOrOp:
return s
return None
@@ -3627,16 +3633,10 @@ class Symbol(object):
# type: (List[Tuple[Any, Any]]) -> Symbol
s = self
for name, templateParams in key:
- if name.is_operator():
- identifier = None
- templateArgs = None
- operator = name
- else:
- identifier = name.identifier
- templateArgs = name.templateArgs
- operator = None
- s = s._find_named_symbol(identifier, templateParams,
- templateArgs, operator,
+ identOrOp = name.identOrOp
+ templateArgs = name.templateArgs
+ s = s._find_named_symbol(identOrOp,
+ templateParams, templateArgs,
templateShorthand=False,
matchSelf=False)
if not s:
@@ -3660,13 +3660,13 @@ class Symbol(object):
firstName = names[0]
if not firstName.is_operator():
while parentSymbol.parent:
- if parentSymbol.find_identifier(firstName.identifier,
+ if parentSymbol.find_identifier(firstName.identOrOp,
matchSelf=matchSelf):
# if we are in the scope of a constructor but wants to reference the class
# we need to walk one extra up
if (len(names) == 1 and typ == 'class' and matchSelf and
- parentSymbol.parent and parentSymbol.parent.identifier and
- parentSymbol.parent.identifier == firstName.identifier):
+ parentSymbol.parent and
+ parentSymbol.parent.identOrOp == firstName.identOrOp):
pass
else:
break
@@ -3675,48 +3675,36 @@ class Symbol(object):
for iName in range(len(names)):
name = names[iName]
if iName + 1 == len(names):
- if name.is_operator():
- identifier = None
- templateArgs = None
- operator = name
- else:
- identifier = name.identifier
- templateArgs = name.templateArgs
- operator = None
+ identOrOp = name.identOrOp
+ templateArgs = name.templateArgs
if iTemplateDecl < len(templateDecls):
assert iTemplateDecl + 1 == len(templateDecls)
templateParams = templateDecls[iTemplateDecl]
else:
assert iTemplateDecl == len(templateDecls)
templateParams = None
- symbol = parentSymbol._find_named_symbol(identifier,
+ symbol = parentSymbol._find_named_symbol(identOrOp,
templateParams, templateArgs,
- operator,
templateShorthand=templateShorthand,
matchSelf=matchSelf)
if symbol is not None:
return symbol
# try without template params and args
- symbol = parentSymbol._find_named_symbol(identifier,
+ symbol = parentSymbol._find_named_symbol(identOrOp,
None, None,
- operator,
templateShorthand=templateShorthand,
matchSelf=matchSelf)
return symbol
else:
- # there shouldn't be anything inside an operator
- assert not name.is_operator()
- identifier = name.identifier
+ identOrOp = name.identOrOp
templateArgs = name.templateArgs
if templateArgs and iTemplateDecl < len(templateDecls):
templateParams = templateDecls[iTemplateDecl]
iTemplateDecl += 1
else:
templateParams = None
- symbol = parentSymbol._find_named_symbol(identifier,
- templateParams,
- templateArgs,
- operator=None,
+ symbol = parentSymbol._find_named_symbol(identOrOp,
+ templateParams, templateArgs,
templateShorthand=templateShorthand,
matchSelf=matchSelf)
if symbol is None:
@@ -3739,8 +3727,8 @@ class Symbol(object):
res.append(text_type(self.templateParams))
res.append('\n')
res.append('\t' * indent)
- if self.identifier:
- res.append(text_type(self.identifier))
+ if self.identOrOp:
+ res.append(text_type(self.identOrOp))
else:
res.append(text_type(self.declaration))
if self.templateArgs:
@@ -3781,6 +3769,8 @@ class DefinitionParser(object):
self.last_match = None # type: Match
self._previous_state = (0, None) # type: Tuple[int, Match]
self.otherErrors = [] # type: List[DefinitionError]
+ # in our tests the following is set to False to capture bad parsing
+ self.allowFallbackExpressionParsing = True
self.warnEnv = warnEnv
self.config = config
@@ -4121,6 +4111,13 @@ class DefinitionParser(object):
# TODO: hmm, would we need to try both with operatorCast and with None?
prefix = self._parse_type(False, 'operatorCast')
prefixType = 'typeOperatorCast'
+ # | simple-type-specifier "(" expression-list [opt] ")"
+ # | simple-type-specifier braced-init-list
+ # | typename-specifier "(" expression-list [opt] ")"
+ # | typename-specifier braced-init-list
+ self.skip_ws()
+ if self.current_char != '(' and self.current_char != '{':
+ self.fail("Expecting '(' or '{' after type in cast expression.")
except DefinitionError as eInner:
self.pos = pos
header = "Error in postfix expression, expected primary expression or type."
@@ -4361,7 +4358,7 @@ class DefinitionParser(object):
# TODO: actually parse the second production
return self._parse_assignment_expression(inTemplate=inTemplate)
- def _parse_expression_fallback(self, end, parser):
+ def _parse_expression_fallback(self, end, parser, allow=True):
# Stupidly "parse" an expression.
# 'end' should be a list of characters which ends the expression.
@@ -4370,6 +4367,10 @@ class DefinitionParser(object):
try:
return parser()
except DefinitionError as e:
+ # some places (e.g., template parameters) we really don't want to use fallback,
+ # and for testing we may want to globally disable it
+ if not allow or not self.allowFallbackExpressionParsing:
+ raise
self.warn("Parsing of expression failed. Using fallback parser."
" Error was:\n%s" % e.description)
self.pos = prevPos
@@ -4480,7 +4481,8 @@ class DefinitionParser(object):
def _parse_nested_name(self, memberPointer=False):
# type: (bool) -> ASTNestedName
- names = []
+ names = [] # type: List[Any]
+ templates = [] # type: List[bool]
self.skip_ws()
rooted = False
@@ -4488,14 +4490,17 @@ class DefinitionParser(object):
rooted = True
while 1:
self.skip_ws()
- if self.skip_word_and_ws('template'):
- self.fail("'template' in nested name not implemented.")
- elif self.skip_word_and_ws('operator'):
- op = self._parse_operator()
- names.append(op)
+ if len(names) > 0:
+ template = self.skip_word_and_ws('template')
+ else:
+ template = False
+ templates.append(template)
+ if self.skip_word_and_ws('operator'):
+ identOrOp = self._parse_operator()
else:
if not self.match(_identifier_re):
if memberPointer and len(names) > 0:
+ templates.pop()
break
self.fail("Expected identifier in nested name.")
identifier = self.matched_text
@@ -4503,24 +4508,24 @@ class DefinitionParser(object):
if identifier in _keywords:
self.fail("Expected identifier in nested name, "
"got keyword: %s" % identifier)
- # try greedily to get template parameters,
- # but otherwise a < might be because we are in an expression
- pos = self.pos
- try:
- templateArgs = self._parse_template_argument_list()
- except DefinitionError as ex:
- self.pos = pos
- templateArgs = None
- self.otherErrors.append(ex)
- identifier = ASTIdentifier(identifier) # type: ignore
- names.append(ASTNestedNameElement(identifier, templateArgs))
+ identOrOp = ASTIdentifier(identifier)
+ # try greedily to get template arguments,
+ # but otherwise a < might be because we are in an expression
+ pos = self.pos
+ try:
+ templateArgs = self._parse_template_argument_list()
+ except DefinitionError as ex:
+ self.pos = pos
+ templateArgs = None
+ self.otherErrors.append(ex)
+ names.append(ASTNestedNameElement(identOrOp, templateArgs))
self.skip_ws()
if not self.skip_string('::'):
if memberPointer:
self.fail("Expected '::' in pointer to member (function).")
break
- return ASTNestedName(names, rooted)
+ return ASTNestedName(names, templates, rooted)
def _parse_trailing_type_spec(self):
# type: () -> Any
@@ -4598,7 +4603,7 @@ class DefinitionParser(object):
self.fail('Expected ")" after "..." in '
'parameters_and_qualifiers.')
break
- # note: it seems that function arguments can always sbe named,
+ # note: it seems that function arguments can always be named,
# even in function pointers and similar.
arg = self._parse_type_with_init(outer=None, named='single')
# TODO: parse default parameters # TODO: didn't we just do that?
@@ -4785,7 +4790,7 @@ class DefinitionParser(object):
if self.match(_identifier_re):
identifier = ASTIdentifier(self.matched_text)
nne = ASTNestedNameElement(identifier, None)
- declId = ASTNestedName([nne], rooted=False)
+ declId = ASTNestedName([nne], [False], rooted=False)
# if it's a member pointer, we may have '::', which should be an error
self.skip_ws()
if self.current_char == ':':
@@ -4919,8 +4924,8 @@ class DefinitionParser(object):
header = "Error in declarator or parameters and qualifiers"
raise self._make_multi_error(prevErrors, header)
- def _parse_initializer(self, outer=None):
- # type: (unicode) -> ASTInitializer
+ def _parse_initializer(self, outer=None, allowFallback=True):
+ # type: (unicode, bool) -> ASTInitializer
self.skip_ws()
# TODO: support paren and brace initialization for memberObject
if not self.skip_string('='):
@@ -4929,15 +4934,18 @@ class DefinitionParser(object):
if outer == 'member':
def parser():
return self._parse_assignment_expression(inTemplate=False)
- value = self._parse_expression_fallback([], parser)
+ value = self._parse_expression_fallback([], parser,
+ allow=allowFallback)
elif outer == 'templateParam':
def parser():
return self._parse_assignment_expression(inTemplate=True)
- value = self._parse_expression_fallback([',', '>'], parser)
+ value = self._parse_expression_fallback([',', '>'], parser,
+ allow=allowFallback)
elif outer is None: # function parameter
def parser():
return self._parse_assignment_expression(inTemplate=False)
- value = self._parse_expression_fallback([',', ')'], parser)
+ value = self._parse_expression_fallback([',', ')'], parser,
+ allow=allowFallback)
else:
self.fail("Internal error, initializer for outer '%s' not "
"implemented." % outer)
@@ -5027,12 +5035,48 @@ class DefinitionParser(object):
return ASTType(declSpecs, decl)
def _parse_type_with_init(self, named, outer):
- # type: (Union[bool, unicode], unicode) -> ASTTypeWithInit
+ # type: (Union[bool, unicode], unicode) -> Any
if outer:
assert outer in ('type', 'member', 'function', 'templateParam')
type = self._parse_type(outer=outer, named=named)
- init = self._parse_initializer(outer=outer)
- return ASTTypeWithInit(type, init)
+ if outer != 'templateParam':
+ init = self._parse_initializer(outer=outer)
+ return ASTTypeWithInit(type, init)
+ # it could also be a constrained type parameter, e.g., C T = int&
+ pos = self.pos
+ eExpr = None
+ try:
+ init = self._parse_initializer(outer=outer, allowFallback=False)
+ # note: init may be None if there is no =
+ if init is None:
+ return ASTTypeWithInit(type, None)
+ # we parsed an expression, so we must have a , or a >,
+ # otherwise the expression didn't get everything
+ self.skip_ws()
+ if self.current_char != ',' and self.current_char != '>':
+ # pretend it didn't happen
+ self.pos = pos
+ init = None
+ else:
+ # we assume that it was indeed an expression
+ return ASTTypeWithInit(type, init)
+ except DefinitionError as e:
+ self.pos = pos
+ eExpr = e
+ if not self.skip_string("="):
+ return ASTTypeWithInit(type, None)
+ try:
+ typeInit = self._parse_type(named=False, outer=None)
+ return ASTTemplateParamConstrainedTypeWithInit(type, typeInit)
+ except DefinitionError as eType:
+ if eExpr is None:
+ raise eType
+ errs = []
+ errs.append((eExpr, "If default is an expression"))
+ errs.append((eType, "If default is a type"))
+ msg = "Error in non-type template parameter"
+ msg += " or constrianted template paramter."
+ raise self._make_multi_error(errs, msg)
def _parse_type_using(self):
# type: () -> ASTTypeUsing
@@ -5156,13 +5200,14 @@ class DefinitionParser(object):
param = ASTTemplateParamType(data)
templateParams.append(param)
else:
- # declare a non-type parameter
+ # declare a non-type parameter, or constrained type parameter
pos = self.pos
try:
param = self._parse_type_with_init('maybe', 'templateParam')
templateParams.append(ASTTemplateParamNonType(param))
except DefinitionError as e:
- prevErrors.append((e, "If non-type template parameter"))
+ msg = "If non-type template parameter or constrained template parameter"
+ prevErrors.append((e, msg))
self.pos = pos
self.skip_ws()
if self.skip_string('>'):
@@ -5386,7 +5431,7 @@ class DefinitionParser(object):
def _make_phony_error_name():
# type: () -> ASTNestedName
nne = ASTNestedNameElement(ASTIdentifier("PhonyNameDueToError"), None)
- return ASTNestedName([nne], rooted=False)
+ return ASTNestedName([nne], [False], rooted=False)
class CPPObject(ObjectDescription):
@@ -5421,7 +5466,7 @@ class CPPObject(ObjectDescription):
# then add the name to the parent scope
symbol = ast.symbol
assert symbol
- assert symbol.identifier is not None
+ assert symbol.identOrOp is not None
assert symbol.templateParams is None
assert symbol.templateArgs is None
parentSymbol = symbol.parent
@@ -5434,7 +5479,7 @@ class CPPObject(ObjectDescription):
if parentDecl is None:
# the parent is not explicitly declared
# TODO: we could warn, but it could be a style to just assume
- # enumerator parnets to be scoped
+ # enumerator parents to be scoped
return
if parentDecl.objectType != 'enum':
# TODO: maybe issue a warning, enumerators in non-enums is weird,
@@ -5444,13 +5489,13 @@ class CPPObject(ObjectDescription):
return
targetSymbol = parentSymbol.parent
- s = targetSymbol.find_identifier(symbol.identifier, matchSelf=False)
+ s = targetSymbol.find_identifier(symbol.identOrOp, matchSelf=False)
if s is not None:
# something is already declared with that name
return
declClone = symbol.declaration.clone()
declClone.enumeratorScopedSymbol = symbol
- Symbol(parent=targetSymbol, identifier=symbol.identifier,
+ Symbol(parent=targetSymbol, identOrOp=symbol.identOrOp,
templateParams=None, templateArgs=None,
declaration=declClone,
docname=self.env.docname)
diff --git a/sphinx/domains/javascript.py b/sphinx/domains/javascript.py
index 9ecf4a4b0..81f86f754 100644
--- a/sphinx/domains/javascript.py
+++ b/sphinx/domains/javascript.py
@@ -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.
"""
diff --git a/sphinx/domains/python.py b/sphinx/domains/python.py
index d64938452..fa96590b3 100644
--- a/sphinx/domains/python.py
+++ b/sphinx/domains/python.py
@@ -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.
"""
diff --git a/sphinx/domains/rst.py b/sphinx/domains/rst.py
index 2a7dffc4d..936dd1b9f 100644
--- a/sphinx/domains/rst.py
+++ b/sphinx/domains/rst.py
@@ -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.
"""
diff --git a/sphinx/domains/std.py b/sphinx/domains/std.py
index bfaa57c4f..68baa04aa 100644
--- a/sphinx/domains/std.py
+++ b/sphinx/domains/std.py
@@ -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
- progname = node.get('std:program')
- target = node.get('reftarget')
- if progname is None or target is None:
- return None
+ if node.get('reftype') == 'option':
+ progname = node.get('std:program')
+ 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):
diff --git a/sphinx/environment/__init__.py b/sphinx/environment/__init__.py
index 5ebf9d4d5..b38e94d68 100644
--- a/sphinx/environment/__init__.py
+++ b/sphinx/environment/__init__.py
@@ -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.
"""
@@ -40,7 +40,6 @@ 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.deprecation import RemovedInSphinx20Warning
from sphinx.environment.adapters.indexentries import IndexEntries
@@ -558,21 +557,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
- else:
- # all extensions support parallel-read
- par_ok = True
+ par_ok = self.app.is_parallel_allowed('read')
+ else:
+ par_ok = False
if par_ok:
self._read_parallel(docnames, self.app, nproc=self.app.parallel)
@@ -878,7 +866,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
diff --git a/sphinx/environment/adapters/__init__.py b/sphinx/environment/adapters/__init__.py
index 9171ac0be..f945c4250 100644
--- a/sphinx/environment/adapters/__init__.py
+++ b/sphinx/environment/adapters/__init__.py
@@ -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.
"""
diff --git a/sphinx/environment/adapters/asset.py b/sphinx/environment/adapters/asset.py
index 02557a8c4..91f2cf8eb 100644
--- a/sphinx/environment/adapters/asset.py
+++ b/sphinx/environment/adapters/asset.py
@@ -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.
"""
diff --git a/sphinx/environment/adapters/indexentries.py b/sphinx/environment/adapters/indexentries.py
index 946e635ef..4a39b1bd0 100644
--- a/sphinx/environment/adapters/indexentries.py
+++ b/sphinx/environment/adapters/indexentries.py
@@ -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
diff --git a/sphinx/environment/adapters/toctree.py b/sphinx/environment/adapters/toctree.py
index 03c1d8aa9..bf725b619 100644
--- a/sphinx/environment/adapters/toctree.py
+++ b/sphinx/environment/adapters/toctree.py
@@ -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.
"""
diff --git a/sphinx/environment/collectors/__init__.py b/sphinx/environment/collectors/__init__.py
index 917b34afb..9d9f5347c 100644
--- a/sphinx/environment/collectors/__init__.py
+++ b/sphinx/environment/collectors/__init__.py
@@ -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.
"""
diff --git a/sphinx/environment/collectors/asset.py b/sphinx/environment/collectors/asset.py
index 3a0e1fefd..0d7a193e3 100644
--- a/sphinx/environment/collectors/asset.py
+++ b/sphinx/environment/collectors/asset.py
@@ -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.
"""
diff --git a/sphinx/environment/collectors/dependencies.py b/sphinx/environment/collectors/dependencies.py
index 5e20d1245..bf42b12e9 100644
--- a/sphinx/environment/collectors/dependencies.py
+++ b/sphinx/environment/collectors/dependencies.py
@@ -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.
"""
diff --git a/sphinx/environment/collectors/indexentries.py b/sphinx/environment/collectors/indexentries.py
index 0b1c35934..f9fa8bab7 100644
--- a/sphinx/environment/collectors/indexentries.py
+++ b/sphinx/environment/collectors/indexentries.py
@@ -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.
"""
diff --git a/sphinx/environment/collectors/metadata.py b/sphinx/environment/collectors/metadata.py
index ae8a8cb4c..7d54d2fe6 100644
--- a/sphinx/environment/collectors/metadata.py
+++ b/sphinx/environment/collectors/metadata.py
@@ -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.
"""
diff --git a/sphinx/environment/collectors/title.py b/sphinx/environment/collectors/title.py
index 3335c2cc7..eb23b975f 100644
--- a/sphinx/environment/collectors/title.py
+++ b/sphinx/environment/collectors/title.py
@@ -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.
"""
diff --git a/sphinx/environment/collectors/toctree.py b/sphinx/environment/collectors/toctree.py
index 91aa21f2e..53e1045d9 100644
--- a/sphinx/environment/collectors/toctree.py
+++ b/sphinx/environment/collectors/toctree.py
@@ -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.
"""
diff --git a/sphinx/errors.py b/sphinx/errors.py
index 7662c95a3..eef1a157a 100644
--- a/sphinx/errors.py
+++ b/sphinx/errors.py
@@ -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.
"""
diff --git a/sphinx/events.py b/sphinx/events.py
index 99decfff5..097f61fc6 100644
--- a/sphinx/events.py
+++ b/sphinx/events.py
@@ -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
diff --git a/sphinx/ext/__init__.py b/sphinx/ext/__init__.py
index e529ee9e5..440c01a15 100644
--- a/sphinx/ext/__init__.py
+++ b/sphinx/ext/__init__.py
@@ -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.
"""
diff --git a/sphinx/ext/apidoc.py b/sphinx/ext/apidoc.py
index 0bdeb9865..cec9d8138 100644
--- a/sphinx/ext/apidoc.py
+++ b/sphinx/ext/apidoc.py
@@ -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')
@@ -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)
diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py
index 48afbcc91..d9e82813d 100644
--- a/sphinx/ext/autodoc/__init__.py
+++ b/sphinx/ext/autodoc/__init__.py
@@ -7,24 +7,22 @@
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 mock, import_module
+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
@@ -32,21 +30,23 @@ 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."""
@@ -383,55 +357,15 @@ 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
with mock(self.env.config.autodoc_mock_imports):
try:
- logger.debug('[autodoc] import %s', self.modname)
- obj = import_module(self.modname, self.env.config.autodoc_warningiserror)
- parent = None
- self.module = obj
- 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
- except (AttributeError, ImportError) as exc:
- 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(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.warning(errmsg)
+ except ImportError as exc:
+ logger.warning(exc.args[0])
self.env.note_reread()
return False
@@ -604,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:
- logger.warning('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]]
@@ -713,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
@@ -767,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
@@ -896,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
@@ -938,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)
@@ -1502,117 +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__()
+
+ def __setitem__(self, key, value):
+ warnings.warn(self.message, RemovedInSphinx20Warning)
+ super(DeprecatedDict, self).__setitem__(key, value)
- The *_special_attrgetters* attribute is used to customize ``getattr()``
- calls that the Documenters make; its entries are of the form ``type:
- getattr_function``.
+ 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]
-
- # 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
- logger.warning(msg, line=self.lineno)
+ _special_attrgetters = DeprecatedDict(
+ 'AutoDirective._special_attrgetters has been deprecated. '
+ 'Please use app.add_autodoc_attrgetter() instead.'
+ ) # type: Dict[Type, Callable]
- 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.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 []
-
- 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 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)
@@ -1623,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)
diff --git a/sphinx/ext/autodoc/directive.py b/sphinx/ext/autodoc/directive.py
new file mode 100644
index 000000000..6de6e5517
--- /dev/null
+++ b/sphinx/ext/autodoc/directive.py
@@ -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
diff --git a/sphinx/ext/autodoc/importer.py b/sphinx/ext/autodoc/importer.py
index 5c28f490d..101cb930f 100644
--- a/sphinx/ext/autodoc/importer.py
+++ b/sphinx/ext/autodoc/importer.py
@@ -5,7 +5,7 @@
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.
"""
@@ -13,13 +13,17 @@ 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, Generator, List, Set # NOQA
+ from typing import Any, Callable, Dict, Generator, List, Optional, Set # NOQA
logger = logging.getLogger(__name__)
@@ -144,3 +148,86 @@ def import_module(modname, warningiserror=False):
# 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
diff --git a/sphinx/ext/autodoc/inspector.py b/sphinx/ext/autodoc/inspector.py
index 50c5a9082..6e07c9547 100644
--- a/sphinx/ext/autodoc/inspector.py
+++ b/sphinx/ext/autodoc/inspector.py
@@ -5,7 +5,7 @@
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.
"""
diff --git a/sphinx/ext/autosectionlabel.py b/sphinx/ext/autosectionlabel.py
index 69b8c6873..fbb7d037f 100644
--- a/sphinx/ext/autosectionlabel.py
+++ b/sphinx/ext/autosectionlabel.py
@@ -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.
"""
diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py
index 21bfe7b13..7a9e59c73 100644
--- a/sphinx/ext/autosummary/__init__.py
+++ b/sphinx/ext/autosummary/__init__.py
@@ -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,8 @@ 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:
@@ -153,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.
@@ -167,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
@@ -176,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
@@ -186,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)
@@ -289,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))
@@ -325,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)
@@ -615,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):
diff --git a/sphinx/ext/autosummary/generate.py b/sphinx/ext/autosummary/generate.py
index f02c50692..aeffcb564 100644
--- a/sphinx/ext/autosummary/generate.py
+++ b/sphinx/ext/autosummary/generate.py
@@ -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__':
diff --git a/sphinx/ext/coverage.py b/sphinx/ext/coverage.py
index 02843ac83..476a0ed46 100644
--- a/sphinx/ext/coverage.py
+++ b/sphinx/ext/coverage.py
@@ -6,7 +6,7 @@
Check Python modules and C API for coverage. Mostly written by Josip
Dzolonga for the Google Highly Open Participation contest.
- :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.
"""
diff --git a/sphinx/ext/doctest.py b/sphinx/ext/doctest.py
index 4110d9c90..e0ce050f7 100644
--- a/sphinx/ext/doctest.py
+++ b/sphinx/ext/doctest.py
@@ -6,7 +6,7 @@
Mimic doctest by automatically executing code snippets and checking
their results.
- :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
diff --git a/sphinx/ext/extlinks.py b/sphinx/ext/extlinks.py
index 00180b35c..c247e6722 100644
--- a/sphinx/ext/extlinks.py
+++ b/sphinx/ext/extlinks.py
@@ -20,7 +20,7 @@
You can also give an explicit caption, e.g. :exmpl:`Foo <foo>`.
- :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.
"""
diff --git a/sphinx/ext/githubpages.py b/sphinx/ext/githubpages.py
index 028b65622..7d673a72d 100644
--- a/sphinx/ext/githubpages.py
+++ b/sphinx/ext/githubpages.py
@@ -5,7 +5,7 @@
To publish HTML docs at GitHub Pages, create .nojekyll file.
- :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.
"""
diff --git a/sphinx/ext/graphviz.py b/sphinx/ext/graphviz.py
index 2a83474ce..546594843 100644
--- a/sphinx/ext/graphviz.py
+++ b/sphinx/ext/graphviz.py
@@ -6,7 +6,7 @@
Allow graphviz-formatted graphs to be included in Sphinx-generated
documents inline.
- :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.
"""
diff --git a/sphinx/ext/ifconfig.py b/sphinx/ext/ifconfig.py
index c700649dd..16042ac3f 100644
--- a/sphinx/ext/ifconfig.py
+++ b/sphinx/ext/ifconfig.py
@@ -16,7 +16,7 @@
namespace of the project configuration (that is, all variables from
``conf.py`` are available.)
- :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.
"""
diff --git a/sphinx/ext/imgconverter.py b/sphinx/ext/imgconverter.py
index d2894b2a3..95f579e36 100644
--- a/sphinx/ext/imgconverter.py
+++ b/sphinx/ext/imgconverter.py
@@ -5,7 +5,7 @@
Image converter extension for 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.
"""
import subprocess
diff --git a/sphinx/ext/imgmath.py b/sphinx/ext/imgmath.py
index 8bf4fcad5..b5f67e713 100644
--- a/sphinx/ext/imgmath.py
+++ b/sphinx/ext/imgmath.py
@@ -5,7 +5,7 @@
Render math in HTML via dvipng or dvisvgm.
- :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.
"""
@@ -30,6 +30,7 @@ from sphinx.util.png import read_png_depth, write_png_depth
from sphinx.util.osutil import ensuredir, ENOENT, cd
from sphinx.util.pycompat import sys_encoding
from sphinx.ext.mathbase import setup_math as mathbase_setup, wrap_displaymath
+from sphinx.ext.mathbase import get_node_equation_number
if False:
# For type annotation
@@ -333,7 +334,8 @@ def html_visit_displaymath(self, node):
self.body.append(self.starttag(node, 'div', CLASS='math'))
self.body.append('<p>')
if node['number']:
- self.body.append('<span class="eqno">(%s)' % node['number'])
+ number = get_node_equation_number(self, node)
+ self.body.append('<span class="eqno">(%s)' % number)
self.add_permalink_ref(node, _('Permalink to this equation'))
self.body.append('</span>')
if fname is None:
diff --git a/sphinx/ext/inheritance_diagram.py b/sphinx/ext/inheritance_diagram.py
index a6e6e7aba..8e01a1b28 100644
--- a/sphinx/ext/inheritance_diagram.py
+++ b/sphinx/ext/inheritance_diagram.py
@@ -32,7 +32,7 @@ r"""
The graph is inserted as a PNG+image map into HTML and a PDF in
LaTeX.
- :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.
"""
diff --git a/sphinx/ext/intersphinx.py b/sphinx/ext/intersphinx.py
index 1ee58353c..52683d309 100644
--- a/sphinx/ext/intersphinx.py
+++ b/sphinx/ext/intersphinx.py
@@ -20,7 +20,7 @@
also be specified individually, e.g. if the docs should be buildable
without Internet access.
- :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.
"""
@@ -304,6 +304,7 @@ def missing_reference(app, env, node, contnode):
in_set = setname
to_try.append((inventories.named_inventory[setname], newtarget))
if domain:
+ node['reftarget'] = newtarget
full_qualified_name = env.get_domain(domain).get_full_qualified_name(node)
if full_qualified_name:
to_try.append((inventories.named_inventory[setname], full_qualified_name))
diff --git a/sphinx/ext/jsmath.py b/sphinx/ext/jsmath.py
index dc57c13c6..a74f0641a 100644
--- a/sphinx/ext/jsmath.py
+++ b/sphinx/ext/jsmath.py
@@ -6,7 +6,7 @@
Set up everything for use of JSMath to display math in HTML
via JavaScript.
- :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.
"""
@@ -16,6 +16,7 @@ import sphinx
from sphinx.locale import _
from sphinx.application import ExtensionError
from sphinx.ext.mathbase import setup_math as mathbase_setup
+from sphinx.ext.mathbase import get_node_equation_number
def html_visit_math(self, node):
@@ -35,7 +36,8 @@ def html_visit_displaymath(self, node):
if i == 0:
# necessary to e.g. set the id property correctly
if node['number']:
- self.body.append('<span class="eqno">(%s)' % node['number'])
+ number = get_node_equation_number(self, node)
+ self.body.append('<span class="eqno">(%s)' % number)
self.add_permalink_ref(node, _('Permalink to this equation'))
self.body.append('</span>')
self.body.append(self.starttag(node, 'div', CLASS='math'))
diff --git a/sphinx/ext/linkcode.py b/sphinx/ext/linkcode.py
index e74ee8529..a42dab528 100644
--- a/sphinx/ext/linkcode.py
+++ b/sphinx/ext/linkcode.py
@@ -5,7 +5,7 @@
Add external links to module code in Python object descriptions.
- :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.
"""
diff --git a/sphinx/ext/mathbase.py b/sphinx/ext/mathbase.py
index f83ca5da8..f2e15b485 100644
--- a/sphinx/ext/mathbase.py
+++ b/sphinx/ext/mathbase.py
@@ -5,7 +5,7 @@
Set up math support in source files and LaTeX/text output.
- :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.
"""
@@ -84,6 +84,13 @@ class MathDomain(Domain):
newnode['target'] = target
return newnode
else:
+ if env.config.math_numfig and env.config.numfig:
+ if docname in env.toc_fignumbers:
+ id = 'equation-' + target
+ number = env.toc_fignumbers[docname]['displaymath'].get(id, ())
+ number = '.'.join(map(str, number))
+ else:
+ number = ''
try:
eqref_format = env.config.math_eqref_format or "({number})"
title = nodes.Text(eqref_format.format(number=number))
@@ -126,6 +133,23 @@ class MathDomain(Domain):
return len(targets) + 1
+def get_node_equation_number(writer, node):
+ if writer.builder.config.math_numfig and writer.builder.config.numfig:
+ figtype = 'displaymath'
+ if writer.builder.name == 'singlehtml':
+ key = u"%s/%s" % (writer.docnames[-1], figtype)
+ else:
+ key = figtype
+
+ id = node['ids'][0]
+ number = writer.builder.fignumbers.get(key, {}).get(id, ())
+ number = '.'.join(map(str, number))
+ else:
+ number = node['number']
+
+ return number
+
+
def wrap_displaymath(math, label, numbering):
# type: (unicode, unicode, bool) -> unicode
def is_equation(part):
@@ -341,6 +365,7 @@ def setup_math(app, htmlinlinevisitors, htmldisplayvisitors):
# type: (Sphinx, Tuple[Callable, Any], Tuple[Callable, Any]) -> None
app.add_config_value('math_number_all', False, 'env')
app.add_config_value('math_eqref_format', None, 'env', string_classes)
+ app.add_config_value('math_numfig', True, 'env')
app.add_domain(MathDomain)
app.add_node(math, override=True,
latex=(latex_visit_math, None),
@@ -348,12 +373,12 @@ def setup_math(app, htmlinlinevisitors, htmldisplayvisitors):
man=(man_visit_math, None),
texinfo=(texinfo_visit_math, None),
html=htmlinlinevisitors)
- app.add_node(displaymath,
- latex=(latex_visit_displaymath, None),
- text=(text_visit_displaymath, None),
- man=(man_visit_displaymath, man_depart_displaymath),
- texinfo=(texinfo_visit_displaymath, texinfo_depart_displaymath),
- html=htmldisplayvisitors)
+ app.add_enumerable_node(displaymath, 'displaymath',
+ latex=(latex_visit_displaymath, None),
+ text=(text_visit_displaymath, None),
+ man=(man_visit_displaymath, man_depart_displaymath),
+ texinfo=(texinfo_visit_displaymath, texinfo_depart_displaymath),
+ html=htmldisplayvisitors)
app.add_node(eqref, latex=(latex_visit_eqref, None))
app.add_role('math', math_role)
app.add_role('eq', EqXRefRole(warn_dangling=True))
diff --git a/sphinx/ext/mathjax.py b/sphinx/ext/mathjax.py
index f25f91e74..8698e2801 100644
--- a/sphinx/ext/mathjax.py
+++ b/sphinx/ext/mathjax.py
@@ -7,7 +7,7 @@
Sphinx's HTML writer -- requires the MathJax JavaScript library on your
webserver/computer.
- :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.
"""
@@ -17,6 +17,7 @@ import sphinx
from sphinx.locale import _
from sphinx.errors import ExtensionError
from sphinx.ext.mathbase import setup_math as mathbase_setup
+from sphinx.ext.mathbase import get_node_equation_number
def html_visit_math(self, node):
@@ -36,7 +37,8 @@ def html_visit_displaymath(self, node):
# necessary to e.g. set the id property correctly
if node['number']:
- self.body.append('<span class="eqno">(%s)' % node['number'])
+ number = get_node_equation_number(self, node)
+ self.body.append('<span class="eqno">(%s)' % number)
self.add_permalink_ref(node, _('Permalink to this equation'))
self.body.append('</span>')
self.body.append(self.builder.config.mathjax_display[0])
diff --git a/sphinx/ext/napoleon/__init__.py b/sphinx/ext/napoleon/__init__.py
index 7aca9b629..b65f7f2a1 100644
--- a/sphinx/ext/napoleon/__init__.py
+++ b/sphinx/ext/napoleon/__init__.py
@@ -5,7 +5,7 @@
Support for NumPy and Google style 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.
"""
diff --git a/sphinx/ext/napoleon/docstring.py b/sphinx/ext/napoleon/docstring.py
index d3a64049b..b349c761f 100644
--- a/sphinx/ext/napoleon/docstring.py
+++ b/sphinx/ext/napoleon/docstring.py
@@ -7,7 +7,7 @@
Classes for docstring parsing and formatting.
- :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.
"""
diff --git a/sphinx/ext/napoleon/iterators.py b/sphinx/ext/napoleon/iterators.py
index b03bcf047..b4bba8863 100644
--- a/sphinx/ext/napoleon/iterators.py
+++ b/sphinx/ext/napoleon/iterators.py
@@ -7,7 +7,7 @@
A collection of helpful iterators.
- :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.
"""
diff --git a/sphinx/ext/pngmath.py b/sphinx/ext/pngmath.py
index 85010b799..717d51756 100644
--- a/sphinx/ext/pngmath.py
+++ b/sphinx/ext/pngmath.py
@@ -6,7 +6,7 @@
Render math in HTML via dvipng. This extension has been deprecated; please
use sphinx.ext.imgmath instead.
- :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.
"""
@@ -30,6 +30,7 @@ from sphinx.util.png import read_png_depth, write_png_depth
from sphinx.util.osutil import ensuredir, ENOENT, cd
from sphinx.util.pycompat import sys_encoding
from sphinx.ext.mathbase import setup_math as mathbase_setup, wrap_displaymath
+from sphinx.ext.mathbase import get_node_equation_number
if False:
# For type annotation
@@ -242,7 +243,8 @@ def html_visit_displaymath(self, node):
self.body.append(self.starttag(node, 'div', CLASS='math'))
self.body.append('<p>')
if node['number']:
- self.body.append('<span class="eqno">(%s)</span>' % node['number'])
+ number = get_node_equation_number(self, node)
+ self.body.append('<span class="eqno">(%s)</span>' % number)
if fname is None:
# something failed -- use text-only as a bad substitute
self.body.append('<span class="math">%s</span></p>\n</div>' %
diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py
index a58422793..e60620b5b 100644
--- a/sphinx/ext/todo.py
+++ b/sphinx/ext/todo.py
@@ -8,7 +8,7 @@
all todos of your project and lists them along with a backlink to the
original location.
- :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.
"""
@@ -178,7 +178,8 @@ def process_todo_nodes(app, doctree, fromdocname):
todo_entry = todo_info['todo']
# Remove targetref from the (copied) node to avoid emitting a
# duplicate label of the original entry when we walk this node.
- del todo_entry['targetref']
+ if 'targetref' in todo_entry:
+ del todo_entry['targetref']
# (Recursively) resolve references in the todo content
env.resolve_references(todo_entry, todo_info['docname'],
diff --git a/sphinx/ext/viewcode.py b/sphinx/ext/viewcode.py
index ce67081d3..d4ff7cebb 100644
--- a/sphinx/ext/viewcode.py
+++ b/sphinx/ext/viewcode.py
@@ -5,7 +5,7 @@
Add links to module code in Python object descriptions.
- :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.
"""
diff --git a/sphinx/extension.py b/sphinx/extension.py
index 0520bf564..98d35b5af 100644
--- a/sphinx/extension.py
+++ b/sphinx/extension.py
@@ -5,7 +5,7 @@
Utilities for Sphinx extensions.
- :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,7 +38,7 @@ class Extension(object):
# The extension supports parallel write or not. The default value
# is ``True``. Sphinx writes parallelly documents even if
# the extension does not tell its status.
- self.parallel_write_safe = kwargs.pop('parallel_read_safe', True)
+ self.parallel_write_safe = kwargs.pop('parallel_write_safe', True)
def verify_required_extensions(app, requirements):
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
index eb309d82a..eef24ee95 100644
--- a/sphinx/highlighting.py
+++ b/sphinx/highlighting.py
@@ -5,7 +5,7 @@
Highlight code blocks using Pygments.
- :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.
"""
diff --git a/sphinx/io.py b/sphinx/io.py
index 8a41069db..2d584de91 100644
--- a/sphinx/io.py
+++ b/sphinx/io.py
@@ -5,7 +5,7 @@
Input/Output files
- :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
@@ -80,7 +80,13 @@ class SphinxStandaloneReader(SphinxBaseReader):
Locale, CitationReferences, DefaultSubstitutions, MoveModuleTargets,
HandleCodeBlocks, AutoNumbering, AutoIndexUpgrader, SortIds,
RemoveTranslatableInline, PreserveTranslatableMessages, FilterSystemMessages,
- RefOnlyBulletListTransform, UnreferencedFootnotesDetector]
+ RefOnlyBulletListTransform, UnreferencedFootnotesDetector
+ ] # type: List[Transform]
+
+ def __init__(self, app, *args, **kwargs):
+ # type: (Sphinx, Any, Any) -> None
+ self.transforms = self.transforms + app.registry.get_transforms()
+ SphinxBaseReader.__init__(self, *args, **kwargs) # type: ignore
class SphinxI18nReader(SphinxBaseReader):
@@ -259,7 +265,7 @@ def read_doc(app, env, filename):
# type: (Sphinx, BuildEnvironment, unicode) -> nodes.document
"""Parse a document and convert to doctree."""
input_class = app.registry.get_source_input(filename)
- reader = SphinxStandaloneReader()
+ reader = SphinxStandaloneReader(app)
source = input_class(app, env, source=None, source_path=filename,
encoding=env.config.source_encoding)
parser = app.registry.create_source_parser(app, filename)
@@ -279,3 +285,9 @@ def read_doc(app, env, filename):
def setup(app):
app.registry.add_source_input('*', SphinxFileInput)
app.registry.add_source_input('restructuredtext', SphinxRSTFileInput)
+
+ return {
+ 'version': 'builtin',
+ 'parallel_read_safe': True,
+ 'parallel_write_safe': True,
+ }
diff --git a/sphinx/jinja2glue.py b/sphinx/jinja2glue.py
index 41d48ad34..8839e48fa 100644
--- a/sphinx/jinja2glue.py
+++ b/sphinx/jinja2glue.py
@@ -5,7 +5,7 @@
Glue code for the jinja2 templating engine.
- :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.
"""
diff --git a/sphinx/make_mode.py b/sphinx/make_mode.py
index 83c8988b0..0bc1a797d 100644
--- a/sphinx/make_mode.py
+++ b/sphinx/make_mode.py
@@ -11,7 +11,7 @@
This is in its own module so that importing it is fast. It should not
import the main Sphinx modules (like sphinx.applications, sphinx.builders).
- :copyright: Copyright 2007-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
diff --git a/sphinx/parsers.py b/sphinx/parsers.py
index 92bea9461..48a155203 100644
--- a/sphinx/parsers.py
+++ b/sphinx/parsers.py
@@ -5,7 +5,7 @@
A Base class for additional parsers.
- :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.
"""
diff --git a/sphinx/pycode/__init__.py b/sphinx/pycode/__init__.py
index 20de2a656..de951a19f 100644
--- a/sphinx/pycode/__init__.py
+++ b/sphinx/pycode/__init__.py
@@ -5,7 +5,7 @@
Utilities parsing and analyzing Python 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.
"""
from __future__ import print_function
diff --git a/sphinx/pycode/parser.py b/sphinx/pycode/parser.py
index 7460dcfce..9aed7f7f4 100644
--- a/sphinx/pycode/parser.py
+++ b/sphinx/pycode/parser.py
@@ -5,7 +5,7 @@
Utilities parsing and analyzing Python 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.
"""
import re
diff --git a/sphinx/pygments_styles.py b/sphinx/pygments_styles.py
index a70005d7c..d29d825d5 100644
--- a/sphinx/pygments_styles.py
+++ b/sphinx/pygments_styles.py
@@ -5,7 +5,7 @@
Sphinx theme specific highlighting styles.
- :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.
"""
diff --git a/sphinx/quickstart.py b/sphinx/quickstart.py
index 75c244c8e..5e403b1d8 100644
--- a/sphinx/quickstart.py
+++ b/sphinx/quickstart.py
@@ -5,7 +5,7 @@
This file has moved to :py:mod:`sphinx.cmd.quickstart`.
- :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.
"""
diff --git a/sphinx/registry.py b/sphinx/registry.py
index b627f23af..e48c12f96 100644
--- a/sphinx/registry.py
+++ b/sphinx/registry.py
@@ -24,18 +24,22 @@ from sphinx.parsers import Parser as SphinxParser
from sphinx.roles import XRefRole
from sphinx.util import logging
from sphinx.util import import_object
+from sphinx.util.console import bold # type: ignore
from sphinx.util.docutils import directive_helper
if False:
# For type annotation
- from typing import Any, Callable, Dict, Iterator, List, Type # NOQA
+ from typing import Any, Callable, Dict, Iterator, List, Type, Union # NOQA
from docutils import nodes # NOQA
from docutils.io import Input # NOQA
from docutils.parsers import Parser # NOQA
+ from docutils.transform import Transform # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.builders import Builder # NOQA
from sphinx.domains import Domain, Index # NOQA
from sphinx.environment import BuildEnvironment # NOQA
+ from sphinx.ext.autodoc import Documenter # NOQA
+ from sphinx.util.typing import RoleFunction # NOQA
logger = logging.getLogger(__name__)
@@ -48,14 +52,23 @@ EXTENSION_BLACKLIST = {
class SphinxComponentRegistry(object):
def __init__(self):
- self.builders = {} # type: Dict[unicode, Type[Builder]]
- self.domains = {} # type: Dict[unicode, Type[Domain]]
- self.source_parsers = {} # type: Dict[unicode, Parser]
- self.source_inputs = {} # type: Dict[unicode, Input]
- self.translators = {} # type: Dict[unicode, nodes.NodeVisitor]
+ self.autodoc_attrgettrs = {} # type: Dict[Type, Callable[[Any, unicode, Any], Any]]
+ self.builders = {} # type: Dict[unicode, Type[Builder]]
+ self.documenters = {} # type: Dict[unicode, Type[Documenter]]
+ self.domains = {} # type: Dict[unicode, Type[Domain]]
+ self.domain_directives = {} # type: Dict[unicode, Dict[unicode, Any]]
+ self.domain_indices = {} # type: Dict[unicode, List[Type[Index]]]
+ self.domain_object_types = {} # type: Dict[unicode, Dict[unicode, ObjType]]
+ self.domain_roles = {} # type: Dict[unicode, Dict[unicode, Union[RoleFunction, XRefRole]]] # NOQA
+ self.post_transforms = [] # type: List[Type[Transform]]
+ self.source_parsers = {} # type: Dict[unicode, Parser]
+ self.source_inputs = {} # type: Dict[unicode, Input]
+ self.translators = {} # type: Dict[unicode, nodes.NodeVisitor]
+ self.transforms = [] # type: List[Type[Transform]]
def add_builder(self, builder):
# type: (Type[Builder]) -> None
+ logger.debug('[app] adding builder: %r', builder)
if not hasattr(builder, 'name'):
raise ExtensionError(__('Builder class %s has no "name" attribute') % builder)
if builder.name in self.builders:
@@ -87,6 +100,7 @@ class SphinxComponentRegistry(object):
def add_domain(self, domain):
# type: (Type[Domain]) -> None
+ logger.debug('[app] adding domain: %r', domain)
if domain.name in self.domains:
raise ExtensionError(__('domain %s already registered') % domain.name)
self.domains[domain.name] = domain
@@ -98,10 +112,20 @@ class SphinxComponentRegistry(object):
def create_domains(self, env):
# type: (BuildEnvironment) -> Iterator[Domain]
for DomainClass in itervalues(self.domains):
- yield DomainClass(env)
+ domain = DomainClass(env)
+
+ # transplant components added by extensions
+ domain.directives.update(self.domain_directives.get(domain.name, {}))
+ domain.roles.update(self.domain_roles.get(domain.name, {}))
+ domain.indices.extend(self.domain_indices.get(domain.name, []))
+ for name, objtype in iteritems(self.domain_object_types.get(domain.name, {})):
+ domain.add_object_type(name, objtype)
+
+ yield domain
def override_domain(self, domain):
# type: (Type[Domain]) -> None
+ logger.debug('[app] overriding domain: %r', domain)
if domain.name not in self.domains:
raise ExtensionError(__('domain %s not yet registered') % domain.name)
if not issubclass(domain, self.domains[domain.name]):
@@ -112,27 +136,37 @@ class SphinxComponentRegistry(object):
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))
if domain not in self.domains:
raise ExtensionError(__('domain %s not yet registered') % domain)
- directive = directive_helper(obj, has_content, argument_spec, **option_spec)
- self.domains[domain].directives[name] = directive
+ directives = self.domain_directives.setdefault(domain, {})
+ directives[name] = directive_helper(obj, has_content, argument_spec, **option_spec)
def add_role_to_domain(self, domain, name, role):
- # type: (unicode, unicode, Any) -> None
+ # type: (unicode, unicode, Union[RoleFunction, XRefRole]) -> None
+ logger.debug('[app] adding role to domain: %r', (domain, name, role))
if domain not in self.domains:
raise ExtensionError(__('domain %s not yet registered') % domain)
- self.domains[domain].roles[name] = role
+ roles = self.domain_roles.setdefault(domain, {})
+ roles[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))
if domain not in self.domains:
raise ExtensionError(__('domain %s not yet registered') % domain)
- self.domains[domain].indices.append(index)
+ indices = self.domain_indices.setdefault(domain, [])
+ indices.append(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))
+
# create a subclass of GenericObject as the new directive
directive = type(directivename, # type: ignore
(GenericObject, object),
@@ -140,26 +174,32 @@ class SphinxComponentRegistry(object):
'parse_node': staticmethod(parse_node),
'doc_field_types': doc_field_types})
- stddomain = self.domains['std']
- stddomain.directives[directivename] = directive
- stddomain.roles[rolename] = XRefRole(innernodeclass=ref_nodeclass)
- stddomain.object_types[directivename] = ObjType(objname or directivename, rolename)
+ self.add_directive_to_domain('std', directivename, directive)
+ self.add_role_to_domain('std', rolename, XRefRole(innernodeclass=ref_nodeclass))
+
+ object_types = self.domain_object_types.setdefault('std', {})
+ object_types[directivename] = ObjType(objname or directivename, rolename)
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))
+
# create a subclass of Target as the new directive
directive = type(directivename, # type: ignore
(Target, object),
{'indextemplate': indextemplate})
- stddomain = self.domains['std']
- stddomain.directives[directivename] = directive
- stddomain.roles[rolename] = XRefRole(innernodeclass=ref_nodeclass)
- stddomain.object_types[directivename] = ObjType(objname or directivename, rolename)
+ self.add_directive_to_domain('std', directivename, directive)
+ self.add_role_to_domain('std', rolename, XRefRole(innernodeclass=ref_nodeclass))
+
+ object_types = self.domain_object_types.setdefault('std', {})
+ object_types[directivename] = ObjType(objname or directivename, rolename)
def add_source_parser(self, suffix, parser):
# type: (unicode, Type[Parser]) -> None
+ logger.debug('[app] adding search source_parser: %r, %r', suffix, parser)
if suffix in self.source_parsers:
raise ExtensionError(__('source_parser for %r is already registered') % suffix)
self.source_parsers[suffix] = parser
@@ -216,6 +256,7 @@ class SphinxComponentRegistry(object):
def add_translator(self, name, translator):
# type: (unicode, Type[nodes.NodeVisitor]) -> None
+ logger.info(bold(__('Change of translator for the %s builder.') % name))
self.translators[name] = translator
def get_translator_class(self, builder):
@@ -228,6 +269,32 @@ class SphinxComponentRegistry(object):
translator_class = self.get_translator_class(builder)
return translator_class(builder, document)
+ def add_transform(self, transform):
+ # type: (Type[Transform]) -> None
+ logger.debug('[app] adding transform: %r', transform)
+ self.transforms.append(transform)
+
+ def get_transforms(self):
+ # type: () -> List[Type[Transform]]
+ return self.transforms
+
+ def add_post_transform(self, transform):
+ # type: (Type[Transform]) -> None
+ logger.debug('[app] adding post transform: %r', transform)
+ self.post_transforms.append(transform)
+
+ def get_post_transforms(self):
+ # type: () -> List[Type[Transform]]
+ return self.post_transforms
+
+ def add_documenter(self, objtype, documenter):
+ # type: (unicode, Type[Documenter]) -> None
+ self.documenters[objtype] = documenter
+
+ def add_autodoc_attrgetter(self, typ, attrgetter):
+ # type: (Type, Callable[[Any, unicode, Any], Any]) -> None
+ self.autodoc_attrgettrs[typ] = attrgetter
+
def load_extension(self, app, extname):
# type: (Sphinx, unicode) -> None
"""Load a Sphinx extension."""
diff --git a/sphinx/roles.py b/sphinx/roles.py
index 4007b9f88..223c6c21f 100644
--- a/sphinx/roles.py
+++ b/sphinx/roles.py
@@ -5,7 +5,7 @@
Handlers for additional ReST roles.
- :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.
"""
diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py
index a6074a863..fc55a2a45 100644
--- a/sphinx/search/__init__.py
+++ b/sphinx/search/__init__.py
@@ -5,7 +5,7 @@
Create a full-text search index for offline search.
- :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
diff --git a/sphinx/search/en.py b/sphinx/search/en.py
index f7ce43350..fe9b7d8da 100644
--- a/sphinx/search/en.py
+++ b/sphinx/search/en.py
@@ -5,7 +5,7 @@
English search language: includes the JS porter stemmer.
- :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.
"""
diff --git a/sphinx/search/ja.py b/sphinx/search/ja.py
index d1d922dd4..0cdc14a11 100644
--- a/sphinx/search/ja.py
+++ b/sphinx/search/ja.py
@@ -5,7 +5,7 @@
Japanese search language: includes routine to split words.
- :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.
"""
diff --git a/sphinx/search/jssplitter.py b/sphinx/search/jssplitter.py
index 56b91c1d0..7166565f1 100644
--- a/sphinx/search/jssplitter.py
+++ b/sphinx/search/jssplitter.py
@@ -7,7 +7,7 @@
DO NOT EDIT. This is generated by utils/jssplitter_generator.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.
"""
diff --git a/sphinx/search/zh.py b/sphinx/search/zh.py
index 5ef4b5888..2301e1103 100644
--- a/sphinx/search/zh.py
+++ b/sphinx/search/zh.py
@@ -5,7 +5,7 @@
Chinese search language: includes routine to split words.
- :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.
"""
diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py
index 8c00a2ff8..cd89fe7f7 100644
--- a/sphinx/setup_command.py
+++ b/sphinx/setup_command.py
@@ -8,7 +8,7 @@
:author: Sebastian Wiesner
:contact: basti.wiesner@gmx.net
- :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
diff --git a/sphinx/templates/epub2/container.xml b/sphinx/templates/epub2/container.xml
deleted file mode 100644
index 326cf15fa..000000000
--- a/sphinx/templates/epub2/container.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
- <rootfiles>
- <rootfile full-path="content.opf" media-type="application/oebps-package+xml"/>
- </rootfiles>
-</container>
diff --git a/sphinx/templates/epub2/content.opf_t b/sphinx/templates/epub2/content.opf_t
deleted file mode 100644
index 5169d0551..000000000
--- a/sphinx/templates/epub2/content.opf_t
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<package xmlns="http://www.idpf.org/2007/opf" version="2.0"
- unique-identifier="%(uid)s">
- <metadata xmlns:opf="http://www.idpf.org/2007/opf"
- xmlns:dc="http://purl.org/dc/elements/1.1/">
- <dc:language>{{ lang }}</dc:language>
- <dc:title>{{ title }}</dc:title>
- <dc:creator opf:role="aut">{{ author }}</dc:creator>
- <dc:publisher>{{ publisher }}</dc:publisher>
- <dc:rights>{{ copyright }}</dc:rights>
- <dc:identifier id="{{ uid }}" opf:scheme="{{ scheme }}">{{ id }}</dc:identifier>
- <dc:date>{{ date }}</dc:date>
- {%- if cover %}
- <meta name="cover" content="{{ cover }}"/>
- {%- endif %}
- </metadata>
- <manifest>
- <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" />
- {%- for item in manifest_items %}
- <item id="{{ item.id }}" href="{{ item.href }}" media-type="{{ item.media_type }}" />
- {%- endfor %}
- </manifest>
- <spine toc="ncx">
- {%- for spine in spines %}
- {%- if spine.linear %}
- <itemref idref="{{ spine.idref }}" />
- {%- else %}
- <itemref idref="{{ spine.idref }}" linear="no" />
- {%- endif %}
- {%- endfor %}
- </spine>
- <guide>
- {%- for guide in guides %}
- <reference type="{{ guide.type }}" title="{{ guide.title }}" href="{{ guide.uri }}" />
- {%- endfor %}
- </guide>
-</package>
diff --git a/sphinx/templates/epub2/mimetype b/sphinx/templates/epub2/mimetype
deleted file mode 100644
index 57ef03f24..000000000
--- a/sphinx/templates/epub2/mimetype
+++ /dev/null
@@ -1 +0,0 @@
-application/epub+zip \ No newline at end of file
diff --git a/sphinx/templates/epub2/toc.ncx_t b/sphinx/templates/epub2/toc.ncx_t
deleted file mode 100644
index 9bb701908..000000000
--- a/sphinx/templates/epub2/toc.ncx_t
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0"?>
-<ncx version="2005-1" xmlns="http://www.daisy.org/z3986/2005/ncx/">
- <head>
- <meta name="dtb:uid" content="{{ uid }}"/>
- <meta name="dtb:depth" content="{{ level }}"/>
- <meta name="dtb:totalPageCount" content="0"/>
- <meta name="dtb:maxPageNumber" content="0"/>
- </head>
- <docTitle>
- <text>{{ title }}</text>
- </docTitle>
- <navMap>
-{{ navpoints }}
- </navMap>
-</ncx>
diff --git a/sphinx/templates/quickstart/Makefile_t b/sphinx/templates/quickstart/Makefile_t
index 4639a982b..2858d9bf7 100644
--- a/sphinx/templates/quickstart/Makefile_t
+++ b/sphinx/templates/quickstart/Makefile_t
@@ -27,7 +27,6 @@ help:
@echo " applehelp to make an Apple Help Book"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
- @echo " epub3 to make an epub3"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
@@ -122,12 +121,6 @@ epub:
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-.PHONY: epub3
-epub3:
- $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
- @echo
- @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
-
.PHONY: latex
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
diff --git a/sphinx/templates/quickstart/make.bat_t b/sphinx/templates/quickstart/make.bat_t
index 8438b5f7e..230977488 100644
--- a/sphinx/templates/quickstart/make.bat_t
+++ b/sphinx/templates/quickstart/make.bat_t
@@ -29,7 +29,6 @@ if "%1" == "help" (
echo. qthelp to make HTML files and a qthelp project
echo. devhelp to make HTML files and a Devhelp project
echo. epub to make an epub
- echo. epub3 to make an epub3
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. text to make text files
echo. man to make manual pages
@@ -153,14 +152,6 @@ if "%1" == "epub" (
goto end
)
-if "%1" == "epub3" (
- %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The epub3 file is in %BUILDDIR%/epub3.
- goto end
-)
-
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
if errorlevel 1 exit /b 1
diff --git a/sphinx/testing/__init__.py b/sphinx/testing/__init__.py
index e246be8c0..c551da36f 100644
--- a/sphinx/testing/__init__.py
+++ b/sphinx/testing/__init__.py
@@ -10,6 +10,6 @@
pytest_plugins = 'sphinx.testing.fixtures'
- :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.
"""
diff --git a/sphinx/testing/fixtures.py b/sphinx/testing/fixtures.py
index 624adc03a..be0037b70 100644
--- a/sphinx/testing/fixtures.py
+++ b/sphinx/testing/fixtures.py
@@ -5,7 +5,7 @@
Sphinx test fixtures for pytest
- :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
diff --git a/sphinx/testing/path.py b/sphinx/testing/path.py
index 634d61332..30c4b49f3 100644
--- a/sphinx/testing/path.py
+++ b/sphinx/testing/path.py
@@ -3,7 +3,7 @@
sphinx.testing.path
~~~~~~~~~~~~~~~~~~~
- :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
diff --git a/sphinx/testing/util.py b/sphinx/testing/util.py
index 91ae821ac..fb2e8f1f5 100644
--- a/sphinx/testing/util.py
+++ b/sphinx/testing/util.py
@@ -5,7 +5,7 @@
Sphinx test suite 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.
"""
import os
diff --git a/sphinx/texinputs/sphinx.sty b/sphinx/texinputs/sphinx.sty
index 80b81f6d6..2b41673db 100644
--- a/sphinx/texinputs/sphinx.sty
+++ b/sphinx/texinputs/sphinx.sty
@@ -183,7 +183,7 @@
% control caption around literal-block
\RequirePackage{capt-of}
\RequirePackage{needspace}
-
+\RequirePackage{remreset}% provides \@removefromreset
% to make pdf with correct encoded bookmarks in Japanese
% this should precede the hyperref package
\ifx\kanjiskip\@undefined
@@ -247,7 +247,10 @@
\fi
\DeclareStringOption[0]{maxlistdepth}% \newcommand*\spx@opt@maxlistdepth{0}
-
+\DeclareStringOption[-1]{numfigreset}
+\DeclareBoolOption[false]{nonumfigreset}
+\DeclareBoolOption[false]{mathnumfig}
+% \DeclareBoolOption[false]{usespart}% not used
% dimensions, we declare the \dimen registers here.
\newdimen\sphinxverbatimsep
\newdimen\sphinxverbatimborder
@@ -349,6 +352,9 @@
\ProcessKeyvalOptions*
% don't allow use of maxlistdepth via \sphinxsetup.
\DisableKeyvalOption{sphinx}{maxlistdepth}
+\DisableKeyvalOption{sphinx}{numfigreset}
+\DisableKeyvalOption{sphinx}{nonumfigreset}
+\DisableKeyvalOption{sphinx}{mathnumfig}
% user interface: options can be changed midway in a document!
\newcommand\sphinxsetup[1]{\setkeys{sphinx}{#1}}
@@ -657,6 +663,7 @@
{\abovecaptionskip\smallskipamount
\belowcaptionskip\smallskipamount}
+
%% FOOTNOTES
%
% Support large numbered footnotes in minipage
@@ -665,6 +672,111 @@
\def\thempfootnote{\arabic{mpfootnote}}
+%% NUMBERING OF FIGURES, TABLES, AND LITERAL BLOCKS
+\ltx@ifundefined{c@chapter}
+ {\newcounter{literalblock}}%
+ {\newcounter{literalblock}[chapter]%
+ \def\theliteralblock{\ifnum\c@chapter>\z@\arabic{chapter}.\fi
+ \arabic{literalblock}}%
+ }%
+\ifspx@opt@nonumfigreset
+ \ltx@ifundefined{c@chapter}{}{%
+ \@removefromreset{figure}{chapter}%
+ \@removefromreset{table}{chapter}%
+ \@removefromreset{literalblock}{chapter}%
+ \ifspx@opt@mathnumfig
+ \@removefromreset{equation}{chapter}%
+ \fi
+ }%
+ \def\thefigure{\arabic{figure}}%
+ \def\thetable {\arabic{table}}%
+ \def\theliteralblock{\arabic{literalblock}}%
+ \ifspx@opt@mathnumfig
+ \def\theequation{\arabic{equation}}%
+ \fi
+\else
+\let\spx@preAthefigure\@empty
+\let\spx@preBthefigure\@empty
+% \ifspx@opt@usespart % <-- LaTeX writer could pass such a 'usespart' boolean
+% % as sphinx.sty package option
+% If document uses \part, (triggered in Sphinx by latex_toplevel_sectioning)
+% LaTeX core per default does not reset chapter or section
+% counters at each part.
+% But if we modify this, we need to redefine \thechapter, \thesection to
+% include the part number and this will cause problems in table of contents
+% because of too wide numbering. Simplest is to do nothing.
+% \fi
+\ifnum\spx@opt@numfigreset>0
+ \ltx@ifundefined{c@chapter}
+ {}
+ {\g@addto@macro\spx@preAthefigure{\ifnum\c@chapter>\z@\arabic{chapter}.}%
+ \g@addto@macro\spx@preBthefigure{\fi}}%
+\fi
+\ifnum\spx@opt@numfigreset>1
+ \@addtoreset{figure}{section}%
+ \@addtoreset{table}{section}%
+ \@addtoreset{literalblock}{section}%
+ \ifspx@opt@mathnumfig
+ \@addtoreset{equation}{section}%
+ \fi
+ \g@addto@macro\spx@preAthefigure{\ifnum\c@section>\z@\arabic{section}.}%
+ \g@addto@macro\spx@preBthefigure{\fi}%
+\fi
+\ifnum\spx@opt@numfigreset>2
+ \@addtoreset{figure}{subsection}%
+ \@addtoreset{table}{subsection}%
+ \@addtoreset{literalblock}{subsection}%
+ \ifspx@opt@mathnumfig
+ \@addtoreset{equation}{subsection}%
+ \fi
+ \g@addto@macro\spx@preAthefigure{\ifnum\c@subsection>\z@\arabic{subsection}.}%
+ \g@addto@macro\spx@preBthefigure{\fi}%
+\fi
+\ifnum\spx@opt@numfigreset>3
+ \@addtoreset{figure}{subsubsection}%
+ \@addtoreset{table}{subsubsection}%
+ \@addtoreset{literalblock}{subsubsection}%
+ \ifspx@opt@mathnumfig
+ \@addtoreset{equation}{subsubsection}%
+ \fi
+ \g@addto@macro\spx@preAthefigure{\ifnum\c@subsubsection>\z@\arabic{subsubsection}.}%
+ \g@addto@macro\spx@preBthefigure{\fi}%
+\fi
+\ifnum\spx@opt@numfigreset>4
+ \@addtoreset{figure}{paragraph}%
+ \@addtoreset{table}{paragraph}%
+ \@addtoreset{literalblock}{paragraph}%
+ \ifspx@opt@mathnumfig
+ \@addtoreset{equation}{paragraph}%
+ \fi
+ \g@addto@macro\spx@preAthefigure{\ifnum\c@subparagraph>\z@\arabic{subparagraph}.}%
+ \g@addto@macro\spx@preBthefigure{\fi}%
+\fi
+\ifnum\spx@opt@numfigreset>5
+ \@addtoreset{figure}{subparagraph}%
+ \@addtoreset{table}{subparagraph}%
+ \@addtoreset{literalblock}{subparagraph}%
+ \ifspx@opt@mathnumfig
+ \@addtoreset{equation}{subparagraph}%
+ \fi
+ \g@addto@macro\spx@preAthefigure{\ifnum\c@subsubparagraph>\z@\arabic{subsubparagraph}.}%
+ \g@addto@macro\spx@preBthefigure{\fi}%
+\fi
+\expandafter\g@addto@macro
+\expandafter\spx@preAthefigure\expandafter{\spx@preBthefigure}%
+\let\thefigure\spx@preAthefigure
+\let\thetable\spx@preAthefigure
+\let\theliteralblock\spx@preAthefigure
+\g@addto@macro\thefigure{\arabic{figure}}%
+\g@addto@macro\thetable{\arabic{table}}%
+\g@addto@macro\theliteralblock{\arabic{literalblock}}%
+ \ifspx@opt@mathnumfig
+ \let\theequation\spx@preAthefigure
+ \g@addto@macro\theequation{\arabic{equation}}%
+ \fi
+\fi
+
+
%% LITERAL BLOCKS
%
% Based on use of "fancyvrb.sty"'s Verbatim.
@@ -680,15 +792,6 @@
\let\endOriginalVerbatim\endVerbatim
% for captions of literal blocks
-% also define `\theH...` macros for hyperref
-\newcounter{literalblock}
-\ltx@ifundefined{c@chapter}
- {\@addtoreset{literalblock}{section}
- \def\theliteralblock {\ifnum\c@section>\z@ \thesection.\fi\arabic{literalblock}}
- \def\theHliteralblock {\theHsection.\arabic{literalblock}}}
- {\@addtoreset{literalblock}{chapter}
- \def\theliteralblock {\ifnum\c@chapter>\z@ \thechapter.\fi\arabic{literalblock}}
- \def\theHliteralblock {\theHchapter.\arabic{literalblock}}}
% at start of caption title
\newcommand*{\fnum@literalblock}{\literalblockname\nobreakspace\theliteralblock}
% this will be overwritten in document preamble by Babel translation
@@ -1356,8 +1459,8 @@
%
\newenvironment{productionlist}{%
% \def\sphinxoptional##1{{\Large[}##1{\Large]}}
- \def\production##1##2{\\\sphinxcode{##1}&::=&\sphinxcode{##2}}%
- \def\productioncont##1{\\& &\sphinxcode{##1}}%
+ \def\production##1##2{\\\sphinxcode{\sphinxupquote{##1}}&::=&\sphinxcode{\sphinxupquote{##2}}}%
+ \def\productioncont##1{\\& &\sphinxcode{\sphinxupquote{##1}}}%
\parindent=2em
\indent
\setlength{\LTpre}{0pt}%
@@ -1438,15 +1541,13 @@
%% TEXT STYLING
%
-% Some custom font markup commands.
-\protected\def\sphinxstrong#1{{\textbf{#1}}}
% to obtain straight quotes we execute \@noligs as patched by upquote, and
% \scantokens is needed in cases where it would be too late for the macro to
% first set catcodes and then fetch its argument. We also make the contents
% breakable at non-escaped . , ; ? ! / using \sphinxbreaksviaactive.
% the macro must be protected if it ends up used in moving arguments,
% in 'alltt' \@noligs is done already, and the \scantokens must be avoided.
-\protected\def\sphinxcode#1{{\def\@tempa{alltt}%
+\protected\def\sphinxupquote#1{{\def\@tempa{alltt}%
\ifx\@tempa\@currenvir\else
\ifspx@opt@inlineliteralwraps
\sphinxbreaksviaactive\let\sphinxafterbreak\empty
@@ -1457,12 +1558,15 @@
\let\do@noligs\sphinx@do@noligs
\@noligs\endlinechar\m@ne\everyeof{}% (<- in case inside \sphinxhref)
\expandafter\scantokens
- \fi {\texttt{#1}}}}
+ \fi {{#1}}}}% extra brace pair to fix end-space gobbling issue...
\def\sphinx@do@noligs #1{\catcode`#1\active\begingroup\lccode`\~`#1\relax
\lowercase{\endgroup\def~{\leavevmode\kern\z@\char`#1 }}}
\def\sphinx@literal@nolig@list {\do\`\do\<\do\>\do\'\do\-}%
-\protected\def\sphinxbfcode#1{\sphinxcode{\bfseries{}#1}}
+% Some custom font markup commands.
+\protected\def\sphinxstrong#1{\textbf{#1}}
+\protected\def\sphinxcode#1{\texttt{#1}}
+\protected\def\sphinxbfcode#1{\textbf{\sphinxcode{#1}}}
\protected\def\sphinxemail#1{\textsf{#1}}
\protected\def\sphinxtablecontinued#1{\textsf{#1}}
\protected\def\sphinxtitleref#1{\emph{#1}}
@@ -1476,21 +1580,21 @@
% additional customizable styling
% FIXME: convert this to package options ?
-\protected\def\sphinxstyleindexentry {\texttt}
-\protected\def\sphinxstyleindexextra #1{ \emph{(#1)}}
-\protected\def\sphinxstyleindexpageref {, \pageref}
-\protected\def\sphinxstyletopictitle #1{\textbf{#1}\par\medskip}
+\protected\def\sphinxstyleindexentry #1{\texttt{#1}}
+\protected\def\sphinxstyleindexextra #1{ \emph{(#1)}}
+\protected\def\sphinxstyleindexpageref #1{, \pageref{#1}}
+\protected\def\sphinxstyletopictitle #1{\textbf{#1}\par\medskip}
\let\sphinxstylesidebartitle\sphinxstyletopictitle
-\protected\def\sphinxstyleothertitle {\textbf}
+\protected\def\sphinxstyleothertitle #1{\textbf{#1}}
\protected\def\sphinxstylesidebarsubtitle #1{~\\\textbf{#1} \smallskip}
% \text.. commands do not allow multiple paragraphs
\protected\def\sphinxstyletheadfamily {\sffamily}
-\protected\def\sphinxstyleemphasis {\emph}
+\protected\def\sphinxstyleemphasis #1{\emph{#1}}
\protected\def\sphinxstyleliteralemphasis#1{\emph{\sphinxcode{#1}}}
-\protected\def\sphinxstylestrong {\textbf}
-\protected\def\sphinxstyleliteralstrong {\sphinxbfcode}
-\protected\def\sphinxstyleabbreviation {\textsc}
-\protected\def\sphinxstyleliteralintitle {\sphinxcode}
+\protected\def\sphinxstylestrong #1{\textbf{#1}}
+\protected\def\sphinxstyleliteralstrong#1{\sphinxbfcode{#1}}
+\protected\def\sphinxstyleabbreviation #1{\textsc{#1}}
+\protected\def\sphinxstyleliteralintitle#1{\sphinxcode{#1}}
\newcommand*\sphinxstylecodecontinued[1]{\footnotesize(#1)}%
\newcommand*\sphinxstylecodecontinues[1]{\footnotesize(#1)}%
% figure legend comes after caption and may contain arbitrary body elements
diff --git a/sphinx/texinputs/sphinxhowto.cls b/sphinx/texinputs/sphinxhowto.cls
index 90680fdee..11a49a205 100644
--- a/sphinx/texinputs/sphinxhowto.cls
+++ b/sphinx/texinputs/sphinxhowto.cls
@@ -25,6 +25,7 @@
% reset these counters in your preamble.
%
\setcounter{secnumdepth}{2}
+\setcounter{tocdepth}{2}% i.e. section and subsection
% Change the title page to look a bit better, and fit in with the fncychap
% ``Bjarne'' style a bit better.
diff --git a/sphinx/themes/agogo/layout.html b/sphinx/themes/agogo/layout.html
index dcf5b0ed7..8bd476cad 100644
--- a/sphinx/themes/agogo/layout.html
+++ b/sphinx/themes/agogo/layout.html
@@ -5,7 +5,7 @@
Sphinx layout template for the agogo theme, originally written
by Andi Albrecht.
- :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" %}
diff --git a/sphinx/themes/agogo/static/agogo.css_t b/sphinx/themes/agogo/static/agogo.css_t
index f9e0d1637..0b5bbe16b 100644
--- a/sphinx/themes/agogo/static/agogo.css_t
+++ b/sphinx/themes/agogo/static/agogo.css_t
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- agogo 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.
*
*/
diff --git a/sphinx/themes/basic/defindex.html b/sphinx/themes/basic/defindex.html
index 303f9668b..5c92348b9 100644
--- a/sphinx/themes/basic/defindex.html
+++ b/sphinx/themes/basic/defindex.html
@@ -4,7 +4,7 @@
Default template for the "index" page.
- :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.
#}{{ warn('Now base template defindex.html is deprecated.') }}
{%- extends "layout.html" %}
diff --git a/sphinx/themes/basic/domainindex.html b/sphinx/themes/basic/domainindex.html
index dafbf72dc..58f0fc990 100644
--- a/sphinx/themes/basic/domainindex.html
+++ b/sphinx/themes/basic/domainindex.html
@@ -4,7 +4,7 @@
Template for domain indices (module index, ...).
- :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 "layout.html" %}
diff --git a/sphinx/themes/basic/genindex-single.html b/sphinx/themes/basic/genindex-single.html
index bbdbfd0d0..1f61fa0f5 100644
--- a/sphinx/themes/basic/genindex-single.html
+++ b/sphinx/themes/basic/genindex-single.html
@@ -4,7 +4,7 @@
Template for a "single" page of a split index.
- :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.
#}
{% macro indexentries(firstname, links) %}
diff --git a/sphinx/themes/basic/genindex-split.html b/sphinx/themes/basic/genindex-split.html
index 12887c10e..42a7a4be3 100644
--- a/sphinx/themes/basic/genindex-split.html
+++ b/sphinx/themes/basic/genindex-split.html
@@ -4,7 +4,7 @@
Template for a "split" index overview page.
- :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 "layout.html" %}
diff --git a/sphinx/themes/basic/genindex.html b/sphinx/themes/basic/genindex.html
index fd96ba642..c852f25e8 100644
--- a/sphinx/themes/basic/genindex.html
+++ b/sphinx/themes/basic/genindex.html
@@ -4,7 +4,7 @@
Template for an "all-in-one" index.
- :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.
#}
{% macro indexentries(firstname, links) %}
diff --git a/sphinx/themes/basic/globaltoc.html b/sphinx/themes/basic/globaltoc.html
index 3b3a9201a..dc6fea373 100644
--- a/sphinx/themes/basic/globaltoc.html
+++ b/sphinx/themes/basic/globaltoc.html
@@ -4,7 +4,7 @@
Sphinx sidebar template: global table of contents.
- :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.
#}
<h3><a href="{{ pathto(master_doc) }}">{{ _('Table Of Contents') }}</a></h3>
diff --git a/sphinx/themes/basic/layout.html b/sphinx/themes/basic/layout.html
index b337a977e..75c1ca568 100644
--- a/sphinx/themes/basic/layout.html
+++ b/sphinx/themes/basic/layout.html
@@ -4,7 +4,7 @@
Master layout template for Sphinx themes.
- :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.
#}
{%- block doctype -%}{%- if html5_doctype %}
diff --git a/sphinx/themes/basic/localtoc.html b/sphinx/themes/basic/localtoc.html
index ca1a73ac0..5d3c7f4fd 100644
--- a/sphinx/themes/basic/localtoc.html
+++ b/sphinx/themes/basic/localtoc.html
@@ -4,7 +4,7 @@
Sphinx sidebar template: local table of contents.
- :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.
#}
{%- if display_toc %}
diff --git a/sphinx/themes/basic/page.html b/sphinx/themes/basic/page.html
index e96f667ba..d2f0bd3f3 100644
--- a/sphinx/themes/basic/page.html
+++ b/sphinx/themes/basic/page.html
@@ -4,7 +4,7 @@
Master template for simple pages.
- :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 "layout.html" %}
diff --git a/sphinx/themes/basic/relations.html b/sphinx/themes/basic/relations.html
index d7fb6f0a4..7c0f4e711 100644
--- a/sphinx/themes/basic/relations.html
+++ b/sphinx/themes/basic/relations.html
@@ -4,7 +4,7 @@
Sphinx sidebar template: relation links.
- :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.
#}
{%- if prev %}
diff --git a/sphinx/themes/basic/search.html b/sphinx/themes/basic/search.html
index ce8fa8924..32432a1e3 100644
--- a/sphinx/themes/basic/search.html
+++ b/sphinx/themes/basic/search.html
@@ -4,7 +4,7 @@
Template for the search page.
- :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 "layout.html" %}
diff --git a/sphinx/themes/basic/searchbox.html b/sphinx/themes/basic/searchbox.html
index 17d84a02b..506877410 100644
--- a/sphinx/themes/basic/searchbox.html
+++ b/sphinx/themes/basic/searchbox.html
@@ -4,18 +4,20 @@
Sphinx sidebar template: quick search box.
- :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.
#}
{%- if pagename != "search" and builder != "singlehtml" %}
<div id="searchbox" style="display: none" role="search">
<h3>{{ _('Quick search') }}</h3>
+ <div class="searchformwrapper">
<form class="search" action="{{ pathto('search') }}" method="get">
- <div><input type="text" name="q" /></div>
- <div><input type="submit" value="{{ _('Go') }}" /></div>
+ <input type="text" name="q" />
+ <input type="submit" value="{{ _('Go') }}" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
+ </div>
</div>
<script type="text/javascript">$('#searchbox').show(0);</script>
{%- endif %}
diff --git a/sphinx/themes/basic/searchresults.html b/sphinx/themes/basic/searchresults.html
index e04ec15d6..1371bf93c 100644
--- a/sphinx/themes/basic/searchresults.html
+++ b/sphinx/themes/basic/searchresults.html
@@ -4,7 +4,7 @@
Template for the body of the search results page.
- :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.
#}
<h1 id="search-documentation">{{ _('Search') }}</h1>
diff --git a/sphinx/themes/basic/sourcelink.html b/sphinx/themes/basic/sourcelink.html
index 3d4f76ddb..ecde6d3c5 100644
--- a/sphinx/themes/basic/sourcelink.html
+++ b/sphinx/themes/basic/sourcelink.html
@@ -4,7 +4,7 @@
Sphinx sidebar template: "show source" link.
- :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.
#}
{%- if show_source and has_source and sourcename %}
diff --git a/sphinx/themes/basic/static/basic.css_t b/sphinx/themes/basic/static/basic.css_t
index d16c760cb..efb997d8f 100644
--- a/sphinx/themes/basic/static/basic.css_t
+++ b/sphinx/themes/basic/static/basic.css_t
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- basic 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.
*
*/
@@ -82,9 +82,21 @@ div.sphinxsidebar input {
}
div.sphinxsidebar #searchbox input[type="text"] {
- width: 170px;
+ float: left;
+ width: 80%;
+ padding: 0.25em;
+ box-sizing: border-box;
}
+div.sphinxsidebar #searchbox input[type="submit"] {
+ float: left;
+ width: 20%;
+ border-left: none;
+ padding: 0.25em;
+ box-sizing: border-box;
+}
+
+
img {
border: 0;
max-width: 100%;
diff --git a/sphinx/themes/basic/static/doctools.js_t b/sphinx/themes/basic/static/doctools.js_t
index 326856cfc..b261a44f3 100644
--- a/sphinx/themes/basic/static/doctools.js_t
+++ b/sphinx/themes/basic/static/doctools.js_t
@@ -4,7 +4,7 @@
*
* Sphinx JavaScript utilities for all documentation.
*
- * :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.
*
*/
diff --git a/sphinx/themes/basic/static/searchtools.js_t b/sphinx/themes/basic/static/searchtools.js_t
index 306fdf55f..e707bb1ea 100644
--- a/sphinx/themes/basic/static/searchtools.js_t
+++ b/sphinx/themes/basic/static/searchtools.js_t
@@ -4,7 +4,7 @@
*
* Sphinx JavaScript utilities for the full-text search.
*
- * :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.
*
*/
diff --git a/sphinx/themes/basic/static/websupport.js b/sphinx/themes/basic/static/websupport.js
index a95bc3a66..78e14bb4a 100644
--- a/sphinx/themes/basic/static/websupport.js
+++ b/sphinx/themes/basic/static/websupport.js
@@ -4,7 +4,7 @@
*
* sphinx.websupport utilities for all documentation.
*
- * :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.
*
*/
diff --git a/sphinx/themes/classic/layout.html b/sphinx/themes/classic/layout.html
index 50b6dc9e0..19f3d0279 100644
--- a/sphinx/themes/classic/layout.html
+++ b/sphinx/themes/classic/layout.html
@@ -4,7 +4,7 @@
Sphinx layout template for the classic 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" %}
diff --git a/sphinx/themes/classic/static/classic.css_t b/sphinx/themes/classic/static/classic.css_t
index 25e1c0261..a84ef8696 100644
--- a/sphinx/themes/classic/static/classic.css_t
+++ b/sphinx/themes/classic/static/classic.css_t
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- classic 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.
*
*/
diff --git a/sphinx/themes/classic/static/sidebar.js_t b/sphinx/themes/classic/static/sidebar.js_t
index 494df24f9..ce8361d9b 100644
--- a/sphinx/themes/classic/static/sidebar.js_t
+++ b/sphinx/themes/classic/static/sidebar.js_t
@@ -16,7 +16,7 @@
* Once the browser is closed the cookie is deleted and the position
* reset to the default (expanded).
*
- * :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.
*
*/
diff --git a/sphinx/themes/epub/epub-cover.html b/sphinx/themes/epub/epub-cover.html
index 763be11ff..436c36aa0 100644
--- a/sphinx/themes/epub/epub-cover.html
+++ b/sphinx/themes/epub/epub-cover.html
@@ -4,7 +4,7 @@
Sample template for the html cover page.
- :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 "layout.html" %}
diff --git a/sphinx/themes/epub/layout.html b/sphinx/themes/epub/layout.html
index f27e4daa1..84d4bf31c 100644
--- a/sphinx/themes/epub/layout.html
+++ b/sphinx/themes/epub/layout.html
@@ -4,7 +4,7 @@
Sphinx layout template for the epub 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" %}
diff --git a/sphinx/themes/epub/static/epub.css_t b/sphinx/themes/epub/static/epub.css_t
index f8ef61e7c..0e8808f4a 100644
--- a/sphinx/themes/epub/static/epub.css_t
+++ b/sphinx/themes/epub/static/epub.css_t
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- epub 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.
*
*/
diff --git a/sphinx/themes/haiku/layout.html b/sphinx/themes/haiku/layout.html
index a6e42d2d2..c93c52dbd 100644
--- a/sphinx/themes/haiku/layout.html
+++ b/sphinx/themes/haiku/layout.html
@@ -4,7 +4,7 @@
Sphinx layout template for the haiku 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" %}
diff --git a/sphinx/themes/haiku/static/haiku.css_t b/sphinx/themes/haiku/static/haiku.css_t
index cb4a2fb62..16d49fea4 100644
--- a/sphinx/themes/haiku/static/haiku.css_t
+++ b/sphinx/themes/haiku/static/haiku.css_t
@@ -16,7 +16,7 @@
* Braden Ewing <brewin@gmail.com>
* Humdinger <humdingerb@gmail.com>
*
- * :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.
*
*/
diff --git a/sphinx/themes/nature/static/nature.css_t b/sphinx/themes/nature/static/nature.css_t
index bb0c83bac..ff2b1d5ff 100644
--- a/sphinx/themes/nature/static/nature.css_t
+++ b/sphinx/themes/nature/static/nature.css_t
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- nature 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.
*
*/
@@ -125,14 +125,11 @@ div.sphinxsidebar input {
font-size: 1em;
}
-div.sphinxsidebar input[type=text]{
+div.sphinxsidebar .searchformwrapper {
margin-left: 20px;
+ margin-right: 20px;
}
-div.sphinxsidebar input[type=submit]{
- margin-left: 20px;
-}
-
/* -- body styles ----------------------------------------------------------- */
a {
diff --git a/sphinx/themes/nonav/layout.html b/sphinx/themes/nonav/layout.html
index 4d79446c4..5e79b2a7a 100644
--- a/sphinx/themes/nonav/layout.html
+++ b/sphinx/themes/nonav/layout.html
@@ -4,7 +4,7 @@
Sphinx layout template for the any help system 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" %}
diff --git a/sphinx/themes/nonav/static/nonav.css b/sphinx/themes/nonav/static/nonav.css
index 554b4b912..b41bd2044 100644
--- a/sphinx/themes/nonav/static/nonav.css
+++ b/sphinx/themes/nonav/static/nonav.css
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- nonav 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.
*
*/
diff --git a/sphinx/themes/pyramid/static/epub.css b/sphinx/themes/pyramid/static/epub.css
index a0cffc066..0df0eaeeb 100644
--- a/sphinx/themes/pyramid/static/epub.css
+++ b/sphinx/themes/pyramid/static/epub.css
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- default 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.
*
*/
diff --git a/sphinx/themes/pyramid/static/pyramid.css_t b/sphinx/themes/pyramid/static/pyramid.css_t
index ca36ef6ac..792f45452 100644
--- a/sphinx/themes/pyramid/static/pyramid.css_t
+++ b/sphinx/themes/pyramid/static/pyramid.css_t
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- pylons 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.
*
*/
@@ -148,12 +148,9 @@ div.sphinxsidebar input {
font-size: 1em;
}
-div.sphinxsidebar input[type=text]{
- margin-left: 20px;
-}
-
-div.sphinxsidebar input[type=submit]{
+div.sphinxsidebar .searchformwrapper {
margin-left: 20px;
+ margin-right: 20px;
}
/* -- sidebars -------------------------------------------------------------- */
diff --git a/sphinx/themes/scrolls/layout.html b/sphinx/themes/scrolls/layout.html
index 893ae17d3..9ebe3b35d 100644
--- a/sphinx/themes/scrolls/layout.html
+++ b/sphinx/themes/scrolls/layout.html
@@ -5,7 +5,7 @@
Sphinx layout template for the scrolls theme, originally written
by Armin Ronacher.
- :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" %}
diff --git a/sphinx/themes/scrolls/static/scrolls.css_t b/sphinx/themes/scrolls/static/scrolls.css_t
index 996a6d22a..3edd869af 100644
--- a/sphinx/themes/scrolls/static/scrolls.css_t
+++ b/sphinx/themes/scrolls/static/scrolls.css_t
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- scrolls 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.
*
*/
diff --git a/sphinx/themes/sphinxdoc/layout.html b/sphinx/themes/sphinxdoc/layout.html
index b37567bf8..91349c970 100644
--- a/sphinx/themes/sphinxdoc/layout.html
+++ b/sphinx/themes/sphinxdoc/layout.html
@@ -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" %}
diff --git a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t
index 3b88e888e..2f4275a6c 100644
--- a/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t
+++ b/sphinx/themes/sphinxdoc/static/sphinxdoc.css_t
@@ -5,7 +5,7 @@
* Sphinx stylesheet -- sphinxdoc theme. Originally created by
* Armin Ronacher for Werkzeug.
*
- * :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.
*
*/
diff --git a/sphinx/themes/traditional/static/traditional.css_t b/sphinx/themes/traditional/static/traditional.css_t
index fb0ab54c9..e5fda3bab 100644
--- a/sphinx/themes/traditional/static/traditional.css_t
+++ b/sphinx/themes/traditional/static/traditional.css_t
@@ -4,7 +4,7 @@
*
* Sphinx stylesheet -- traditional docs.python.org 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.
*
*/
diff --git a/sphinx/theming.py b/sphinx/theming.py
index 78c73b63f..33c4c76be 100644
--- a/sphinx/theming.py
+++ b/sphinx/theming.py
@@ -5,7 +5,7 @@
Theming support for 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.
"""
diff --git a/sphinx/transforms/__init__.py b/sphinx/transforms/__init__.py
index 0ceced214..acfff6a4d 100644
--- a/sphinx/transforms/__init__.py
+++ b/sphinx/transforms/__init__.py
@@ -5,7 +5,7 @@
Docutils transforms used by Sphinx when reading documents.
- :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.
"""
@@ -346,5 +346,5 @@ class SphinxSmartQuotes(SmartQuotes):
texttype = {True: 'literal', # "literal" text is not changed:
False: 'plain'}
for txtnode in txtnodes:
- smartquotable = not is_smartquotable(txtnode)
- yield (texttype[smartquotable], txtnode.astext())
+ notsmartquotable = not is_smartquotable(txtnode)
+ yield (texttype[notsmartquotable], txtnode.astext())
diff --git a/sphinx/transforms/compact_bullet_list.py b/sphinx/transforms/compact_bullet_list.py
index 8c930c8bc..0121dd12f 100644
--- a/sphinx/transforms/compact_bullet_list.py
+++ b/sphinx/transforms/compact_bullet_list.py
@@ -5,7 +5,7 @@
Docutils transforms used by Sphinx when reading documents.
- :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.
"""
diff --git a/sphinx/transforms/i18n.py b/sphinx/transforms/i18n.py
index d08cc81f4..5ae33d86a 100644
--- a/sphinx/transforms/i18n.py
+++ b/sphinx/transforms/i18n.py
@@ -5,7 +5,7 @@
Docutils transforms used by Sphinx when reading documents.
- :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.
"""
diff --git a/sphinx/transforms/post_transforms/__init__.py b/sphinx/transforms/post_transforms/__init__.py
index a3f742e53..b65d929e2 100644
--- a/sphinx/transforms/post_transforms/__init__.py
+++ b/sphinx/transforms/post_transforms/__init__.py
@@ -5,7 +5,7 @@
Docutils transforms used by 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.
"""
diff --git a/sphinx/transforms/post_transforms/images.py b/sphinx/transforms/post_transforms/images.py
index 788684e40..d09f57e67 100644
--- a/sphinx/transforms/post_transforms/images.py
+++ b/sphinx/transforms/post_transforms/images.py
@@ -5,7 +5,7 @@
Docutils transforms used by 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.
"""
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 4b62dc5f0..938ec71db 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -5,7 +5,7 @@
Utility functions for 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 absolute_import
diff --git a/sphinx/util/console.py b/sphinx/util/console.py
index 63a619f55..8069dd9c9 100644
--- a/sphinx/util/console.py
+++ b/sphinx/util/console.py
@@ -5,7 +5,7 @@
Format colored console output.
- :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.
"""
diff --git a/sphinx/util/docfields.py b/sphinx/util/docfields.py
index 4bce071c0..2f952d7cc 100644
--- a/sphinx/util/docfields.py
+++ b/sphinx/util/docfields.py
@@ -6,7 +6,7 @@
"Doc fields" are reST field lists in object descriptions that will
be domain-specifically transformed to a more appealing presentation.
- :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
diff --git a/sphinx/util/docstrings.py b/sphinx/util/docstrings.py
index c2ef91a66..bc4b96a56 100644
--- a/sphinx/util/docstrings.py
+++ b/sphinx/util/docstrings.py
@@ -5,7 +5,7 @@
Utilities for docstring processing.
- :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.
"""
diff --git a/sphinx/util/docutils.py b/sphinx/util/docutils.py
index 00ea5919e..bfaff758f 100644
--- a/sphinx/util/docutils.py
+++ b/sphinx/util/docutils.py
@@ -5,7 +5,7 @@
Utility functions for docutils.
- :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
@@ -18,7 +18,7 @@ from contextlib import contextmanager
import docutils
from docutils.languages import get_language
-from docutils.statemachine import ViewList
+from docutils.statemachine import StateMachine, ViewList
from docutils.parsers.rst import directives, roles, convert_directive_function
from docutils.utils import Reporter
@@ -31,8 +31,9 @@ report_re = re.compile('^(.+?:(?:\\d+)?): \\((DEBUG|INFO|WARNING|ERROR|SEVERE)/(
if False:
# For type annotation
- from typing import Any, Callable, Iterator, List, Tuple # NOQA
+ from typing import Any, Callable, Generator, Iterator, List, Tuple # NOQA
from docutils import nodes # NOQA
+ from docutils.statemachine import State # NOQA
from sphinx.environment import BuildEnvironment # NOQA
from sphinx.io import SphinxFileInput # NOQA
@@ -216,3 +217,22 @@ def directive_helper(obj, has_content=None, argument_spec=None, **option_spec):
raise ExtensionError(__('when adding directive classes, no '
'additional arguments may be given'))
return obj
+
+
+@contextmanager
+def switch_source_input(state, content):
+ # type: (State, ViewList) -> Generator
+ """Switch current source input of state temporarily."""
+ try:
+ # remember the original ``get_source_and_line()`` method
+ get_source_and_line = state.memo.reporter.get_source_and_line
+
+ # replace it by new one
+ state_machine = StateMachine([], None)
+ state_machine.input_lines = content
+ state.memo.reporter.get_source_and_line = state_machine.get_source_and_line
+
+ yield
+ finally:
+ # restore the method
+ state.memo.reporter.get_source_and_line = get_source_and_line
diff --git a/sphinx/util/fileutil.py b/sphinx/util/fileutil.py
index fe98117d2..3fd570273 100644
--- a/sphinx/util/fileutil.py
+++ b/sphinx/util/fileutil.py
@@ -5,7 +5,7 @@
File utility functions for 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 absolute_import
diff --git a/sphinx/util/i18n.py b/sphinx/util/i18n.py
index 09b53b4a0..75a8506fa 100644
--- a/sphinx/util/i18n.py
+++ b/sphinx/util/i18n.py
@@ -5,7 +5,7 @@
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 gettext
diff --git a/sphinx/util/images.py b/sphinx/util/images.py
index 1c2b4033a..46187775d 100644
--- a/sphinx/util/images.py
+++ b/sphinx/util/images.py
@@ -5,7 +5,7 @@
Image utility functions for 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 absolute_import
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index da13b8af0..62cd1a7e9 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -5,7 +5,7 @@
Helpers for inspecting Python modules.
- :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
diff --git a/sphinx/util/inventory.py b/sphinx/util/inventory.py
index 40c0dc648..837188b5a 100644
--- a/sphinx/util/inventory.py
+++ b/sphinx/util/inventory.py
@@ -5,7 +5,7 @@
Inventory utility functions for 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.
"""
import re
diff --git a/sphinx/util/jsdump.py b/sphinx/util/jsdump.py
index 73aa2ce03..6776691cf 100644
--- a/sphinx/util/jsdump.py
+++ b/sphinx/util/jsdump.py
@@ -6,7 +6,7 @@
This module implements a simple JavaScript serializer.
Uses the basestring encode function from simplejson by Bob Ippolito.
- :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.
"""
diff --git a/sphinx/util/jsonimpl.py b/sphinx/util/jsonimpl.py
index 09c04dc6a..fbaa72978 100644
--- a/sphinx/util/jsonimpl.py
+++ b/sphinx/util/jsonimpl.py
@@ -5,7 +5,7 @@
JSON serializer implementation wrapper.
- :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.
"""
diff --git a/sphinx/util/logging.py b/sphinx/util/logging.py
index 00c12ec4f..04bf91830 100644
--- a/sphinx/util/logging.py
+++ b/sphinx/util/logging.py
@@ -5,7 +5,7 @@
Logging utility functions for 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 absolute_import
@@ -53,7 +53,7 @@ VERBOSITY_MAP.update({
COLOR_MAP = defaultdict(lambda: 'blue') # type: Dict[int, unicode]
COLOR_MAP.update({
logging.ERROR: 'darkred',
- logging.WARNING: 'darkred',
+ logging.WARNING: 'red',
logging.DEBUG: 'darkgray',
})
diff --git a/sphinx/util/matching.py b/sphinx/util/matching.py
index 401f5f002..bddf84f5c 100644
--- a/sphinx/util/matching.py
+++ b/sphinx/util/matching.py
@@ -5,7 +5,7 @@
Pattern-matching utility functions for 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.
"""
diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py
index cf57edb07..4ff4937b9 100644
--- a/sphinx/util/nodes.py
+++ b/sphinx/util/nodes.py
@@ -5,7 +5,7 @@
Docutils node-related utility functions for 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 absolute_import
diff --git a/sphinx/util/osutil.py b/sphinx/util/osutil.py
index a8bff11c4..b38e58e5d 100644
--- a/sphinx/util/osutil.py
+++ b/sphinx/util/osutil.py
@@ -5,7 +5,7 @@
Operating system-related utility functions for 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
diff --git a/sphinx/util/parallel.py b/sphinx/util/parallel.py
index 9bc3c36e1..6340e4dfc 100644
--- a/sphinx/util/parallel.py
+++ b/sphinx/util/parallel.py
@@ -5,7 +5,7 @@
Parallel building 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.
"""
diff --git a/sphinx/util/png.py b/sphinx/util/png.py
index cc4447e4e..d22839fbf 100644
--- a/sphinx/util/png.py
+++ b/sphinx/util/png.py
@@ -5,7 +5,7 @@
PNG image manipulation helpers.
- :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.
"""
diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py
index 7f7ee4e9b..e1a2bad9a 100644
--- a/sphinx/util/pycompat.py
+++ b/sphinx/util/pycompat.py
@@ -5,7 +5,7 @@
Stuff for Python version compatibility.
- :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.
"""
diff --git a/sphinx/util/requests.py b/sphinx/util/requests.py
index fb8761481..4bd4c042e 100644
--- a/sphinx/util/requests.py
+++ b/sphinx/util/requests.py
@@ -5,7 +5,7 @@
Simple requests package loader
- :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.
"""
diff --git a/sphinx/util/rst.py b/sphinx/util/rst.py
index 6977cda96..5860b0fd5 100644
--- a/sphinx/util/rst.py
+++ b/sphinx/util/rst.py
@@ -5,7 +5,7 @@
reST helper functions.
- :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
diff --git a/sphinx/util/stemmer/__init__.py b/sphinx/util/stemmer/__init__.py
index a41373a81..a10da7370 100644
--- a/sphinx/util/stemmer/__init__.py
+++ b/sphinx/util/stemmer/__init__.py
@@ -5,7 +5,7 @@
Word stemming utilities for 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.
"""
diff --git a/sphinx/util/tags.py b/sphinx/util/tags.py
index 24f64bece..2c4855e91 100644
--- a/sphinx/util/tags.py
+++ b/sphinx/util/tags.py
@@ -3,7 +3,7 @@
sphinx.util.tags
~~~~~~~~~~~~~~~~
- :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.
"""
diff --git a/sphinx/util/template.py b/sphinx/util/template.py
index 87e81d823..a78871349 100644
--- a/sphinx/util/template.py
+++ b/sphinx/util/template.py
@@ -5,7 +5,7 @@
Templates utility functions for 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.
"""
diff --git a/sphinx/util/texescape.py b/sphinx/util/texescape.py
index 07f5390c4..8d37e0f60 100644
--- a/sphinx/util/texescape.py
+++ b/sphinx/util/texescape.py
@@ -5,7 +5,7 @@
TeX escaping helper.
- :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.
"""
diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py
index d30cc230a..793504b77 100644
--- a/sphinx/util/typing.py
+++ b/sphinx/util/typing.py
@@ -5,7 +5,7 @@
The composit types for 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.
"""
diff --git a/sphinx/util/websupport.py b/sphinx/util/websupport.py
index 4d91cb77c..59133b9e1 100644
--- a/sphinx/util/websupport.py
+++ b/sphinx/util/websupport.py
@@ -3,7 +3,7 @@
sphinx.util.websupport
~~~~~~~~~~~~~~~~~~~~~~
- :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.
"""
diff --git a/sphinx/versioning.py b/sphinx/versioning.py
index 1e7c452bd..953ef4f6b 100644
--- a/sphinx/versioning.py
+++ b/sphinx/versioning.py
@@ -6,7 +6,7 @@
Implements the low-level algorithms Sphinx uses for the versioning of
doctrees.
- :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 uuid import uuid4
diff --git a/sphinx/websupport/__init__.py b/sphinx/websupport/__init__.py
index 528343f8c..51d906fa6 100644
--- a/sphinx/websupport/__init__.py
+++ b/sphinx/websupport/__init__.py
@@ -5,7 +5,7 @@
Base Module for web support functions.
- :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.
"""
diff --git a/sphinx/websupport/errors.py b/sphinx/websupport/errors.py
index 587d7e7e7..7456659ec 100644
--- a/sphinx/websupport/errors.py
+++ b/sphinx/websupport/errors.py
@@ -5,7 +5,7 @@
Contains Error classes 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.
"""
diff --git a/sphinx/websupport/search/__init__.py b/sphinx/websupport/search/__init__.py
index 0f90e009b..e1e871ba0 100644
--- a/sphinx/websupport/search/__init__.py
+++ b/sphinx/websupport/search/__init__.py
@@ -5,7 +5,7 @@
Server side search support 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.
"""
diff --git a/sphinx/websupport/search/nullsearch.py b/sphinx/websupport/search/nullsearch.py
index afae1ca57..422b398c9 100644
--- a/sphinx/websupport/search/nullsearch.py
+++ b/sphinx/websupport/search/nullsearch.py
@@ -5,7 +5,7 @@
The default search adapter, does nothing.
- :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.
"""
diff --git a/sphinx/websupport/search/whooshsearch.py b/sphinx/websupport/search/whooshsearch.py
index f007c3cdc..94cce8ed7 100644
--- a/sphinx/websupport/search/whooshsearch.py
+++ b/sphinx/websupport/search/whooshsearch.py
@@ -5,7 +5,7 @@
Whoosh search adapter.
- :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.
"""
diff --git a/sphinx/websupport/search/xapiansearch.py b/sphinx/websupport/search/xapiansearch.py
index 23be038e5..4df4769e2 100644
--- a/sphinx/websupport/search/xapiansearch.py
+++ b/sphinx/websupport/search/xapiansearch.py
@@ -5,7 +5,7 @@
Xapian search adapter.
- :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.
"""
diff --git a/sphinx/websupport/storage/__init__.py b/sphinx/websupport/storage/__init__.py
index adfdec4a5..727e86da4 100644
--- a/sphinx/websupport/storage/__init__.py
+++ b/sphinx/websupport/storage/__init__.py
@@ -5,7 +5,7 @@
Storage for the websupport 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.
"""
diff --git a/sphinx/websupport/storage/differ.py b/sphinx/websupport/storage/differ.py
index 449d038da..1358d8645 100644
--- a/sphinx/websupport/storage/differ.py
+++ b/sphinx/websupport/storage/differ.py
@@ -5,7 +5,7 @@
A differ for creating an HTML representations of proposal diffs
- :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.
"""
diff --git a/sphinx/websupport/storage/sqlalchemy_db.py b/sphinx/websupport/storage/sqlalchemy_db.py
index a2dfc35b9..e1c86dd9d 100644
--- a/sphinx/websupport/storage/sqlalchemy_db.py
+++ b/sphinx/websupport/storage/sqlalchemy_db.py
@@ -6,7 +6,7 @@
SQLAlchemy table and mapper definitions used by the
:class:`sphinx.websupport.storage.sqlalchemystorage.SQLAlchemyStorage`.
- :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.
"""
diff --git a/sphinx/websupport/storage/sqlalchemystorage.py b/sphinx/websupport/storage/sqlalchemystorage.py
index dc5e9400b..b018ea0a3 100644
--- a/sphinx/websupport/storage/sqlalchemystorage.py
+++ b/sphinx/websupport/storage/sqlalchemystorage.py
@@ -5,7 +5,7 @@
An SQLAlchemy storage backend.
- :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.
"""
diff --git a/sphinx/writers/__init__.py b/sphinx/writers/__init__.py
index 6b157a83a..79eacbbfb 100644
--- a/sphinx/writers/__init__.py
+++ b/sphinx/writers/__init__.py
@@ -5,6 +5,6 @@
Custom docutils writers.
- :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.
"""
diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py
index b3419b70a..b3d27e31a 100644
--- a/sphinx/writers/html.py
+++ b/sphinx/writers/html.py
@@ -5,7 +5,7 @@
docutils writers handling Sphinx' custom 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.
"""
diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py
index 1efd060f2..a47fee77e 100644
--- a/sphinx/writers/html5.py
+++ b/sphinx/writers/html5.py
@@ -5,7 +5,7 @@
Experimental docutils writers for HTML5 handling Sphinx' custom 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.
"""
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index 751aabf4e..de472b36c 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -8,7 +8,7 @@
Much of this code is adapted from Dave Kuhlman's "docpy" writer from his
docutils sandbox.
- :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.
"""
@@ -48,7 +48,8 @@ BEGIN_DOC = r'''
URI_SCHEMES = ('mailto:', 'http:', 'https:', 'ftp:')
-SECNUMDEPTH = 3
+LATEXSECTIONNAMES = ["part", "chapter", "section", "subsection",
+ "subsubsection", "paragraph", "subparagraph"]
DEFAULT_SETTINGS = {
'latex_engine': 'pdflatex',
@@ -501,9 +502,9 @@ def rstdim_to_latexdim(width_str):
class LaTeXTranslator(nodes.NodeVisitor):
- sectionnames = ["part", "chapter", "section", "subsection",
- "subsubsection", "paragraph", "subparagraph"]
+ secnumdepth = 2 # legacy sphinxhowto.cls uses this, whereas article.cls
+ # default is originally 3. For book/report, 2 is already LaTeX default.
ignore_missing_images = False
# sphinx specific document classes
@@ -532,16 +533,6 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.compact_list = 0
self.first_param = 0
- # determine top section level
- if builder.config.latex_toplevel_sectioning:
- self.top_sectionlevel = \
- self.sectionnames.index(builder.config.latex_toplevel_sectioning)
- else:
- if document.settings.docclass == 'howto':
- self.top_sectionlevel = 2
- else:
- self.top_sectionlevel = 1
-
# sort out some elements
self.elements = DEFAULT_SETTINGS.copy()
self.elements.update(ADDITIONAL_SETTINGS.get(builder.config.latex_engine, {}))
@@ -562,16 +553,60 @@ class LaTeXTranslator(nodes.NodeVisitor):
self.elements.update({
'releasename': _('Release'),
})
+
+ # we assume LaTeX class provides \chapter command except in case
+ # of non-Japanese 'howto' case
+ self.sectionnames = LATEXSECTIONNAMES[:]
if document.settings.docclass == 'howto':
docclass = builder.config.latex_docclass.get('howto', 'article')
+ if docclass[0] == 'j': # Japanese class...
+ pass
+ else:
+ self.sectionnames.remove('chapter')
else:
docclass = builder.config.latex_docclass.get('manual', 'report')
self.elements['docclass'] = docclass
+
+ # determine top section level
+ self.top_sectionlevel = 1
+ if builder.config.latex_toplevel_sectioning:
+ try:
+ self.top_sectionlevel = \
+ self.sectionnames.index(builder.config.latex_toplevel_sectioning)
+ except ValueError:
+ logger.warning('unknown %r toplevel_sectioning for class %r' %
+ (builder.config.latex_toplevel_sectioning, docclass))
+
if builder.config.today:
self.elements['date'] = builder.config.today
else:
self.elements['date'] = format_date(builder.config.today_fmt or _('%b %d, %Y'), # type: ignore # NOQA
language=builder.config.language)
+
+ if builder.config.numfig:
+ self.numfig_secnum_depth = builder.config.numfig_secnum_depth
+ if self.numfig_secnum_depth > 0: # default is 1
+ # numfig_secnum_depth as passed to sphinx.sty indices same names as in
+ # LATEXSECTIONNAMES but with -1 for part, 0 for chapter, 1 for section...
+ if len(self.sectionnames) < len(LATEXSECTIONNAMES) and \
+ self.top_sectionlevel > 0:
+ self.numfig_secnum_depth += self.top_sectionlevel
+ else:
+ self.numfig_secnum_depth += self.top_sectionlevel - 1
+ # this (minus one) will serve as minimum to LaTeX's secnumdepth
+ self.numfig_secnum_depth = min(self.numfig_secnum_depth,
+ len(LATEXSECTIONNAMES) - 1)
+ # if passed key value is < 1 LaTeX will act as if 0; see sphinx.sty
+ self.elements['sphinxpkgoptions'] += \
+ (',numfigreset=%s' % self.numfig_secnum_depth)
+ else:
+ self.elements['sphinxpkgoptions'] += ',nonumfigreset'
+ try:
+ if builder.config.math_numfig:
+ self.elements['sphinxpkgoptions'] += ',mathnumfig'
+ except AttributeError:
+ pass
+
if builder.config.latex_logo:
# no need for \\noindent here, used in flushright
self.elements['logo'] = '\\sphinxincludegraphics{%s}\\par' % \
@@ -628,23 +663,32 @@ class LaTeXTranslator(nodes.NodeVisitor):
return '\\usepackage{%s}' % (packagename,)
usepackages = (declare_package(*p) for p in builder.usepackages)
self.elements['usepackages'] += "\n".join(usepackages)
+
+ minsecnumdepth = self.secnumdepth # 2 from legacy sphinx manual/howto
if document.get('tocdepth'):
- # redece tocdepth if `part` or `chapter` is used for top_sectionlevel
+ # reduce tocdepth if `part` or `chapter` is used for top_sectionlevel
# tocdepth = -1: show only parts
# tocdepth = 0: show parts and chapters
# tocdepth = 1: show parts, chapters and sections
# tocdepth = 2: show parts, chapters, sections and subsections
# ...
tocdepth = document['tocdepth'] + self.top_sectionlevel - 2
- maxdepth = len(self.sectionnames) - self.top_sectionlevel
- if tocdepth > maxdepth:
+ if len(self.sectionnames) < len(LATEXSECTIONNAMES) and \
+ self.top_sectionlevel > 0:
+ tocdepth += 1 # because top_sectionlevel is shifted by -1
+ if tocdepth > len(LATEXSECTIONNAMES) - 2: # default is 5 <-> subparagraph
logger.warning('too large :maxdepth:, ignored.')
- tocdepth = maxdepth
+ tocdepth = len(LATEXSECTIONNAMES) - 2
self.elements['tocdepth'] = '\\setcounter{tocdepth}{%d}' % tocdepth
- if tocdepth >= SECNUMDEPTH:
- # Increase secnumdepth if tocdepth is depther than default SECNUMDEPTH
- self.elements['secnumdepth'] = '\\setcounter{secnumdepth}{%d}' % tocdepth
+ minsecnumdepth = max(minsecnumdepth, tocdepth)
+
+ if builder.config.numfig and (builder.config.numfig_secnum_depth > 0):
+ minsecnumdepth = max(minsecnumdepth, self.numfig_secnum_depth - 1)
+
+ if minsecnumdepth > self.secnumdepth:
+ self.elements['secnumdepth'] = '\\setcounter{secnumdepth}{%d}' %\
+ minsecnumdepth
if getattr(document.settings, 'contentsname', None):
self.elements['contentsname'] = \
@@ -1172,12 +1216,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_desc_addname(self, node):
# type: (nodes.Node) -> None
- self.body.append(r'\sphinxcode{')
+ self.body.append(r'\sphinxcode{\sphinxupquote{')
self.literal_whitespace += 1
def depart_desc_addname(self, node):
# type: (nodes.Node) -> None
- self.body.append('}')
+ self.body.append('}}')
self.literal_whitespace -= 1
def visit_desc_type(self, node):
@@ -1198,13 +1242,13 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_desc_name(self, node):
# type: (nodes.Node) -> None
- self.body.append(r'\sphinxbfcode{')
+ self.body.append(r'\sphinxbfcode{\sphinxupquote{')
self.no_contractions += 1
self.literal_whitespace += 1
def depart_desc_name(self, node):
# type: (nodes.Node) -> None
- self.body.append('}')
+ self.body.append('}}')
self.literal_whitespace -= 1
self.no_contractions -= 1
@@ -1243,11 +1287,11 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_desc_annotation(self, node):
# type: (nodes.Node) -> None
- self.body.append(r'\sphinxbfcode{')
+ self.body.append(r'\sphinxbfcode{\sphinxupquote{')
def depart_desc_annotation(self, node):
# type: (nodes.Node) -> None
- self.body.append('}')
+ self.body.append('}}')
def visit_desc_content(self, node):
# type: (nodes.Node) -> None
@@ -2133,12 +2177,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_literal_emphasis(self, node):
# type: (nodes.Node) -> None
- self.body.append(r'\sphinxstyleliteralemphasis{')
+ self.body.append(r'\sphinxstyleliteralemphasis{\sphinxupquote{')
self.no_contractions += 1
def depart_literal_emphasis(self, node):
# type: (nodes.Node) -> None
- self.body.append('}')
+ self.body.append('}}')
self.no_contractions -= 1
def visit_strong(self, node):
@@ -2151,12 +2195,12 @@ class LaTeXTranslator(nodes.NodeVisitor):
def visit_literal_strong(self, node):
# type: (nodes.Node) -> None
- self.body.append(r'\sphinxstyleliteralstrong{')
+ self.body.append(r'\sphinxstyleliteralstrong{\sphinxupquote{')
self.no_contractions += 1
def depart_literal_strong(self, node):
# type: (nodes.Node) -> None
- self.body.append('}')
+ self.body.append('}}')
self.no_contractions -= 1
def visit_abbreviation(self, node):
@@ -2215,14 +2259,14 @@ class LaTeXTranslator(nodes.NodeVisitor):
# type: (nodes.Node) -> None
self.no_contractions += 1
if self.in_title:
- self.body.append(r'\sphinxstyleliteralintitle{')
+ self.body.append(r'\sphinxstyleliteralintitle{\sphinxupquote{')
else:
- self.body.append(r'\sphinxcode{')
+ self.body.append(r'\sphinxcode{\sphinxupquote{')
def depart_literal(self, node):
# type: (nodes.Node) -> None
self.no_contractions -= 1
- self.body.append('}')
+ self.body.append('}}')
def visit_footnote_reference(self, node):
# type: (nodes.Node) -> None
diff --git a/sphinx/writers/manpage.py b/sphinx/writers/manpage.py
index 71c2aac0b..1d645ce5f 100644
--- a/sphinx/writers/manpage.py
+++ b/sphinx/writers/manpage.py
@@ -5,7 +5,7 @@
Manual page writer, extended for Sphinx custom 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.
"""
diff --git a/sphinx/writers/texinfo.py b/sphinx/writers/texinfo.py
index d7e08510e..b73557f86 100644
--- a/sphinx/writers/texinfo.py
+++ b/sphinx/writers/texinfo.py
@@ -5,7 +5,7 @@
Custom docutils writer for Texinfo.
- :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.
"""
diff --git a/sphinx/writers/text.py b/sphinx/writers/text.py
index d2b2f9045..b6e3f4cec 100644
--- a/sphinx/writers/text.py
+++ b/sphinx/writers/text.py
@@ -5,7 +5,7 @@
Custom docutils writer for plain text.
- :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
diff --git a/sphinx/writers/websupport.py b/sphinx/writers/websupport.py
index 1e7f4babd..a962faf4d 100644
--- a/sphinx/writers/websupport.py
+++ b/sphinx/writers/websupport.py
@@ -5,7 +5,7 @@
sphinx.websupport writer that adds comment-related annotations.
- :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.
"""
diff --git a/sphinx/writers/xml.py b/sphinx/writers/xml.py
index 9cb64216a..f94fe847c 100644
--- a/sphinx/writers/xml.py
+++ b/sphinx/writers/xml.py
@@ -5,7 +5,7 @@
Docutils-native XML and pseudo-XML writers.
- :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.
"""
diff --git a/tests/conftest.py b/tests/conftest.py
index 28dbd6ed4..9fb06edab 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -3,18 +3,51 @@
pytest config for sphinx/tests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- :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
+import shutil
+import sys
+import warnings
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():
return path(os.path.dirname(__file__) or '.').abspath() / 'roots'
+
+
+def pytest_report_header(config):
+ return 'Running Sphinx test suite (with Python %s)...' % (
+ sys.version.split()[0])
+
+
+def _initialize_test_directory(session):
+ testroot = os.path.join(str(session.config.rootdir), 'tests')
+ tempdir = os.path.abspath(os.getenv('SPHINX_TEST_TEMPDIR',
+ os.path.join(testroot, 'build')))
+ os.environ['SPHINX_TEST_TEMPDIR'] = tempdir
+
+ print('Temporary files will be placed in %s.' % tempdir)
+
+ if os.path.exists(tempdir):
+ shutil.rmtree(tempdir)
+
+ os.makedirs(tempdir)
+
+
+def pytest_sessionstart(session):
+ _initialize_test_directory(session)
diff --git a/tests/py35/test_autodoc_py35.py b/tests/py35/test_autodoc_py35.py
index 9a94dbd27..439ebd67a 100644
--- a/tests/py35/test_autodoc_py35.py
+++ b/tests/py35/test_autodoc_py35.py
@@ -6,7 +6,7 @@
Test the autodoc extension. This tests mainly the Documenters; the auto
directives are tested in a test source file translated by test_build.
- :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,14 +108,14 @@ def test_generate():
logging.setup(app, app._status, app._warning)
def assert_warns(warn_str, objtype, name, **kw):
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
assert len(directive.result) == 0, directive.result
assert warn_str in app._warning.getvalue()
app._warning.truncate(0)
def assert_works(objtype, name, **kw):
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
assert directive.result
# print '\n'.join(directive.result)
@@ -129,7 +129,7 @@ def test_generate():
assert set(processed_docstrings) | set(processed_signatures) == set(items)
def assert_result_contains(item, objtype, name, **kw):
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
# print '\n'.join(directive.result)
assert app._warning.getvalue() == ''
@@ -137,7 +137,7 @@ def test_generate():
del directive.result[:]
def assert_order(items, objtype, name, member_order, **kw):
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.options.member_order = member_order
inst.generate(**kw)
assert app._warning.getvalue() == ''
diff --git a/tests/roots/test-apidoc-toc/mypackage/__init__.py b/tests/roots/test-apidoc-toc/mypackage/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/roots/test-apidoc-toc/mypackage/__init__.py
diff --git a/tests/roots/test-apidoc-toc/mypackage/main.py b/tests/roots/test-apidoc-toc/mypackage/main.py
new file mode 100755
index 000000000..5d3da04b9
--- /dev/null
+++ b/tests/roots/test-apidoc-toc/mypackage/main.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python
+import os
+
+import mod_resource
+
+import mod_something
+
+
+if __name__ == "__main__":
+ print("Hello, world! -> something returns: {}".format(mod_something.something()))
+
+ res_path = \
+ os.path.join(os.path.dirname(mod_resource.__file__), 'resource.txt')
+ with open(res_path) as f:
+ text = f.read()
+ print("From mod_resource:resource.txt -> {}".format(text))
diff --git a/tests/roots/test-apidoc-toc/mypackage/no_init/foo.py b/tests/roots/test-apidoc-toc/mypackage/no_init/foo.py
new file mode 100644
index 000000000..ce059b276
--- /dev/null
+++ b/tests/roots/test-apidoc-toc/mypackage/no_init/foo.py
@@ -0,0 +1 @@
+MESSAGE="There's no __init__.py in this folder, hence we should be left out"
diff --git a/tests/roots/test-apidoc-toc/mypackage/resource/__init__.py b/tests/roots/test-apidoc-toc/mypackage/resource/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/tests/roots/test-apidoc-toc/mypackage/resource/__init__.py
diff --git a/tests/roots/test-apidoc-toc/mypackage/resource/resource.txt b/tests/roots/test-apidoc-toc/mypackage/resource/resource.txt
new file mode 100644
index 000000000..5b64c924d
--- /dev/null
+++ b/tests/roots/test-apidoc-toc/mypackage/resource/resource.txt
@@ -0,0 +1 @@
+This is a text resource to be included in this otherwise empty module. No python contents here. \ No newline at end of file
diff --git a/tests/roots/test-apidoc-toc/mypackage/something/__init__.py b/tests/roots/test-apidoc-toc/mypackage/something/__init__.py
new file mode 100644
index 000000000..259184ba3
--- /dev/null
+++ b/tests/roots/test-apidoc-toc/mypackage/something/__init__.py
@@ -0,0 +1 @@
+"Subpackage Something" \ No newline at end of file
diff --git a/tests/roots/test-domain-cpp/index.rst b/tests/roots/test-domain-cpp/index.rst
index 618e51037..2df5ec848 100644
--- a/tests/roots/test-domain-cpp/index.rst
+++ b/tests/roots/test-domain-cpp/index.rst
@@ -28,14 +28,20 @@ directives
An unscoped enum.
+ .. cpp:enumerator:: A
+
.. cpp:enum-class:: MyScopedEnum
A scoped enum.
+ .. cpp:enumerator:: B
+
.. cpp:enum-struct:: protected MyScopedVisibilityEnum : std::underlying_type<MySpecificEnum>::type
A scoped enum with non-default visibility, and with a specified underlying type.
+ .. cpp:enumerator:: B
+
.. cpp:function:: void paren_1(int, float)
.. cpp:function:: void paren_2(int, float)
diff --git a/tests/roots/test-ext-autodoc/target/__init__.py b/tests/roots/test-ext-autodoc/target/__init__.py
new file mode 100644
index 000000000..bd00bf183
--- /dev/null
+++ b/tests/roots/test-ext-autodoc/target/__init__.py
@@ -0,0 +1,225 @@
+# -*- coding: utf-8 -*-
+
+import enum
+from six import StringIO, add_metaclass
+from sphinx.ext.autodoc import add_documenter # NOQA
+
+
+__all__ = ['Class']
+
+#: documentation for the integer
+integer = 1
+
+
+def raises(exc, func, *args, **kwds):
+ """Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*."""
+ pass
+
+
+class CustomEx(Exception):
+ """My custom exception."""
+
+ def f(self):
+ """Exception method."""
+
+
+class CustomDataDescriptor(object):
+ """Descriptor class docstring."""
+
+ def __init__(self, doc):
+ self.__doc__ = doc
+
+ def __get__(self, obj, type=None):
+ if obj is None:
+ return self
+ return 42
+
+ def meth(self):
+ """Function."""
+ return "The Answer"
+
+
+class CustomDataDescriptorMeta(type):
+ """Descriptor metaclass docstring."""
+
+
+@add_metaclass(CustomDataDescriptorMeta)
+class CustomDataDescriptor2(CustomDataDescriptor):
+ """Descriptor class with custom metaclass docstring."""
+
+
+def _funky_classmethod(name, b, c, d, docstring=None):
+ """Generates a classmethod for a class from a template by filling out
+ some arguments."""
+ def template(cls, a, b, c, d=4, e=5, f=6):
+ return a, b, c, d, e, f
+ from functools import partial
+ function = partial(template, b=b, c=c, d=d)
+ function.__name__ = name
+ function.__doc__ = docstring
+ return classmethod(function)
+
+
+class Base(object):
+ def inheritedmeth(self):
+ """Inherited function."""
+
+
+class Derived(Base):
+ def inheritedmeth(self):
+ # no docstring here
+ pass
+
+
+class Class(Base):
+ """Class to document."""
+
+ descr = CustomDataDescriptor("Descriptor instance docstring.")
+
+ def meth(self):
+ """Function."""
+
+ def undocmeth(self):
+ pass
+
+ def skipmeth(self):
+ """Method that should be skipped."""
+
+ def excludemeth(self):
+ """Method that should be excluded."""
+
+ # should not be documented
+ skipattr = 'foo'
+
+ #: should be documented -- süß
+ attr = 'bar'
+
+ @property
+ def prop(self):
+ """Property."""
+
+ docattr = 'baz'
+ """should likewise be documented -- süß"""
+
+ udocattr = 'quux'
+ u"""should be documented as well - süß"""
+
+ # initialized to any class imported from another module
+ mdocattr = StringIO()
+ """should be documented as well - süß"""
+
+ roger = _funky_classmethod("roger", 2, 3, 4)
+
+ moore = _funky_classmethod("moore", 9, 8, 7,
+ docstring="moore(a, e, f) -> happiness")
+
+ def __init__(self, arg):
+ self.inst_attr_inline = None #: an inline documented instance attr
+ #: a documented instance attribute
+ self.inst_attr_comment = None
+ self.inst_attr_string = None
+ """a documented instance attribute"""
+ self._private_inst_attr = None #: a private instance attribute
+
+ def __special1__(self):
+ """documented special method"""
+
+ def __special2__(self):
+ # undocumented special method
+ pass
+
+
+class CustomDict(dict):
+ """Docstring."""
+
+
+def function(foo, *args, **kwds):
+ """
+ Return spam.
+ """
+ pass
+
+
+class Outer(object):
+ """Foo"""
+
+ class Inner(object):
+ """Foo"""
+
+ def meth(self):
+ """Foo"""
+
+ # should be documented as an alias
+ factory = dict
+
+
+class DocstringSig(object):
+ def meth(self):
+ """meth(FOO, BAR=1) -> BAZ
+First line of docstring
+
+ rest of docstring
+ """
+
+ def meth2(self):
+ """First line, no signature
+ Second line followed by indentation::
+
+ indented line
+ """
+
+ @property
+ def prop1(self):
+ """DocstringSig.prop1(self)
+ First line of docstring
+ """
+ return 123
+
+ @property
+ def prop2(self):
+ """First line of docstring
+ Second line of docstring
+ """
+ return 456
+
+
+class StrRepr(str):
+ def __repr__(self):
+ return self
+
+
+class AttCls(object):
+ a1 = StrRepr('hello\nworld')
+ a2 = None
+
+
+class InstAttCls(object):
+ """Class with documented class and instance attributes."""
+
+ #: Doc comment for class attribute InstAttCls.ca1.
+ #: It can have multiple lines.
+ ca1 = 'a'
+
+ ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only.
+
+ ca3 = 'c'
+ """Docstring for class attribute InstAttCls.ca3."""
+
+ def __init__(self):
+ #: Doc comment for instance attribute InstAttCls.ia1
+ self.ia1 = 'd'
+
+ self.ia2 = 'e'
+ """Docstring for instance attribute InstAttCls.ia2."""
+
+
+class EnumCls(enum.Enum):
+ """
+ this is enum class
+ """
+
+ #: doc for val1
+ val1 = 12
+ val2 = 23 #: doc for val2
+ val3 = 34
+ """doc for val3"""
diff --git a/tests/roots/test-ext-math/index.rst b/tests/roots/test-ext-math/index.rst
index 9d16824f6..4237b73ff 100644
--- a/tests/roots/test-ext-math/index.rst
+++ b/tests/roots/test-ext-math/index.rst
@@ -2,8 +2,10 @@ Test Math
=========
.. toctree::
+ :numbered: 1
math
+ page
.. math:: a^2+b^2=c^2
diff --git a/tests/roots/test-ext-math/page.rst b/tests/roots/test-ext-math/page.rst
new file mode 100644
index 000000000..ef8040910
--- /dev/null
+++ b/tests/roots/test-ext-math/page.rst
@@ -0,0 +1,9 @@
+Test multiple pages
+===================
+
+.. math::
+ :label: bar
+
+ a = b + 1
+
+Referencing equations :eq:`foo` and :eq:`bar`.
diff --git a/tests/roots/test-ext-todo/index.rst b/tests/roots/test-ext-todo/index.rst
index 6b95f73fd..781473d6a 100644
--- a/tests/roots/test-ext-todo/index.rst
+++ b/tests/roots/test-ext-todo/index.rst
@@ -7,3 +7,5 @@ test for sphinx.ext.todo
bar
.. todolist::
+
+.. todolist::
diff --git a/tests/roots/test-extensions/conf.py b/tests/roots/test-extensions/conf.py
new file mode 100644
index 000000000..9a3cbc844
--- /dev/null
+++ b/tests/roots/test-extensions/conf.py
@@ -0,0 +1,4 @@
+import os
+import sys
+
+sys.path.insert(0, os.path.abspath('.'))
diff --git a/tests/roots/test-extensions/read_parallel.py b/tests/roots/test-extensions/read_parallel.py
new file mode 100644
index 000000000..a3e052f95
--- /dev/null
+++ b/tests/roots/test-extensions/read_parallel.py
@@ -0,0 +1,4 @@
+def setup(app):
+ return {
+ 'parallel_read_safe': True
+ }
diff --git a/tests/roots/test-extensions/read_serial.py b/tests/roots/test-extensions/read_serial.py
new file mode 100644
index 000000000..c55570a5c
--- /dev/null
+++ b/tests/roots/test-extensions/read_serial.py
@@ -0,0 +1,4 @@
+def setup(app):
+ return {
+ 'parallel_read_safe': False
+ }
diff --git a/tests/roots/test-extensions/write_parallel.py b/tests/roots/test-extensions/write_parallel.py
new file mode 100644
index 000000000..ebc48ef9b
--- /dev/null
+++ b/tests/roots/test-extensions/write_parallel.py
@@ -0,0 +1,4 @@
+def setup(app):
+ return {
+ 'parallel_write_safe': True,
+ }
diff --git a/tests/roots/test-extensions/write_serial.py b/tests/roots/test-extensions/write_serial.py
new file mode 100644
index 000000000..75494ce77
--- /dev/null
+++ b/tests/roots/test-extensions/write_serial.py
@@ -0,0 +1,4 @@
+def setup(app):
+ return {
+ 'parallel_write_safe': False
+ }
diff --git a/tests/roots/test-latex-numfig/conf.py b/tests/roots/test-latex-numfig/conf.py
new file mode 100644
index 000000000..506186b26
--- /dev/null
+++ b/tests/roots/test-latex-numfig/conf.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+
+master_doc = 'index'
+
+extensions = ['sphinx.ext.imgmath'] # for math_numfig
+
+latex_documents = [
+ ('indexmanual', 'SphinxManual.tex', 'Test numfig manual',
+ 'Sphinx', 'manual'),
+ ('indexhowto', 'SphinxHowTo.tex', 'Test numfig howto',
+ 'Sphinx', 'howto'),
+]
diff --git a/tests/roots/test-latex-numfig/index.rst b/tests/roots/test-latex-numfig/index.rst
new file mode 100644
index 000000000..6b8b9688c
--- /dev/null
+++ b/tests/roots/test-latex-numfig/index.rst
@@ -0,0 +1,9 @@
+=================
+test-latex-numfig
+=================
+
+.. toctree::
+ :numbered:
+
+ indexmanual
+ indexhowto
diff --git a/tests/roots/test-latex-numfig/indexhowto.rst b/tests/roots/test-latex-numfig/indexhowto.rst
new file mode 100644
index 000000000..4749f1ecd
--- /dev/null
+++ b/tests/roots/test-latex-numfig/indexhowto.rst
@@ -0,0 +1,10 @@
+=======================
+test-latex-numfig-howto
+=======================
+
+This is a part
+==============
+
+This is a section
+-----------------
+
diff --git a/tests/roots/test-latex-numfig/indexmanual.rst b/tests/roots/test-latex-numfig/indexmanual.rst
new file mode 100644
index 000000000..8bab4fbfd
--- /dev/null
+++ b/tests/roots/test-latex-numfig/indexmanual.rst
@@ -0,0 +1,13 @@
+========================
+test-latex-numfig-manual
+========================
+
+First part
+==========
+
+This is chapter
+---------------
+
+This is section
+~~~~~~~~~~~~~~~
+
diff --git a/tests/roots/test-root/autodoc.txt b/tests/roots/test-root/autodoc.txt
index aa0dffba1..3c83ebf6e 100644
--- a/tests/roots/test-root/autodoc.txt
+++ b/tests/roots/test-root/autodoc.txt
@@ -5,7 +5,7 @@ Just testing a few autodoc possibilities...
.. automodule:: util
-.. automodule:: test_autodoc
+.. automodule:: autodoc_target
:members:
.. autofunction:: function
@@ -34,7 +34,7 @@ Just testing a few autodoc possibilities...
.. autoclass:: MarkupError
-.. currentmodule:: test_autodoc
+.. currentmodule:: autodoc_target
.. autoclass:: InstAttCls
:members:
diff --git a/tests/roots/test-root/autodoc_target.py b/tests/roots/test-root/autodoc_target.py
new file mode 100644
index 000000000..bd00bf183
--- /dev/null
+++ b/tests/roots/test-root/autodoc_target.py
@@ -0,0 +1,225 @@
+# -*- coding: utf-8 -*-
+
+import enum
+from six import StringIO, add_metaclass
+from sphinx.ext.autodoc import add_documenter # NOQA
+
+
+__all__ = ['Class']
+
+#: documentation for the integer
+integer = 1
+
+
+def raises(exc, func, *args, **kwds):
+ """Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*."""
+ pass
+
+
+class CustomEx(Exception):
+ """My custom exception."""
+
+ def f(self):
+ """Exception method."""
+
+
+class CustomDataDescriptor(object):
+ """Descriptor class docstring."""
+
+ def __init__(self, doc):
+ self.__doc__ = doc
+
+ def __get__(self, obj, type=None):
+ if obj is None:
+ return self
+ return 42
+
+ def meth(self):
+ """Function."""
+ return "The Answer"
+
+
+class CustomDataDescriptorMeta(type):
+ """Descriptor metaclass docstring."""
+
+
+@add_metaclass(CustomDataDescriptorMeta)
+class CustomDataDescriptor2(CustomDataDescriptor):
+ """Descriptor class with custom metaclass docstring."""
+
+
+def _funky_classmethod(name, b, c, d, docstring=None):
+ """Generates a classmethod for a class from a template by filling out
+ some arguments."""
+ def template(cls, a, b, c, d=4, e=5, f=6):
+ return a, b, c, d, e, f
+ from functools import partial
+ function = partial(template, b=b, c=c, d=d)
+ function.__name__ = name
+ function.__doc__ = docstring
+ return classmethod(function)
+
+
+class Base(object):
+ def inheritedmeth(self):
+ """Inherited function."""
+
+
+class Derived(Base):
+ def inheritedmeth(self):
+ # no docstring here
+ pass
+
+
+class Class(Base):
+ """Class to document."""
+
+ descr = CustomDataDescriptor("Descriptor instance docstring.")
+
+ def meth(self):
+ """Function."""
+
+ def undocmeth(self):
+ pass
+
+ def skipmeth(self):
+ """Method that should be skipped."""
+
+ def excludemeth(self):
+ """Method that should be excluded."""
+
+ # should not be documented
+ skipattr = 'foo'
+
+ #: should be documented -- süß
+ attr = 'bar'
+
+ @property
+ def prop(self):
+ """Property."""
+
+ docattr = 'baz'
+ """should likewise be documented -- süß"""
+
+ udocattr = 'quux'
+ u"""should be documented as well - süß"""
+
+ # initialized to any class imported from another module
+ mdocattr = StringIO()
+ """should be documented as well - süß"""
+
+ roger = _funky_classmethod("roger", 2, 3, 4)
+
+ moore = _funky_classmethod("moore", 9, 8, 7,
+ docstring="moore(a, e, f) -> happiness")
+
+ def __init__(self, arg):
+ self.inst_attr_inline = None #: an inline documented instance attr
+ #: a documented instance attribute
+ self.inst_attr_comment = None
+ self.inst_attr_string = None
+ """a documented instance attribute"""
+ self._private_inst_attr = None #: a private instance attribute
+
+ def __special1__(self):
+ """documented special method"""
+
+ def __special2__(self):
+ # undocumented special method
+ pass
+
+
+class CustomDict(dict):
+ """Docstring."""
+
+
+def function(foo, *args, **kwds):
+ """
+ Return spam.
+ """
+ pass
+
+
+class Outer(object):
+ """Foo"""
+
+ class Inner(object):
+ """Foo"""
+
+ def meth(self):
+ """Foo"""
+
+ # should be documented as an alias
+ factory = dict
+
+
+class DocstringSig(object):
+ def meth(self):
+ """meth(FOO, BAR=1) -> BAZ
+First line of docstring
+
+ rest of docstring
+ """
+
+ def meth2(self):
+ """First line, no signature
+ Second line followed by indentation::
+
+ indented line
+ """
+
+ @property
+ def prop1(self):
+ """DocstringSig.prop1(self)
+ First line of docstring
+ """
+ return 123
+
+ @property
+ def prop2(self):
+ """First line of docstring
+ Second line of docstring
+ """
+ return 456
+
+
+class StrRepr(str):
+ def __repr__(self):
+ return self
+
+
+class AttCls(object):
+ a1 = StrRepr('hello\nworld')
+ a2 = None
+
+
+class InstAttCls(object):
+ """Class with documented class and instance attributes."""
+
+ #: Doc comment for class attribute InstAttCls.ca1.
+ #: It can have multiple lines.
+ ca1 = 'a'
+
+ ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only.
+
+ ca3 = 'c'
+ """Docstring for class attribute InstAttCls.ca3."""
+
+ def __init__(self):
+ #: Doc comment for instance attribute InstAttCls.ia1
+ self.ia1 = 'd'
+
+ self.ia2 = 'e'
+ """Docstring for instance attribute InstAttCls.ia2."""
+
+
+class EnumCls(enum.Enum):
+ """
+ this is enum class
+ """
+
+ #: doc for val1
+ val1 = 12
+ val2 = 23 #: doc for val2
+ val3 = 34
+ """doc for val3"""
diff --git a/tests/run.py b/tests/run.py
deleted file mode 100755
index a8439ba02..000000000
--- a/tests/run.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
- Sphinx unit test driver
- ~~~~~~~~~~~~~~~~~~~~~~~
-
- This script runs the Sphinx unit test suite.
-
- :copyright: Copyright 2007-2017 by the Sphinx team, see AUTHORS.
- :license: BSD, see LICENSE for details.
-"""
-from __future__ import print_function
-
-import os
-import sys
-import warnings
-import traceback
-import shutil
-
-testroot = os.path.dirname(__file__) or '.'
-sys.path.insert(0, os.path.abspath(os.path.join(testroot, os.path.pardir)))
-
-# filter warnings of test dependencies
-warnings.filterwarnings('ignore', category=DeprecationWarning, module='site') # virtualenv
-warnings.filterwarnings('ignore', category=ImportWarning, module='backports')
-warnings.filterwarnings('ignore', category=ImportWarning, module='pkgutil')
-warnings.filterwarnings('ignore', category=ImportWarning, module='pytest_cov')
-warnings.filterwarnings('ignore', category=PendingDeprecationWarning, module=r'_pytest\..*')
-
-# check dependencies before testing
-print('Checking dependencies...')
-for modname in ('pytest', 'mock', 'six', 'docutils', 'jinja2', 'pygments',
- 'snowballstemmer', 'babel', 'html5lib'):
- try:
- __import__(modname)
- except ImportError as err:
- if modname == 'mock' and sys.version_info[0] == 3:
- continue
- traceback.print_exc()
- print('The %r package is needed to run the Sphinx test suite.' % modname)
- sys.exit(1)
-
-# find a temp dir for testing and clean it up now
-os.environ['SPHINX_TEST_TEMPDIR'] = \
- os.path.abspath(os.path.join(testroot, 'build')) \
- if 'SPHINX_TEST_TEMPDIR' not in os.environ \
- else os.path.abspath(os.environ['SPHINX_TEST_TEMPDIR'])
-
-tempdir = os.environ['SPHINX_TEST_TEMPDIR']
-print('Temporary files will be placed in %s.' % tempdir)
-if os.path.exists(tempdir):
- shutil.rmtree(tempdir)
-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))
diff --git a/tests/test_api_translator.py b/tests/test_api_translator.py
index 35b24732b..4e4230ba3 100644
--- a/tests/test_api_translator.py
+++ b/tests/test_api_translator.py
@@ -5,7 +5,7 @@
Test the Sphinx API for translator.
- :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.
"""
diff --git a/tests/test_application.py b/tests/test_application.py
index 785a78878..12b6bbe60 100644
--- a/tests/test_application.py
+++ b/tests/test_application.py
@@ -5,13 +5,14 @@
Test the Sphinx 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.
"""
from docutils import nodes
from sphinx.application import ExtensionError
from sphinx.domains import Domain
+from sphinx.util import logging
from sphinx.testing.util import strip_escseq
import pytest
@@ -86,3 +87,38 @@ def test_add_source_parser(app, status, warning):
assert set(app.registry.get_source_parsers().keys()) == set(['*', '.md', '.test'])
assert app.registry.get_source_parsers()['.md'].__name__ == 'DummyMarkdownParser'
assert app.registry.get_source_parsers()['.test'].__name__ == 'TestSourceParser'
+
+
+@pytest.mark.sphinx(testroot='extensions')
+def test_add_is_parallel_allowed(app, status, warning):
+ logging.setup(app, status, warning)
+
+ assert app.is_parallel_allowed('read') is True
+ assert app.is_parallel_allowed('write') is True
+ assert warning.getvalue() == ''
+
+ app.setup_extension('read_parallel')
+ assert app.is_parallel_allowed('read') is True
+ assert app.is_parallel_allowed('write') is True
+ assert warning.getvalue() == ''
+ app.extensions.pop('read_parallel')
+
+ app.setup_extension('write_parallel')
+ assert app.is_parallel_allowed('read') is False
+ assert app.is_parallel_allowed('write') is True
+ assert 'the write_parallel extension does not declare' in warning.getvalue()
+ app.extensions.pop('write_parallel')
+ warning.truncate(0) # reset warnings
+
+ app.setup_extension('read_serial')
+ assert app.is_parallel_allowed('read') is False
+ assert app.is_parallel_allowed('write') is True
+ assert warning.getvalue() == ''
+ app.extensions.pop('read_serial')
+
+ app.setup_extension('write_serial')
+ assert app.is_parallel_allowed('read') is False
+ assert app.is_parallel_allowed('write') is False
+ assert 'the write_serial extension does not declare' in warning.getvalue()
+ app.extensions.pop('write_serial')
+ warning.truncate(0) # reset warnings
diff --git a/tests/test_autodoc.py b/tests/test_autodoc.py
index 4ab58d891..d9c94bc0d 100644
--- a/tests/test_autodoc.py
+++ b/tests/test_autodoc.py
@@ -6,17 +6,16 @@
Test the autodoc extension. This tests mainly the Documenters; the auto
directives are tested in a test source file translated by test_build.
- :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
from six import PY3
from sphinx.testing.util import SphinxTestApp, Struct # NOQA
import pytest
-import enum
-from six import StringIO, add_metaclass
from docutils.statemachine import ViewList
from sphinx.ext.autodoc import AutoDirective, add_documenter, \
@@ -28,18 +27,23 @@ app = None
@pytest.fixture(scope='module', autouse=True)
def setup_module(rootdir, sphinx_test_tempdir):
- global app
- srcdir = sphinx_test_tempdir / 'autodoc-root'
- if not srcdir.exists():
- (rootdir/'test-root').copytree(srcdir)
- app = SphinxTestApp(srcdir=srcdir)
- app.builder.env.app = app
- app.builder.env.temp_data['docname'] = 'dummy'
- app.connect('autodoc-process-docstring', process_docstring)
- app.connect('autodoc-process-signature', process_signature)
- app.connect('autodoc-skip-member', skip_member)
- yield
- app.cleanup()
+ try:
+ global app
+ srcdir = sphinx_test_tempdir / 'autodoc-root'
+ if not srcdir.exists():
+ (rootdir / 'test-root').copytree(srcdir)
+ testroot = rootdir / 'test-ext-autodoc'
+ sys.path.append(testroot)
+ app = SphinxTestApp(srcdir=srcdir)
+ app.builder.env.app = app
+ app.builder.env.temp_data['docname'] = 'dummy'
+ app.connect('autodoc-process-docstring', process_docstring)
+ app.connect('autodoc-process-signature', process_signature)
+ app.connect('autodoc-skip-member', skip_member)
+ yield
+ finally:
+ app.cleanup()
+ sys.path.remove(testroot)
directive = options = None
@@ -65,6 +69,7 @@ def setup_test():
members = [],
member_order = 'alphabetic',
exclude_members = set(),
+ ignore_module_all = False,
)
directive = Struct(
@@ -115,7 +120,7 @@ def test_parse_name():
logging.setup(app, app._status, app._warning)
def verify(objtype, name, result):
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
assert inst.parse_name()
assert (inst.modname, inst.objpath, inst.args, inst.retann) == result
@@ -157,7 +162,7 @@ def test_parse_name():
@pytest.mark.usefixtures('setup_test')
def test_format_signature():
def formatsig(objtype, name, obj, args, retann):
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.fullname = name
inst.doc_as_attr = False # for class objtype
inst.object = obj
@@ -262,7 +267,7 @@ def test_format_signature():
@pytest.mark.usefixtures('setup_test')
def test_get_doc():
def getdocl(objtype, obj, encoding=None):
- inst = AutoDirective._registry[objtype](directive, 'tmp')
+ inst = app.registry.documenters[objtype](directive, 'tmp')
inst.object = obj
inst.objpath = [obj.__name__]
inst.doc_as_attr = False
@@ -417,7 +422,7 @@ def test_get_doc():
# class has __init__ method without docstring and
# __new__ method with docstring
# class docstring: depends on config value which one is taken
- class I:
+ class I: # NOQA
"""Class docstring"""
def __new__(cls):
"""New docstring"""
@@ -428,6 +433,8 @@ def test_get_doc():
directive.env.config.autoclass_content = 'both'
assert getdocl('class', I) == ['Class docstring', '', 'New docstring']
+ from target import Base, Derived
+
# NOTE: inspect.getdoc seems not to work with locally defined classes
directive.env.config.autodoc_inherit_docstrings = False
assert getdocl('method', Base.inheritedmeth) == ['Inherited function.']
@@ -439,7 +446,7 @@ def test_get_doc():
@pytest.mark.usefixtures('setup_test')
def test_docstring_processing():
def process(objtype, name, obj):
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.object = obj
inst.fullname = name
return list(inst.process_doc(inst.get_doc()))
@@ -496,7 +503,7 @@ def test_docstring_property_processing():
def genarate_docstring(objtype, name, **kw):
del processed_docstrings[:]
del processed_signatures[:]
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
results = list(directive.result)
docstrings = inst.get_doc()[0]
@@ -505,24 +512,24 @@ def test_docstring_property_processing():
directive.env.config.autodoc_docstring_signature = False
results, docstrings = \
- genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop1')
+ genarate_docstring('attribute', 'target.DocstringSig.prop1')
assert '.. py:attribute:: DocstringSig.prop1' in results
assert 'First line of docstring' in docstrings
assert 'DocstringSig.prop1(self)' in docstrings
results, docstrings = \
- genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop2')
+ genarate_docstring('attribute', 'target.DocstringSig.prop2')
assert '.. py:attribute:: DocstringSig.prop2' in results
assert 'First line of docstring' in docstrings
assert 'Second line of docstring' in docstrings
directive.env.config.autodoc_docstring_signature = True
results, docstrings = \
- genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop1')
+ genarate_docstring('attribute', 'target.DocstringSig.prop1')
assert '.. py:attribute:: DocstringSig.prop1' in results
assert 'First line of docstring' in docstrings
assert 'DocstringSig.prop1(self)' not in docstrings
results, docstrings = \
- genarate_docstring('attribute', 'test_autodoc.DocstringSig.prop2')
+ genarate_docstring('attribute', 'target.DocstringSig.prop2')
assert '.. py:attribute:: DocstringSig.prop2' in results
assert 'First line of docstring' in docstrings
assert 'Second line of docstring' in docstrings
@@ -548,7 +555,7 @@ def test_new_documenter():
def assert_result_contains(item, objtype, name, **kw):
app._warning.truncate(0)
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
# print '\n'.join(directive.result)
assert app._warning.getvalue() == ''
@@ -556,11 +563,13 @@ def test_new_documenter():
del directive.result[:]
options.members = ['integer']
- assert_result_contains('.. py:data:: integer', 'module', 'test_autodoc')
+ assert_result_contains('.. py:data:: integer', 'module', 'target')
@pytest.mark.usefixtures('setup_test')
def test_attrgetter_using():
+ from target import Class
+
def assert_getter_works(objtype, name, obj, attrs=[], **kw):
getattr_spy = []
@@ -572,7 +581,7 @@ def test_attrgetter_using():
AutoDirective._special_attrgetters[type] = special_getattr
del getattr_spy[:]
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
hooked_members = [s[1] for s in getattr_spy]
@@ -585,10 +594,10 @@ def test_attrgetter_using():
options.members = ALL
options.inherited_members = False
- assert_getter_works('class', 'test_autodoc.Class', Class, ['meth'])
+ assert_getter_works('class', 'target.Class', Class, ['meth'])
options.inherited_members = True
- assert_getter_works('class', 'test_autodoc.Class', Class, ['meth', 'inheritedmeth'])
+ assert_getter_works('class', 'target.Class', Class, ['meth', 'inheritedmeth'])
@pytest.mark.usefixtures('setup_test')
@@ -596,7 +605,7 @@ def test_generate():
logging.setup(app, app._status, app._warning)
def assert_warns(warn_str, objtype, name, **kw):
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
assert len(directive.result) == 0, directive.result
@@ -604,7 +613,7 @@ def test_generate():
app._warning.truncate(0)
def assert_works(objtype, name, **kw):
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
assert directive.result
# print '\n'.join(directive.result)
@@ -618,7 +627,7 @@ def test_generate():
assert set(processed_docstrings) | set(processed_signatures) == set(items)
def assert_result_contains(item, objtype, name, **kw):
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.generate(**kw)
# print '\n'.join(directive.result)
assert app._warning.getvalue() == ''
@@ -626,7 +635,7 @@ def test_generate():
del directive.result[:]
def assert_order(items, objtype, name, member_order, **kw):
- inst = AutoDirective._registry[objtype](directive, name)
+ inst = app.registry.documenters[objtype](directive, name)
inst.options.member_order = member_order
inst.generate(**kw)
assert app._warning.getvalue() == ''
@@ -657,11 +666,11 @@ def test_generate():
assert_warns("failed to import function 'foobar' from module 'util'",
'function', 'util.foobar', more_content=None)
# method missing
- assert_warns("failed to import method 'Class.foobar' from module 'test_autodoc';",
- 'method', 'test_autodoc.Class.foobar', more_content=None)
+ assert_warns("failed to import method 'Class.foobar' from module 'target';",
+ 'method', 'target.Class.foobar', more_content=None)
# test auto and given content mixing
- directive.env.ref_context['py:module'] = 'test_autodoc'
+ directive.env.ref_context['py:module'] = 'target'
assert_result_contains(' Function.', 'method', 'Class.meth')
add_content = ViewList()
add_content.append('Content.', '', 0)
@@ -676,72 +685,77 @@ def test_generate():
assert len(directive.result) == 0
# assert that exceptions can be documented
- assert_works('exception', 'test_autodoc.CustomEx', all_members=True)
- assert_works('exception', 'test_autodoc.CustomEx')
+ assert_works('exception', 'target.CustomEx', all_members=True)
+ assert_works('exception', 'target.CustomEx')
# test diverse inclusion settings for members
- should = [('class', 'test_autodoc.Class')]
+ should = [('class', 'target.Class')]
assert_processes(should, 'class', 'Class')
- should.extend([('method', 'test_autodoc.Class.meth')])
+ should.extend([('method', 'target.Class.meth')])
options.members = ['meth']
options.exclude_members = set(['excludemeth'])
assert_processes(should, 'class', 'Class')
- should.extend([('attribute', 'test_autodoc.Class.prop'),
- ('attribute', 'test_autodoc.Class.descr'),
- ('attribute', 'test_autodoc.Class.attr'),
- ('attribute', 'test_autodoc.Class.docattr'),
- ('attribute', 'test_autodoc.Class.udocattr'),
- ('attribute', 'test_autodoc.Class.mdocattr'),
- ('attribute', 'test_autodoc.Class.inst_attr_comment'),
- ('attribute', 'test_autodoc.Class.inst_attr_inline'),
- ('attribute', 'test_autodoc.Class.inst_attr_string'),
- ('method', 'test_autodoc.Class.moore'),
+ should.extend([('attribute', 'target.Class.prop'),
+ ('attribute', 'target.Class.descr'),
+ ('attribute', 'target.Class.attr'),
+ ('attribute', 'target.Class.docattr'),
+ ('attribute', 'target.Class.udocattr'),
+ ('attribute', 'target.Class.mdocattr'),
+ ('attribute', 'target.Class.inst_attr_comment'),
+ ('attribute', 'target.Class.inst_attr_inline'),
+ ('attribute', 'target.Class.inst_attr_string'),
+ ('method', 'target.Class.moore'),
])
options.members = ALL
assert_processes(should, 'class', 'Class')
options.undoc_members = True
- should.extend((('attribute', 'test_autodoc.Class.skipattr'),
- ('method', 'test_autodoc.Class.undocmeth'),
- ('method', 'test_autodoc.Class.roger')))
+ should.extend((('attribute', 'target.Class.skipattr'),
+ ('method', 'target.Class.undocmeth'),
+ ('method', 'target.Class.roger')))
assert_processes(should, 'class', 'Class')
options.inherited_members = True
- should.append(('method', 'test_autodoc.Class.inheritedmeth'))
+ should.append(('method', 'target.Class.inheritedmeth'))
assert_processes(should, 'class', 'Class')
# test special members
options.special_members = ['__special1__']
- should.append(('method', 'test_autodoc.Class.__special1__'))
+ should.append(('method', 'target.Class.__special1__'))
assert_processes(should, 'class', 'Class')
options.special_members = ALL
- should.append(('method', 'test_autodoc.Class.__special2__'))
+ should.append(('method', 'target.Class.__special2__'))
assert_processes(should, 'class', 'Class')
options.special_members = False
options.members = []
# test module flags
- assert_result_contains('.. py:module:: test_autodoc',
- 'module', 'test_autodoc')
+ assert_result_contains('.. py:module:: target',
+ 'module', 'target')
options.synopsis = 'Synopsis'
- assert_result_contains(' :synopsis: Synopsis', 'module', 'test_autodoc')
+ assert_result_contains(' :synopsis: Synopsis', 'module', 'target')
options.deprecated = True
- assert_result_contains(' :deprecated:', 'module', 'test_autodoc')
+ assert_result_contains(' :deprecated:', 'module', 'target')
options.platform = 'Platform'
- assert_result_contains(' :platform: Platform', 'module', 'test_autodoc')
+ assert_result_contains(' :platform: Platform', 'module', 'target')
# test if __all__ is respected for modules
options.members = ALL
- assert_result_contains('.. py:class:: Class(arg)', 'module', 'test_autodoc')
+ assert_result_contains('.. py:class:: Class(arg)', 'module', 'target')
try:
assert_result_contains('.. py:exception:: CustomEx',
- 'module', 'test_autodoc')
+ 'module', 'target')
except AssertionError:
pass
else:
assert False, 'documented CustomEx which is not in __all__'
+ # test ignore-module-all
+ options.ignore_module_all = True
+ assert_result_contains('.. py:class:: Class(arg)', 'module', 'target')
+ assert_result_contains('.. py:exception:: CustomEx', 'module', 'target')
+
# test noindex flag
options.members = []
options.noindex = True
- assert_result_contains(' :noindex:', 'module', 'test_autodoc')
+ assert_result_contains(' :noindex:', 'module', 'target')
assert_result_contains(' :noindex:', 'class', 'Base')
# okay, now let's get serious about mixing Python and C signature stuff
@@ -749,14 +763,14 @@ def test_generate():
all_members=True)
# test inner class handling
- assert_processes([('class', 'test_autodoc.Outer'),
- ('class', 'test_autodoc.Outer.Inner'),
- ('method', 'test_autodoc.Outer.Inner.meth')],
+ assert_processes([('class', 'target.Outer'),
+ ('class', 'target.Outer.Inner'),
+ ('method', 'target.Outer.Inner.meth')],
'class', 'Outer', all_members=True)
# test descriptor docstrings
assert_result_contains(' Descriptor instance docstring.',
- 'attribute', 'test_autodoc.Class.descr')
+ 'attribute', 'target.Class.descr')
# test generation for C modules (which have no source file)
directive.env.ref_context['py:module'] = 'time'
@@ -764,7 +778,7 @@ def test_generate():
assert_processes([('function', 'time.asctime')], 'function', 'asctime')
# test autodoc_member_order == 'source'
- directive.env.ref_context['py:module'] = 'test_autodoc'
+ directive.env.ref_context['py:module'] = 'target'
options.private_members = True
if PY3:
roger_line = ' .. py:classmethod:: Class.roger(a, *, b=2, c=3, d=4, e=5, f=6)'
@@ -790,7 +804,7 @@ def test_generate():
del directive.env.ref_context['py:module']
# test attribute initialized to class instance from other module
- directive.env.temp_data['autodoc:class'] = 'test_autodoc.Class'
+ directive.env.temp_data['autodoc:class'] = 'target.Class'
assert_result_contains(u' should be documented as well - s\xfc\xdf',
'attribute', 'mdocattr')
del directive.env.temp_data['autodoc:class']
@@ -798,25 +812,25 @@ def test_generate():
# test autodoc_docstring_signature
assert_result_contains(
'.. py:method:: DocstringSig.meth(FOO, BAR=1) -> BAZ', 'method',
- 'test_autodoc.DocstringSig.meth')
+ 'target.DocstringSig.meth')
assert_result_contains(
- ' rest of docstring', 'method', 'test_autodoc.DocstringSig.meth')
+ ' rest of docstring', 'method', 'target.DocstringSig.meth')
assert_result_contains(
'.. py:method:: DocstringSig.meth2()', 'method',
- 'test_autodoc.DocstringSig.meth2')
+ 'target.DocstringSig.meth2')
assert_result_contains(
' indented line', 'method',
- 'test_autodoc.DocstringSig.meth2')
+ 'target.DocstringSig.meth2')
assert_result_contains(
'.. py:classmethod:: Class.moore(a, e, f) -> happiness', 'method',
- 'test_autodoc.Class.moore')
+ 'target.Class.moore')
# test new attribute documenter behavior
- directive.env.ref_context['py:module'] = 'test_autodoc'
+ directive.env.ref_context['py:module'] = 'target'
options.undoc_members = True
- assert_processes([('class', 'test_autodoc.AttCls'),
- ('attribute', 'test_autodoc.AttCls.a1'),
- ('attribute', 'test_autodoc.AttCls.a2'),
+ assert_processes([('class', 'target.AttCls'),
+ ('attribute', 'target.AttCls.a1'),
+ ('attribute', 'target.AttCls.a2'),
], 'class', 'AttCls')
assert_result_contains(
' :annotation: = hello world', 'attribute', 'AttCls.a1')
@@ -826,40 +840,40 @@ def test_generate():
# test explicit members with instance attributes
del directive.env.temp_data['autodoc:class']
del directive.env.temp_data['autodoc:module']
- directive.env.ref_context['py:module'] = 'test_autodoc'
+ directive.env.ref_context['py:module'] = 'target'
options.inherited_members = False
options.undoc_members = False
options.members = ALL
assert_processes([
- ('class', 'test_autodoc.InstAttCls'),
- ('attribute', 'test_autodoc.InstAttCls.ca1'),
- ('attribute', 'test_autodoc.InstAttCls.ca2'),
- ('attribute', 'test_autodoc.InstAttCls.ca3'),
- ('attribute', 'test_autodoc.InstAttCls.ia1'),
- ('attribute', 'test_autodoc.InstAttCls.ia2'),
+ ('class', 'target.InstAttCls'),
+ ('attribute', 'target.InstAttCls.ca1'),
+ ('attribute', 'target.InstAttCls.ca2'),
+ ('attribute', 'target.InstAttCls.ca3'),
+ ('attribute', 'target.InstAttCls.ia1'),
+ ('attribute', 'target.InstAttCls.ia2'),
], 'class', 'InstAttCls')
del directive.env.temp_data['autodoc:class']
del directive.env.temp_data['autodoc:module']
options.members = ['ca1', 'ia1']
assert_processes([
- ('class', 'test_autodoc.InstAttCls'),
- ('attribute', 'test_autodoc.InstAttCls.ca1'),
- ('attribute', 'test_autodoc.InstAttCls.ia1'),
+ ('class', 'target.InstAttCls'),
+ ('attribute', 'target.InstAttCls.ca1'),
+ ('attribute', 'target.InstAttCls.ia1'),
], 'class', 'InstAttCls')
del directive.env.temp_data['autodoc:class']
del directive.env.temp_data['autodoc:module']
del directive.env.ref_context['py:module']
# test members with enum attributes
- directive.env.ref_context['py:module'] = 'test_autodoc'
+ directive.env.ref_context['py:module'] = 'target'
options.inherited_members = False
options.undoc_members = False
options.members = ALL
assert_processes([
- ('class', 'test_autodoc.EnumCls'),
- ('attribute', 'test_autodoc.EnumCls.val1'),
- ('attribute', 'test_autodoc.EnumCls.val2'),
- ('attribute', 'test_autodoc.EnumCls.val3'),
+ ('class', 'target.EnumCls'),
+ ('attribute', 'target.EnumCls.val1'),
+ ('attribute', 'target.EnumCls.val2'),
+ ('attribute', 'target.EnumCls.val3'),
], 'class', 'EnumCls')
assert_result_contains(
' :annotation: = 12', 'attribute', 'EnumCls.val1')
@@ -873,11 +887,11 @@ def test_generate():
# test descriptor class documentation
options.members = ['CustomDataDescriptor', 'CustomDataDescriptor2']
assert_result_contains('.. py:class:: CustomDataDescriptor(doc)',
- 'module', 'test_autodoc')
+ 'module', 'target')
assert_result_contains(' .. py:method:: CustomDataDescriptor.meth()',
- 'module', 'test_autodoc')
+ 'module', 'target')
assert_result_contains('.. py:class:: CustomDataDescriptor2(doc)',
- 'module', 'test_autodoc')
+ 'module', 'target')
# test mocked module imports
options.members = ['TestAutodoc']
@@ -889,224 +903,3 @@ def test_generate():
options.members = ['decoratedFunction']
assert_result_contains('.. py:function:: decoratedFunction()',
'module', 'autodoc_missing_imports')
-
-
-# --- generate fodder ------------
-__all__ = ['Class']
-
-#: documentation for the integer
-integer = 1
-
-
-def raises(exc, func, *args, **kwds):
- """Raise AssertionError if ``func(*args, **kwds)`` does not raise *exc*."""
- pass
-
-
-class CustomEx(Exception):
- """My custom exception."""
-
- def f(self):
- """Exception method."""
-
-
-class CustomDataDescriptor(object):
- """Descriptor class docstring."""
-
- def __init__(self, doc):
- self.__doc__ = doc
-
- def __get__(self, obj, type=None):
- if obj is None:
- return self
- return 42
-
- def meth(self):
- """Function."""
- return "The Answer"
-
-
-class CustomDataDescriptorMeta(type):
- """Descriptor metaclass docstring."""
-
-
-@add_metaclass(CustomDataDescriptorMeta)
-class CustomDataDescriptor2(CustomDataDescriptor):
- """Descriptor class with custom metaclass docstring."""
-
-
-def _funky_classmethod(name, b, c, d, docstring=None):
- """Generates a classmethod for a class from a template by filling out
- some arguments."""
- def template(cls, a, b, c, d=4, e=5, f=6):
- return a, b, c, d, e, f
- from functools import partial
- function = partial(template, b=b, c=c, d=d)
- function.__name__ = name
- function.__doc__ = docstring
- return classmethod(function)
-
-
-class Base(object):
- def inheritedmeth(self):
- """Inherited function."""
-
-
-class Derived(Base):
- def inheritedmeth(self):
- # no docstring here
- pass
-
-
-class Class(Base):
- """Class to document."""
-
- descr = CustomDataDescriptor("Descriptor instance docstring.")
-
- def meth(self):
- """Function."""
-
- def undocmeth(self):
- pass
-
- def skipmeth(self):
- """Method that should be skipped."""
-
- def excludemeth(self):
- """Method that should be excluded."""
-
- # should not be documented
- skipattr = 'foo'
-
- #: should be documented -- süß
- attr = 'bar'
-
- @property
- def prop(self):
- """Property."""
-
- docattr = 'baz'
- """should likewise be documented -- süß"""
-
- udocattr = 'quux'
- u"""should be documented as well - süß"""
-
- # initialized to any class imported from another module
- mdocattr = StringIO()
- """should be documented as well - süß"""
-
- roger = _funky_classmethod("roger", 2, 3, 4)
-
- moore = _funky_classmethod("moore", 9, 8, 7,
- docstring="moore(a, e, f) -> happiness")
-
- def __init__(self, arg):
- self.inst_attr_inline = None #: an inline documented instance attr
- #: a documented instance attribute
- self.inst_attr_comment = None
- self.inst_attr_string = None
- """a documented instance attribute"""
- self._private_inst_attr = None #: a private instance attribute
-
- def __special1__(self):
- """documented special method"""
-
- def __special2__(self):
- # undocumented special method
- pass
-
-
-class CustomDict(dict):
- """Docstring."""
-
-
-def function(foo, *args, **kwds):
- """
- Return spam.
- """
- pass
-
-
-class Outer(object):
- """Foo"""
-
- class Inner(object):
- """Foo"""
-
- def meth(self):
- """Foo"""
-
- # should be documented as an alias
- factory = dict
-
-
-class DocstringSig(object):
- def meth(self):
- """meth(FOO, BAR=1) -> BAZ
-First line of docstring
-
- rest of docstring
- """
-
- def meth2(self):
- """First line, no signature
- Second line followed by indentation::
-
- indented line
- """
-
- @property
- def prop1(self):
- """DocstringSig.prop1(self)
- First line of docstring
- """
- return 123
-
- @property
- def prop2(self):
- """First line of docstring
- Second line of docstring
- """
- return 456
-
-
-class StrRepr(str):
- def __repr__(self):
- return self
-
-
-class AttCls(object):
- a1 = StrRepr('hello\nworld')
- a2 = None
-
-
-class InstAttCls(object):
- """Class with documented class and instance attributes."""
-
- #: Doc comment for class attribute InstAttCls.ca1.
- #: It can have multiple lines.
- ca1 = 'a'
-
- ca2 = 'b' #: Doc comment for InstAttCls.ca2. One line only.
-
- ca3 = 'c'
- """Docstring for class attribute InstAttCls.ca3."""
-
- def __init__(self):
- #: Doc comment for instance attribute InstAttCls.ia1
- self.ia1 = 'd'
-
- self.ia2 = 'e'
- """Docstring for instance attribute InstAttCls.ia2."""
-
-
-class EnumCls(enum.Enum):
- """
- this is enum class
- """
-
- #: doc for val1
- val1 = 12
- val2 = 23 #: doc for val2
- val3 = 34
- """doc for val3"""
diff --git a/tests/test_build.py b/tests/test_build.py
index 387e308a8..df0458aa3 100644
--- a/tests/test_build.py
+++ b/tests/test_build.py
@@ -5,7 +5,7 @@
Test 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.
"""
@@ -34,8 +34,8 @@ def nonascii_srcdir(request, rootdir, sphinx_test_tempdir):
basedir = sphinx_test_tempdir / request.node.originalname
# Windows with versions prior to 3.2 (I think) doesn't support unicode on system path
# so we force a non-unicode path in that case
- if sys.platform == "win32" and \
- not (sys.version_info.major >= 3 and sys.version_info.minor >= 2):
+ if (sys.platform == "win32" and
+ not (sys.version_info.major >= 3 and sys.version_info.minor >= 2)):
return basedir / 'all'
try:
srcdir = basedir / test_name
diff --git a/tests/test_build_applehelp.py b/tests/test_build_applehelp.py
index 4418cb265..31d4ca4df 100644
--- a/tests/test_build_applehelp.py
+++ b/tests/test_build_applehelp.py
@@ -7,7 +7,7 @@
test the HTML itself; that's already handled by
:file:`test_build_html.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.
"""
diff --git a/tests/test_build_epub.py b/tests/test_build_epub.py
index 397547734..e5d86b0ed 100644
--- a/tests/test_build_epub.py
+++ b/tests/test_build_epub.py
@@ -245,5 +245,3 @@ def test_epub_writing_mode(app):
# vertical / writing-mode (CSS)
css = (app.outdir / '_static' / 'epub.css').text()
assert 'writing-mode: vertical-rl;' in css
-
-
diff --git a/tests/test_build_gettext.py b/tests/test_build_gettext.py
index f256140fe..c14013f9a 100644
--- a/tests/test_build_gettext.py
+++ b/tests/test_build_gettext.py
@@ -5,7 +5,7 @@
Test the build process with gettext builder with the test root.
- :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
diff --git a/tests/test_build_html.py b/tests/test_build_html.py
index b4fec18ba..8265c8471 100644
--- a/tests/test_build_html.py
+++ b/tests/test_build_html.py
@@ -5,7 +5,7 @@
Test the HTML builder and check output against XPath.
- :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.
"""
@@ -15,7 +15,6 @@ from itertools import cycle, chain
from six import PY3
-from sphinx import __display_version__
from sphinx.util.inventory import InventoryFile
from sphinx.testing.util import remove_unicode_literals, strip_escseq
import xml.etree.cElementTree as ElementTree
@@ -182,8 +181,8 @@ def test_html_warnings(app, warning):
r'-| |-'),
],
'autodoc.html': [
- (".//dt[@id='test_autodoc.Class']", ''),
- (".//dt[@id='test_autodoc.function']/em", r'\*\*kwds'),
+ (".//dt[@id='autodoc_target.Class']", ''),
+ (".//dt[@id='autodoc_target.function']/em", r'\*\*kwds'),
(".//dd/p", r'Return spam\.'),
],
'extapi.html': [
diff --git a/tests/test_build_html5.py b/tests/test_build_html5.py
index 39b064b1c..4ac70be51 100644
--- a/tests/test_build_html5.py
+++ b/tests/test_build_html5.py
@@ -10,7 +10,7 @@
https://github.com/sphinx-doc/sphinx/pull/2805/files
- :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,8 +90,8 @@ def cached_etree_parse():
r'-| |-'),
],
'autodoc.html': [
- (".//dt[@id='test_autodoc.Class']", ''),
- (".//dt[@id='test_autodoc.function']/em", r'\*\*kwds'),
+ (".//dt[@id='autodoc_target.Class']", ''),
+ (".//dt[@id='autodoc_target.function']/em", r'\*\*kwds'),
(".//dd/p", r'Return spam\.'),
],
'extapi.html': [
diff --git a/tests/test_build_latex.py b/tests/test_build_latex.py
index b78bcf637..ab91d7a48 100644
--- a/tests/test_build_latex.py
+++ b/tests/test_build_latex.py
@@ -5,7 +5,7 @@
Test the build process with LaTeX builder with the test root.
- :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
@@ -335,6 +335,56 @@ def test_numref_with_language_ja(app, status, warning):
'\\nameref{\\detokenize{foo:foo}}}') in result
+@pytest.mark.sphinx('latex', testroot='latex-numfig')
+def test_latex_obey_numfig_is_false(app, status, warning):
+ app.builder.build_all()
+
+ result = (app.outdir / 'SphinxManual.tex').text(encoding='utf8')
+ assert '\\usepackage{sphinx}' in result
+
+ result = (app.outdir / 'SphinxHowTo.tex').text(encoding='utf8')
+ assert '\\usepackage{sphinx}' in result
+
+
+@pytest.mark.sphinx(
+ 'latex', testroot='latex-numfig',
+ confoverrides={'numfig': True, 'numfig_secnum_depth': 0})
+def test_latex_obey_numfig_secnum_depth_is_zero(app, status, warning):
+ app.builder.build_all()
+
+ result = (app.outdir / 'SphinxManual.tex').text(encoding='utf8')
+ assert '\\usepackage[,nonumfigreset,mathnumfig]{sphinx}' in result
+
+ result = (app.outdir / 'SphinxHowTo.tex').text(encoding='utf8')
+ assert '\\usepackage[,nonumfigreset,mathnumfig]{sphinx}' in result
+
+
+@pytest.mark.sphinx(
+ 'latex', testroot='latex-numfig',
+ confoverrides={'numfig': True, 'numfig_secnum_depth': 2})
+def test_latex_obey_numfig_secnum_depth_is_two(app, status, warning):
+ app.builder.build_all()
+
+ result = (app.outdir / 'SphinxManual.tex').text(encoding='utf8')
+ assert '\\usepackage[,numfigreset=2,mathnumfig]{sphinx}' in result
+
+ result = (app.outdir / 'SphinxHowTo.tex').text(encoding='utf8')
+ assert '\\usepackage[,numfigreset=3,mathnumfig]{sphinx}' in result
+
+
+@pytest.mark.sphinx(
+ 'latex', testroot='latex-numfig',
+ confoverrides={'numfig': True, 'math_numfig': False})
+def test_latex_obey_numfig_but_math_numfig_false(app, status, warning):
+ app.builder.build_all()
+
+ result = (app.outdir / 'SphinxManual.tex').text(encoding='utf8')
+ assert '\\usepackage[,numfigreset=1]{sphinx}' in result
+
+ result = (app.outdir / 'SphinxHowTo.tex').text(encoding='utf8')
+ assert '\\usepackage[,numfigreset=2]{sphinx}' in result
+
+
@pytest.mark.sphinx('latex')
def test_latex_add_latex_package(app, status, warning):
app.add_latex_package('foo')
@@ -712,19 +762,16 @@ def test_latex_logo_if_not_found(app, status, warning):
assert isinstance(exc, SphinxError)
-@pytest.mark.sphinx('latex', testroot='toctree-maxdepth',
- confoverrides={'latex_documents': [
- ('index', 'SphinxTests.tex', 'Sphinx Tests Documentation',
- 'Georg Brandl', 'manual'),
- ]})
+@pytest.mark.sphinx('latex', testroot='toctree-maxdepth')
def test_toctree_maxdepth_manual(app, status, warning):
app.builder.build_all()
- result = (app.outdir / 'SphinxTests.tex').text(encoding='utf8')
+ result = (app.outdir / 'Python.tex').text(encoding='utf8')
print(result)
print(status.getvalue())
print(warning.getvalue())
assert '\\setcounter{tocdepth}{1}' in result
assert '\\setcounter{secnumdepth}' not in result
+ assert '\\chapter{Foo}' in result
@pytest.mark.sphinx(
@@ -741,6 +788,7 @@ def test_toctree_maxdepth_howto(app, status, warning):
print(warning.getvalue())
assert '\\setcounter{tocdepth}{2}' in result
assert '\\setcounter{secnumdepth}' not in result
+ assert '\\section{Foo}' in result
@pytest.mark.sphinx(
@@ -754,6 +802,7 @@ def test_toctree_not_found(app, status, warning):
print(warning.getvalue())
assert '\\setcounter{tocdepth}' not in result
assert '\\setcounter{secnumdepth}' not in result
+ assert '\\chapter{Foo A}' in result
@pytest.mark.sphinx(
@@ -804,6 +853,26 @@ def test_latex_toplevel_sectioning_is_part(app, status, warning):
print(status.getvalue())
print(warning.getvalue())
assert '\\part{Foo}' in result
+ assert '\\chapter{Foo A}' in result
+ assert '\\chapter{Foo B}' in result
+
+
+@pytest.mark.sphinx(
+ 'latex', testroot='toctree-maxdepth',
+ confoverrides={'latex_toplevel_sectioning': 'part',
+ 'latex_documents': [
+ ('index', 'Python.tex', 'Sphinx Tests Documentation',
+ 'Georg Brandl', 'howto')
+ ]})
+def test_latex_toplevel_sectioning_is_part_with_howto(app, status, warning):
+ app.builder.build_all()
+ result = (app.outdir / 'Python.tex').text(encoding='utf8')
+ print(result)
+ print(status.getvalue())
+ print(warning.getvalue())
+ assert '\\part{Foo}' in result
+ assert '\\section{Foo A}' in result
+ assert '\\section{Foo B}' in result
@pytest.mark.sphinx(
@@ -820,6 +889,22 @@ def test_latex_toplevel_sectioning_is_chapter(app, status, warning):
@pytest.mark.sphinx(
'latex', testroot='toctree-maxdepth',
+ confoverrides={'latex_toplevel_sectioning': 'chapter',
+ 'latex_documents': [
+ ('index', 'Python.tex', 'Sphinx Tests Documentation',
+ 'Georg Brandl', 'howto')
+ ]})
+def test_latex_toplevel_sectioning_is_chapter_with_howto(app, status, warning):
+ app.builder.build_all()
+ result = (app.outdir / 'Python.tex').text(encoding='utf8')
+ print(result)
+ print(status.getvalue())
+ print(warning.getvalue())
+ assert '\\section{Foo}' in result
+
+
+@pytest.mark.sphinx(
+ 'latex', testroot='toctree-maxdepth',
confoverrides={'latex_toplevel_sectioning': 'section'})
def test_latex_toplevel_sectioning_is_section(app, status, warning):
app.builder.build_all()
diff --git a/tests/test_build_linkcheck.py b/tests/test_build_linkcheck.py
index cc3d6e24f..839a15628 100644
--- a/tests/test_build_linkcheck.py
+++ b/tests/test_build_linkcheck.py
@@ -5,7 +5,7 @@
Test the build process with manpage builder with the test root.
- :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
diff --git a/tests/test_build_manpage.py b/tests/test_build_manpage.py
index 953332c73..3448d6eeb 100644
--- a/tests/test_build_manpage.py
+++ b/tests/test_build_manpage.py
@@ -5,7 +5,7 @@
Test the build process with manpage builder with the test root.
- :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
diff --git a/tests/test_build_qthelp.py b/tests/test_build_qthelp.py
index 3e4815fbe..de676e6e0 100644
--- a/tests/test_build_qthelp.py
+++ b/tests/test_build_qthelp.py
@@ -7,7 +7,7 @@
test the HTML itself; that's already handled by
:file:`test_build_html.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.
"""
diff --git a/tests/test_build_texinfo.py b/tests/test_build_texinfo.py
index c4238c659..114f194fe 100644
--- a/tests/test_build_texinfo.py
+++ b/tests/test_build_texinfo.py
@@ -5,7 +5,7 @@
Test the build process with Texinfo builder with the test root.
- :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
diff --git a/tests/test_build_text.py b/tests/test_build_text.py
index 81e354ecd..9bfbe1206 100644
--- a/tests/test_build_text.py
+++ b/tests/test_build_text.py
@@ -5,7 +5,7 @@
Test the build process with Text builder with the test root.
- :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 pytest
diff --git a/tests/test_catalogs.py b/tests/test_catalogs.py
index b3e17a0a1..4bfbb18a3 100644
--- a/tests/test_catalogs.py
+++ b/tests/test_catalogs.py
@@ -5,7 +5,7 @@
Test the base build process.
- :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 shutil
diff --git a/tests/test_config.py b/tests/test_config.py
index 578f6e55c..3f38c7ab8 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -6,7 +6,7 @@
Test the sphinx.config.Config class and its handling in the
Application 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.
"""
from six import PY3, iteritems
diff --git a/tests/test_correct_year.py b/tests/test_correct_year.py
index a8058f08c..e7501bb6a 100644
--- a/tests/test_correct_year.py
+++ b/tests/test_correct_year.py
@@ -5,7 +5,7 @@
Test copyright year adjustment
- :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 pytest
diff --git a/tests/test_directive_code.py b/tests/test_directive_code.py
index e3069061b..f62f44f13 100644
--- a/tests/test_directive_code.py
+++ b/tests/test_directive_code.py
@@ -5,7 +5,7 @@
Test the code-block directive.
- :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.
"""
diff --git a/tests/test_directive_only.py b/tests/test_directive_only.py
index d8017f469..010eae384 100644
--- a/tests/test_directive_only.py
+++ b/tests/test_directive_only.py
@@ -5,7 +5,7 @@
Test the only directive with the test root.
- :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.
"""
diff --git a/tests/test_docutilsconf.py b/tests/test_docutilsconf.py
index fd5cf7a61..91bf8fc95 100644
--- a/tests/test_docutilsconf.py
+++ b/tests/test_docutilsconf.py
@@ -5,7 +5,7 @@
Test docutils.conf support for several writers.
- :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,7 @@ def test_texinfo(app, status, warning):
@pytest.mark.sphinx('html', testroot='docutilsconf',
docutilsconf='[general]\nsource_link=true\n')
-@pytest.mark.skip(sys.platform == "win32" and \
+@pytest.mark.skip(sys.platform == "win32" and
not (sys.version_info.major >= 3 and sys.version_info.minor >= 2),
reason="Python < 3.2 on Win32 doesn't handle non-ASCII paths right")
def test_docutils_source_link_with_nonascii_file(app, status, warning):
diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py
index f3f0037f5..3561e76ce 100644
--- a/tests/test_domain_cpp.py
+++ b/tests/test_domain_cpp.py
@@ -5,7 +5,7 @@
Tests the C++ 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.
"""
@@ -25,6 +25,7 @@ def parse(name, string):
cpp_id_attributes = ["id_attr"]
cpp_paren_attributes = ["paren_attr"]
parser = DefinitionParser(string, None, Config())
+ parser.allowFallbackExpressionParsing = False
ast = parser.parse_declaration(name)
parser.assert_end()
# The scopedness would usually have been set by CPPEnumObject
@@ -100,13 +101,13 @@ def test_fundamental_types():
if t == "std::nullptr_t":
id = "NSt9nullptr_tE"
return "1f%s" % id
- check("function", "void f(%s arg)" % t, {1: makeIdV1(), 2:makeIdV2()})
+ check("function", "void f(%s arg)" % t, {1: makeIdV1(), 2: makeIdV2()})
def test_expressions():
def exprCheck(expr, id):
ids = 'IE1CIA%s_1aE'
- check('class', 'template<> C<a[%s]>' % expr, {2:ids % expr, 3:ids % id})
+ check('class', 'template<> C<a[%s]>' % expr, {2: ids % expr, 3: ids % id})
# primary
exprCheck('nullptr', 'LDnE')
exprCheck('true', 'L1E')
@@ -117,9 +118,9 @@ def test_expressions():
for i in ints:
for u in unsignedSuffix:
for l in longSuffix:
- expr = i + u + l;
+ expr = i + u + l
exprCheck(expr, 'L' + expr + 'E')
- expr = i + l + u;
+ expr = i + l + u
exprCheck(expr, 'L' + expr + 'E')
for suffix in ['', 'f', 'F', 'l', 'L']:
expr = '5.0' + suffix
@@ -199,55 +200,64 @@ def test_expressions():
# a < expression that starts with something that could be a template
exprCheck('A < 42', 'lt1AL42E')
check('function', 'template<> void f(A<B, 2> &v)',
- {2:"IE1fR1AI1BX2EE", 3:"IE1fR1AI1BXL2EEE"})
+ {2: "IE1fR1AI1BX2EE", 3: "IE1fR1AI1BXL2EEE"})
exprCheck('A<1>::value', 'N1AIXL1EEE5valueE')
- check('class', "template<int T = 42> A", {2:"I_iE1A"})
- check('enumerator', 'A = std::numeric_limits<unsigned long>::max()', {2:"1A"})
+ check('class', "template<int T = 42> A", {2: "I_iE1A"})
+ check('enumerator', 'A = std::numeric_limits<unsigned long>::max()', {2: "1A"})
+
+ exprCheck('operator()()', 'clclE')
+ exprCheck('operator()<int>()', 'clclIiEE')
def test_type_definitions():
- check("type", "public bool b", {1:"b", 2:"1b"}, "bool b")
- check("type", "bool A::b", {1:"A::b", 2:"N1A1bE"})
- check("type", "bool *b", {1:"b", 2:"1b"})
- check("type", "bool *const b", {1:"b", 2:"1b"})
- check("type", "bool *volatile const b", {1:"b", 2:"1b"})
- check("type", "bool *volatile const b", {1:"b", 2:"1b"})
- check("type", "bool *volatile const *b", {1:"b", 2:"1b"})
- check("type", "bool &b", {1:"b", 2:"1b"})
- check("type", "bool b[]", {1:"b", 2:"1b"})
- check("type", "std::pair<int, int> coord", {1:"coord", 2:"5coord"})
- check("type", "long long int foo", {1:"foo", 2:"3foo"})
+ check("type", "public bool b", {1: "b", 2: "1b"}, "bool b")
+ check("type", "bool A::b", {1: "A::b", 2: "N1A1bE"})
+ check("type", "bool *b", {1: "b", 2: "1b"})
+ check("type", "bool *const b", {1: "b", 2: "1b"})
+ check("type", "bool *volatile const b", {1: "b", 2: "1b"})
+ check("type", "bool *volatile const b", {1: "b", 2: "1b"})
+ check("type", "bool *volatile const *b", {1: "b", 2: "1b"})
+ check("type", "bool &b", {1: "b", 2: "1b"})
+ check("type", "bool b[]", {1: "b", 2: "1b"})
+ check("type", "std::pair<int, int> coord", {1: "coord", 2: "5coord"})
+ check("type", "long long int foo", {1: "foo", 2: "3foo"})
check("type", 'std::vector<std::pair<std::string, long long>> module::blah',
- {1:"module::blah", 2:"N6module4blahE"})
- check("type", "std::function<void()> F", {1:"F", 2:"1F"})
- check("type", "std::function<R(A1, A2)> F", {1:"F", 2:"1F"})
- check("type", "std::function<R(A1, A2, A3)> F", {1:"F", 2:"1F"})
- check("type", "std::function<R(A1, A2, A3, As...)> F", {1:"F", 2:"1F"})
+ {1: "module::blah", 2: "N6module4blahE"})
+ check("type", "std::function<void()> F", {1: "F", 2: "1F"})
+ check("type", "std::function<R(A1, A2)> F", {1: "F", 2: "1F"})
+ check("type", "std::function<R(A1, A2, A3)> F", {1: "F", 2: "1F"})
+ check("type", "std::function<R(A1, A2, A3, As...)> F", {1: "F", 2: "1F"})
check("type", "MyContainer::const_iterator",
- {1:"MyContainer::const_iterator", 2:"N11MyContainer14const_iteratorE"})
+ {1: "MyContainer::const_iterator", 2: "N11MyContainer14const_iteratorE"})
check("type",
"public MyContainer::const_iterator",
- {1:"MyContainer::const_iterator", 2:"N11MyContainer14const_iteratorE"},
+ {1: "MyContainer::const_iterator", 2: "N11MyContainer14const_iteratorE"},
output="MyContainer::const_iterator")
# test decl specs on right
- check("type", "bool const b", {1:"b", 2:"1b"})
+ check("type", "bool const b", {1: "b", 2: "1b"})
# test name in global scope
- check("type", "bool ::B::b", {1:"B::b", 2:"N1B1bE"})
+ check("type", "bool ::B::b", {1: "B::b", 2: "N1B1bE"})
- check('type', 'A = B', {2:'1A'})
- check('type', 'A = decltype(b)', {2:'1A'})
+ check('type', 'A = B', {2: '1A'})
+ check('type', 'A = decltype(b)', {2: '1A'})
# from breathe#267 (named function parameters for function pointers
check('type', 'void (*gpio_callback_t)(struct device *port, uint32_t pin)',
- {1:'gpio_callback_t', 2:'15gpio_callback_t'})
- check('type', 'void (*f)(std::function<void(int i)> g)', {1:'f', 2:'1f'})
+ {1: 'gpio_callback_t', 2: '15gpio_callback_t'})
+ check('type', 'void (*f)(std::function<void(int i)> g)', {1: 'f', 2: '1f'})
+
+ check('type', 'T = A::template B<int>::template C<double>', {2: '1T'})
+
+ check('type', 'T = Q<A::operator()>', {2: '1T'})
+ check('type', 'T = Q<A::operator()<int>>', {2: '1T'})
+ check('type', 'T = Q<A::operator bool>', {2: '1T'})
def test_concept_definitions():
check('concept', 'template<typename Param> A::B::Concept',
- {2:'I0EN1A1B7ConceptE'})
+ {2: 'I0EN1A1B7ConceptE'})
check('concept', 'template<typename A, typename B, typename ...C> Foo',
- {2:'I00DpE3Foo'})
+ {2: 'I00DpE3Foo'})
with pytest.raises(DefinitionError):
parse('concept', 'Foo')
with pytest.raises(DefinitionError):
@@ -256,269 +266,270 @@ def test_concept_definitions():
def test_member_definitions():
check('member', ' const std::string & name = 42',
- {1:"name__ssCR", 2:"4name"}, output='const std::string &name = 42')
- check('member', ' const std::string & name', {1:"name__ssCR", 2:"4name"},
+ {1: "name__ssCR", 2: "4name"}, output='const std::string &name = 42')
+ check('member', ' const std::string & name', {1: "name__ssCR", 2: "4name"},
output='const std::string &name')
check('member', ' const std::string & name [ n ]',
- {1:"name__ssCRA", 2:"4name"}, output='const std::string &name[n]')
+ {1: "name__ssCRA", 2: "4name"}, output='const std::string &name[n]')
check('member', 'const std::vector< unsigned int, long> &name',
- {1:"name__std::vector:unsigned-i.l:CR", 2:"4name"},
+ {1: "name__std::vector:unsigned-i.l:CR", 2: "4name"},
output='const std::vector<unsigned int, long> &name')
- check('member', 'module::myclass foo[n]', {1:"foo__module::myclassA", 2:"3foo"})
- check('member', 'int *const p', {1:'p__iPC', 2:'1p'})
- check('member', 'extern int myInt', {1:'myInt__i', 2:'5myInt'})
- check('member', 'thread_local int myInt', {1:'myInt__i', 2:'5myInt'})
- check('member', 'extern thread_local int myInt', {1:'myInt__i', 2:'5myInt'})
- check('member', 'thread_local extern int myInt', {1:'myInt__i', 2:'5myInt'},
+ check('member', 'module::myclass foo[n]', {1: "foo__module::myclassA", 2: "3foo"})
+ check('member', 'int *const p', {1: 'p__iPC', 2: '1p'})
+ check('member', 'extern int myInt', {1: 'myInt__i', 2: '5myInt'})
+ check('member', 'thread_local int myInt', {1: 'myInt__i', 2: '5myInt'})
+ check('member', 'extern thread_local int myInt', {1: 'myInt__i', 2: '5myInt'})
+ check('member', 'thread_local extern int myInt', {1: 'myInt__i', 2: '5myInt'},
'extern thread_local int myInt')
def test_function_definitions():
- check('function', 'operator bool() const', {1:"castto-b-operatorC", 2:"NKcvbEv"})
+ check('function', 'operator bool() const', {1: "castto-b-operatorC", 2: "NKcvbEv"})
check('function', 'A::operator bool() const',
- {1:"A::castto-b-operatorC", 2:"NK1AcvbEv"})
+ {1: "A::castto-b-operatorC", 2: "NK1AcvbEv"})
check('function', 'A::operator bool() volatile const &',
- {1:"A::castto-b-operatorVCR", 2:"NVKR1AcvbEv"})
+ {1: "A::castto-b-operatorVCR", 2: "NVKR1AcvbEv"})
check('function', 'A::operator bool() volatile const &&',
- {1:"A::castto-b-operatorVCO", 2:"NVKO1AcvbEv"})
+ {1: "A::castto-b-operatorVCO", 2: "NVKO1AcvbEv"})
check('function', 'bool namespaced::theclass::method(arg1, arg2)',
- {1:"namespaced::theclass::method__arg1.arg2",
- 2:"N10namespaced8theclass6methodE4arg14arg2"})
+ {1: "namespaced::theclass::method__arg1.arg2",
+ 2: "N10namespaced8theclass6methodE4arg14arg2"})
x = 'std::vector<std::pair<std::string, int>> &module::test(register int ' \
'foo, bar, std::string baz = "foobar, blah, bleh") const = 0'
- check('function', x, {1:"module::test__i.bar.ssC",
- 2:"NK6module4testEi3barNSt6stringE"})
+ check('function', x, {1: "module::test__i.bar.ssC",
+ 2: "NK6module4testEi3barNSt6stringE"})
check('function', 'void f(std::pair<A, B>)',
- {1:"f__std::pair:A.B:", 2:"1fNSt4pairI1A1BEE"})
+ {1: "f__std::pair:A.B:", 2: "1fNSt4pairI1A1BEE"})
check('function', 'explicit module::myclass::foo::foo()',
- {1:"module::myclass::foo::foo", 2:"N6module7myclass3foo3fooEv"})
+ {1: "module::myclass::foo::foo", 2: "N6module7myclass3foo3fooEv"})
check('function', 'module::myclass::foo::~foo()',
- {1:"module::myclass::foo::~foo", 2:"N6module7myclass3fooD0Ev"})
+ {1: "module::myclass::foo::~foo", 2: "N6module7myclass3fooD0Ev"})
check('function', 'int printf(const char *fmt, ...)',
- {1:"printf__cCP.z", 2:"6printfPKcz"})
+ {1: "printf__cCP.z", 2: "6printfPKcz"})
check('function', 'int foo(const unsigned int j)',
- {1:"foo__unsigned-iC", 2:"3fooKj"})
+ {1: "foo__unsigned-iC", 2: "3fooKj"})
check('function', 'int foo(const int *const ptr)',
- {1:"foo__iCPC", 2:"3fooPCKi"})
+ {1: "foo__iCPC", 2: "3fooPCKi"})
check('function', 'module::myclass::operator std::vector<std::string>()',
- {1:"module::myclass::castto-std::vector:ss:-operator",
- 2:"N6module7myclasscvNSt6vectorINSt6stringEEEEv"})
+ {1: "module::myclass::castto-std::vector:ss:-operator",
+ 2: "N6module7myclasscvNSt6vectorINSt6stringEEEEv"})
check('function',
'void operator()(const boost::array<VertexID, 2> &v) const',
- {1:"call-operator__boost::array:VertexID.2:CRC",
- 2:"NKclERKN5boost5arrayI8VertexIDX2EEE",
- 3:"NKclERKN5boost5arrayI8VertexIDXL2EEEE"})
+ {1: "call-operator__boost::array:VertexID.2:CRC",
+ 2: "NKclERKN5boost5arrayI8VertexIDX2EEE",
+ 3: "NKclERKN5boost5arrayI8VertexIDXL2EEEE"})
check('function',
'void operator()(const boost::array<VertexID, 2, "foo, bar"> &v) const',
- {1:'call-operator__boost::array:VertexID.2."foo,--bar":CRC',
- 2:'NKclERKN5boost5arrayI8VertexIDX2EX"foo, bar"EEE',
- 3:'NKclERKN5boost5arrayI8VertexIDXL2EEXLA9_KcEEEE'})
+ {1: 'call-operator__boost::array:VertexID.2."foo,--bar":CRC',
+ 2: 'NKclERKN5boost5arrayI8VertexIDX2EX"foo, bar"EEE',
+ 3: 'NKclERKN5boost5arrayI8VertexIDXL2EEXLA9_KcEEEE'})
check('function', 'MyClass::MyClass(MyClass::MyClass&&)',
- {1:"MyClass::MyClass__MyClass::MyClassRR",
- 2:"N7MyClass7MyClassERRN7MyClass7MyClassE"})
- check('function', 'constexpr int get_value()', {1:"get_valueCE", 2:"9get_valuev"})
+ {1: "MyClass::MyClass__MyClass::MyClassRR",
+ 2: "N7MyClass7MyClassERRN7MyClass7MyClassE"})
+ check('function', 'constexpr int get_value()', {1: "get_valueCE", 2: "9get_valuev"})
check('function', 'static constexpr int get_value()',
- {1:"get_valueCE", 2:"9get_valuev"})
+ {1: "get_valueCE", 2: "9get_valuev"})
check('function', 'int get_value() const noexcept',
- {1:"get_valueC", 2:"NK9get_valueEv"})
+ {1: "get_valueC", 2: "NK9get_valueEv"})
check('function', 'int get_value() const noexcept = delete',
- {1:"get_valueC", 2:"NK9get_valueEv"})
+ {1: "get_valueC", 2: "NK9get_valueEv"})
check('function', 'int get_value() volatile const',
- {1:"get_valueVC", 2:"NVK9get_valueEv"})
+ {1: "get_valueVC", 2: "NVK9get_valueEv"})
check('function', 'MyClass::MyClass(MyClass::MyClass&&) = default',
- {1:"MyClass::MyClass__MyClass::MyClassRR",
- 2:"N7MyClass7MyClassERRN7MyClass7MyClassE"})
+ {1: "MyClass::MyClass__MyClass::MyClassRR",
+ 2: "N7MyClass7MyClassERRN7MyClass7MyClassE"})
check('function', 'virtual MyClass::a_virtual_function() const override',
- {1:"MyClass::a_virtual_functionC", 2:"NK7MyClass18a_virtual_functionEv"})
- check('function', 'A B() override', {1:"B", 2:"1Bv"})
- check('function', 'A B() final', {1:"B", 2:"1Bv"})
- check('function', 'A B() final override', {1:"B", 2:"1Bv"})
- check('function', 'A B() override final', {1:"B", 2:"1Bv"},
+ {1: "MyClass::a_virtual_functionC", 2: "NK7MyClass18a_virtual_functionEv"})
+ check('function', 'A B() override', {1: "B", 2: "1Bv"})
+ check('function', 'A B() final', {1: "B", 2: "1Bv"})
+ check('function', 'A B() final override', {1: "B", 2: "1Bv"})
+ check('function', 'A B() override final', {1: "B", 2: "1Bv"},
output='A B() final override')
check('function', 'MyClass::a_member_function() volatile',
- {1:"MyClass::a_member_functionV", 2:"NV7MyClass17a_member_functionEv"})
+ {1: "MyClass::a_member_functionV", 2: "NV7MyClass17a_member_functionEv"})
check('function', 'MyClass::a_member_function() volatile const',
- {1:"MyClass::a_member_functionVC", 2:"NVK7MyClass17a_member_functionEv"})
+ {1: "MyClass::a_member_functionVC", 2: "NVK7MyClass17a_member_functionEv"})
check('function', 'MyClass::a_member_function() &&',
- {1:"MyClass::a_member_functionO", 2:"NO7MyClass17a_member_functionEv"})
+ {1: "MyClass::a_member_functionO", 2: "NO7MyClass17a_member_functionEv"})
check('function', 'MyClass::a_member_function() &',
- {1:"MyClass::a_member_functionR", 2:"NR7MyClass17a_member_functionEv"})
+ {1: "MyClass::a_member_functionR", 2: "NR7MyClass17a_member_functionEv"})
check('function', 'MyClass::a_member_function() const &',
- {1:"MyClass::a_member_functionCR", 2:"NKR7MyClass17a_member_functionEv"})
+ {1: "MyClass::a_member_functionCR", 2: "NKR7MyClass17a_member_functionEv"})
check('function', 'int main(int argc, char *argv[])',
- {1:"main__i.cPA", 2:"4mainiA_Pc"})
+ {1: "main__i.cPA", 2: "4mainiA_Pc"})
check('function', 'MyClass &MyClass::operator++()',
- {1:"MyClass::inc-operator", 2:"N7MyClassppEv"})
+ {1: "MyClass::inc-operator", 2: "N7MyClassppEv"})
check('function', 'MyClass::pointer MyClass::operator->()',
- {1:"MyClass::pointer-operator", 2:"N7MyClassptEv"})
+ {1: "MyClass::pointer-operator", 2: "N7MyClassptEv"})
x = 'std::vector<std::pair<std::string, int>> &module::test(register int ' \
'foo, bar[n], std::string baz = "foobar, blah, bleh") const = 0'
- check('function', x, {1:"module::test__i.barA.ssC",
- 2:"NK6module4testEiAn_3barNSt6stringE",
- 3:"NK6module4testEiA1n_3barNSt6stringE"})
+ check('function', x, {1: "module::test__i.barA.ssC",
+ 2: "NK6module4testEiAn_3barNSt6stringE",
+ 3: "NK6module4testEiA1n_3barNSt6stringE"})
check('function',
'int foo(Foo f = Foo(double(), std::make_pair(int(2), double(3.4))))',
- {1:"foo__Foo", 2:"3foo3Foo"})
- check('function', 'int foo(A a = x(a))', {1:"foo__A", 2:"3foo1A"})
+ {1: "foo__Foo", 2: "3foo3Foo"})
+ check('function', 'int foo(A a = x(a))', {1: "foo__A", 2: "3foo1A"})
with pytest.raises(DefinitionError):
parse('function', 'int foo(B b=x(a)')
with pytest.raises(DefinitionError):
parse('function', 'int foo)C c=x(a))')
with pytest.raises(DefinitionError):
parse('function', 'int foo(D d=x(a')
- check('function', 'int foo(const A&... a)', {1:"foo__ACRDp", 2:"3fooDpRK1A"})
- check('function', 'virtual void f()', {1:"f", 2:"1fv"})
+ check('function', 'int foo(const A&... a)', {1: "foo__ACRDp", 2: "3fooDpRK1A"})
+ check('function', 'virtual void f()', {1: "f", 2: "1fv"})
# test for ::nestedName, from issue 1738
check("function", "result(int val, ::std::error_category const &cat)",
- {1:"result__i.std::error_categoryCR", 2:"6resultiRNSt14error_categoryE"})
- check("function", "int *f()", {1:"f", 2:"1fv"})
+ {1: "result__i.std::error_categoryCR", 2: "6resultiRNSt14error_categoryE"})
+ check("function", "int *f()", {1: "f", 2: "1fv"})
# tests derived from issue #1753 (skip to keep sanity)
- check("function", "f(int (&array)[10])", {2:"1fRA10_i", 3:"1fRAL10E_i"})
- check("function", "void f(int (&array)[10])", {2:"1fRA10_i", 3:"1fRAL10E_i"})
- check("function", "void f(float *q(double))", {2:"1fFPfdE"})
- check("function", "void f(float *(*q)(double))", {2:"1fPFPfdE"})
- check("function", "void f(float (*q)(double))", {2:"1fPFfdE"})
- check("function", "int (*f(double d))(float)", {1:"f__double", 2:"1fd"})
- check("function", "int (*f(bool b))[5]", {1:"f__b", 2:"1fb"})
+ check("function", "f(int (&array)[10])", {2: "1fRA10_i", 3: "1fRAL10E_i"})
+ check("function", "void f(int (&array)[10])", {2: "1fRA10_i", 3: "1fRAL10E_i"})
+ check("function", "void f(float *q(double))", {2: "1fFPfdE"})
+ check("function", "void f(float *(*q)(double))", {2: "1fPFPfdE"})
+ check("function", "void f(float (*q)(double))", {2: "1fPFfdE"})
+ check("function", "int (*f(double d))(float)", {1: "f__double", 2: "1fd"})
+ check("function", "int (*f(bool b))[5]", {1: "f__b", 2: "1fb"})
check("function", "int (*A::f(double d) const)(float)",
- {1:"A::f__doubleC", 2:"NK1A1fEd"})
+ {1: "A::f__doubleC", 2: "NK1A1fEd"})
check("function", "void f(std::shared_ptr<int(double)> ptr)",
- {2:"1fNSt10shared_ptrIFidEEE"})
- check("function", "void f(int *const p)", {1:"f__iPC", 2:"1fPCi"})
- check("function", "void f(int *volatile const p)", {1:"f__iPVC", 2:"1fPVCi"})
+ {2: "1fNSt10shared_ptrIFidEEE"})
+ check("function", "void f(int *const p)", {1: "f__iPC", 2: "1fPCi"})
+ check("function", "void f(int *volatile const p)", {1: "f__iPVC", 2: "1fPVCi"})
- check('function', 'extern int f()', {1:'f', 2:'1fv'})
+ check('function', 'extern int f()', {1: 'f', 2: '1fv'})
- check('function', 'decltype(auto) f()', {1: 'f', 2:"1fv"})
+ check('function', 'decltype(auto) f()', {1: 'f', 2: "1fv"})
# TODO: make tests for functions in a template, e.g., Test<int&&()>
# such that the id generation for function type types is correct.
check('function', 'friend std::ostream &f(std::ostream&, int)',
- {1:'f__osR.i', 2:'1fRNSt7ostreamEi'})
+ {1: 'f__osR.i', 2: '1fRNSt7ostreamEi'})
# from breathe#223
- check('function', 'void f(struct E e)', {1:'f__E', 2:'1f1E'})
- check('function', 'void f(class E e)', {1:'f__E', 2:'1f1E'})
- check('function', 'void f(typename E e)', {1:'f__E', 2:'1f1E'})
- check('function', 'void f(enum E e)', {1:'f__E', 2:'1f1E'})
- check('function', 'void f(union E e)', {1:'f__E', 2:'1f1E'})
+ check('function', 'void f(struct E e)', {1: 'f__E', 2: '1f1E'})
+ check('function', 'void f(class E e)', {1: 'f__E', 2: '1f1E'})
+ check('function', 'void f(typename E e)', {1: 'f__E', 2: '1f1E'})
+ check('function', 'void f(enum E e)', {1: 'f__E', 2: '1f1E'})
+ check('function', 'void f(union E e)', {1: 'f__E', 2: '1f1E'})
# pointer to member (function)
- check('function', 'void f(int C::*)', {2:'1fM1Ci'})
- check('function', 'void f(int C::* p)', {2:'1fM1Ci'})
- check('function', 'void f(int ::C::* p)', {2:'1fM1Ci'})
- check('function', 'void f(int C::* const)', {2:'1fKM1Ci'})
- check('function', 'void f(int C::* const&)', {2:'1fRKM1Ci'})
- check('function', 'void f(int C::* volatile)', {2:'1fVM1Ci'})
- check('function', 'void f(int C::* const volatile)', {2:'1fVKM1Ci'},
+ check('function', 'void f(int C::*)', {2: '1fM1Ci'})
+ check('function', 'void f(int C::* p)', {2: '1fM1Ci'})
+ check('function', 'void f(int ::C::* p)', {2: '1fM1Ci'})
+ check('function', 'void f(int C::* const)', {2: '1fKM1Ci'})
+ check('function', 'void f(int C::* const&)', {2: '1fRKM1Ci'})
+ check('function', 'void f(int C::* volatile)', {2: '1fVM1Ci'})
+ check('function', 'void f(int C::* const volatile)', {2: '1fVKM1Ci'},
output='void f(int C::* volatile const)')
- check('function', 'void f(int C::* volatile const)', {2:'1fVKM1Ci'})
- check('function', 'void f(int (C::*)(float, double))', {2:'1fM1CFifdE'})
- check('function', 'void f(int (C::* p)(float, double))', {2:'1fM1CFifdE'})
- check('function', 'void f(int (::C::* p)(float, double))', {2:'1fM1CFifdE'})
- check('function', 'void f(void (C::*)() const &)', {2:'1fM1CKRFvvE'})
- check('function', 'int C::* f(int, double)', {2:'1fid'})
- check('function', 'void f(int C::* *)', {2:'1fPM1Ci'})
+ check('function', 'void f(int C::* volatile const)', {2: '1fVKM1Ci'})
+ check('function', 'void f(int (C::*)(float, double))', {2: '1fM1CFifdE'})
+ check('function', 'void f(int (C::* p)(float, double))', {2: '1fM1CFifdE'})
+ check('function', 'void f(int (::C::* p)(float, double))', {2: '1fM1CFifdE'})
+ check('function', 'void f(void (C::*)() const &)', {2: '1fM1CKRFvvE'})
+ check('function', 'int C::* f(int, double)', {2: '1fid'})
+ check('function', 'void f(int C::* *)', {2: '1fPM1Ci'})
def test_operators():
check('function', 'void operator new [ ] ()',
- {1:"new-array-operator", 2:"nav"}, output='void operator new[]()')
+ {1: "new-array-operator", 2: "nav"}, output='void operator new[]()')
check('function', 'void operator delete ()',
- {1:"delete-operator", 2:"dlv"}, output='void operator delete()')
+ {1: "delete-operator", 2: "dlv"}, output='void operator delete()')
check('function', 'operator bool() const',
- {1:"castto-b-operatorC", 2:"NKcvbEv"}, output='operator bool() const')
+ {1: "castto-b-operatorC", 2: "NKcvbEv"}, output='operator bool() const')
check('function', 'void operator * ()',
- {1:"mul-operator", 2:"mlv"}, output='void operator*()')
+ {1: "mul-operator", 2: "mlv"}, output='void operator*()')
check('function', 'void operator - ()',
- {1:"sub-operator", 2:"miv"}, output='void operator-()')
+ {1: "sub-operator", 2: "miv"}, output='void operator-()')
check('function', 'void operator + ()',
- {1:"add-operator", 2:"plv"}, output='void operator+()')
+ {1: "add-operator", 2: "plv"}, output='void operator+()')
check('function', 'void operator = ()',
- {1:"assign-operator", 2:"aSv"}, output='void operator=()')
+ {1: "assign-operator", 2: "aSv"}, output='void operator=()')
check('function', 'void operator / ()',
- {1:"div-operator", 2:"dvv"}, output='void operator/()')
+ {1: "div-operator", 2: "dvv"}, output='void operator/()')
check('function', 'void operator % ()',
- {1:"mod-operator", 2:"rmv"}, output='void operator%()')
+ {1: "mod-operator", 2: "rmv"}, output='void operator%()')
check('function', 'void operator ! ()',
- {1:"not-operator", 2:"ntv"}, output='void operator!()')
+ {1: "not-operator", 2: "ntv"}, output='void operator!()')
check('function', 'void operator "" _udl()',
- {2:'li4_udlv'}, output='void operator""_udl()')
+ {2: 'li4_udlv'}, output='void operator""_udl()')
def test_class_definitions():
- check('class', 'public A', {1:"A", 2:"1A"}, output='A')
- check('class', 'private A', {1:"A", 2:"1A"})
- check('class', 'A final', {1:'A', 2:'1A'})
+ check('class', 'public A', {1: "A", 2: "1A"}, output='A')
+ check('class', 'private A', {1: "A", 2: "1A"})
+ check('class', 'A final', {1: 'A', 2: '1A'})
# test bases
- check('class', 'A', {1:"A", 2:"1A"})
- check('class', 'A::B::C', {1:"A::B::C", 2:"N1A1B1CE"})
- check('class', 'A : B', {1:"A", 2:"1A"})
- check('class', 'A : private B', {1:"A", 2:"1A"}, output='A : B')
- check('class', 'A : public B', {1:"A", 2:"1A"})
- check('class', 'A : B, C', {1:"A", 2:"1A"})
- check('class', 'A : B, protected C, D', {1:"A", 2:"1A"})
- check('class', 'A : virtual private B', {1:'A', 2:'1A'}, output='A : virtual B')
- check('class', 'A : B, virtual C', {1:'A', 2:'1A'})
- check('class', 'A : public virtual B', {1:'A', 2:'1A'})
- check('class', 'A : B, C...', {1:'A', 2:'1A'})
- check('class', 'A : B..., C', {1:'A', 2:'1A'})
+ check('class', 'A', {1: "A", 2: "1A"})
+ check('class', 'A::B::C', {1: "A::B::C", 2: "N1A1B1CE"})
+ check('class', 'A : B', {1: "A", 2: "1A"})
+ check('class', 'A : private B', {1: "A", 2: "1A"}, output='A : B')
+ check('class', 'A : public B', {1: "A", 2: "1A"})
+ check('class', 'A : B, C', {1: "A", 2: "1A"})
+ check('class', 'A : B, protected C, D', {1: "A", 2: "1A"})
+ check('class', 'A : virtual private B', {1: 'A', 2: '1A'}, output='A : virtual B')
+ check('class', 'A : B, virtual C', {1: 'A', 2: '1A'})
+ check('class', 'A : public virtual B', {1: 'A', 2: '1A'})
+ check('class', 'A : B, C...', {1: 'A', 2: '1A'})
+ check('class', 'A : B..., C', {1: 'A', 2: '1A'})
# from #4094
- check('class', 'template<class, class = std::void_t<>> has_var', {2:'I00E7has_var'})
- check('class', 'template<class T> has_var<T, std::void_t<decltype(&T::var)>>', {2:'I0E7has_varI1TNSt6void_tIDTadN1T3varEEEEE'})
+ check('class', 'template<class, class = std::void_t<>> has_var', {2: 'I00E7has_var'})
+ check('class', 'template<class T> has_var<T, std::void_t<decltype(&T::var)>>',
+ {2: 'I0E7has_varI1TNSt6void_tIDTadN1T3varEEEEE'})
def test_enum_definitions():
- check('enum', 'A', {2:"1A"})
- check('enum', 'A : std::underlying_type<B>::type', {2:"1A"})
- check('enum', 'A : unsigned int', {2:"1A"})
- check('enum', 'public A', {2:"1A"}, output='A')
- check('enum', 'private A', {2:"1A"})
+ check('enum', 'A', {2: "1A"})
+ check('enum', 'A : std::underlying_type<B>::type', {2: "1A"})
+ check('enum', 'A : unsigned int', {2: "1A"})
+ check('enum', 'public A', {2: "1A"}, output='A')
+ check('enum', 'private A', {2: "1A"})
- check('enumerator', 'A', {2:"1A"})
- check('enumerator', 'A = std::numeric_limits<unsigned long>::max()', {2:"1A"})
+ check('enumerator', 'A', {2: "1A"})
+ check('enumerator', 'A = std::numeric_limits<unsigned long>::max()', {2: "1A"})
def test_templates():
- check('class', "A<T>", {2:"IE1AI1TE"}, output="template<> A<T>")
+ check('class', "A<T>", {2: "IE1AI1TE"}, output="template<> A<T>")
# first just check which objects support templating
- check('class', "template<> A", {2:"IE1A"})
- check('function', "template<> void A()", {2:"IE1Av"})
- check('member', "template<> A a", {2:"IE1a"})
- check('type', "template<> a = A", {2:"IE1a"})
+ check('class', "template<> A", {2: "IE1A"})
+ check('function', "template<> void A()", {2: "IE1Av"})
+ check('member', "template<> A a", {2: "IE1a"})
+ check('type', "template<> a = A", {2: "IE1a"})
with pytest.raises(DefinitionError):
parse('enum', "template<> A")
with pytest.raises(DefinitionError):
parse('enumerator', "template<> A")
# then all the real tests
- check('class', "template<typename T1, typename T2> A", {2:"I00E1A"})
- check('type', "template<> a", {2:"IE1a"})
+ check('class', "template<typename T1, typename T2> A", {2: "I00E1A"})
+ check('type', "template<> a", {2: "IE1a"})
- check('class', "template<typename T> A", {2:"I0E1A"})
- check('class', "template<class T> A", {2:"I0E1A"})
- check('class', "template<typename ...T> A", {2:"IDpE1A"})
- check('class', "template<typename...> A", {2:"IDpE1A"})
- check('class', "template<typename = Test> A", {2:"I0E1A"})
- check('class', "template<typename T = Test> A", {2:"I0E1A"})
+ check('class', "template<typename T> A", {2: "I0E1A"})
+ check('class', "template<class T> A", {2: "I0E1A"})
+ check('class', "template<typename ...T> A", {2: "IDpE1A"})
+ check('class', "template<typename...> A", {2: "IDpE1A"})
+ check('class', "template<typename = Test> A", {2: "I0E1A"})
+ check('class', "template<typename T = Test> A", {2: "I0E1A"})
- check('class', "template<template<typename> typename T> A", {2:"II0E0E1A"})
+ check('class', "template<template<typename> typename T> A", {2: "II0E0E1A"})
check('class', "template<template<typename> typename> A", {2: "II0E0E1A"})
- check('class', "template<template<typename> typename ...T> A", {2:"II0EDpE1A"})
+ check('class', "template<template<typename> typename ...T> A", {2: "II0EDpE1A"})
check('class', "template<template<typename> typename...> A", {2: "II0EDpE1A"})
- check('class', "template<int> A", {2:"I_iE1A"})
- check('class', "template<int T> A", {2:"I_iE1A"})
- check('class', "template<int... T> A", {2:"I_DpiE1A"})
- check('class', "template<int T = 42> A", {2:"I_iE1A"})
- check('class', "template<int = 42> A", {2:"I_iE1A"})
+ check('class', "template<int> A", {2: "I_iE1A"})
+ check('class', "template<int T> A", {2: "I_iE1A"})
+ check('class', "template<int... T> A", {2: "I_DpiE1A"})
+ check('class', "template<int T = 42> A", {2: "I_iE1A"})
+ check('class', "template<int = 42> A", {2: "I_iE1A"})
- check('class', "template<> A<NS::B<>>", {2:"IE1AIN2NS1BIEEE"})
+ check('class', "template<> A<NS::B<>>", {2: "IE1AIN2NS1BIEEE"})
# from #2058
check('function',
@@ -526,8 +537,8 @@ def test_templates():
"inline std::basic_ostream<Char, Traits> &operator<<("
"std::basic_ostream<Char, Traits> &os, "
"const c_string_view_base<const Char, Traits> &str)",
- {2:"I00ElsRNSt13basic_ostreamI4Char6TraitsEE"
- "RK18c_string_view_baseIK4Char6TraitsE"})
+ {2: "I00ElsRNSt13basic_ostreamI4Char6TraitsEE"
+ "RK18c_string_view_baseIK4Char6TraitsE"})
# template introductions
with pytest.raises(DefinitionError):
@@ -535,73 +546,75 @@ def test_templates():
with pytest.raises(DefinitionError):
parse('enumerator', 'abc::ns::foo{id_0, id_1, id_2} A')
check('class', 'abc::ns::foo{id_0, id_1, id_2} xyz::bar',
- {2:'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'})
+ {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'})
check('class', 'abc::ns::foo{id_0, id_1, ...id_2} xyz::bar',
- {2:'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'})
+ {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'})
check('class', 'abc::ns::foo{id_0, id_1, id_2} xyz::bar<id_0, id_1, id_2>',
- {2:'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barI4id_04id_14id_2EE'})
+ {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barI4id_04id_14id_2EE'})
check('class', 'abc::ns::foo{id_0, id_1, ...id_2} xyz::bar<id_0, id_1, id_2...>',
- {2:'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barI4id_04id_1Dp4id_2EE'})
+ {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barI4id_04id_1Dp4id_2EE'})
- check('class', 'template<> Concept{U} A<int>::B', {2:'IEI0EX7ConceptI1UEEN1AIiE1BE'})
+ check('class', 'template<> Concept{U} A<int>::B', {2: 'IEI0EX7ConceptI1UEEN1AIiE1BE'})
check('type', 'abc::ns::foo{id_0, id_1, id_2} xyz::bar = ghi::qux',
- {2:'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'})
+ {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'})
check('type', 'abc::ns::foo{id_0, id_1, ...id_2} xyz::bar = ghi::qux',
- {2:'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'})
+ {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'})
check('function', 'abc::ns::foo{id_0, id_1, id_2} void xyz::bar()',
- {2:'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barEv'})
+ {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barEv'})
check('function', 'abc::ns::foo{id_0, id_1, ...id_2} void xyz::bar()',
- {2:'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barEv'})
+ {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barEv'})
check('member', 'abc::ns::foo{id_0, id_1, id_2} ghi::qux xyz::bar',
- {2:'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'})
+ {2: 'I000EXN3abc2ns3fooEI4id_04id_14id_2EEN3xyz3barE'})
check('member', 'abc::ns::foo{id_0, id_1, ...id_2} ghi::qux xyz::bar',
- {2:'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'})
- check('concept', 'Iterator{T, U} Another', {2:'I00EX8IteratorI1T1UEE7Another'})
+ {2: 'I00DpEXN3abc2ns3fooEI4id_04id_1sp4id_2EEN3xyz3barE'})
+ check('concept', 'Iterator{T, U} Another', {2: 'I00EX8IteratorI1T1UEE7Another'})
check('concept', 'template<typename ...Pack> Numerics = (... && Numeric<Pack>)',
- {2:'IDpE8Numerics'})
+ {2: 'IDpE8Numerics'})
# explicit specializations of members
- check('member', 'template<> int A<int>::a', {2:'IEN1AIiE1aE'})
+ check('member', 'template<> int A<int>::a', {2: 'IEN1AIiE1aE'})
check('member', 'template int A<int>::a', {2: 'IEN1AIiE1aE'},
output='template<> int A<int>::a') # same as above
- check('member', 'template<> template<> int A<int>::B<int>::b', {2:'IEIEN1AIiE1BIiE1bE'})
+ check('member', 'template<> template<> int A<int>::B<int>::b', {2: 'IEIEN1AIiE1BIiE1bE'})
check('member', 'template int A<int>::B<int>::b', {2: 'IEIEN1AIiE1BIiE1bE'},
output='template<> template<> int A<int>::B<int>::b') # same as above
+ # defaulted constrained type parameters
+ check('type', 'template<C T = int&> A', {2: 'I_1CE1A'})
+
def test_template_args():
# from breathe#218
check('function',
"template<typename F> "
"void allow(F *f, typename func<F, B, G != 1>::type tt)",
- {2:"I0E5allowP1FN4funcI1F1BXG != 1EE4typeE",
- 3:"I0E5allowP1FN4funcI1F1BXne1GL1EEE4typeE"})
+ {2: "I0E5allowP1FN4funcI1F1BXG != 1EE4typeE",
+ 3: "I0E5allowP1FN4funcI1F1BXne1GL1EEE4typeE"})
# from #3542
check('type', "template<typename T> "
"enable_if_not_array_t = std::enable_if_t<!is_array<T>::value, int>",
- {2:"I0E21enable_if_not_array_t"})
-
+ {2: "I0E21enable_if_not_array_t"})
def test_attributes():
# style: C++
- check('member', '[[]] int f', {1:'f__i', 2:'1f'})
- check('member', '[ [ ] ] int f', {1:'f__i', 2:'1f'},
+ check('member', '[[]] int f', {1: 'f__i', 2: '1f'})
+ check('member', '[ [ ] ] int f', {1: 'f__i', 2: '1f'},
# this will fail when the proper grammar is implemented
output='[[ ]] int f')
- check('member', '[[a]] int f', {1:'f__i', 2:'1f'})
+ check('member', '[[a]] int f', {1: 'f__i', 2: '1f'})
# style: GNU
- check('member', '__attribute__(()) int f', {1:'f__i', 2:'1f'})
- check('member', '__attribute__((a)) int f', {1:'f__i', 2:'1f'})
- check('member', '__attribute__((a, b)) int f', {1:'f__i', 2:'1f'})
+ check('member', '__attribute__(()) int f', {1: 'f__i', 2: '1f'})
+ check('member', '__attribute__((a)) int f', {1: 'f__i', 2: '1f'})
+ check('member', '__attribute__((a, b)) int f', {1: 'f__i', 2: '1f'})
# style: user-defined id
- check('member', 'id_attr int f', {1:'f__i', 2:'1f'})
+ check('member', 'id_attr int f', {1: 'f__i', 2: '1f'})
# style: user-defined paren
- check('member', 'paren_attr() int f', {1:'f__i', 2:'1f'})
- check('member', 'paren_attr(a) int f', {1:'f__i', 2:'1f'})
- check('member', 'paren_attr("") int f', {1:'f__i', 2:'1f'})
- check('member', 'paren_attr(()[{}][]{}) int f', {1:'f__i', 2:'1f'})
+ check('member', 'paren_attr() int f', {1: 'f__i', 2: '1f'})
+ check('member', 'paren_attr(a) int f', {1: 'f__i', 2: '1f'})
+ check('member', 'paren_attr("") int f', {1: 'f__i', 2: '1f'})
+ check('member', 'paren_attr(()[{}][]{}) int f', {1: 'f__i', 2: '1f'})
with pytest.raises(DefinitionError):
parse('member', 'paren_attr(() int f')
with pytest.raises(DefinitionError):
@@ -617,7 +630,7 @@ def test_attributes():
# position: decl specs
check('function', 'static inline __attribute__(()) void f()',
- {1:'f', 2:'1fv'},
+ {1: 'f', 2: '1fv'},
output='__attribute__(()) static inline void f()')
diff --git a/tests/test_domain_js.py b/tests/test_domain_js.py
index 22faf4458..a609dcefe 100644
--- a/tests/test_domain_js.py
+++ b/tests/test_domain_js.py
@@ -5,7 +5,7 @@
Tests 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.
"""
diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py
index bf391053f..0c1d28dd9 100644
--- a/tests/test_domain_py.py
+++ b/tests/test_domain_py.py
@@ -5,7 +5,7 @@
Tests 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.
"""
diff --git a/tests/test_domain_rst.py b/tests/test_domain_rst.py
index 1e55e92a1..8cfe7e284 100644
--- a/tests/test_domain_rst.py
+++ b/tests/test_domain_rst.py
@@ -5,7 +5,7 @@
Tests 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.
"""
diff --git a/tests/test_domain_std.py b/tests/test_domain_std.py
index edd5a0ebf..06573fa38 100644
--- a/tests/test_domain_std.py
+++ b/tests/test_domain_std.py
@@ -5,7 +5,7 @@
Tests the std 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.
"""
diff --git a/tests/test_environment.py b/tests/test_environment.py
index 611d34577..6f9ffec08 100644
--- a/tests/test_environment.py
+++ b/tests/test_environment.py
@@ -5,7 +5,7 @@
Test the BuildEnvironment 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.
"""
import pytest
@@ -22,7 +22,7 @@ def setup_module(rootdir, sphinx_test_tempdir):
global app, env
srcdir = sphinx_test_tempdir / 'root-envtest'
if not srcdir.exists():
- (rootdir/'test-root').copytree(srcdir)
+ (rootdir / 'test-root').copytree(srcdir)
app = SphinxTestApp(srcdir=srcdir)
env = app.env
yield
diff --git a/tests/test_environment_indexentries.py b/tests/test_environment_indexentries.py
index b9de151cc..03e4d9662 100644
--- a/tests/test_environment_indexentries.py
+++ b/tests/test_environment_indexentries.py
@@ -5,7 +5,7 @@
Test the sphinx.environment.managers.indexentries.
- :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.
"""
diff --git a/tests/test_environment_toctree.py b/tests/test_environment_toctree.py
index f7a24d1fc..26334858b 100644
--- a/tests/test_environment_toctree.py
+++ b/tests/test_environment_toctree.py
@@ -5,7 +5,7 @@
Test the sphinx.environment.managers.toctree.
- :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.
"""
diff --git a/tests/test_ext_apidoc.py b/tests/test_ext_apidoc.py
index d98dbabb6..2bfc8016e 100644
--- a/tests/test_ext_apidoc.py
+++ b/tests/test_ext_apidoc.py
@@ -5,7 +5,7 @@
Test the sphinx.apidoc module.
- :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.
"""
@@ -188,3 +188,80 @@ def test_extension_parsed(make_app, apidoc):
with open(outdir / 'conf.py') as f:
rst = f.read()
assert "sphinx.ext.mathjax" in rst
+
+
+@pytest.mark.apidoc(
+ coderoot='test-apidoc-toc/mypackage',
+ options=["--implicit-namespaces"],
+)
+def test_toc_all_references_should_exist_pep420_enabled(make_app, apidoc):
+ """All references in toc should exist. This test doesn't say if
+ directories with empty __init__.py and and nothing else should be
+ skipped, just ensures consistency between what's referenced in the toc
+ and what is created. This is the variant with pep420 enabled.
+ """
+ outdir = apidoc.outdir
+ assert (outdir / 'conf.py').isfile()
+
+ toc = extract_toc(outdir / 'mypackage.rst')
+
+ refs = [l.strip() for l in toc.splitlines() if l.strip()]
+ found_refs = []
+ missing_files = []
+ for ref in refs:
+ if ref and ref[0] in (':', '#'):
+ continue
+ found_refs.append(ref)
+ filename = "{}.rst".format(ref)
+ if not (outdir / filename).isfile():
+ missing_files.append(filename)
+
+ assert len(missing_files) == 0, \
+ 'File(s) referenced in TOC not found: {}\n' \
+ 'TOC:\n{}'.format(", ".join(missing_files), toc)
+
+
+@pytest.mark.apidoc(
+ coderoot='test-apidoc-toc/mypackage',
+)
+def test_toc_all_references_should_exist_pep420_disabled(make_app, apidoc):
+ """All references in toc should exist. This test doesn't say if
+ directories with empty __init__.py and and nothing else should be
+ skipped, just ensures consistency between what's referenced in the toc
+ and what is created. This is the variant with pep420 disabled.
+ """
+ outdir = apidoc.outdir
+ assert (outdir / 'conf.py').isfile()
+
+ toc = extract_toc(outdir / 'mypackage.rst')
+
+ refs = [l.strip() for l in toc.splitlines() if l.strip()]
+ found_refs = []
+ missing_files = []
+ for ref in refs:
+ if ref and ref[0] in (':', '#'):
+ continue
+ filename = "{}.rst".format(ref)
+ found_refs.append(ref)
+ if not (outdir / filename).isfile():
+ missing_files.append(filename)
+
+ assert len(missing_files) == 0, \
+ 'File(s) referenced in TOC not found: {}\n' \
+ 'TOC:\n{}'.format(", ".join(missing_files), toc)
+
+
+def extract_toc(path):
+ """Helper: Extract toc section from package rst file"""
+ with open(path) as f:
+ rst = f.read()
+
+ # Read out the part containing the toctree
+ toctree_start = "\n.. toctree::\n"
+ toctree_end = "\nSubmodules"
+
+ start_idx = rst.index(toctree_start)
+ end_idx = rst.index(toctree_end, start_idx)
+ toctree = rst[start_idx + len(toctree_start):end_idx]
+
+ return toctree
diff --git a/tests/test_ext_autodoc.py b/tests/test_ext_autodoc.py
index 1c1ebf7a0..e7057df0f 100644
--- a/tests/test_ext_autodoc.py
+++ b/tests/test_ext_autodoc.py
@@ -5,7 +5,7 @@
Test the autodoc extension.
- :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.
"""
diff --git a/tests/test_ext_autosectionlabel.py b/tests/test_ext_autosectionlabel.py
index 4726a2378..1266edbc3 100644
--- a/tests/test_ext_autosectionlabel.py
+++ b/tests/test_ext_autosectionlabel.py
@@ -5,7 +5,7 @@
Test sphinx.ext.autosectionlabel extension.
- :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.
"""
diff --git a/tests/test_ext_autosummary.py b/tests/test_ext_autosummary.py
index b59f0cbc8..ce5aa6e85 100644
--- a/tests/test_ext_autosummary.py
+++ b/tests/test_ext_autosummary.py
@@ -5,7 +5,7 @@
Test the autosummary extension.
- :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.
"""
@@ -57,10 +57,14 @@ def test_mangle_signature():
@pytest.mark.sphinx('dummy', **default_kw)
-def test_get_items_summary(app, status, warning):
+def test_get_items_summary(make_app, app_params):
+ import sphinx.ext.autosummary
+ import sphinx.ext.autosummary.generate
+ args, kwargs = app_params
+ app = make_app(*args, **kwargs)
+ sphinx.ext.autosummary.generate.setup_documenters(app)
# monkey-patch Autosummary.get_items so we can easily get access to it's
# results..
- import sphinx.ext.autosummary
orig_get_items = sphinx.ext.autosummary.Autosummary.get_items
autosummary_items = {}
@@ -73,6 +77,10 @@ def test_get_items_summary(app, status, warning):
def handler(app, what, name, obj, options, lines):
assert isinstance(lines, list)
+
+ # ensure no docstring is processed twice:
+ assert 'THIS HAS BEEN HANDLED' not in lines
+ lines.append('THIS HAS BEEN HANDLED')
app.connect('autodoc-process-docstring', handler)
sphinx.ext.autosummary.Autosummary.get_items = new_get_items
@@ -81,7 +89,7 @@ def test_get_items_summary(app, status, warning):
finally:
sphinx.ext.autosummary.Autosummary.get_items = orig_get_items
- html_warnings = warning.getvalue()
+ html_warnings = app._warning.getvalue()
assert html_warnings == ''
expected_values = {
@@ -163,7 +171,8 @@ def test_import_by_name():
assert parent is sphinx.ext.autosummary
assert modname == 'sphinx.ext.autosummary'
- prefixed_name, obj, parent, modname = import_by_name('sphinx.ext.autosummary.Autosummary.get_items')
+ prefixed_name, obj, parent, modname = \
+ import_by_name('sphinx.ext.autosummary.Autosummary.get_items')
assert prefixed_name == 'sphinx.ext.autosummary.Autosummary.get_items'
assert obj == sphinx.ext.autosummary.Autosummary.get_items
assert parent is sphinx.ext.autosummary.Autosummary
diff --git a/tests/test_ext_coverage.py b/tests/test_ext_coverage.py
index ff3fb4c02..a8f222a00 100644
--- a/tests/test_ext_coverage.py
+++ b/tests/test_ext_coverage.py
@@ -5,7 +5,7 @@
Test the coverage 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.
"""
@@ -21,9 +21,9 @@ def test_build(app, status, warning):
py_undoc = (app.outdir / 'python.txt').text()
assert py_undoc.startswith('Undocumented Python objects\n'
'===========================\n')
- assert 'test_autodoc\n------------\n' in py_undoc
+ assert 'autodoc_target\n--------------\n' in py_undoc
assert ' * Class -- missing methods:\n' in py_undoc
- assert ' * process_docstring\n' in py_undoc
+ assert ' * raises\n' in py_undoc
assert ' * function\n' not in py_undoc # these two are documented
assert ' * Class\n' not in py_undoc # in autodoc.txt
@@ -40,9 +40,9 @@ def test_build(app, status, warning):
# the key is the full path to the header file, which isn't testable
assert list(undoc_c.values())[0] == set([('function', 'Py_SphinxTest')])
- assert 'test_autodoc' in undoc_py
- assert 'funcs' in undoc_py['test_autodoc']
- assert 'process_docstring' in undoc_py['test_autodoc']['funcs']
- assert 'classes' in undoc_py['test_autodoc']
- assert 'Class' in undoc_py['test_autodoc']['classes']
- assert 'undocmeth' in undoc_py['test_autodoc']['classes']['Class']
+ assert 'autodoc_target' in undoc_py
+ assert 'funcs' in undoc_py['autodoc_target']
+ assert 'raises' in undoc_py['autodoc_target']['funcs']
+ assert 'classes' in undoc_py['autodoc_target']
+ assert 'Class' in undoc_py['autodoc_target']['classes']
+ assert 'undocmeth' in undoc_py['autodoc_target']['classes']['Class']
diff --git a/tests/test_ext_doctest.py b/tests/test_ext_doctest.py
index fa3ad6bc4..020357879 100644
--- a/tests/test_ext_doctest.py
+++ b/tests/test_ext_doctest.py
@@ -5,7 +5,7 @@
Test the doctest extension.
- :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 pytest
diff --git a/tests/test_ext_githubpages.py b/tests/test_ext_githubpages.py
index 56ce7b775..18ee51480 100644
--- a/tests/test_ext_githubpages.py
+++ b/tests/test_ext_githubpages.py
@@ -5,7 +5,7 @@
Test sphinx.ext.githubpages extension.
- :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.
"""
diff --git a/tests/test_ext_graphviz.py b/tests/test_ext_graphviz.py
index 1d2a3ab2f..762add6f0 100644
--- a/tests/test_ext_graphviz.py
+++ b/tests/test_ext_graphviz.py
@@ -5,7 +5,7 @@
Test sphinx.ext.graphviz extension.
- :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,7 @@ def test_graphviz_png_html(app, status, warning):
r'}\" />\n</div>')
assert re.search(html, content, re.S)
+
@pytest.mark.sphinx('html', testroot='ext-graphviz',
confoverrides={'graphviz_output_format': 'svg'})
@pytest.mark.usefixtures('if_graphviz_found')
@@ -80,6 +81,7 @@ def test_graphviz_svg_html(app, status, warning):
r'</div>')
assert re.search(html, content, re.S)
+
@pytest.mark.sphinx('latex', testroot='ext-graphviz')
@pytest.mark.usefixtures('if_graphviz_found')
def test_graphviz_latex(app, status, warning):
diff --git a/tests/test_ext_ifconfig.py b/tests/test_ext_ifconfig.py
index 5c59caaaf..b4c941512 100644
--- a/tests/test_ext_ifconfig.py
+++ b/tests/test_ext_ifconfig.py
@@ -5,7 +5,7 @@
Test sphinx.ext.ifconfig extension.
- :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.
"""
diff --git a/tests/test_ext_imgconverter.py b/tests/test_ext_imgconverter.py
index cc84001df..8f610377c 100644
--- a/tests/test_ext_imgconverter.py
+++ b/tests/test_ext_imgconverter.py
@@ -5,7 +5,7 @@
Test sphinx.ext.imgconverter extension.
- :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.
"""
diff --git a/tests/test_ext_inheritance_diagram.py b/tests/test_ext_inheritance_diagram.py
index 40edfa937..deb04ce15 100644
--- a/tests/test_ext_inheritance_diagram.py
+++ b/tests/test_ext_inheritance_diagram.py
@@ -5,7 +5,7 @@
Test sphinx.ext.inheritance_diagram extension.
- :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.
"""
diff --git a/tests/test_ext_intersphinx.py b/tests/test_ext_intersphinx.py
index 594aa81b8..19f8613c6 100644
--- a/tests/test_ext_intersphinx.py
+++ b/tests/test_ext_intersphinx.py
@@ -5,7 +5,7 @@
Test the intersphinx extension.
- :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.
"""
@@ -194,7 +194,7 @@ def test_missing_reference_stddomain(tempdir, app, status, warning):
inv_file = tempdir / 'inventory'
inv_file.write_bytes(inventory_v2)
app.config.intersphinx_mapping = {
- 'https://docs.python.org/': inv_file,
+ 'cmd': ('https://docs.python.org/', inv_file),
}
app.config.intersphinx_cache_limit = 0
@@ -213,6 +213,12 @@ def test_missing_reference_stddomain(tempdir, app, status, warning):
rn = missing_reference(app, app.env, node, contnode)
assert rn.astext() == 'ls -l'
+ # refers inventory by name
+ kwargs = {}
+ node, contnode = fake_node('std', 'option', 'cmd:ls -l', '-l', **kwargs)
+ rn = missing_reference(app, app.env, node, contnode)
+ assert rn.astext() == '-l'
+
@pytest.mark.sphinx('html', testroot='ext-intersphinx-cppdomain')
def test_missing_reference_cppdomain(tempdir, app, status, warning):
@@ -240,7 +246,6 @@ def test_missing_reference_cppdomain(tempdir, app, status, warning):
' title="(in foo v2.0)">bartype</a>' in html)
-
def test_missing_reference_jsdomain(tempdir, app, status, warning):
inv_file = tempdir / 'inventory'
inv_file.write_bytes(inventory_v2)
diff --git a/tests/test_ext_math.py b/tests/test_ext_math.py
index 92501a3db..5bf4ebb15 100644
--- a/tests/test_ext_math.py
+++ b/tests/test_ext_math.py
@@ -5,15 +5,29 @@
Test math extensions.
- :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
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'})
@@ -139,3 +157,52 @@ def test_math_eqref_format_latex(app, status, warning):
content = (app.outdir / 'test.tex').text()
macro = r'Referencing equation Eq.\\ref{equation:math:foo}.'
assert re.search(macro, content, re.S)
+
+
+@pytest.mark.sphinx('html', testroot='ext-math',
+ confoverrides={'extensions': ['sphinx.ext.mathjax'],
+ 'numfig': True,
+ 'math_numfig': True})
+def test_mathjax_numfig_html(app, status, warning):
+ app.builder.build_all()
+
+ content = (app.outdir / 'math.html').text()
+ html = ('<div class="math" id="equation-math:0">\n'
+ '<span class="eqno">(1.2)')
+ assert html in content
+ html = ('<p>Referencing equation <a class="reference internal" '
+ 'href="#equation-foo">(1.1)</a>.</p>')
+ assert html in content
+
+
+@pytest.mark.sphinx('html', testroot='ext-math',
+ confoverrides={'extensions': ['sphinx.ext.jsmath'],
+ 'jsmath_path': 'dummy.js',
+ 'numfig': True,
+ 'math_numfig': True})
+def test_jsmath_numfig_html(app, status, warning):
+ app.builder.build_all()
+
+ content = (app.outdir / 'math.html').text()
+ html = '<span class="eqno">(1.2)<a class="headerlink" href="#equation-math:0"'
+ assert html in content
+ html = ('<p>Referencing equation <a class="reference internal" '
+ 'href="#equation-foo">(1.1)</a>.</p>')
+ assert html in content
+
+
+@pytest.mark.sphinx('html', testroot='ext-math',
+ confoverrides={'extensions': ['sphinx.ext.imgmath'],
+ 'numfig': True,
+ 'numfig_secnum_depth': 0,
+ 'math_numfig': True})
+def test_imgmath_numfig_html(app, status, warning):
+ app.builder.build_all()
+
+ content = (app.outdir / 'page.html').text()
+ html = '<span class="eqno">(3)<a class="headerlink" href="#equation-bar"'
+ assert html in content
+ html = ('<p>Referencing equations <a class="reference internal" '
+ 'href="math.html#equation-foo">(1)</a> and '
+ '<a class="reference internal" href="#equation-bar">(3)</a>.</p>')
+ assert html in content
diff --git a/tests/test_ext_napoleon.py b/tests/test_ext_napoleon.py
index b2ca7fe7a..d8d6adc65 100644
--- a/tests/test_ext_napoleon.py
+++ b/tests/test_ext_napoleon.py
@@ -6,7 +6,7 @@
Tests for :mod:`sphinx.ext.napoleon.__init__` module.
- :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.
"""
diff --git a/tests/test_ext_napoleon_docstring.py b/tests/test_ext_napoleon_docstring.py
index e71d517fe..1865b004c 100644
--- a/tests/test_ext_napoleon_docstring.py
+++ b/tests/test_ext_napoleon_docstring.py
@@ -6,7 +6,7 @@
Tests for :mod:`sphinx.ext.napoleon.docstring` module.
- :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.
"""
diff --git a/tests/test_ext_napoleon_iterators.py b/tests/test_ext_napoleon_iterators.py
index 5258d9b79..bf144275d 100644
--- a/tests/test_ext_napoleon_iterators.py
+++ b/tests/test_ext_napoleon_iterators.py
@@ -6,7 +6,7 @@
Tests for :mod:`sphinx.ext.napoleon.iterators` module.
- :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.
"""
diff --git a/tests/test_ext_todo.py b/tests/test_ext_todo.py
index 4f01a07ab..0260b821d 100644
--- a/tests/test_ext_todo.py
+++ b/tests/test_ext_todo.py
@@ -5,7 +5,7 @@
Test sphinx.ext.todo extension.
- :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.
"""
@@ -85,8 +85,9 @@ def test_todo_not_included(app, status, warning):
assert len(todos) == 2
assert set(todo[1].astext() for todo in todos) == set(['todo in foo', 'todo in bar'])
+
@pytest.mark.sphinx('latex', testroot='ext-todo', freshenv=True,
- confoverrides={'todo_include_todos': True, 'todo_emit_warnings': True})
+ confoverrides={'todo_include_todos': True})
def test_todo_valid_link(app, status, warning):
"""
Test that the inserted "original entry" links for todo items have a target
@@ -99,16 +100,17 @@ def test_todo_valid_link(app, status, warning):
content = (app.outdir / 'TodoTests.tex').text()
- # Look for the link to foo. We could equally well look for the link to bar.
+ # Look for the link to foo. Note that there are two of them because the
+ # source document uses todolist twice. We could equally well look for links
+ # to bar.
link = r'\{\\hyperref\[\\detokenize\{(.*?foo.*?)}]\{\\sphinxcrossref{' \
r'\\sphinxstyleemphasis{original entry}}}}'
m = re.findall(link, content)
- assert len(m) == 1
+ assert len(m) == 2
target = m[0]
# Look for the targets of this link.
- labels = [m for m in re.findall(r'\\label\{([^}]*)}', content)
- if m == target]
+ labels = [m for m in re.findall(r'\\label\{([^}]*)}', content) if m == target]
# If everything is correct we should have exactly one target.
assert len(labels) == 1
diff --git a/tests/test_ext_viewcode.py b/tests/test_ext_viewcode.py
index 4dceaa488..3f6612c76 100644
--- a/tests/test_ext_viewcode.py
+++ b/tests/test_ext_viewcode.py
@@ -5,7 +5,7 @@
Test sphinx.ext.viewcode extension.
- :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.
"""
diff --git a/tests/test_highlighting.py b/tests/test_highlighting.py
index 938181fe1..5660869bd 100644
--- a/tests/test_highlighting.py
+++ b/tests/test_highlighting.py
@@ -5,7 +5,7 @@
Test the Pygments highlighting bridge.
- :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.
"""
diff --git a/tests/test_intl.py b/tests/test_intl.py
index 6b72438bd..cb13b00f3 100644
--- a/tests/test_intl.py
+++ b/tests/test_intl.py
@@ -6,7 +6,7 @@
Test message patching for internationalization purposes. Runs the text
builder in the test root.
- :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
@@ -222,6 +222,7 @@ def test_text_inconsistency_warnings(app, warning):
u'.*/refs_inconsistency.txt:\\d+: WARNING: citation not found: ref3')
assert_re_search(expected_citation_warning_expr, warnings)
+
@sphinx_intl
@pytest.mark.sphinx('text')
@pytest.mark.test_params(shared_result='test_intl_basic')
diff --git a/tests/test_io.py b/tests/test_io.py
index ecd4a1009..1c8fee86b 100644
--- a/tests/test_io.py
+++ b/tests/test_io.py
@@ -5,7 +5,7 @@
Tests io modules.
- :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.
"""
diff --git a/tests/test_markup.py b/tests/test_markup.py
index 9c41845fc..c48096e34 100644
--- a/tests/test_markup.py
+++ b/tests/test_markup.py
@@ -5,7 +5,7 @@
Test various Sphinx-specific markup extensions.
- :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.
"""
@@ -135,7 +135,7 @@ def get_verifier(verify, verify_re):
'``code sample``',
('<p><code class="(samp )?docutils literal"><span class="pre">'
'code</span>&#160;&#160; <span class="pre">sample</span></code></p>'),
- r'\\sphinxcode{code sample}',
+ r'\\sphinxcode{\\sphinxupquote{code sample}}',
),
(
# correct interpretation of code with whitespace
@@ -143,7 +143,7 @@ def get_verifier(verify, verify_re):
':samp:`code sample`',
('<p><code class="(samp )?docutils literal"><span class="pre">'
'code</span>&#160;&#160; <span class="pre">sample</span></code></p>'),
- r'\\sphinxcode{code sample}',
+ r'\\sphinxcode{\\sphinxupquote{code sample}}',
),
(
# interpolation of braces in samp and file roles (HTML only)
@@ -152,7 +152,7 @@ def get_verifier(verify, verify_re):
('<p><code class="samp docutils literal"><span class="pre">a</span>'
'<em><span class="pre">b</span></em>'
'<span class="pre">c</span></code></p>'),
- '\\sphinxcode{a\\sphinxstyleemphasis{b}c}',
+ '\\sphinxcode{\\sphinxupquote{a\\sphinxstyleemphasis{b}c}}',
),
(
# interpolation of arrows in menuselection
@@ -175,7 +175,7 @@ def get_verifier(verify, verify_re):
':option:`--with-option`',
('<p><code( class="xref std std-option docutils literal")?>'
'<span class="pre">--with-option</span></code></p>$'),
- r'\\sphinxcode{-{-}with-option}$',
+ r'\\sphinxcode{\\sphinxupquote{-{-}with-option}}$',
),
(
# verify smarty-pants quotes
@@ -190,14 +190,14 @@ def get_verifier(verify, verify_re):
'``"John"``',
('<p><code class="docutils literal"><span class="pre">'
'&quot;John&quot;</span></code></p>'),
- '\\sphinxcode{"John"}',
+ '\\sphinxcode{\\sphinxupquote{"John"}}',
),
(
# verify classes for inline roles
'verify',
':manpage:`mp(1)`',
'<p><em class="manpage">mp(1)</em></p>',
- '\\sphinxstyleliteralemphasis{mp(1)}',
+ '\\sphinxstyleliteralemphasis{\\sphinxupquote{mp(1)}}',
),
(
# correct escaping in normal mode
diff --git a/tests/test_metadata.py b/tests/test_metadata.py
index 58f573b0a..a00d76f87 100644
--- a/tests/test_metadata.py
+++ b/tests/test_metadata.py
@@ -5,7 +5,7 @@
Test our handling of metadata in files with bibliographic metadata.
- :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.
"""
diff --git a/tests/test_pycode.py b/tests/test_pycode.py
index 2b5ae1514..400c47dc5 100644
--- a/tests/test_pycode.py
+++ b/tests/test_pycode.py
@@ -41,7 +41,8 @@ def test_ModuleAnalyzer_for_file():
def test_ModuleAnalyzer_for_module():
analyzer = ModuleAnalyzer.for_module('sphinx')
assert analyzer.modname == 'sphinx'
- assert analyzer.srcname == SPHINX_MODULE_PATH
+ assert analyzer.srcname in (SPHINX_MODULE_PATH,
+ os.path.abspath(SPHINX_MODULE_PATH))
assert analyzer.encoding == 'utf-8'
diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py
index f69a0a58e..b1b0fc535 100644
--- a/tests/test_quickstart.py
+++ b/tests/test_quickstart.py
@@ -5,7 +5,7 @@
Test the sphinx.quickstart module.
- :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.
"""
@@ -96,7 +96,6 @@ def test_do_prompt_inputstrip():
def test_do_prompt_with_nonascii():
- d = {}
answers = {
'Q1': u'\u30c9\u30a4\u30c4',
}
diff --git a/tests/test_search.py b/tests/test_search.py
index f1825dfa4..fc5fb7e04 100644
--- a/tests/test_search.py
+++ b/tests/test_search.py
@@ -5,7 +5,7 @@
Test the search index 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.
"""
diff --git a/tests/test_setup_command.py b/tests/test_setup_command.py
index 562b0a715..e1f976b8a 100644
--- a/tests/test_setup_command.py
+++ b/tests/test_setup_command.py
@@ -5,7 +5,7 @@
Test setup_command for distutils.
- :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.
"""
diff --git a/tests/test_templating.py b/tests/test_templating.py
index b0070f06a..550b3bc7d 100644
--- a/tests/test_templating.py
+++ b/tests/test_templating.py
@@ -5,15 +5,19 @@
Test templating.
- :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 pytest
+from sphinx.ext.autosummary.generate import setup_documenters
@pytest.mark.sphinx('html', testroot='templating')
-def test_layout_overloading(app, status, warning):
+def test_layout_overloading(make_app, app_params):
+ args, kwargs = app_params
+ app = make_app(*args, **kwargs)
+ setup_documenters(app)
app.builder.build_update()
result = (app.outdir / 'contents.html').text(encoding='utf-8')
@@ -22,7 +26,10 @@ def test_layout_overloading(app, status, warning):
@pytest.mark.sphinx('html', testroot='templating')
-def test_autosummary_class_template_overloading(app, status, warning):
+def test_autosummary_class_template_overloading(make_app, app_params):
+ args, kwargs = app_params
+ app = make_app(*args, **kwargs)
+ setup_documenters(app)
app.builder.build_update()
result = (app.outdir / 'generated' / 'sphinx.application.TemplateBridge.html').text(
diff --git a/tests/test_theming.py b/tests/test_theming.py
index 0977e1274..dfe583918 100644
--- a/tests/test_theming.py
+++ b/tests/test_theming.py
@@ -5,7 +5,7 @@
Test the Theme 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.
"""
diff --git a/tests/test_toctree.py b/tests/test_toctree.py
index 18910197f..42ec0ce89 100644
--- a/tests/test_toctree.py
+++ b/tests/test_toctree.py
@@ -5,7 +5,7 @@
Test the HTML builder and check output against XPath.
- :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 pytest
diff --git a/tests/test_util.py b/tests/test_util.py
index aae54eaf0..189e221b2 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -5,7 +5,7 @@
Tests util functions.
- :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.
"""
@@ -95,7 +95,6 @@ def test_parselinenos():
parselinenos('3-1', 10)
-
def test_xmlname_check():
checker = xmlname_checker()
assert checker.match('id-pub')
diff --git a/tests/test_util_fileutil.py b/tests/test_util_fileutil.py
index 849ccce22..69f51f52c 100644
--- a/tests/test_util_fileutil.py
+++ b/tests/test_util_fileutil.py
@@ -5,7 +5,7 @@
Tests sphinx.util.fileutil functions.
- :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 sphinx.util.fileutil import copy_asset, copy_asset_file
diff --git a/tests/test_util_i18n.py b/tests/test_util_i18n.py
index 53e0e4cf1..bec4e91e9 100644
--- a/tests/test_util_i18n.py
+++ b/tests/test_util_i18n.py
@@ -5,7 +5,7 @@
Test i18n util.
- :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
diff --git a/tests/test_util_images.py b/tests/test_util_images.py
index 6f67dcc82..624690831 100644
--- a/tests/test_util_images.py
+++ b/tests/test_util_images.py
@@ -5,7 +5,7 @@
Test images util.
- :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
@@ -44,22 +44,22 @@ def test_guess_mimetype(testroot):
assert guess_mimetype('IMG.PNG') == 'image/png'
# guess by content
- assert guess_mimetype(content=(testroot/GIF_FILENAME).bytes()) == 'image/gif'
- assert guess_mimetype(content=(testroot/PNG_FILENAME).bytes()) == 'image/png'
- assert guess_mimetype(content=(testroot/PDF_FILENAME).bytes()) is None
- assert guess_mimetype(content=(testroot/TXT_FILENAME).bytes()) is None
- assert guess_mimetype(content=(testroot/TXT_FILENAME).bytes(),
+ assert guess_mimetype(content=(testroot / GIF_FILENAME).bytes()) == 'image/gif'
+ assert guess_mimetype(content=(testroot / PNG_FILENAME).bytes()) == 'image/png'
+ assert guess_mimetype(content=(testroot / PDF_FILENAME).bytes()) is None
+ assert guess_mimetype(content=(testroot / TXT_FILENAME).bytes()) is None
+ assert guess_mimetype(content=(testroot / TXT_FILENAME).bytes(),
default='text/plain') == 'text/plain'
# the priority of params: filename > content > default
assert guess_mimetype('img.png',
- content=(testroot/GIF_FILENAME).bytes(),
+ content=(testroot / GIF_FILENAME).bytes(),
default='text/plain') == 'image/png'
assert guess_mimetype('no_extension',
- content=(testroot/GIF_FILENAME).bytes(),
+ content=(testroot / GIF_FILENAME).bytes(),
default='text/plain') == 'image/gif'
assert guess_mimetype('no_extension',
- content=(testroot/TXT_FILENAME).bytes(),
+ content=(testroot / TXT_FILENAME).bytes(),
default='text/plain') == 'text/plain'
diff --git a/tests/test_util_inspect.py b/tests/test_util_inspect.py
index 63e04ee76..f0188cafa 100644
--- a/tests/test_util_inspect.py
+++ b/tests/test_util_inspect.py
@@ -5,7 +5,7 @@
Tests util.inspect functions.
- :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
@@ -113,7 +113,6 @@ def test_getargspec_bound_methods():
assert expected_bound == inspect.getargspec(wrapped_bound_method)
-
def test_Signature():
# literals
with pytest.raises(TypeError):
diff --git a/tests/test_util_logging.py b/tests/test_util_logging.py
index 7ae086872..48eed82b0 100644
--- a/tests/test_util_logging.py
+++ b/tests/test_util_logging.py
@@ -5,7 +5,7 @@
Test logging util.
- :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
@@ -183,7 +183,7 @@ def test_warning_location(app, status, warning):
assert 'index.txt:10: WARNING: message2' in warning.getvalue()
logger.warning('message3', location=None)
- assert colorize('darkred', 'WARNING: message3') in warning.getvalue()
+ assert colorize('red', 'WARNING: message3') in warning.getvalue()
node = nodes.Node()
node.source, node.line = ('index.txt', 10)
@@ -200,7 +200,7 @@ def test_warning_location(app, status, warning):
node.source, node.line = (None, None)
logger.warning('message7', location=node)
- assert colorize('darkred', 'WARNING: message7') in warning.getvalue()
+ assert colorize('red', 'WARNING: message7') in warning.getvalue()
def test_pending_warnings(app, status, warning):
@@ -236,7 +236,7 @@ def test_colored_logs(app, status, warning):
assert colorize('darkgray', 'message1') in status.getvalue()
assert 'message2\n' in status.getvalue() # not colored
assert 'message3\n' in status.getvalue() # not colored
- assert colorize('darkred', 'WARNING: message4') in warning.getvalue()
+ assert colorize('red', 'WARNING: message4') in warning.getvalue()
assert 'WARNING: message5\n' in warning.getvalue() # not colored
assert colorize('darkred', 'WARNING: message6') in warning.getvalue()
diff --git a/tests/test_util_matching.py b/tests/test_util_matching.py
index 3b84f4735..fc38470d3 100644
--- a/tests/test_util_matching.py
+++ b/tests/test_util_matching.py
@@ -5,7 +5,7 @@
Tests sphinx.util.matching functions.
- :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 sphinx.util.matching import compile_matchers, Matcher
diff --git a/tests/test_util_nodes.py b/tests/test_util_nodes.py
index c392c2bc7..c58ecc205 100644
--- a/tests/test_util_nodes.py
+++ b/tests/test_util_nodes.py
@@ -5,7 +5,7 @@
Tests uti.nodes functions.
- :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 textwrap import dedent
diff --git a/tests/test_util_rst.py b/tests/test_util_rst.py
index 5fce6e3eb..406ea710e 100644
--- a/tests/test_util_rst.py
+++ b/tests/test_util_rst.py
@@ -5,7 +5,7 @@
Tests sphinx.util.rst functions.
- :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 sphinx.util.rst import escape
diff --git a/tests/test_versioning.py b/tests/test_versioning.py
index b73c00fa6..e17d250e5 100644
--- a/tests/test_versioning.py
+++ b/tests/test_versioning.py
@@ -5,7 +5,7 @@
Test the versioning implementation.
- :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.
"""
@@ -28,7 +28,7 @@ def setup_module(rootdir, sphinx_test_tempdir):
global app, original, original_uids
srcdir = sphinx_test_tempdir / 'test-versioning'
if not srcdir.exists():
- (rootdir/'test-versioning').copytree(srcdir)
+ (rootdir / 'test-versioning').copytree(srcdir)
app = SphinxTestApp(srcdir=srcdir)
app.builder.env.app = app
app.connect('doctree-resolved', on_doctree_resolved)
diff --git a/tests/test_websupport.py b/tests/test_websupport.py
index 51cb2b287..10942798c 100644
--- a/tests/test_websupport.py
+++ b/tests/test_websupport.py
@@ -5,7 +5,7 @@
Test 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.
"""
diff --git a/tests/test_writer_latex.py b/tests/test_writer_latex.py
index b026f8d17..5c73469ec 100644
--- a/tests/test_writer_latex.py
+++ b/tests/test_writer_latex.py
@@ -5,7 +5,7 @@
Test the LaTeX writer
- :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
diff --git a/tox.ini b/tox.ini
index 00b3c99e2..810b76f0c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,69 +1,65 @@
[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
+usedevelop = True
+passenv =
+ https_proxy http_proxy no_proxy PERL PERL5LIB
+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.
+
# 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 =
+ PYTHONWARNINGS = all,ignore::ImportWarning:pkgutil,ignore::ImportWarning:importlib._bootstrap,ignore::ImportWarning:importlib._bootstrap_external,ignore::ImportWarning:pytest_cov.plugin,ignore::DeprecationWarning:site,ignore::DeprecationWarning:_pytest.assertion.rewrite,ignore::DeprecationWarning:_pytest.fixtures
SPHINX_TEST_TEMPDIR = {envdir}/testbuild
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}
+ pytest -Wall --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:coverage]
+description =
+ Run code coverage checks.
+setenv =
+ PYTEST_ADDOPTS = --cov sphinx --cov-config {toxinidir}/setup.cfg
+commands =
+ {[testenv]commands}
+ coverage report
[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}
diff --git a/utils/checks.py b/utils/checks.py
index 03104d78a..90d89439e 100644
--- a/utils/checks.py
+++ b/utils/checks.py
@@ -5,7 +5,7 @@
Custom, Sphinx-only flake8 plugins.
- :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.
"""
diff --git a/utils/jssplitter_generator.py b/utils/jssplitter_generator.py
index 05b8628b3..b7273a5c1 100644
--- a/utils/jssplitter_generator.py
+++ b/utils/jssplitter_generator.py
@@ -122,7 +122,7 @@ python_src = '''# -*- coding: utf-8 -*-
DO NOT EDIT. This is generated by utils/jssplitter_generator.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.
"""