Fix #6068: doctest: `skipif` option may remove the code block from documentation

This commit is contained in:
Takeshi KOMIYA 2019-02-28 01:05:37 +09:00
parent 6f973d410b
commit 0377adb82e
2 changed files with 20 additions and 10 deletions

View File

@ -22,6 +22,7 @@ Bugs fixed
* #6019: imgconverter: Including multipage PDF fails * #6019: imgconverter: Including multipage PDF fails
* #6047: autodoc: ``autofunction`` emits a warning for method objects * #6047: autodoc: ``autofunction`` emits a warning for method objects
* #6028: graphviz: Ensure the graphviz filenames are reproducible * #6028: graphviz: Ensure the graphviz filenames are reproducible
* #6068: doctest: ``skipif`` option may remove the code block from documentation
Testing Testing
-------- --------

View File

@ -90,16 +90,6 @@ class TestDirective(SphinxDirective):
def run(self): def run(self):
# type: () -> List[nodes.Node] # type: () -> List[nodes.Node]
if 'skipif' in self.options:
condition = self.options['skipif']
context = {} # type: Dict[str, Any]
if self.config.doctest_global_setup:
exec(self.config.doctest_global_setup, context)
should_skip = eval(condition, context)
if self.config.doctest_global_cleanup:
exec(self.config.doctest_global_cleanup, context)
if should_skip:
return []
# use ordinary docutils nodes for test code: they get special attributes # use ordinary docutils nodes for test code: they get special attributes
# so that our builder recognizes them, and the other builders are happy. # so that our builder recognizes them, and the other builders are happy.
code = '\n'.join(self.content) code = '\n'.join(self.content)
@ -161,6 +151,8 @@ class TestDirective(SphinxDirective):
self.state.document.reporter.warning( self.state.document.reporter.warning(
__("'%s' is not a valid pyversion option") % spec, __("'%s' is not a valid pyversion option") % spec,
line=self.lineno) line=self.lineno)
if 'skipif' in self.options:
node['skipif'] = self.options['skipif']
return [node] return [node]
@ -411,6 +403,20 @@ Doctest summary
return node.line - 1 return node.line - 1
return None return None
def skipped(self, node):
# type: (nodes.Element) -> bool
if 'skipif' not in node:
return False
else:
condition = node['skipif']
context = {} # type: Dict[str, Any]
if self.config.doctest_global_setup:
exec(self.config.doctest_global_setup, context)
should_skip = eval(condition, context)
if self.config.doctest_global_cleanup:
exec(self.config.doctest_global_cleanup, context)
return should_skip
def test_doc(self, docname, doctree): def test_doc(self, docname, doctree):
# type: (unicode, nodes.Node) -> None # type: (unicode, nodes.Node) -> None
groups = {} # type: Dict[unicode, TestGroup] groups = {} # type: Dict[unicode, TestGroup]
@ -437,6 +443,9 @@ Doctest summary
return isinstance(node, (nodes.literal_block, nodes.comment)) \ return isinstance(node, (nodes.literal_block, nodes.comment)) \
and 'testnodetype' in node and 'testnodetype' in node
for node in doctree.traverse(condition): for node in doctree.traverse(condition):
if self.skipped(node):
continue
source = node['test'] if 'test' in node else node.astext() source = node['test'] if 'test' in node else node.astext()
filename = self.get_filename_for_node(node, docname) filename = self.get_filename_for_node(node, docname)
line_number = self.get_line_number(node) line_number = self.get_line_number(node)