1. Georg Brandl
  2. sphinx


georg.brandl  committed 7059229

* Add docs for sphinx.ext.doctest.
* Update parse_node functions.

  • Participants
  • Parent commits 17af190
  • Branches default

Comments (0)

Files changed (5)

File doc/Makefile

View file
 	@echo "Link check complete; look for any errors in the above output " \
 	      "or in .build/linkcheck/output.txt."
+	mkdir -p .build/doctest .build/doctrees
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) .build/doctest

File doc/conf.py

View file
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.addons.*') or your custom ones.
-extensions = ['ext', 'sphinx.ext.autodoc']
+extensions = ['ext', 'sphinx.ext.autodoc', 'sphinx.ext.doctest']
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['.templates']

File doc/ext.py

View file
 dir_sig_re = re.compile(r'\.\. ([^:]+)::(.*)$')
-def parse_directive(sig, signode):
+def parse_directive(env, sig, signode):
     if not sig.startswith('.'):
         sig = '.. %s::' % sig
         signode += addnodes.desc_name(sig, sig)
-        return
+        return sig
     m = dir_sig_re.match(sig)
     if not m:
         signode += addnodes.desc_name(sig, sig)
-        return
+        return sig
     name, args = m.groups()
-    name = '.. %s::' % name
-    signode += addnodes.desc_name(name, name)
+    dec_name = '.. %s::' % name
+    signode += addnodes.desc_name(dec_name, dec_name)
     signode += addnodes.desc_classname(args, args)
+    return name
-def parse_role(sig, signode):
+def parse_role(env, sig, signode):
     signode += addnodes.desc_name(':%s:' % sig, ':%s:' % sig)
+    return sig
 def setup(app):

File doc/ext/appapi.rst

View file
 application object representing the Sphinx process.  This application object has
 the following public API:
-.. method:: Application.add_builder(builder)
+.. method:: Sphinx.add_builder(builder)
    Register a new builder.  *builder* must be a class that inherits from
-.. method:: Application.add_config_value(name, default, rebuild_env)
+.. method:: Sphinx.add_config_value(name, default, rebuild_env)
    Register a configuration value.  This is necessary for Sphinx to recognize
    new values and set default values accordingly.  The *name* should be prefixed
    in the setting only takes effect when a document is parsed -- this means that
    the whole environment must be rebuilt.
-.. method:: Application.add_event(name)
+.. method:: Sphinx.add_event(name)
    Register an event called *name*.
-.. method:: Application.add_node(node)
+.. method:: Sphinx.add_node(node)
    Register a Docutils node class.  This is necessary for Docutils internals.
    It may also be used in the future to validate nodes in the parsed documents.
-.. method:: Application.add_directive(name, cls, content, arguments, **options)
+.. method:: Sphinx.add_directive(name, cls, content, arguments, **options)
    Register a Docutils directive.  *name* must be the prospective directive
    name, *func* the directive function for details about the signature and
    .. XXX once we target docutils 0.5, update this
-.. method:: Application.add_role(name, role)
+.. method:: Sphinx.add_role(name, role)
    Register a Docutils role.  *name* must be the role name that occurs in the
    source, *role* the role function (see the `Docutils documentation
    <http://docutils.sourceforge.net/docs/howto/rst-roles.html>`_ on details).
-.. method:: Application.add_description_unit(directivename, rolename, indexdesc='', parse_node=None)
+.. method:: Sphinx.add_description_unit(directivename, rolename, indexdesc='', parse_node=None)
    This method is a very convenient way to add a new type of information that
    can be cross-referenced.  It will do this:
      description units.
    * If you provide *parse_node*, it must be a function that takes a string and
      a docutils node, and it must populate the node with children parsed from
-     the string.  See the :file:`ext.py` file in the source for this
-     documentation for details.
+     the string.  It must then return the name of the item to be used in
+     cross-referencing and index entries.  See the :file:`ext.py` file in the
+     source for this documentation for an example.
    For example, if you have this call in a custom Sphinx extension::
    For the role content, you have the same options as for standard Sphinx roles
    (see :ref:`xref-syntax`).
-.. method:: Application.connect(event, callback)
+.. method:: Sphinx.connect(event, callback)
    Register *callback* to be called when *event* is emitted.  For details on
    available core events and the arguments of callback functions, please see
    The method returns a "listener ID" that can be used as an argument to
-.. method:: Application.disconnect(listener_id)
+.. method:: Sphinx.disconnect(listener_id)
    Unregister callback *listener_id*.
-.. method:: Application.emit(event, *arguments)
+.. method:: Sphinx.emit(event, *arguments)
    Emit *event* and pass *arguments* to the callback functions.  Do not emit
    core Sphinx events in extensions!

File doc/ext/doctest.rst

View file
+.. highlight:: rest
 :mod:`sphinx.ext.doctest` -- Test snippets in the documentation
 .. module:: sphinx.ext.doctest
    :synopsis: Test snippets in the documentation.
+.. index:: pair: automatic; testing
+           single: doctest
+           pair: testing; snippets
+This extension allows you to test snippets in the documentation in a natural
+way.  It works by collecting specially-marked up code blocks and running them as
+doctest tests.
+Within one document, test code is partitioned in *groups*, where each group
+consists of:
+* zero or more *setup code* blocks (e.g. importing the module to test)
+* one or more *test* blocks
+When building the docs with the ``doctest`` builder, groups are collected for
+each document and run one after the other, first executing setup code blocks,
+then the test blocks in the order they appear in the file.
+There are two kinds of test blocks:
+* *doctest-style* blocks mimic interactive sessions by interleaving Python code
+  (including the interpreter prompt) and output.
+* *code-output-style* blocks consist of an ordinary piece of Python code, and
+  optionally, a piece of output for that code.
+The doctest extension provides four directives.  The *group* argument is
+interpreted as follows: if it is empty, the block is assigned to the group named
+``default``.  If it is ``*``, the block is assigned to all groups (including the
+``default`` group).  Otherwise, it must be a comma-separated list of group
+.. directive:: .. testsetup:: [group]
+   A setup code block.  This code is not shown in the output for other builders,
+   but executed before the doctests of the group(s) it belongs to.
+.. directive:: .. doctest:: [group]
+   A doctest-style code block.  You can use standard :mod:`doctest` flags for
+   controlling how actual output is compared with what you give as output.  By
+   default, these options are enabled: ``ELLIPSIS`` (allowing you to put
+   ellipses in the expected output that match anything in the actual output),
+   ``IGNORE_EXCEPTION_DETAIL`` (not comparing tracebacks),
+   ``DONT_ACCEPT_TRUE_FOR_1`` (by default, doctest accepts "True" in the output
+   where "1" is given -- this is a relic of pre-Python 2.2 times).
+.. directive:: .. testcode:: [group]
+   A code block for a code-output-style test.
+.. directive:: .. testoutput:: [group]
+   The corresponding output for the last :dir:`testcode` block.
+   This directive supports two options:
+   * ``hide``, a flag option, hides the output block in other builders.  By
+     default it is shown as a literal block without highlighting.
+   * ``options``, a string option, can be used to give doctest flags
+     (comma-separated) just like in normal doctest blocks.
+   Example::
+      .. testoutput::
+         :hide:
+         Output text.
+The following is an example for the usage of the directives.  The test via
+:dir:`doctest` and the test via :dir:`testcode` and :dir:`testoutput` are
+completely equivalent. ::
+   The parrot module
+   =================
+   .. testsetup:: *
+      import parrot
+   The parrot module is a module about parrots.
+   Doctest example:
+   .. doctest::
+      >>> parrot.voom(3000)
+      This parrot wouldn't voom if you put 3000 volts through it!
+   Test-Output example:
+   .. testcode:: 
+      parrot.voom(3000)
+   This would output:
+   .. testoutput::
+      This parrot wouldn't voom if you put 3000 volts through it!
+There are also these config values for customizing the doctest extension:
+.. confval:: doctest_path
+   A list of directories that will be added to :data:`sys.path` when the doctest
+   builder is used.  (Make sure it contains absolute paths.)
+.. confval:: doctest_test_doctest_blocks
+   If ``True`` (the default), standard reST doctest blocks will be tested too.
+   They will be assigned to a group named ``doctest_block``.
+   reST doctest blocks are simply doctests put into a paragraph of their own,
+   like so::
+      Some documentation text.
+      >>> print 1
+      1
+      Some more documentation text.
+   If this value is true, the above snippet is interpreted by the doctest
+   builder exactly like the following::
+      Some documentation text.
+      .. doctest:: doctest_block
+         >>> print 1
+         1
+      Some more documentation text.      
+   This feature makes it easy for you to test doctests in docstrings included
+   with the :mod:`~sphinx.ext.autodoc` extension without marking them up with a
+   special directive.