summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES59
-rw-r--r--doc/contents.rst1
-rw-r--r--doc/develop.rst2
-rw-r--r--doc/development/tutorials/helloworld.rst162
-rw-r--r--doc/development/tutorials/index.rst11
-rw-r--r--doc/development/tutorials/todo.rst (renamed from doc/extdev/tutorial.rst)124
-rw-r--r--doc/extdev/index.rst111
-rw-r--r--doc/faq.rst2
-rw-r--r--doc/latex.rst29
-rw-r--r--doc/usage/configuration.rst18
-rw-r--r--doc/usage/extensions/viewcode.rst7
-rw-r--r--doc/usage/installation.rst4
-rw-r--r--doc/usage/markdown.rst39
-rw-r--r--setup.py1
-rw-r--r--sphinx/builders/html.py13
-rw-r--r--sphinx/builders/htmlhelp.py23
-rw-r--r--sphinx/builders/latex/__init__.py20
-rw-r--r--sphinx/cmd/build.py7
-rw-r--r--sphinx/cmd/quickstart.py8
-rw-r--r--sphinx/config.py6
-rw-r--r--sphinx/domains/changeset.py11
-rw-r--r--sphinx/domains/cpp.py91
-rw-r--r--sphinx/environment/adapters/indexentries.py4
-rw-r--r--sphinx/environment/collectors/indexentries.py4
-rw-r--r--sphinx/ext/apidoc.py2
-rw-r--r--sphinx/ext/autodoc/__init__.py10
-rw-r--r--sphinx/ext/autosummary/__init__.py4
-rw-r--r--sphinx/ext/imgmath.py5
-rw-r--r--sphinx/ext/todo.py5
-rw-r--r--sphinx/highlighting.py3
-rw-r--r--sphinx/locale/__init__.py8
-rw-r--r--sphinx/pycode/parser.py4
-rw-r--r--sphinx/search/__init__.py6
-rw-r--r--sphinx/templates/quickstart/conf.py_t5
-rw-r--r--sphinx/testing/path.py6
-rw-r--r--sphinx/texinputs/sphinxhowto.cls15
-rw-r--r--sphinx/texinputs/sphinxmanual.cls19
-rw-r--r--sphinx/transforms/post_transforms/code.py3
-rw-r--r--sphinx/transforms/post_transforms/images.py4
-rw-r--r--sphinx/util/__init__.py14
-rw-r--r--sphinx/util/images.py5
-rw-r--r--sphinx/util/inspect.py4
-rw-r--r--sphinx/util/jsonimpl.py4
-rw-r--r--sphinx/util/nodes.py5
-rw-r--r--sphinx/util/pycompat.py4
-rw-r--r--sphinx/util/typing.py5
-rw-r--r--sphinx/writers/html.py2
-rw-r--r--sphinx/writers/html5.py2
-rw-r--r--sphinx/writers/latex.py25
-rw-r--r--tests/roots/test-build-htmlhelp/conf.py4
-rw-r--r--tests/roots/test-build-htmlhelp/index.rst19
-rw-r--r--tests/roots/test-build-htmlhelp/make.bat64
-rw-r--r--tests/roots/test-ext-todo/foo.rst6
-rw-r--r--tests/test_build_htmlhelp.py32
-rw-r--r--tests/test_domain_cpp.py3
-rw-r--r--tests/test_domain_py.py13
-rw-r--r--tests/test_ext_todo.py18
-rw-r--r--tests/test_intl.py6
-rw-r--r--tests/test_quickstart.py2
59 files changed, 709 insertions, 384 deletions
diff --git a/CHANGES b/CHANGES
index d46acccc1..dcd20947b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -17,6 +17,7 @@ Dependencies
which in Ubuntu xenial are provided by package ``fonts-freefont-otf``, and
e.g. in Fedora 29 via package ``texlive-gnu-freefont``.
* requests 2.5.0 or above
+* The six package is no longer a dependency.
Incompatible changes
--------------------
@@ -45,6 +46,11 @@ Incompatible changes
block. As a result, they are highlighted as python3 by default.
* The order of argument for ``HTMLTranslator``, ``HTML5Translator`` and
``ManualPageTranslator`` are changed
+* LaTeX: hard-coded redefinitions of ``\l@section`` and ``\l@subsection``
+ formerly done during loading of ``'manual'`` docclass get executed later, at
+ time of ``\sphinxtableofcontents``. This means that custom user definitions
+ from LaTeX preamble now get overwritten. Use ``\sphinxtableofcontentshook``
+ to insert custom user definitions. See :ref:`latex-macros`.
Deprecated
----------
@@ -127,6 +133,10 @@ Features added
* LaTeX: support rendering (not in math, yet) of Greek and Cyrillic Unicode
letters in non-Cyrillic document even with ``'pdflatex'`` as
:confval:`latex_engine` (refs: #5645)
+* #5660: The ``versionadded``, ``versionchanged`` and ``deprecated`` directives
+ are now generated with their own specific CSS classes
+ (``added``, ``changed`` and ``deprecated``, respectively) in addition to the
+ generic ``versionmodified`` class.
* #5841: apidoc: Add --extensions option to sphinx-apidoc
Bugs fixed
@@ -149,7 +159,7 @@ Bugs fixed
Testing
--------
-Release 1.8.3 (in development)
+Release 1.8.4 (in development)
==============================
Dependencies
@@ -167,6 +177,22 @@ Features added
Bugs fixed
----------
+Testing
+--------
+
+Release 1.8.3 (released Dec 26, 2018)
+=====================================
+
+Features added
+--------------
+
+* LaTeX: it is possible to insert custom material to appear on back of title
+ page, see discussion of ``'maketitle'`` key of :confval:`latex_elements`
+ (``'manual'`` docclass only)
+
+Bugs fixed
+----------
+
* #5725: mathjax: Use CDN URL for "latest" version by default
* #5460: html search does not work with some 3rd party themes
* #5520: LaTeX, caption package incompatibility since Sphinx 1.6
@@ -179,9 +205,13 @@ Bugs fixed
* #5636: C++, fix parsing of floating point literals.
* #5496 (again): C++, fix assertion in partial builds with duplicates.
* #5724: quickstart: sphinx-quickstart fails when $LC_ALL is empty
-
-Testing
---------
+* #1956: Default conf.py is not PEP8-compliant
+* #5849: LaTeX: document class ``\maketitle`` is overwritten with no
+ possibility to use original meaning in place of Sphinx custom one
+* #5834: apidoc: wrong help for ``--tocfile``
+* #5800: todo: crashed if todo is defined in TextElement
+* #5846: htmlhelp: convert hex escaping to decimal escaping in .hhc/.hhk files
+* htmlhelp: broken .hhk file generated when title contains a double quote
Release 1.8.2 (released Nov 11, 2018)
=====================================
@@ -551,27 +581,6 @@ Documentation
* #5083: Fix wrong make.bat option for internationalization.
* #5115: napoleon: add admonitions added by #4613 to the docs.
-Release 1.7.10 (in development)
-===============================
-
-Dependencies
-------------
-
-Incompatible changes
---------------------
-
-Deprecated
-----------
-
-Features added
---------------
-
-Bugs fixed
-----------
-
-Testing
---------
-
Release 1.7.9 (released Sep 05, 2018)
=====================================
diff --git a/doc/contents.rst b/doc/contents.rst
index dc9baf269..f3a1cd2f8 100644
--- a/doc/contents.rst
+++ b/doc/contents.rst
@@ -25,6 +25,7 @@ Sphinx documentation contents
templating
latex
extdev/index
+ development/tutorials/index
faq
glossary
diff --git a/doc/develop.rst b/doc/develop.rst
index 60ccaf79b..d061aae61 100644
--- a/doc/develop.rst
+++ b/doc/develop.rst
@@ -100,7 +100,7 @@ This is the current list of contributed extensions in that repository:
- zopeext: provide an ``autointerface`` directive for using `Zope interfaces`_
-See the :ref:`extension tutorial <exttut>` on getting started with writing your
+See the :doc:`extension tutorials <../development/tutorials/index>` on getting started with writing your
own extensions.
diff --git a/doc/development/tutorials/helloworld.rst b/doc/development/tutorials/helloworld.rst
new file mode 100644
index 000000000..5ce8db66c
--- /dev/null
+++ b/doc/development/tutorials/helloworld.rst
@@ -0,0 +1,162 @@
+Developing a "Hello world" directive
+====================================
+
+The objective of this tutorial is to create a very basic extension that adds a new
+directive that outputs a paragraph containing `hello world`.
+
+Only basic information is provided in this tutorial. For more information,
+refer to the :doc:`other tutorials <index>` that go into more
+details.
+
+.. warning:: For this extension, you will need some basic understanding of docutils_
+ and Python.
+
+Creating a new extension file
+-----------------------------
+
+Your extension file could be in any folder of your project. In our case,
+let's do the following:
+
+#. Create an :file:`_ext` folder in :file:`source`.
+#. Create a new Python file in the :file:`_ext` folder called
+ :file:`helloworld.py`.
+
+ Here is an example of the folder structure you might obtain:
+
+ .. code-block:: text
+
+ └── source
+    ├── _ext
+ │   └── helloworld.py
+    ├── _static
+    ├── _themes
+    ├── conf.py
+    ├── somefolder
+    ├── somefile.rst
+    └── someotherfile.rst
+
+Writing the extension
+---------------------
+
+Open :file:`helloworld.py` and paste the following code in it:
+
+.. code-block:: python
+
+ from docutils import nodes
+ from docutils.parsers.rst import Directive
+
+
+ class HelloWorld(Directive):
+ def run(self):
+ paragraph_node = nodes.paragraph(text='Hello World!')
+ return [paragraph_node]
+
+
+ def setup(app):
+ app.add_directive("helloworld", HelloWorld)
+
+
+Some essential things are happening in this example, and you will see them
+in all directives:
+
+.. rubric:: Directive declaration
+
+Our new directive is declared in the ``HelloWorld`` class, it extends
+docutils_' ``Directive`` class. All extensions that create directives
+should extend this class.
+
+.. rubric:: ``run`` method
+
+This method is a requirement and it is part of every directive. It contains
+the main logic of the directive and it returns a list of docutils nodes to
+be processed by Sphinx.
+
+.. seealso::
+
+ :doc:`todo`
+
+.. rubric:: docutils nodes
+
+The ``run`` method returns a list of nodes. Nodes are docutils' way of
+representing the content of a document. There are many types of nodes
+available: text, paragraph, reference, table, etc.
+
+.. seealso::
+
+ `The docutils documentation on nodes <docutils nodes>`_
+
+The ``nodes.paragraph`` class creates a new paragraph node. A paragraph
+node typically contains some text that we can set during instantiation using
+the ``text`` parameter.
+
+.. rubric:: ``setup`` function
+
+This function is a requirement. We use it to plug our new directive into
+Sphinx.
+The simplest thing you can do it call the ``app.add_directive`` method.
+
+.. note::
+
+ The first argument is the name of the directive itself as used in an rST file.
+
+ In our case, we would use ``helloworld``:
+
+ .. code-block:: rst
+
+ Some intro text here...
+
+ .. helloworld::
+
+ Some more text here...
+
+
+Updating the conf.py file
+-------------------------
+
+The extension file has to be declared in your :file:`conf.py` file to make
+Sphinx aware of it:
+
+#. Open :file:`conf.py`. It is in the :file:`source` folder by default.
+#. Add ``sys.path.append(os.path.abspath("./_ext"))`` before
+ the ``extensions`` variable declaration (if it exists).
+#. Update or create the ``extensions`` list and add the
+ extension file name to the list:
+
+ .. code-block:: python
+
+ extensions.append('helloworld')
+
+You can now use the extension.
+
+.. admonition:: Example
+
+ .. code-block:: rst
+
+ Some intro text here...
+
+ .. helloworld::
+
+ Some more text here...
+
+ The sample above would generate:
+
+ .. code-block:: text
+
+ Some intro text here...
+
+ Hello World!
+
+ Some more text here...
+
+This is the very basic principle of an extension that creates a new directive.
+
+For a more advanced example, refer to :doc:`todo`.
+
+Further reading
+---------------
+
+You can create your own nodes if needed, refer to the
+:doc:`todo` for more information.
+
+.. _docutils: http://docutils.sourceforge.net/
+.. _`docutils nodes`: http://docutils.sourceforge.net/docs/ref/doctree.html \ No newline at end of file
diff --git a/doc/development/tutorials/index.rst b/doc/development/tutorials/index.rst
new file mode 100644
index 000000000..cb8dce435
--- /dev/null
+++ b/doc/development/tutorials/index.rst
@@ -0,0 +1,11 @@
+Extension tutorials
+===================
+
+Refer to the following tutorials to get started with extension development.
+
+.. toctree::
+ :caption: Directive tutorials
+ :maxdepth: 1
+
+ helloworld
+ todo
diff --git a/doc/extdev/tutorial.rst b/doc/development/tutorials/todo.rst
index 33b45035e..e68a39342 100644
--- a/doc/extdev/tutorial.rst
+++ b/doc/development/tutorials/todo.rst
@@ -1,7 +1,5 @@
-.. _exttut:
-
-Tutorial: Writing a simple extension
-====================================
+Developing a "TODO" extension
+=============================
This section is intended as a walkthrough for the creation of custom extensions.
It covers the basics of writing and activating an extension, as well as
@@ -12,112 +10,12 @@ include todo entries in the documentation, and to collect these in a central
place. (A similar "todo" extension is distributed with Sphinx.)
-Important objects
------------------
-
-There are several key objects whose API you will use while writing an
-extension. These are:
-
-**Application**
- The application object (usually called ``app``) is an instance of
- :class:`.Sphinx`. It controls most high-level functionality, such as the
- setup of extensions, event dispatching and producing output (logging).
-
- If you have the environment object, the application is available as
- ``env.app``.
-
-**Environment**
- The build environment object (usually called ``env``) is an instance of
- :class:`.BuildEnvironment`. It is responsible for parsing the source
- documents, stores all metadata about the document collection and is
- serialized to disk after each build.
-
- Its API provides methods to do with access to metadata, resolving references,
- etc. It can also be used by extensions to cache information that should
- persist for incremental rebuilds.
-
- If you have the application or builder object, the environment is available
- as ``app.env`` or ``builder.env``.
-
-**Builder**
- The builder object (usually called ``builder``) is an instance of a specific
- subclass of :class:`.Builder`. Each builder class knows how to convert the
- parsed documents into an output format, or otherwise process them (e.g. check
- external links).
-
- If you have the application object, the builder is available as
- ``app.builder``.
-
-**Config**
- The config object (usually called ``config``) provides the values of
- configuration values set in :file:`conf.py` as attributes. It is an instance
- of :class:`.Config`.
-
- The config is available as ``app.config`` or ``env.config``.
-
-
-Build Phases
-------------
-
-One thing that is vital in order to understand extension mechanisms is the way
-in which a Sphinx project is built: this works in several phases.
-
-**Phase 0: Initialization**
-
- In this phase, almost nothing of interest to us happens. The source
- directory is searched for source files, and extensions are initialized.
- Should a stored build environment exist, it is loaded, otherwise a new one is
- created.
-
-**Phase 1: Reading**
-
- In Phase 1, all source files (and on subsequent builds, those that are new or
- changed) are read and parsed. This is the phase where directives and roles
- are encountered by docutils, and the corresponding code is executed. The
- output of this phase is a *doctree* for each source file; that is a tree of
- docutils nodes. For document elements that aren't fully known until all
- existing files are read, temporary nodes are created.
-
- There are nodes provided by docutils, which are documented `in the docutils
- documentation <http://docutils.sourceforge.net/docs/ref/doctree.html>`__.
- Additional nodes are provided by Sphinx and :ref:`documented here <nodes>`.
-
- During reading, the build environment is updated with all meta- and cross
- reference data of the read documents, such as labels, the names of headings,
- described Python objects and index entries. This will later be used to
- replace the temporary nodes.
-
- The parsed doctrees are stored on the disk, because it is not possible to
- hold all of them in memory.
-
-**Phase 2: Consistency checks**
-
- Some checking is done to ensure no surprises in the built documents.
-
-**Phase 3: Resolving**
-
- Now that the metadata and cross-reference data of all existing documents is
- known, all temporary nodes are replaced by nodes that can be converted into
- output using components called tranform. For example, links are created for
- object references that exist, and simple literal nodes are created for those
- that don't.
-
-**Phase 4: Writing**
-
- This phase converts the resolved doctrees to the desired output format, such
- as HTML or LaTeX. This happens via a so-called docutils writer that visits
- the individual nodes of each doctree and produces some output in the process.
-
-.. note::
-
- Some builders deviate from this general build plan, for example, the builder
- that checks external links does not need anything more than the parsed
- doctrees and therefore does not have phases 2--4.
-
-
Extension Design
----------------
+.. note:: To understand the design this extension, refer to
+ :ref:`important-objects` and :ref:`build-phases`.
+
We want the extension to add the following to Sphinx:
* A "todo" directive, containing some content that is marked with "TODO", and
@@ -174,12 +72,13 @@ the individual calls do is the following:
If the third argument was ``'html'``, HTML documents would be full rebuild if the
config value changed its value. This is needed for config values that
- influence reading (build phase 1).
+ influence reading (build :ref:`phase 1 <build-phases>`).
* :meth:`~Sphinx.add_node` adds a new *node class* to the build system. It also
can specify visitor functions for each supported output format. These visitor
- functions are needed when the new nodes stay until phase 4 -- since the
- ``todolist`` node is always replaced in phase 3, it doesn't need any.
+ functions are needed when the new nodes stay until :ref:`phase 4 <build-phases>`
+ -- since the ``todolist`` node is always replaced in :ref:`phase 3 <build-phases>`,
+ it doesn't need any.
We need to create the two node classes ``todo`` and ``todolist`` later.
@@ -276,7 +175,7 @@ The ``todo`` directive function looks like this::
return [targetnode, todo_node]
Several important things are covered here. First, as you can see, you can refer
-to the build environment instance using ``self.state.document.settings.env``.
+to the :ref:`build environment instance <important-objects>` using ``self.state.document.settings.env``.
Then, to act as a link target (from the todolist), the todo directive needs to
return a target node in addition to the todo node. The target ID (in HTML, this
@@ -340,7 +239,8 @@ Here we clear out all todos whose docname matches the given one from the
added again during parsing.
The other handler belongs to the :event:`doctree-resolved` event. This event is
-emitted at the end of phase 3 and allows custom resolving to be done::
+emitted at the end of :ref:`phase 3 <build-phases>` and allows custom resolving
+to be done::
def process_todo_nodes(app, doctree, fromdocname):
if not app.config.todo_include_todos:
diff --git a/doc/extdev/index.rst b/doc/extdev/index.rst
index b5336373d..da0d0e2d0 100644
--- a/doc/extdev/index.rst
+++ b/doc/extdev/index.rst
@@ -52,6 +52,115 @@ Note that it is still necessary to register the builder using
.. _entry points: https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
+.. _important-objects:
+
+Important objects
+-----------------
+
+There are several key objects whose API you will use while writing an
+extension. These are:
+
+**Application**
+ The application object (usually called ``app``) is an instance of
+ :class:`.Sphinx`. It controls most high-level functionality, such as the
+ setup of extensions, event dispatching and producing output (logging).
+
+ If you have the environment object, the application is available as
+ ``env.app``.
+
+**Environment**
+ The build environment object (usually called ``env``) is an instance of
+ :class:`.BuildEnvironment`. It is responsible for parsing the source
+ documents, stores all metadata about the document collection and is
+ serialized to disk after each build.
+
+ Its API provides methods to do with access to metadata, resolving references,
+ etc. It can also be used by extensions to cache information that should
+ persist for incremental rebuilds.
+
+ If you have the application or builder object, the environment is available
+ as ``app.env`` or ``builder.env``.
+
+**Builder**
+ The builder object (usually called ``builder``) is an instance of a specific
+ subclass of :class:`.Builder`. Each builder class knows how to convert the
+ parsed documents into an output format, or otherwise process them (e.g. check
+ external links).
+
+ If you have the application object, the builder is available as
+ ``app.builder``.
+
+**Config**
+ The config object (usually called ``config``) provides the values of
+ configuration values set in :file:`conf.py` as attributes. It is an instance
+ of :class:`.Config`.
+
+ The config is available as ``app.config`` or ``env.config``.
+
+To see an example of use of these objects, refer to :doc:`../development/tutorials/index`.
+
+.. _build-phases:
+
+Build Phases
+------------
+
+One thing that is vital in order to understand extension mechanisms is the way
+in which a Sphinx project is built: this works in several phases.
+
+**Phase 0: Initialization**
+
+ In this phase, almost nothing of interest to us happens. The source
+ directory is searched for source files, and extensions are initialized.
+ Should a stored build environment exist, it is loaded, otherwise a new one is
+ created.
+
+**Phase 1: Reading**
+
+ In Phase 1, all source files (and on subsequent builds, those that are new or
+ changed) are read and parsed. This is the phase where directives and roles
+ are encountered by docutils, and the corresponding code is executed. The
+ output of this phase is a *doctree* for each source file; that is a tree of
+ docutils nodes. For document elements that aren't fully known until all
+ existing files are read, temporary nodes are created.
+
+ There are nodes provided by docutils, which are documented `in the docutils
+ documentation <http://docutils.sourceforge.net/docs/ref/doctree.html>`__.
+ Additional nodes are provided by Sphinx and :ref:`documented here <nodes>`.
+
+ During reading, the build environment is updated with all meta- and cross
+ reference data of the read documents, such as labels, the names of headings,
+ described Python objects and index entries. This will later be used to
+ replace the temporary nodes.
+
+ The parsed doctrees are stored on the disk, because it is not possible to
+ hold all of them in memory.
+
+**Phase 2: Consistency checks**
+
+ Some checking is done to ensure no surprises in the built documents.
+
+**Phase 3: Resolving**
+
+ Now that the metadata and cross-reference data of all existing documents is
+ known, all temporary nodes are replaced by nodes that can be converted into
+ output using components called tranform. For example, links are created for
+ object references that exist, and simple literal nodes are created for those
+ that don't.
+
+**Phase 4: Writing**
+
+ This phase converts the resolved doctrees to the desired output format, such
+ as HTML or LaTeX. This happens via a so-called docutils writer that visits
+ the individual nodes of each doctree and produces some output in the process.
+
+.. note::
+
+ Some builders deviate from this general build plan, for example, the builder
+ that checks external links does not need anything more than the parsed
+ doctrees and therefore does not have phases 2--4.
+
+To see an example of application, refer to :doc:`../development/tutorials/todo`.
+
.. _ext-metadata:
Extension metadata
@@ -82,8 +191,8 @@ APIs used for writing extensions
--------------------------------
.. toctree::
+ :maxdepth: 2
- tutorial
appapi
projectapi
envapi
diff --git a/doc/faq.rst b/doc/faq.rst
index 920ef6651..4b608b780 100644
--- a/doc/faq.rst
+++ b/doc/faq.rst
@@ -30,7 +30,7 @@ How do I...
``sidebartoc`` block.
... write my own extension?
- See the :ref:`extension tutorial <exttut>`.
+ See the :doc:`/development/tutorials/index`.
... convert from my existing docs using MoinMoin markup?
The easiest way is to convert to xhtml, then convert `xhtml to reST`_.
diff --git a/doc/latex.rst b/doc/latex.rst
index 63e860a64..7a4d0be03 100644
--- a/doc/latex.rst
+++ b/doc/latex.rst
@@ -365,6 +365,8 @@ Here are some macros from the package file :file:`sphinx.sty` and class files
:file:`sphinxhowto.cls`, :file:`sphinxmanual.cls`, which have public names
thus allowing redefinitions. Check the respective files for the defaults.
+.. _latex-macros:
+
Macros
~~~~~~
@@ -390,13 +392,32 @@ Macros
.. versionadded:: 1.6.3
``\sphinxstylecodecontinued`` and ``\sphinxstylecodecontinues``.
- the table of contents is typeset via ``\sphinxtableofcontents`` which is a
- wrapper (whose definition can be found in :file:`sphinxhowto.cls` or in
- :file:`sphinxmanual.cls`) of standard ``\tableofcontents``.
+ wrapper (defined differently in :file:`sphinxhowto.cls` and in
+ :file:`sphinxmanual.cls`) of standard ``\tableofcontents``. The macro
+ ``\sphinxtableofcontentshook`` is executed during its expansion right before
+ ``\tableofcontents`` itself.
.. versionchanged:: 1.5
formerly, the meaning of ``\tableofcontents`` was modified by Sphinx.
-- the ``\maketitle`` command is redefined by the class files
- :file:`sphinxmanual.cls` and :file:`sphinxhowto.cls`.
+ .. versionchanged:: 2.0
+ hard-coded redefinitions of ``\l@section`` and ``\l@subsection`` formerly
+ done during loading of ``'manual'`` docclass are now executed later via
+ ``\sphinxtableofcontentshook``. This macro is also executed by the
+ ``'howto'`` docclass, but defaults to empty with it.
+- a custom ``\sphinxmaketitle`` is defined in the class files
+ :file:`sphinxmanual.cls` and :file:`sphinxhowto.cls` and is used as
+ default setting of ``'maketitle'`` :confval:`latex_elements` key.
+
+ .. versionchanged:: 1.8.3
+ formerly, ``\maketitle`` from LaTeX document class was modified by
+ Sphinx.
+- for ``'manual'`` docclass a macro ``\sphinxbackoftitlepage``, if it is
+ defined, gets executed at end of ``\sphinxmaketitle``, before the final
+ ``\clearpage``. Use either the ``'maketitle'`` key or the ``'preamble'`` key
+ of :confval:`latex_elements` to add a custom definition of
+ ``\sphinxbackoftitlepage``.
+
+ .. versionadded:: 1.8.3
- the citation reference is typeset via ``\sphinxcite`` which is a wrapper
of standard ``\cite``.
diff --git a/doc/usage/configuration.rst b/doc/usage/configuration.rst
index 3e20cf7dc..5400697eb 100644
--- a/doc/usage/configuration.rst
+++ b/doc/usage/configuration.rst
@@ -2279,10 +2279,22 @@ information.
Previously this was done from inside :file:`sphinx.sty`.
``'maketitle'``
- "maketitle" call, default ``'\\maketitle'`` (but it has been
- redefined by the Sphinx ``manual`` and ``howto`` classes.) Override
- if you want to generate a differently-styled title page.
+ "maketitle" call, default ``'\\sphinxmaketitle'``. Override
+ if you want to generate a differently styled title page.
+ .. hint::
+
+ If the key value is set to
+ ``r'\newcommand\sphinxbackoftitlepage{<Extra
+ material>}\sphinxmaketitle'``, then ``<Extra material>`` will be
+ typeset on back of title page (``'manual'`` docclass only).
+
+ .. versionchanged:: 1.8.3
+ Original ``\maketitle`` from document class is not overwritten,
+ hence is re-usable as part of some custom setting for this key.
+ .. versionadded:: 1.8.3
+ ``\sphinxbackoftitlepage`` optional macro. It can also be defined
+ inside ``'preamble'`` key rather than this one.
``'releasename'``
value that prefixes ``'release'`` element on title page, default
``'Release'``. As for *title* and *author* used in the tuples of
diff --git a/doc/usage/extensions/viewcode.rst b/doc/usage/extensions/viewcode.rst
index cc7dbb07a..d3c3c44fb 100644
--- a/doc/usage/extensions/viewcode.rst
+++ b/doc/usage/extensions/viewcode.rst
@@ -41,10 +41,9 @@ Configuration
.. confval:: viewcode_follow_imported_members
- If this is ``True``, viewcode extension will follow alias objects that
- imported from another module such as functions, classes and attributes. As
- side effects, this option else they produce nothing. The default is
- ``True``.
+ If this is ``True``, viewcode extension will emit
+ :event:`viewcode-follow-imported` event to resolve the name of the module
+ by other extensions. The default is ``True``.
.. versionadded:: 1.3
diff --git a/doc/usage/installation.rst b/doc/usage/installation.rst
index 7efb6735d..f51b3084e 100644
--- a/doc/usage/installation.rst
+++ b/doc/usage/installation.rst
@@ -113,8 +113,7 @@ Prompt* (:kbd:`⊞Win-r` and type :command:`cmd`). Once the command prompt is
open, type :command:`python --version` and press Enter. If Python is
available, you will see the version of Python printed to the screen. If you do
not have Python installed, refer to the `Hitchhikers Guide to Python's`__
-Python on Windows installation guides. You can install either `Python 3`__ or
-`Python 2.7`__. Python 3 is recommended.
+Python on Windows installation guides. You must install `Python 3`__.
Once Python is installed, you can install Sphinx using :command:`pip`. Refer
to the :ref:`pip installation instructions <install-pypi>` below for more
@@ -122,7 +121,6 @@ information.
__ https://docs.python-guide.org/
__ https://docs.python-guide.org/starting/install3/win/
-__ https://docs.python-guide.org/starting/install/win/
.. _install-pypi:
diff --git a/doc/usage/markdown.rst b/doc/usage/markdown.rst
index ed0cce013..7593ea6b0 100644
--- a/doc/usage/markdown.rst
+++ b/doc/usage/markdown.rst
@@ -22,26 +22,41 @@ Configuration
To configure your Sphinx project for Markdown support, proceed as follows:
-#. Install *recommonmark*::
+#. Install the Markdown parser *recommonmark* from its source on GitHub::
- pip install recommonmark
+ pip install git+https://github.com/rtfd/recommonmark
-#. Add the Markdown parser to the ``source_parsers`` configuration variable in
- your Sphinx configuration file::
+ .. note::
- source_parsers = {
- '.md': 'recommonmark.parser.CommonMarkParser',
- }
+ The configuration as explained here requires recommonmark version
+ 0.5.0.dev or higher, which is at the time of writing not available on
+ PyPI. If you want to use a released recommonmark version, follow the
+ instructions in the `Sphinx 1.8 documentation`__.
+
+__ https://www.sphinx-doc.org/en/1.8/usage/markdown.html
+
+#. Add *recommonmark* to the
+ :confval:`list of configured extensions <extensions>`::
- You can replace ``.md`` with a filename extension of your choice.
+ extensions = ['recommonmark']
-#. Add the Markdown filename extension to the ``source_suffix`` configuration
- variable::
+ .. versionchanged:: 1.8
+ Version 1.8 deprecates and version 3.0 removes the ``source_parsers``
+ configuration variable that was used by older *recommonmark* versions.
- source_suffix = ['.rst', '.md']
+#. If you want to use Markdown files with extensions other than ``.md``, adjust
+ the :confval:`source_suffix` variable. The following example configures
+ Sphinx to parse all files with the extensions ``.md`` and ``.txt`` as
+ Markdown::
+
+ source_suffix = {
+ '.rst': 'restructuredtext',
+ '.txt': 'markdown',
+ '.md': 'markdown',
+ }
#. You can further configure *recommonmark* to allow custom syntax that
- standard *CommonMark* doesn't support. Read more in the `recommonmark
+ standard *CommonMark* doesn't support. Read more in the `recommonmark
documentation`__.
__ https://recommonmark.readthedocs.io/en/latest/auto_structify.html
diff --git a/setup.py b/setup.py
index 50c4b3f3a..6e28a10fc 100644
--- a/setup.py
+++ b/setup.py
@@ -15,7 +15,6 @@ if sys.version_info < (3, 5):
sys.exit(1)
install_requires = [
- 'six>=1.5',
'Jinja2>=2.3',
'Pygments>=2.0',
'docutils>=0.12',
diff --git a/sphinx/builders/html.py b/sphinx/builders/html.py
index 075fec8e3..b8b03c072 100644
--- a/sphinx/builders/html.py
+++ b/sphinx/builders/html.py
@@ -25,7 +25,6 @@ from docutils.frontend import OptionParser
from docutils.io import DocTreeInput, StringOutput
from docutils.readers.doctree import Reader as DoctreeReader
from docutils.utils import relative_path
-from six import text_type
from sphinx import package_dir, __display_version__
from sphinx.application import ENV_PICKLE_FILENAME
@@ -86,10 +85,10 @@ def get_stable_hash(obj):
return get_stable_hash(list(obj.items()))
elif isinstance(obj, (list, tuple)):
obj = sorted(get_stable_hash(o) for o in obj)
- return md5(text_type(obj).encode()).hexdigest()
+ return md5(str(obj).encode()).hexdigest()
-class Stylesheet(text_type):
+class Stylesheet(str):
"""A metadata of stylesheet.
To keep compatibility with old themes, an instance of stylesheet behaves as
@@ -101,7 +100,7 @@ class Stylesheet(text_type):
def __new__(cls, filename, *args, **attributes):
# type: (str, str, str) -> None
- self = text_type.__new__(cls, filename) # type: ignore
+ self = str.__new__(cls, filename) # type: ignore
self.filename = filename
self.attributes = attributes
self.attributes.setdefault('rel', 'stylesheet')
@@ -146,7 +145,7 @@ class JSContainer(list):
return ret
-class JavaScript(text_type):
+class JavaScript(str):
"""A metadata of javascript file.
To keep compatibility with old themes, an instance of javascript behaves as
@@ -158,7 +157,7 @@ class JavaScript(text_type):
def __new__(cls, filename, **attributes):
# type: (str, **str) -> None
- self = text_type.__new__(cls, filename) # type: ignore
+ self = str.__new__(cls, filename) # type: ignore
self.filename = filename
self.attributes = attributes
self.attributes.setdefault('type', 'text/javascript')
@@ -1633,7 +1632,7 @@ def setup(app):
app.add_config_value('html_sidebars', {}, 'html')
app.add_config_value('html_additional_pages', {}, 'html')
app.add_config_value('html_domain_indices', True, 'html', [list])
- app.add_config_value('html_add_permalinks', '\u00B6', 'html')
+ app.add_config_value('html_add_permalinks', '¶', 'html')
app.add_config_value('html_use_index', True, 'html')
app.add_config_value('html_split_index', False, 'html')
app.add_config_value('html_copy_source', True, 'html')
diff --git a/sphinx/builders/htmlhelp.py b/sphinx/builders/htmlhelp.py
index 4a9c7e36b..641761b69 100644
--- a/sphinx/builders/htmlhelp.py
+++ b/sphinx/builders/htmlhelp.py
@@ -25,7 +25,7 @@ from sphinx.util.osutil import make_filename_from_project
if False:
# For type annotation
- from typing import Any, Dict, IO, List, Tuple # NOQA
+ from typing import Any, Dict, IO, List, Match, Tuple # NOQA
from sphinx.application import Sphinx # NOQA
from sphinx.config import Config # NOQA
@@ -169,6 +169,20 @@ chm_locales = {
}
+def chm_htmlescape(s, quote=True):
+ # type: (str, bool) -> str
+ """
+ chm_htmlescape() is a wrapper of html.escape().
+ .hhc/.hhk files don't recognize hex escaping, we need convert
+ hex escaping to decimal escaping. for example: ``&#x27;`` -> ``&#39;``
+ html.escape() may generates a hex escaping ``&#x27;`` for single
+ quote ``'``, this wrapper fixes this.
+ """
+ s = html.escape(s, quote)
+ s = s.replace('&#x27;', '&#39;') # re-escape as decimal
+ return s
+
+
class HTMLHelpBuilder(StandaloneHTMLBuilder):
"""
Builder that also outputs Windows HTML help project, contents and
@@ -278,7 +292,7 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
write_toc(subnode, ullevel)
elif isinstance(node, nodes.reference):
link = node['refuri']
- title = html.escape(node.astext()).replace('"', '&quot;')
+ title = chm_htmlescape(node.astext(), True)
f.write(object_sitemap % (title, link))
elif isinstance(node, nodes.bullet_list):
if ullevel != 0:
@@ -305,10 +319,9 @@ class HTMLHelpBuilder(StandaloneHTMLBuilder):
# type: (str, List[Tuple[str, str]], List[Tuple[str, List[Tuple[str, str]]]]) -> None # NOQA
def write_param(name, value):
# type: (str, str) -> None
- item = ' <param name="%s" value="%s">\n' % \
- (name, value)
+ item = ' <param name="%s" value="%s">\n' % (name, value)
f.write(item)
- title = html.escape(title)
+ title = chm_htmlescape(title, True)
f.write('<LI> <OBJECT type="text/sitemap">\n')
write_param('Keyword', title)
if len(refs) == 0:
diff --git a/sphinx/builders/latex/__init__.py b/sphinx/builders/latex/__init__.py
index a69e8f914..2d423a1dd 100644
--- a/sphinx/builders/latex/__init__.py
+++ b/sphinx/builders/latex/__init__.py
@@ -12,7 +12,6 @@ import os
from os import path
from docutils.frontend import OptionParser
-from six import text_type
from sphinx import package_dir, addnodes, highlighting
from sphinx.builders import Builder
@@ -24,7 +23,7 @@ from sphinx.builders.latex.transforms import (
from sphinx.config import ENUM
from sphinx.environment import NoUri
from sphinx.environment.adapters.asset import ImageAdapter
-from sphinx.errors import SphinxError, ConfigError
+from sphinx.errors import SphinxError
from sphinx.locale import _, __
from sphinx.transforms import SphinxTransformer
from sphinx.util import texescape, logging, status_iterator
@@ -413,23 +412,6 @@ class LaTeXBuilder(Builder):
def validate_config_values(app, config):
# type: (Sphinx, Config) -> None
- for document in config.latex_documents:
- try:
- text_type(document[2])
- except UnicodeDecodeError:
- raise ConfigError(
- __('Invalid latex_documents.title found (might contain non-ASCII chars. '
- 'Please use u"..." notation instead): %r') % (document,)
- )
-
- try:
- text_type(document[3])
- except UnicodeDecodeError:
- raise ConfigError(
- __('Invalid latex_documents.author found (might contain non-ASCII chars. '
- 'Please use u"..." notation instead): %r') % (document,)
- )
-
for key in list(config.latex_elements):
if key not in DEFAULT_SETTINGS:
msg = __("Unknown configure key: latex_elements[%r]. ignored.")
diff --git a/sphinx/cmd/build.py b/sphinx/cmd/build.py
index f2efa9638..15c6827ff 100644
--- a/sphinx/cmd/build.py
+++ b/sphinx/cmd/build.py
@@ -16,7 +16,6 @@ import sys
import traceback
from docutils.utils import SystemMessage
-from six import text_type
import sphinx.locale
from sphinx import __display_version__, package_dir
@@ -53,17 +52,17 @@ def handle_exception(app, args, exception, stderr=sys.stderr):
print(terminal_safe(exception.args[0]), file=stderr)
elif isinstance(exception, SphinxError):
print(red('%s:' % exception.category), file=stderr)
- print(terminal_safe(text_type(exception)), file=stderr)
+ print(terminal_safe(str(exception)), file=stderr)
elif isinstance(exception, UnicodeError):
print(red(__('Encoding error:')), file=stderr)
- print(terminal_safe(text_type(exception)), file=stderr)
+ print(terminal_safe(str(exception)), file=stderr)
tbpath = save_traceback(app)
print(red(__('The full traceback has been saved in %s, if you want '
'to report the issue to the developers.') % tbpath),
file=stderr)
elif isinstance(exception, RuntimeError) and 'recursion depth' in str(exception):
print(red(__('Recursion error:')), file=stderr)
- print(terminal_safe(text_type(exception)), file=stderr)
+ print(terminal_safe(str(exception)), file=stderr)
print(file=stderr)
print(__('This can happen with very large or deeply nested source '
'files. You can carefully increase the default Python '
diff --git a/sphinx/cmd/quickstart.py b/sphinx/cmd/quickstart.py
index b3db8900e..d3e41aa54 100644
--- a/sphinx/cmd/quickstart.py
+++ b/sphinx/cmd/quickstart.py
@@ -32,7 +32,6 @@ except ImportError:
USE_LIBEDIT = False
from docutils.utils import column_width
-from six import text_type
import sphinx.locale
from sphinx import __display_version__, package_dir
@@ -158,7 +157,7 @@ def term_decode(text):
warnings.warn('term_decode() is deprecated.',
RemovedInSphinx40Warning, stacklevel=2)
- if isinstance(text, text_type):
+ if isinstance(text, str):
return text
# Use the known encoding, if possible
@@ -391,10 +390,9 @@ def generate(d, overwrite=True, silent=False, templatedir=None):
d['project_underline'] = column_width(d['project']) * '='
d.setdefault('extensions', [])
d['copyright'] = time.strftime('%Y') + ', ' + d['author']
- d['author_texescaped'] = text_type(d['author']).\
- translate(texescape.tex_escape_map)
+ d['author_texescaped'] = d['author'].translate(texescape.tex_escape_map)
d['project_doc'] = d['project'] + ' Documentation'
- d['project_doc_texescaped'] = text_type(d['project'] + ' Documentation').\
+ d['project_doc_texescaped'] = (d['project'] + ' Documentation').\
translate(texescape.tex_escape_map)
# escape backslashes and single quotes in strings that are put into
diff --git a/sphinx/config.py b/sphinx/config.py
index 002b2a559..338de770c 100644
--- a/sphinx/config.py
+++ b/sphinx/config.py
@@ -16,8 +16,6 @@ from collections import OrderedDict
from os import path, getenv
from typing import Any, NamedTuple, Union
-from six import text_type
-
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
from sphinx.errors import ConfigError, ExtensionError
from sphinx.locale import _, __
@@ -41,7 +39,7 @@ copyright_year_re = re.compile(r'^((\d{4}-)?)(\d{4})(?=[ ,])')
ConfigValue = NamedTuple('ConfigValue', [('name', str),
('value', Any),
- ('rebuild', Union[bool, text_type])])
+ ('rebuild', Union[bool, str])])
def is_serializable(obj):
@@ -78,7 +76,7 @@ class ENUM:
# RemovedInSphinx40Warning
-string_classes = [text_type] # type: List
+string_classes = [str] # type: List
class Config:
diff --git a/sphinx/domains/changeset.py b/sphinx/domains/changeset.py
index 21626ba35..4a515d2cc 100644
--- a/sphinx/domains/changeset.py
+++ b/sphinx/domains/changeset.py
@@ -34,6 +34,12 @@ versionlabels = {
'deprecated': _('Deprecated since version %s'),
}
+versionlabel_classes = {
+ 'versionadded': 'added',
+ 'versionchanged': 'changed',
+ 'deprecated': 'deprecated',
+}
+
locale.versionlabels = DeprecatedDict(
versionlabels,
'sphinx.locale.versionlabels is deprecated. '
@@ -78,6 +84,7 @@ class VersionChange(SphinxDirective):
messages = []
if self.content:
self.state.nested_parse(self.content, self.content_offset, node)
+ classes = ['versionmodified', versionlabel_classes[self.name]]
if len(node):
if isinstance(node[0], nodes.paragraph) and node[0].rawsource:
content = nodes.inline(node[0].rawsource, translatable=True)
@@ -87,11 +94,11 @@ class VersionChange(SphinxDirective):
node[0].replace_self(nodes.paragraph('', '', content, translatable=False))
para = cast(nodes.paragraph, node[0])
- para.insert(0, nodes.inline('', '%s: ' % text, classes=['versionmodified']))
+ para.insert(0, nodes.inline('', '%s: ' % text, classes=classes))
else:
para = nodes.paragraph('', '',
nodes.inline('', '%s.' % text,
- classes=['versionmodified']),
+ classes=classes),
translatable=False)
node.append(para)
diff --git a/sphinx/domains/cpp.py b/sphinx/domains/cpp.py
index 70f1208df..51ebe35f1 100644
--- a/sphinx/domains/cpp.py
+++ b/sphinx/domains/cpp.py
@@ -14,7 +14,6 @@ from copy import deepcopy
from docutils import nodes, utils
from docutils.parsers.rst import directives
-from six import text_type
from sphinx import addnodes
from sphinx.deprecation import RemovedInSphinx40Warning
@@ -635,7 +634,7 @@ class ASTBase:
def __str__(self):
# type: () -> str
- return self._stringify(lambda ast: text_type(ast))
+ return self._stringify(lambda ast: str(ast))
def get_display_string(self):
# type: () -> str
@@ -666,7 +665,7 @@ class ASTCPPAttribute(ASTBase):
def describe_signature(self, signode):
# type: (addnodes.desc_signature) -> None
- txt = text_type(self)
+ txt = str(self)
signode.append(nodes.Text(txt, txt))
@@ -705,7 +704,7 @@ class ASTGnuAttributeList(ASTBase):
def describe_signature(self, signode):
# type: (addnodes.desc_signature) -> None
- txt = text_type(self)
+ txt = str(self)
signode.append(nodes.Text(txt, txt))
@@ -739,7 +738,7 @@ class ASTParenAttribute(ASTBase):
def describe_signature(self, signode):
# type: (addnodes.desc_signature) -> None
- txt = text_type(self)
+ txt = str(self)
signode.append(nodes.Text(txt, txt))
@@ -779,7 +778,7 @@ class ASTBooleanLiteral(ASTBase):
return 'L0E'
def describe_signature(self, signode, mode, env, symbol):
- signode.append(nodes.Text(text_type(self)))
+ signode.append(nodes.Text(str(self)))
class ASTNumberLiteral(ASTBase):
@@ -796,7 +795,7 @@ class ASTNumberLiteral(ASTBase):
return "L%sE" % self.data
def describe_signature(self, signode, mode, env, symbol):
- txt = text_type(self)
+ txt = str(self)
signode.append(nodes.Text(txt, txt))
@@ -835,7 +834,7 @@ class ASTCharLiteral(ASTBase):
return self.type + str(self.value)
def describe_signature(self, signode, mode, env, symbol):
- txt = text_type(self)
+ txt = str(self)
signode.append(nodes.Text(txt, txt))
@@ -854,7 +853,7 @@ class ASTStringLiteral(ASTBase):
return "LA%d_KcE" % (len(self.data) - 2)
def describe_signature(self, signode, mode, env, symbol):
- txt = text_type(self)
+ txt = str(self)
signode.append(nodes.Text(txt, txt))
@@ -917,7 +916,7 @@ class ASTFoldExpr(ASTBase):
# type: (int) -> str
assert version >= 3
if version == 3:
- return text_type(self)
+ return str(self)
# TODO: find the right mangling scheme
assert False
@@ -1473,7 +1472,7 @@ class ASTFallbackExpr(ASTBase):
def get_id(self, version):
# type: (int) -> str
- return text_type(self.expr)
+ return str(self.expr)
def describe_signature(self, signode, mode, env, symbol):
signode += nodes.Text(self.expr)
@@ -1511,7 +1510,7 @@ class ASTIdentifier(ASTBase):
if self.is_anon():
return 'Ut%d_%s' % (len(self.identifier) - 1, self.identifier[1:])
else:
- return text_type(len(self.identifier)) + self.identifier
+ return str(len(self.identifier)) + self.identifier
# and this is where we finally make a difference between __str__ and the display string
@@ -1994,7 +1993,7 @@ class ASTOperator(ASTBase):
def describe_signature(self, signode, mode, env, prefix, templateArgs, symbol):
# type: (addnodes.desc_signature, str, Any, str, str, Symbol) -> None
_verify_description_mode(mode)
- identifier = text_type(self)
+ identifier = str(self)
if mode == 'lastIsName':
signode += addnodes.desc_name(identifier, identifier)
else:
@@ -2043,7 +2042,7 @@ class ASTOperatorType(ASTOperator):
def get_name_no_template(self):
# type: () -> str
- return text_type(self)
+ return str(self)
class ASTOperatorLiteral(ASTOperator):
@@ -2078,9 +2077,9 @@ class ASTTemplateArgConstant(ASTBase):
def get_id(self, version):
# type: (int) -> str
if version == 1:
- return text_type(self).replace(' ', '-')
+ return str(self).replace(' ', '-')
if version == 2:
- return 'X' + text_type(self) + 'E'
+ return 'X' + str(self) + 'E'
return 'X' + self.value.get_id(version) + 'E'
def describe_signature(self, signode, mode, env, symbol):
@@ -2155,7 +2154,7 @@ class ASTNestedNameElement(ASTBase):
def describe_signature(self, signode, mode, env, prefix, symbol):
# type: (addnodes.desc_signature, str, BuildEnvironment, str, Symbol) -> None
- tArgs = text_type(self.templateArgs) if self.templateArgs is not None else ''
+ tArgs = str(self.templateArgs) if self.templateArgs is not None else ''
self.identOrOp.describe_signature(signode, mode, env, prefix, tArgs, symbol)
if self.templateArgs is not None:
self.templateArgs.describe_signature(signode, mode, env, symbol)
@@ -2188,7 +2187,7 @@ class ASTNestedName(ASTBase):
def get_id(self, version, modifiers=''):
# type: (int, str) -> str
if version == 1:
- tt = text_type(self)
+ tt = str(self)
if tt in _id_shorthands_v1:
return _id_shorthands_v1[tt]
else:
@@ -2223,9 +2222,9 @@ class ASTNestedName(ASTBase):
_verify_description_mode(mode)
# just print the name part, with template args, not template params
if mode == 'noneIsName':
- signode += nodes.Text(text_type(self))
+ signode += nodes.Text(str(self))
elif mode == 'param':
- name = text_type(self)
+ name = str(self)
signode += nodes.emphasis(name, name)
elif mode == 'markType' or mode == 'lastIsName':
# Each element should be a pending xref targeting the complete
@@ -2258,10 +2257,10 @@ class ASTNestedName(ASTBase):
if template:
dest += nodes.Text("template ")
first = False
- txt_nne = text_type(nne)
+ txt_nne = str(nne)
if txt_nne != '':
if nne.templateArgs and iTemplateParams < len(templateParams):
- templateParamsPrefix += text_type(templateParams[iTemplateParams])
+ templateParamsPrefix += str(templateParams[iTemplateParams])
iTemplateParams += 1
nne.describe_signature(dest, 'markType',
env, templateParamsPrefix + prefix, symbol)
@@ -2306,7 +2305,7 @@ class ASTTrailingTypeSpecFundamental(ASTBase):
def describe_signature(self, signode, mode, env, symbol):
# type: (addnodes.desc_signature, str, BuildEnvironment, Symbol) -> None
- signode += nodes.Text(text_type(self.name))
+ signode += nodes.Text(str(self.name))
class ASTTrailingTypeSpecName(ASTBase):
@@ -2354,7 +2353,7 @@ class ASTTrailingTypeSpecDecltypeAuto(ASTBase):
def describe_signature(self, signode, mode, env, symbol):
# type: (addnodes.desc_signature, str, BuildEnvironment, Symbol) -> None
- signode.append(nodes.Text(text_type(self)))
+ signode.append(nodes.Text(str(self)))
class ASTTrailingTypeSpecDecltype(ASTBase):
@@ -2467,7 +2466,7 @@ class ASTParametersQualifiers(ASTBase):
if not first:
res.append(', ')
first = False
- res.append(text_type(a))
+ res.append(str(a))
res.append(')')
if self.volatile:
res.append(' volatile')
@@ -2478,7 +2477,7 @@ class ASTParametersQualifiers(ASTBase):
res.append(self.refQual)
if self.exceptionSpec:
res.append(' ')
- res.append(text_type(self.exceptionSpec))
+ res.append(str(self.exceptionSpec))
if self.final:
res.append(' final')
if self.override:
@@ -2515,13 +2514,13 @@ class ASTParametersQualifiers(ASTBase):
if self.refQual:
_add_text(signode, self.refQual)
if self.exceptionSpec:
- _add_anno(signode, text_type(self.exceptionSpec))
+ _add_anno(signode, str(self.exceptionSpec))
if self.final:
_add_anno(signode, 'final')
if self.override:
_add_anno(signode, 'override')
if self.initializer:
- _add_text(signode, '= ' + text_type(self.initializer))
+ _add_text(signode, '= ' + str(self.initializer))
class ASTDeclSpecsSimple(ASTBase):
@@ -2653,7 +2652,7 @@ class ASTDeclSpecs(ASTBase):
if len(res) > 0:
res.append(" ")
res.append(transform(self.trailingTypeSpec))
- r = text_type(self.rightSpecs)
+ r = str(self.rightSpecs)
if len(r) > 0:
if len(res) > 0:
res.append(" ")
@@ -2704,7 +2703,7 @@ class ASTArray(ASTBase):
return 'A'
if version == 2:
if self.size:
- return 'A' + text_type(self.size) + '_'
+ return 'A' + str(self.size) + '_'
else:
return 'A_'
if self.size:
@@ -3321,7 +3320,7 @@ class ASTType(ASTBase):
_verify_description_mode(mode)
self.declSpecs.describe_signature(signode, 'markType', env, symbol)
if (self.decl.require_space_after_declSpecs() and
- len(text_type(self.declSpecs)) > 0):
+ len(str(self.declSpecs)) > 0):
signode += nodes.Text(' ')
# for parameters that don't really declare new names we get 'markType',
# this should not be propagated, but be 'noneIsName'.
@@ -3929,8 +3928,8 @@ class Symbol:
param = templateParams.params[i]
arg = templateArgs.args[i]
# TODO: doing this by string manipulation is probably not the most efficient
- paramName = text_type(param.name)
- argTxt = text_type(arg)
+ paramName = str(param.name)
+ argTxt = str(arg)
isArgPackExpansion = argTxt.endswith('...')
if param.isPack != isArgPackExpansion:
return True
@@ -3958,13 +3957,13 @@ class Symbol:
return False
if templateParams:
# TODO: do better comparison
- if text_type(s.templateParams) != text_type(templateParams):
+ if str(s.templateParams) != str(templateParams):
return False
if (s.templateArgs is None) != (templateArgs is None):
return False
if s.templateArgs:
# TODO: do better comparison
- if text_type(s.templateArgs) != text_type(templateArgs):
+ if str(s.templateArgs) != str(templateArgs):
return False
return True
if matchSelf and matches(self):
@@ -4253,7 +4252,7 @@ class Symbol:
if not ourChild.declaration:
ourChild._fill_empty(otherChild.declaration, otherChild.docname)
elif ourChild.docname != otherChild.docname:
- name = text_type(ourChild.declaration)
+ name = str(ourChild.declaration)
msg = __("Duplicate declaration, also defined in '%s'.\n"
"Declaration is '%s'.")
msg = msg % (ourChild.docname, name)
@@ -4401,20 +4400,20 @@ class Symbol:
res.append('::')
else:
if self.templateParams:
- res.append(text_type(self.templateParams))
+ res.append(str(self.templateParams))
res.append('\n')
res.append('\t' * indent)
if self.identOrOp:
- res.append(text_type(self.identOrOp))
+ res.append(str(self.identOrOp))
else:
- res.append(text_type(self.declaration))
+ res.append(str(self.declaration))
if self.templateArgs:
- res.append(text_type(self.templateArgs))
+ res.append(str(self.templateArgs))
if self.declaration:
res.append(": ")
if self.isRedeclaration:
res.append('!!duplicate!! ')
- res.append(text_type(self.declaration))
+ res.append(str(self.declaration))
if self.docname:
res.append('\t(')
res.append(self.docname)
@@ -6151,7 +6150,7 @@ class DefinitionParser:
msg += " Declaration:\n\t"
if templatePrefix:
msg += "%s\n\t" % templatePrefix
- msg += text_type(nestedName)
+ msg += str(nestedName)
self.warn(msg)
newTemplates = []
@@ -6445,7 +6444,7 @@ class CPPObject(ObjectDescription):
parentDecl = parentSymbol.declaration
if parentDecl is not None and parentDecl.objectType == 'function':
self.warn("C++ declarations inside functions are not supported." +
- " Parent function is " + text_type(parentSymbol.get_full_nested_name()))
+ " Parent function is " + str(parentSymbol.get_full_nested_name()))
name = _make_phony_error_name()
symbol = parentSymbol.add_name(name)
env.temp_data['cpp:last_symbol'] = symbol
@@ -6928,7 +6927,7 @@ class CPPDomain(Domain):
templateShorthand=True,
matchSelf=True, recurseInAnon=True)
if s is None or s.declaration is None:
- txtName = text_type(name)
+ txtName = str(name)
if txtName.startswith('std::') or txtName == 'std':
raise NoUri()
return None, None
@@ -7031,7 +7030,7 @@ class CPPDomain(Domain):
continue
assert symbol.docname
fullNestedName = symbol.get_full_nested_name()
- name = text_type(fullNestedName).lstrip(':')
+ name = str(fullNestedName).lstrip(':')
dispname = fullNestedName.get_display_string().lstrip(':')
objectType = symbol.declaration.objectType
docname = symbol.docname
@@ -7050,7 +7049,7 @@ class CPPDomain(Domain):
rootSymbol = self.data['root_symbol']
parentSymbol = rootSymbol.direct_lookup(parentKey)
parentName = parentSymbol.get_full_nested_name()
- return '::'.join([text_type(parentName), target])
+ return '::'.join([str(parentName), target])
def setup(app):
diff --git a/sphinx/environment/adapters/indexentries.py b/sphinx/environment/adapters/indexentries.py
index 772a72715..4ca1c71f6 100644
--- a/sphinx/environment/adapters/indexentries.py
+++ b/sphinx/environment/adapters/indexentries.py
@@ -12,8 +12,6 @@ import re
import unicodedata
from itertools import groupby
-from six import text_type
-
from sphinx.locale import _, __
from sphinx.util import split_into, logging
@@ -44,7 +42,7 @@ class IndexEntries:
# Force the word to be unicode if it's a ASCII bytestring.
# This will solve problems with unicode normalization later.
# For instance the RFC role will add bytestrings at the moment
- word = text_type(word)
+ word = str(word)
entry = dic.get(word)
if not entry:
dic[word] = entry = [[], {}, key]
diff --git a/sphinx/environment/collectors/indexentries.py b/sphinx/environment/collectors/indexentries.py
index 5ab309407..27d2c771b 100644
--- a/sphinx/environment/collectors/indexentries.py
+++ b/sphinx/environment/collectors/indexentries.py
@@ -8,8 +8,6 @@
:license: BSD, see LICENSE for details.
"""
-from six import text_type
-
from sphinx import addnodes
from sphinx.environment.collectors import EnvironmentCollector
from sphinx.util import split_index_msg, logging
@@ -45,7 +43,7 @@ class IndexEntriesCollector(EnvironmentCollector):
for entry in node['entries']:
split_index_msg(entry[0], entry[1])
except ValueError as exc:
- logger.warning(text_type(exc), location=node)
+ logger.warning(str(exc), location=node)
node.parent.remove(node)
else:
for entry in node['entries']:
diff --git a/sphinx/ext/apidoc.py b/sphinx/ext/apidoc.py
index 2bb7384f4..6fe4921ab 100644
--- a/sphinx/ext/apidoc.py
+++ b/sphinx/ext/apidoc.py
@@ -336,7 +336,7 @@ Note: By default this script will not overwrite already created files."""))
dest='includeprivate',
help=__('include "_private" modules'))
parser.add_argument('--tocfile', action='store', dest='tocfile', default='modules',
- help=__("don't create a table of contents file"))
+ help=__("filename of table of contents (default: modules)"))
parser.add_argument('-T', '--no-toc', action='store_false', dest='tocfile',
help=__("don't create a table of contents file"))
parser.add_argument('-E', '--no-headings', action='store_true',
diff --git a/sphinx/ext/autodoc/__init__.py b/sphinx/ext/autodoc/__init__.py
index 900f4a378..ebd3a37b7 100644
--- a/sphinx/ext/autodoc/__init__.py
+++ b/sphinx/ext/autodoc/__init__.py
@@ -12,12 +12,10 @@
import inspect
import re
-import sys
import warnings
from typing import Any
from docutils.statemachine import StringList
-from six import text_type
import sphinx
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
@@ -461,13 +459,7 @@ class Documenter:
def get_sourcename(self):
# type: () -> str
if self.analyzer:
- # prevent encoding errors when the file name is non-ASCII
- if not isinstance(self.analyzer.srcname, text_type):
- filename = text_type(self.analyzer.srcname,
- sys.getfilesystemencoding(), 'replace')
- else:
- filename = self.analyzer.srcname
- return '%s:docstring of %s' % (filename, self.fullname)
+ return '%s:docstring of %s' % (self.analyzer.srcname, self.fullname)
return 'docstring of %s' % self.fullname
def add_content(self, more_content, no_docstring=False):
diff --git a/sphinx/ext/autosummary/__init__.py b/sphinx/ext/autosummary/__init__.py
index b0ffe093c..45e66e911 100644
--- a/sphinx/ext/autosummary/__init__.py
+++ b/sphinx/ext/autosummary/__init__.py
@@ -65,7 +65,6 @@ from docutils import nodes
from docutils.parsers.rst import directives
from docutils.parsers.rst.states import RSTStateMachine, state_classes
from docutils.statemachine import StringList
-from six import text_type
import sphinx
from sphinx import addnodes
@@ -160,8 +159,7 @@ def autosummary_table_visit_html(self, node):
par = cast(nodes.paragraph, col1_entry[0])
for j, subnode in enumerate(list(par)):
if isinstance(subnode, nodes.Text):
- new_text = text_type(subnode.astext())
- new_text = new_text.replace(" ", "\u00a0")
+ new_text = subnode.astext().replace(" ", "\u00a0")
par[j] = nodes.Text(new_text)
except IndexError:
pass
diff --git a/sphinx/ext/imgmath.py b/sphinx/ext/imgmath.py
index d93d3fb50..377da12f1 100644
--- a/sphinx/ext/imgmath.py
+++ b/sphinx/ext/imgmath.py
@@ -17,7 +17,6 @@ from os import path
from subprocess import Popen, PIPE
from docutils import nodes
-from six import text_type
import sphinx
from sphinx.errors import SphinxError
@@ -290,7 +289,7 @@ def html_visit_math(self, node):
try:
fname, depth = render_math(self, '$' + node.astext() + '$')
except MathExtError as exc:
- msg = text_type(exc)
+ msg = str(exc)
sm = nodes.system_message(msg, type='WARNING', level=2,
backrefs=[], source=node.astext())
sm.walkabout(self)
@@ -317,7 +316,7 @@ def html_visit_displaymath(self, node):
try:
fname, depth = render_math(self, latex)
except MathExtError as exc:
- msg = text_type(exc)
+ msg = str(exc)
sm = nodes.system_message(msg, type='WARNING', level=2,
backrefs=[], source=node.astext())
sm.walkabout(self)
diff --git a/sphinx/ext/todo.py b/sphinx/ext/todo.py
index 62fea7df8..1d8f9cb60 100644
--- a/sphinx/ext/todo.py
+++ b/sphinx/ext/todo.py
@@ -173,7 +173,10 @@ def process_todo_nodes(app, doctree, fromdocname):
try:
newnode['refuri'] = app.builder.get_relative_uri(
fromdocname, todo_info['docname'])
- newnode['refuri'] += '#' + todo_info['target']['refid']
+ if 'refid' in todo_info['target']:
+ newnode['refuri'] += '#' + todo_info['target']['refid']
+ else:
+ newnode['refuri'] += '#' + todo_info['target']['ids'][0]
except NoUri:
# ignore if no URI can be determined, e.g. for LaTeX output
pass
diff --git a/sphinx/highlighting.py b/sphinx/highlighting.py
index 12fec930e..5fac63963 100644
--- a/sphinx/highlighting.py
+++ b/sphinx/highlighting.py
@@ -20,7 +20,6 @@ from pygments.lexers import PythonLexer, Python3Lexer, PythonConsoleLexer, \
CLexer, TextLexer, RstLexer
from pygments.styles import get_style_by_name
from pygments.util import ClassNotFound
-from six import text_type
from sphinx.deprecation import RemovedInSphinx30Warning
from sphinx.ext import doctest
@@ -113,7 +112,7 @@ class PygmentsBridge:
def highlight_block(self, source, lang, opts=None, location=None, force=False, **kwargs):
# type: (str, str, Any, Any, bool, Any) -> str
- if not isinstance(source, text_type):
+ if not isinstance(source, str):
source = source.decode()
# find out which lexer to use
diff --git a/sphinx/locale/__init__.py b/sphinx/locale/__init__.py
index 8d4058972..79d601460 100644
--- a/sphinx/locale/__init__.py
+++ b/sphinx/locale/__init__.py
@@ -14,8 +14,6 @@ import warnings
from collections import UserString, defaultdict
from gettext import NullTranslations
-from six import text_type
-
from sphinx.deprecation import RemovedInSphinx30Warning
if False:
@@ -41,7 +39,7 @@ class _TranslationProxy(UserString):
# type: (Callable, str) -> object
if not args:
# not called with "function" and "arguments", but a plain string
- return text_type(func)
+ return str(func)
return object.__new__(cls)
def __getnewargs__(self):
@@ -73,7 +71,7 @@ class _TranslationProxy(UserString):
def __dir__(self):
# type: () -> List[str]
- return dir(text_type)
+ return dir(str)
def __str__(self):
# type: () -> str
@@ -124,7 +122,7 @@ class _TranslationProxy(UserString):
def __repr__(self):
# type: () -> str
try:
- return 'i' + repr(text_type(self.data))
+ return 'i' + repr(str(self.data))
except Exception:
return '<%s broken>' % self.__class__.__name__
diff --git a/sphinx/pycode/parser.py b/sphinx/pycode/parser.py
index ec04aecab..8aa2815d0 100644
--- a/sphinx/pycode/parser.py
+++ b/sphinx/pycode/parser.py
@@ -16,8 +16,6 @@ import tokenize
from token import NAME, NEWLINE, INDENT, DEDENT, NUMBER, OP, STRING
from tokenize import COMMENT, NL
-from six import text_type
-
if False:
# For type annotation
from typing import Any, Dict, IO, List, Tuple # NOQA
@@ -349,7 +347,7 @@ class VariableCommentPicker(ast.NodeVisitor):
targets = get_assign_targets(self.previous)
varnames = get_lvar_names(targets[0], self.get_self())
for varname in varnames:
- if isinstance(node.value.s, text_type):
+ if isinstance(node.value.s, str):
docstring = node.value.s
else:
docstring = node.value.s.decode(self.encoding or 'utf-8')
diff --git a/sphinx/search/__init__.py b/sphinx/search/__init__.py
index 2fd43ca4f..6100fc453 100644
--- a/sphinx/search/__init__.py
+++ b/sphinx/search/__init__.py
@@ -13,8 +13,6 @@ import re
import warnings
from os import path
-from six import text_type
-
from docutils import nodes
from sphinx import addnodes
@@ -351,9 +349,9 @@ class IndexBuilder:
otypes[domainname, type] = typeindex
otype = domain.object_types.get(type)
if otype:
- # use unicode() to fire translation proxies
+ # use str() to fire translation proxies
onames[typeindex] = (domainname, type,
- text_type(domain.get_type_name(otype)))
+ str(domain.get_type_name(otype)))
else:
onames[typeindex] = (domainname, type, type)
if anchor == fullname:
diff --git a/sphinx/templates/quickstart/conf.py_t b/sphinx/templates/quickstart/conf.py_t
index c43b219a3..90f3113ed 100644
--- a/sphinx/templates/quickstart/conf.py_t
+++ b/sphinx/templates/quickstart/conf.py_t
@@ -1,7 +1,7 @@
# Configuration file for the Sphinx documentation builder.
#
-# This file does only contain a selection of the most common options. For a
-# full list see the documentation:
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
# http://www.sphinx-doc.org/en/master/config
# -- Path setup --------------------------------------------------------------
@@ -167,3 +167,4 @@ intersphinx_mapping = {'https://docs.python.org/': None}
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
{%- endif %}
+
diff --git a/sphinx/testing/path.py b/sphinx/testing/path.py
index d80bb0786..9477391b4 100644
--- a/sphinx/testing/path.py
+++ b/sphinx/testing/path.py
@@ -9,8 +9,6 @@ import os
import shutil
import sys
-from six import text_type
-
if False:
# For type annotation
import builtins # NOQA
@@ -20,7 +18,7 @@ if False:
FILESYSTEMENCODING = sys.getfilesystemencoding() or sys.getdefaultencoding()
-class path(text_type):
+class path(str):
"""
Represents a path which behaves like a string.
"""
@@ -222,4 +220,4 @@ class path(text_type):
def __repr__(self):
# type: () -> str
- return '%s(%s)' % (self.__class__.__name__, text_type.__repr__(self))
+ return '%s(%s)' % (self.__class__.__name__, super().__repr__())
diff --git a/sphinx/texinputs/sphinxhowto.cls b/sphinx/texinputs/sphinxhowto.cls
index 64c2feb64..f2572b3b4 100644
--- a/sphinx/texinputs/sphinxhowto.cls
+++ b/sphinx/texinputs/sphinxhowto.cls
@@ -3,7 +3,7 @@
%
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
-\ProvidesClass{sphinxhowto}[2018/09/18 v1.8.1 Document class (Sphinx HOWTO)]
+\ProvidesClass{sphinxhowto}[2018/12/23 v2.0 Document class (Sphinx howto)]
% 'oneside' option overriding the 'twoside' default
\newif\if@oneside
@@ -30,7 +30,7 @@
% Change the title page to look a bit better, and fit in with the fncychap
% ``Bjarne'' style a bit better.
%
-\renewcommand{\maketitle}{%
+\newcommand{\sphinxmaketitle}{%
\noindent\rule{\textwidth}{1pt}\par
\begingroup % for PDF information dictionary
\def\endgraf{ }\def\and{\& }%
@@ -57,15 +57,16 @@
%\gdef\@thanks{}\gdef\@author{}\gdef\@title{}
}
-\newcommand{\sphinxtableofcontents}{
+\newcommand{\sphinxtableofcontents}{%
\begingroup
- \parskip = 0mm
+ \parskip \z@skip
+ \sphinxtableofcontentshook
\tableofcontents
\endgroup
- \rule{\textwidth}{1pt}
- \vspace{12pt}
+ \noindent\rule{\textwidth}{1pt}\par
+ \vspace{12pt}%
}
-
+\newcommand\sphinxtableofcontentshook{}
\pagenumbering{arabic}
% Fix the bibliography environment to add an entry to the Table of
diff --git a/sphinx/texinputs/sphinxmanual.cls b/sphinx/texinputs/sphinxmanual.cls
index ef8ce01a1..eabc1af7b 100644
--- a/sphinx/texinputs/sphinxmanual.cls
+++ b/sphinx/texinputs/sphinxmanual.cls
@@ -3,7 +3,7 @@
%
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
-\ProvidesClass{sphinxmanual}[2018/09/18 v1.8.1 Document class (Sphinx manual)]
+\ProvidesClass{sphinxmanual}[2018/12/23 v2.0 Document class (Sphinx manual)]
% chapters starting at odd pages (overridden by 'openany' document option)
\PassOptionsToClass{openright}{\sphinxdocclass}
@@ -33,9 +33,9 @@
% Change the title page to look a bit better, and fit in with the fncychap
% ``Bjarne'' style a bit better.
%
-\renewcommand{\maketitle}{%
- \let\spx@tempa\relax
- \ifHy@pageanchor\def\spx@tempa{\Hy@pageanchortrue}\fi
+\newcommand{\sphinxmaketitle}{%
+ \let\sphinxrestorepageanchorsetting\relax
+ \ifHy@pageanchor\def\sphinxrestorepageanchorsetting{\Hy@pageanchortrue}\fi
\hypersetup{pageanchor=false}% avoid duplicate destination warnings
\begin{titlepage}%
\let\footnotesize\small
@@ -69,14 +69,17 @@
\setcounter{footnote}{0}%
\let\thanks\relax\let\maketitle\relax
%\gdef\@thanks{}\gdef\@author{}\gdef\@title{}
+ \clearpage
+ \ifdefined\sphinxbackoftitlepage\sphinxbackoftitlepage\fi
\if@openright\cleardoublepage\else\clearpage\fi
- \spx@tempa
+ \sphinxrestorepageanchorsetting
}
\newcommand{\sphinxtableofcontents}{%
\pagenumbering{roman}%
\begingroup
\parskip \z@skip
+ \sphinxtableofcontentshook
\tableofcontents
\endgroup
% before resetting page counter, let's do the right thing.
@@ -87,8 +90,10 @@
% This is needed to get the width of the section # area wide enough in the
% library reference. Doing it here keeps it the same for all the manuals.
%
-\renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.6em}}
-\renewcommand*\l@subsection{\@dottedtocline{2}{4.1em}{3.5em}}
+\newcommand{\sphinxtableofcontentshook}{%
+ \renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.6em}}%
+ \renewcommand*\l@subsection{\@dottedtocline{2}{4.1em}{3.5em}}%
+}
% Fix the bibliography environment to add an entry to the Table of
% Contents.
diff --git a/sphinx/transforms/post_transforms/code.py b/sphinx/transforms/post_transforms/code.py
index a732842c2..610437ac6 100644
--- a/sphinx/transforms/post_transforms/code.py
+++ b/sphinx/transforms/post_transforms/code.py
@@ -13,7 +13,6 @@ from typing import NamedTuple
from docutils import nodes
from pygments.lexers import PythonConsoleLexer, guess_lexer
-from six import text_type
from sphinx import addnodes
from sphinx.ext import doctest
@@ -25,7 +24,7 @@ if False:
from sphinx.application import Sphinx # NOQA
-HighlightSetting = NamedTuple('HighlightSetting', [('language', text_type),
+HighlightSetting = NamedTuple('HighlightSetting', [('language', str),
('lineno_threshold', int)])
diff --git a/sphinx/transforms/post_transforms/images.py b/sphinx/transforms/post_transforms/images.py
index 8f63dbda5..a863a00fa 100644
--- a/sphinx/transforms/post_transforms/images.py
+++ b/sphinx/transforms/post_transforms/images.py
@@ -13,7 +13,6 @@ from hashlib import sha1
from math import ceil
from docutils import nodes
-from six import text_type
from sphinx.locale import __
from sphinx.transforms import SphinxTransform
@@ -118,8 +117,7 @@ class ImageDownloader(BaseImageConverter):
node['uri'] = path
self.app.env.images.add_file(self.env.docname, path)
except Exception as exc:
- logger.warning(__('Could not fetch remote image: %s [%s]') %
- (node['uri'], text_type(exc)))
+ logger.warning(__('Could not fetch remote image: %s [%s]') % (node['uri'], exc))
class DataURIExtractor(BaseImageConverter):
diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py
index 11a2a9327..26d19ac6a 100644
--- a/sphinx/util/__init__.py
+++ b/sphinx/util/__init__.py
@@ -26,7 +26,6 @@ from time import mktime, strptime
from urllib.parse import urlsplit, urlunsplit, quote_plus, parse_qsl, urlencode
from docutils.utils import relative_path
-from six import text_type
from sphinx.deprecation import RemovedInSphinx30Warning, RemovedInSphinx40Warning
from sphinx.errors import PycodeError, SphinxParallelError, ExtensionError
@@ -70,9 +69,7 @@ def path_stabilize(filepath):
# type: (str) -> str
"normalize path separater and unicode string"
newpath = filepath.replace(os.path.sep, SEP)
- if isinstance(newpath, text_type):
- newpath = unicodedata.normalize('NFC', newpath)
- return newpath
+ return unicodedata.normalize('NFC', newpath)
def get_matching_files(dirname, exclude_matchers=()):
@@ -637,9 +634,9 @@ def display_chunk(chunk):
# type: (Any) -> str
if isinstance(chunk, (list, tuple)):
if len(chunk) == 1:
- return text_type(chunk[0])
+ return str(chunk[0])
return '%s .. %s' % (chunk[0], chunk[-1])
- return text_type(chunk)
+ return str(chunk)
def old_status_iterator(iterable, summary, color="darkgreen", stringify_func=display_chunk):
@@ -696,15 +693,12 @@ def rfc1123_to_epoch(rfc1123):
def xmlname_checker():
# type: () -> Pattern
# https://www.w3.org/TR/REC-xml/#NT-Name
- # Only Python 3.3 or newer support character code in regular expression
name_start_chars = [
':', ['A', 'Z'], '_', ['a', 'z'], ['\u00C0', '\u00D6'],
['\u00D8', '\u00F6'], ['\u00F8', '\u02FF'], ['\u0370', '\u037D'],
['\u037F', '\u1FFF'], ['\u200C', '\u200D'], ['\u2070', '\u218F'],
['\u2C00', '\u2FEF'], ['\u3001', '\uD7FF'], ['\uF900', '\uFDCF'],
- ['\uFDF0', '\uFFFD']]
-
- name_start_chars.append(['\U00010000', '\U000EFFFF'])
+ ['\uFDF0', '\uFFFD'], ['\U00010000', '\U000EFFFF']]
name_chars = [
"\\-", "\\.", ['0', '9'], '\u00B7', ['\u0300', '\u036F'],
diff --git a/sphinx/util/images.py b/sphinx/util/images.py
index c74394c81..eaa188496 100644
--- a/sphinx/util/images.py
+++ b/sphinx/util/images.py
@@ -17,7 +17,6 @@ from os import path
from typing import NamedTuple
import imagesize
-from six import text_type
from sphinx.deprecation import RemovedInSphinx30Warning
@@ -42,8 +41,8 @@ mime_suffixes = OrderedDict([
('.svgz', 'image/svg+xml'),
])
-DataURI = NamedTuple('DataURI', [('mimetype', text_type),
- ('charset', text_type),
+DataURI = NamedTuple('DataURI', [('mimetype', str),
+ ('charset', str),
('data', bytes)])
diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py
index 7a0b8c5ba..4973111cf 100644
--- a/sphinx/util/inspect.py
+++ b/sphinx/util/inspect.py
@@ -103,16 +103,12 @@ def getargspec(func):
def isenumclass(x):
# type: (Type) -> bool
"""Check if the object is subclass of enum."""
- if enum is None:
- return False
return inspect.isclass(x) and issubclass(x, enum.Enum)
def isenumattribute(x):
# type: (Any) -> bool
"""Check if the object is attribute of enum."""
- if enum is None:
- return False
return isinstance(x, enum.Enum)
diff --git a/sphinx/util/jsonimpl.py b/sphinx/util/jsonimpl.py
index eb4117f90..8054be0d7 100644
--- a/sphinx/util/jsonimpl.py
+++ b/sphinx/util/jsonimpl.py
@@ -11,8 +11,6 @@
import json
from collections import UserString
-from six import text_type
-
if False:
# For type annotation
from typing import Any, IO # NOQA
@@ -23,7 +21,7 @@ class SphinxJSONEncoder(json.JSONEncoder):
def default(self, obj):
# type: (Any) -> str
if isinstance(obj, UserString):
- return text_type(obj)
+ return str(obj)
return super().default(obj)
diff --git a/sphinx/util/nodes.py b/sphinx/util/nodes.py
index e95313745..ddf78185e 100644
--- a/sphinx/util/nodes.py
+++ b/sphinx/util/nodes.py
@@ -12,7 +12,6 @@ import re
from typing import Any, cast
from docutils import nodes
-from six import text_type
from sphinx import addnodes
from sphinx.locale import __
@@ -115,7 +114,7 @@ def repr_domxml(node, length=80):
try:
text = node.asdom().toxml()
except Exception:
- text = text_type(node)
+ text = str(node)
if length and len(text) > length:
text = text[:length] + '...'
return text
@@ -398,7 +397,7 @@ def inline_all_toctrees(builder, docnameset, docname, tree, colorfunc, traversed
tree = cast(nodes.document, tree.deepcopy())
for toctreenode in tree.traverse(addnodes.toctree):
newnodes = []
- includefiles = map(text_type, toctreenode['includefiles'])
+ includefiles = map(str, toctreenode['includefiles'])
for includefile in includefiles:
if includefile not in traversed:
try:
diff --git a/sphinx/util/pycompat.py b/sphinx/util/pycompat.py
index 0256ce0c2..df310368e 100644
--- a/sphinx/util/pycompat.py
+++ b/sphinx/util/pycompat.py
@@ -14,8 +14,6 @@ from html import escape as htmlescape # NOQA
from io import TextIOWrapper # NOQA
from textwrap import indent # NOQA
-from six import text_type
-
from sphinx.deprecation import RemovedInSphinx40Warning
from sphinx.locale import __
from sphinx.util import logging
@@ -64,7 +62,7 @@ def convert_with_2to3(filepath):
lineno, offset = err.context[1]
# try to match ParseError details with SyntaxError details
raise SyntaxError(err.msg, (filepath, lineno, offset, err.value))
- return text_type(tree)
+ return str(tree)
class UnicodeMixin:
diff --git a/sphinx/util/typing.py b/sphinx/util/typing.py
index cf6c49daf..ecfd61f01 100644
--- a/sphinx/util/typing.py
+++ b/sphinx/util/typing.py
@@ -12,7 +12,6 @@ from typing import Any, Callable, Dict, List, Tuple, Union
from docutils import nodes
from docutils.parsers.rst.states import Inliner
-from six import text_type
# An entry of Directive.option_spec
@@ -22,11 +21,11 @@ DirectiveOption = Callable[[str], Any]
TextlikeNode = Union[nodes.Text, nodes.TextElement]
# common role functions
-RoleFunction = Callable[[text_type, text_type, text_type, int, Inliner, Dict, List[text_type]],
+RoleFunction = Callable[[str, str, str, int, Inliner, Dict, List[str]],
Tuple[List[nodes.Node], List[nodes.system_message]]]
# title getter functions for enumerable nodes (see sphinx.domains.std)
-TitleGetter = Callable[[nodes.Node], text_type]
+TitleGetter = Callable[[nodes.Node], str]
# inventory data on memory
Inventory = Dict[str, Dict[str, Tuple[str, str, str, str]]]
diff --git a/sphinx/writers/html.py b/sphinx/writers/html.py
index f7366767f..014c0272c 100644
--- a/sphinx/writers/html.py
+++ b/sphinx/writers/html.py
@@ -92,7 +92,7 @@ class HTMLTranslator(SphinxTranslator, BaseTranslator):
self.permalink_text = self.config.html_add_permalinks
# support backwards-compatible setting to a bool
if not isinstance(self.permalink_text, str):
- self.permalink_text = self.permalink_text and '\u00B6' or ''
+ self.permalink_text = self.permalink_text and '¶' or ''
self.permalink_text = self.encode(self.permalink_text)
self.secnumber_suffix = self.config.html_secnumber_suffix
self.param_separator = ''
diff --git a/sphinx/writers/html5.py b/sphinx/writers/html5.py
index 2a8380d73..88e95ceff 100644
--- a/sphinx/writers/html5.py
+++ b/sphinx/writers/html5.py
@@ -62,7 +62,7 @@ class HTML5Translator(SphinxTranslator, BaseTranslator):
self.permalink_text = self.config.html_add_permalinks
# support backwards-compatible setting to a bool
if not isinstance(self.permalink_text, str):
- self.permalink_text = self.permalink_text and '\u00B6' or ''
+ self.permalink_text = self.permalink_text and '¶' or ''
self.permalink_text = self.encode(self.permalink_text)
self.secnumber_suffix = self.config.html_secnumber_suffix
self.param_separator = ''
diff --git a/sphinx/writers/latex.py b/sphinx/writers/latex.py
index c7f4388d6..d88a6ab5e 100644
--- a/sphinx/writers/latex.py
+++ b/sphinx/writers/latex.py
@@ -20,7 +20,6 @@ from typing import Iterable, cast
from docutils import nodes, writers
from docutils.writers.latex2e import Babel
-from six import text_type
from sphinx import addnodes
from sphinx import highlighting
@@ -159,7 +158,7 @@ DEFAULT_SETTINGS = {
'releasename': '',
'makeindex': '\\makeindex',
'shorthandoff': '',
- 'maketitle': '\\maketitle',
+ 'maketitle': '\\sphinxmaketitle',
'tableofcontents': '\\sphinxtableofcontents',
'atendofbody': '',
'printindex': '\\printindex',
@@ -759,7 +758,7 @@ class LaTeXTranslator(SphinxTranslator):
def idescape(self, id):
# type: (str) -> str
- return '\\detokenize{%s}' % text_type(id).translate(tex_replace_map).\
+ return '\\detokenize{%s}' % str(id).translate(tex_replace_map).\
encode('ascii', 'backslashreplace').decode('ascii').\
replace('\\', '_')
@@ -780,34 +779,34 @@ class LaTeXTranslator(SphinxTranslator):
figure = self.builder.config.numfig_format['figure'].split('%s', 1)
if len(figure) == 1:
ret.append('\\def\\fnum@figure{%s}\n' %
- text_type(figure[0]).strip().translate(tex_escape_map))
+ str(figure[0]).strip().translate(tex_escape_map))
else:
- definition = text_type(figure[0]).strip().translate(tex_escape_map)
+ definition = str(figure[0]).strip().translate(tex_escape_map)
ret.append(self.babel_renewcommand('\\figurename', definition))
if figure[1]:
ret.append('\\makeatletter\n')
ret.append('\\def\\fnum@figure{\\figurename\\thefigure%s}\n' %
- text_type(figure[1]).strip().translate(tex_escape_map))
+ str(figure[1]).strip().translate(tex_escape_map))
ret.append('\\makeatother\n')
table = self.builder.config.numfig_format['table'].split('%s', 1)
if len(table) == 1:
ret.append('\\def\\fnum@table{%s}\n' %
- text_type(table[0]).strip().translate(tex_escape_map))
+ str(table[0]).strip().translate(tex_escape_map))
else:
- definition = text_type(table[0]).strip().translate(tex_escape_map)
+ definition = str(table[0]).strip().translate(tex_escape_map)
ret.append(self.babel_renewcommand('\\tablename', definition))
if table[1]:
ret.append('\\makeatletter\n')
ret.append('\\def\\fnum@table{\\tablename\\thetable%s}\n' %
- text_type(table[1]).strip().translate(tex_escape_map))
+ str(table[1]).strip().translate(tex_escape_map))
ret.append('\\makeatother\n')
codeblock = self.builder.config.numfig_format['code-block'].split('%s', 1)
if len(codeblock) == 1:
pass # FIXME
else:
- definition = text_type(codeblock[0]).strip().translate(tex_escape_map)
+ definition = str(codeblock[0]).strip().translate(tex_escape_map)
ret.append(self.babel_renewcommand('\\literalblockname', definition))
if codeblock[1]:
pass # FIXME
@@ -824,7 +823,7 @@ class LaTeXTranslator(SphinxTranslator):
if i > 0:
ret.append('\\indexspace\n')
ret.append('\\bigletter{%s}\n' %
- text_type(letter).translate(tex_escape_map))
+ str(letter).translate(tex_escape_map))
for entry in entries:
if not entry[3]:
continue
@@ -2003,7 +2002,7 @@ class LaTeXTranslator(SphinxTranslator):
id = node.get('refuri', '')[1:].replace('#', ':')
title = node.get('title', '%s')
- title = text_type(title).translate(tex_escape_map).replace('\\%s', '%s')
+ title = str(title).translate(tex_escape_map).replace('\\%s', '%s')
if '\\{name\\}' in title or '\\{number\\}' in title:
# new style format (cf. "Fig.%{number}")
title = title.replace('\\{name\\}', '{name}').replace('\\{number\\}', '{number}')
@@ -2451,7 +2450,7 @@ class LaTeXTranslator(SphinxTranslator):
def encode(self, text):
# type: (str) -> str
- text = text_type(text).translate(tex_escape_map)
+ text = str(text).translate(tex_escape_map)
if self.literal_whitespace:
# Insert a blank before the newline, to avoid
# ! LaTeX Error: There's no line here to end.
diff --git a/tests/roots/test-build-htmlhelp/conf.py b/tests/roots/test-build-htmlhelp/conf.py
new file mode 100644
index 000000000..95293e956
--- /dev/null
+++ b/tests/roots/test-build-htmlhelp/conf.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+
+project = 'test'
+master_doc = 'index'
diff --git a/tests/roots/test-build-htmlhelp/index.rst b/tests/roots/test-build-htmlhelp/index.rst
new file mode 100644
index 000000000..641c2467d
--- /dev/null
+++ b/tests/roots/test-build-htmlhelp/index.rst
@@ -0,0 +1,19 @@
+Index markup
+------------
+
+.. index::
+ single: entry
+ pair: entry; pair
+ double: entry; double
+ triple: index; entry; triple
+ keyword: with
+ see: from; to
+ seealso: fromalso; toalso
+
+.. index::
+ !Main, !Other
+ !single: entry; pair
+
+.. index:: triple-quoted string, Unicode Consortium, raw string
+ single: """; string literal
+ single: '''; string literal \ No newline at end of file
diff --git a/tests/roots/test-build-htmlhelp/make.bat b/tests/roots/test-build-htmlhelp/make.bat
new file mode 100644
index 000000000..333fd1439
--- /dev/null
+++ b/tests/roots/test-build-htmlhelp/make.bat
@@ -0,0 +1,64 @@
+@echo off
+setlocal
+
+pushd %~dp0
+
+set this=%~n0
+
+if not defined PYTHON set PYTHON=py
+
+if not defined SPHINXBUILD (
+ %PYTHON% -c "import sphinx" > nul 2> nul
+ if errorlevel 1 (
+ echo Installing sphinx with %PYTHON%
+ %PYTHON% -m pip install sphinx
+ if errorlevel 1 exit /B
+ )
+ set SPHINXBUILD=%PYTHON% -c "import sphinx.cmd.build, sys; sys.exit(sphinx.cmd.build.main())"
+)
+
+rem Search for HHC in likely places
+set HTMLHELP=
+where hhc /q && set HTMLHELP=hhc && goto :skiphhcsearch
+where /R ..\externals hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc"
+if not exist "%HTMLHELP%" where /R "%ProgramFiles(x86)%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc"
+if not exist "%HTMLHELP%" where /R "%ProgramFiles%" hhc > "%TEMP%\hhc.loc" 2> nul && set /P HTMLHELP= < "%TEMP%\hhc.loc" & del "%TEMP%\hhc.loc"
+if not exist "%HTMLHELP%" (
+ echo.
+ echo.The HTML Help Workshop was not found. Set the HTMLHELP variable
+ echo.to the path to hhc.exe or download and install it from
+ echo.http://msdn.microsoft.com/en-us/library/ms669985
+ exit /B 1
+)
+echo hhc.exe path: %HTMLHELP%
+
+if "%BUILDDIR%" EQU "" set BUILDDIR=build
+
+%SPHINXBUILD% >nul 2> nul
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ popd
+ exit /B 1
+)
+
+set SPHINXOPTS=-D html_theme_options.body_max_width=none %SPHINXOPTS%
+
+cmd /S /C "%SPHINXBUILD% %SPHINXOPTS% -bhtmlhelp -dbuild\doctrees . "%BUILDDIR%\htmlhelp"
+
+"%HTMLHELP%" "%BUILDDIR%\htmlhelp\test.hhp"
+rem hhc.exe seems to always exit with code 1, reset to 0 for less than 2
+if not errorlevel 2 cmd /C exit /b 0
+
+echo.
+if errorlevel 1 (
+ echo.Build failed (exit code %ERRORLEVEL%^), check for error messages
+ echo.above. Any output will be found in %BUILDDIR%\%1
+) else (
+ echo.Build succeeded. All output should be in %BUILDDIR%\%1
+)
+
+popd
diff --git a/tests/roots/test-ext-todo/foo.rst b/tests/roots/test-ext-todo/foo.rst
index 269199977..12e9f63c5 100644
--- a/tests/roots/test-ext-todo/foo.rst
+++ b/tests/roots/test-ext-todo/foo.rst
@@ -2,3 +2,9 @@ foo
===
.. todo:: todo in foo
+
+.. py:function:: hello()
+
+ :param bug: #5800
+
+ .. todo:: todo in param field
diff --git a/tests/test_build_htmlhelp.py b/tests/test_build_htmlhelp.py
index 124462aa5..b56d42ee3 100644
--- a/tests/test_build_htmlhelp.py
+++ b/tests/test_build_htmlhelp.py
@@ -8,8 +8,12 @@
:license: BSD, see LICENSE for details.
"""
+import re
+
import pytest
+from sphinx.builders.htmlhelp import chm_htmlescape
+
from sphinx.builders.htmlhelp import default_htmlhelp_basename
from sphinx.config import Config
@@ -29,3 +33,31 @@ def test_default_htmlhelp_basename():
config = Config({'project': 'Sphinx Documentation'})
config.init_values()
assert default_htmlhelp_basename(config) == 'sphinxdoc'
+
+
+@pytest.mark.sphinx('htmlhelp', testroot='build-htmlhelp')
+def test_chm(app):
+ app.build()
+
+ # check .hhk file
+ outname = app.builder.config.htmlhelp_basename
+ hhk_path = str(app.outdir / outname + '.hhk')
+
+ with open(hhk_path, 'rb') as f:
+ data = f.read()
+ m = re.search(br'&#[xX][0-9a-fA-F]+;', data)
+ assert m is None, 'Hex escaping exists in .hhk file: ' + str(m.group(0))
+
+
+def test_chm_htmlescape():
+ assert chm_htmlescape('Hello world') == 'Hello world'
+ assert chm_htmlescape(u'Unicode 文字') == u'Unicode 文字'
+ assert chm_htmlescape('&#x45') == '&amp;#x45'
+
+ assert chm_htmlescape('<Hello> "world"') == '&lt;Hello&gt; &quot;world&quot;'
+ assert chm_htmlescape('<Hello> "world"', True) == '&lt;Hello&gt; &quot;world&quot;'
+ assert chm_htmlescape('<Hello> "world"', False) == '&lt;Hello&gt; "world"'
+
+ assert chm_htmlescape("Hello 'world'") == "Hello &#39;world&#39;"
+ assert chm_htmlescape("Hello 'world'", True) == "Hello &#39;world&#39;"
+ assert chm_htmlescape("Hello 'world'", False) == "Hello 'world'"
diff --git a/tests/test_domain_cpp.py b/tests/test_domain_cpp.py
index ab9cf9be2..6da91df82 100644
--- a/tests/test_domain_cpp.py
+++ b/tests/test_domain_cpp.py
@@ -12,7 +12,6 @@ import re
import sys
import pytest
-from six import text_type
import sphinx.domains.cpp as cppDomain
from sphinx import addnodes
@@ -39,7 +38,7 @@ def check(name, input, idDict, output=None):
if output is None:
output = input
ast = parse(name, input)
- res = text_type(ast)
+ res = str(ast)
if res != output:
print("")
print("Input: ", input)
diff --git a/tests/test_domain_py.py b/tests/test_domain_py.py
index bdb9f5fec..9d24d138e 100644
--- a/tests/test_domain_py.py
+++ b/tests/test_domain_py.py
@@ -11,7 +11,6 @@
import pytest
from docutils import nodes
from mock import Mock
-from six import text_type
from sphinx import addnodes
from sphinx.domains.python import py_sig_re, _pseudo_parse_arglist, PythonDomain
@@ -30,22 +29,22 @@ def parse(sig):
def test_function_signatures():
rv = parse('func(a=1) -> int object')
- assert text_type(rv) == 'a=1'
+ assert rv == 'a=1'
rv = parse('func(a=1, [b=None])')
- assert text_type(rv) == 'a=1, [b=None]'
+ assert rv == 'a=1, [b=None]'
rv = parse('func(a=1[, b=None])')
- assert text_type(rv) == 'a=1, [b=None]'
+ assert rv == 'a=1, [b=None]'
rv = parse("compile(source : string, filename, symbol='file')")
- assert text_type(rv) == "source : string, filename, symbol='file'"
+ assert rv == "source : string, filename, symbol='file'"
rv = parse('func(a=[], [b=None])')
- assert text_type(rv) == 'a=[], [b=None]'
+ assert rv == 'a=[], [b=None]'
rv = parse('func(a=[][, b=None])')
- assert text_type(rv) == 'a=[], [b=None]'
+ assert rv == 'a=[], [b=None]'
@pytest.mark.sphinx('dummy', testroot='domain-py')
diff --git a/tests/test_ext_todo.py b/tests/test_ext_todo.py
index e5aff7598..5e7ade9f6 100644
--- a/tests/test_ext_todo.py
+++ b/tests/test_ext_todo.py
@@ -40,13 +40,19 @@ def test_todo(app, status, warning):
'<p class="last">todo in foo</p>')
assert re.search(html, content, re.S)
+ html = ('<p class="first admonition-title">Todo</p>\n'
+ '<p class="last">todo in param field</p>')
+ assert re.search(html, content, re.S)
+
# check emitted warnings
assert 'WARNING: TODO entry found: todo in foo' in warning.getvalue()
assert 'WARNING: TODO entry found: todo in bar' in warning.getvalue()
# check handled event
- assert len(todos) == 2
- assert set(todo[1].astext() for todo in todos) == set(['todo in foo', 'todo in bar'])
+ assert len(todos) == 3
+ assert set(todo[1].astext() for todo in todos) == {'todo in foo',
+ 'todo in bar',
+ 'todo in param field'}
@pytest.mark.sphinx('html', testroot='ext-todo', freshenv=True,
@@ -81,8 +87,10 @@ def test_todo_not_included(app, status, warning):
assert 'WARNING: TODO entry found: todo in bar' in warning.getvalue()
# check handled event
- assert len(todos) == 2
- assert set(todo[1].astext() for todo in todos) == set(['todo in foo', 'todo in bar'])
+ assert len(todos) == 3
+ assert set(todo[1].astext() for todo in todos) == {'todo in foo',
+ 'todo in bar',
+ 'todo in param field'}
@pytest.mark.sphinx('latex', testroot='ext-todo', freshenv=True,
@@ -105,7 +113,7 @@ def test_todo_valid_link(app, status, warning):
link = r'\{\\hyperref\[\\detokenize\{(.*?foo.*?)}]\{\\sphinxcrossref{' \
r'\\sphinxstyleemphasis{original entry}}}}'
m = re.findall(link, content)
- assert len(m) == 2
+ assert len(m) == 4
target = m[0]
# Look for the targets of this link.
diff --git a/tests/test_intl.py b/tests/test_intl.py
index ee4defa0e..4961d2550 100644
--- a/tests/test_intl.py
+++ b/tests/test_intl.py
@@ -705,20 +705,20 @@ def test_html_versionchanges(app):
return ''
expect1 = (
- """<p><span class="versionmodified">Deprecated since version 1.0: </span>"""
+ """<p><span class="versionmodified deprecated">Deprecated since version 1.0: </span>"""
"""THIS IS THE <em>FIRST</em> PARAGRAPH OF DEPRECATED.</p>\n"""
"""<p>THIS IS THE <em>SECOND</em> PARAGRAPH OF DEPRECATED.</p>\n""")
matched_content = get_content(result, "deprecated")
assert expect1 == matched_content
expect2 = (
- """<p><span class="versionmodified">New in version 1.0: </span>"""
+ """<p><span class="versionmodified added">New in version 1.0: </span>"""
"""THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSIONADDED.</p>\n""")
matched_content = get_content(result, "versionadded")
assert expect2 == matched_content
expect3 = (
- """<p><span class="versionmodified">Changed in version 1.0: </span>"""
+ """<p><span class="versionmodified changed">Changed in version 1.0: </span>"""
"""THIS IS THE <em>FIRST</em> PARAGRAPH OF VERSIONCHANGED.</p>\n""")
matched_content = get_content(result, "versionchanged")
assert expect3 == matched_content
diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py
index f990de857..0085f257e 100644
--- a/tests/test_quickstart.py
+++ b/tests/test_quickstart.py
@@ -12,7 +12,6 @@ import time
from io import StringIO
import pytest
-from six import text_type
from sphinx import application
from sphinx.cmd import quickstart as qs
@@ -35,7 +34,6 @@ def mock_input(answers, needanswer=False):
raise AssertionError('answer for %r missing and no default '
'present' % prompt)
called.add(prompt)
- prompt = text_type(prompt)
for question in answers:
if prompt.startswith(qs.PROMPT_PREFIX + question):
return answers[question]