Skip to content

Commit 784e763

Browse files
authored
Merge pull request #8025 from tk0miya/6698_no-trim-flags
Close #6698: doctest: Add :trim-flags: and :no-trim-flags: options
2 parents fcf63a2 + 059dc10 commit 784e763

6 files changed

Lines changed: 69 additions & 12 deletions

File tree

‎CHANGES‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ Features added
4242
* #7768: i18n: :confval:`figure_language_filename` supports ``docpath`` token
4343
* #5208: linkcheck: Support checks for local links
4444
* #5090: setuptools: Link verbosity to distutils' -v and -q option
45+
* #6698: doctest: Add ``:trim-doctest-flags:`` and ``:no-trim-doctest-flags:``
46+
options to doctest, testcode and testoutput directives
4547
* #7052: add ``:noindexentry:`` to the Python, C, C++, and Javascript domains.
4648
Update the documentation to better reflect the relationship between this option
4749
and the ``:noindex:`` option.

‎doc/usage/extensions/doctest.rst‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ a comma-separated list of group names.
6767
default set of flags is specified by the :confval:`doctest_default_flags`
6868
configuration variable.
6969

70-
This directive supports three options:
70+
This directive supports five options:
7171

7272
* ``hide``, a flag option, hides the doctest block in other builders. By
7373
default it is shown as a highlighted doctest block.
@@ -102,6 +102,11 @@ a comma-separated list of group names.
102102

103103
Supported PEP-440 operands and notations
104104

105+
* ``trim-doctest-flags`` and ``no-trim-doctest-flags``, a flag option,
106+
doctest flags (comments looking like ``# doctest: FLAG, ...``) at the
107+
ends of lines and ``<BLANKLINE>`` markers are removed (or not removed)
108+
individually. Default is ``trim-doctest-flags``.
109+
105110
Note that like with standard doctests, you have to use ``<BLANKLINE>`` to
106111
signal a blank line in the expected output. The ``<BLANKLINE>`` is removed
107112
when building presentation output (HTML, LaTeX etc.).
@@ -119,11 +124,16 @@ a comma-separated list of group names.
119124
120125
A code block for a code-output-style test.
121126

122-
This directive supports one option:
127+
This directive supports three options:
123128

124129
* ``hide``, a flag option, hides the code block in other builders. By
125130
default it is shown as a highlighted code block.
126131

132+
* ``trim-doctest-flags`` and ``no-trim-doctest-flags``, a flag option,
133+
doctest flags (comments looking like ``# doctest: FLAG, ...``) at the
134+
ends of lines and ``<BLANKLINE>`` markers are removed (or not removed)
135+
individually. Default is ``trim-doctest-flags``.
136+
127137
.. note::
128138

129139
Code in a ``testcode`` block is always executed all at once, no matter how
@@ -149,14 +159,19 @@ a comma-separated list of group names.
149159
The corresponding output, or the exception message, for the last
150160
:rst:dir:`testcode` block.
151161

152-
This directive supports two options:
162+
This directive supports four options:
153163

154164
* ``hide``, a flag option, hides the output block in other builders. By
155165
default it is shown as a literal block without highlighting.
156166

157167
* ``options``, a string option, can be used to give doctest flags
158168
(comma-separated) just like in normal doctest blocks.
159169

170+
* ``trim-doctest-flags`` and ``no-trim-doctest-flags``, a flag option,
171+
doctest flags (comments looking like ``# doctest: FLAG, ...``) at the
172+
ends of lines and ``<BLANKLINE>`` markers are removed (or not removed)
173+
individually. Default is ``trim-doctest-flags``.
174+
160175
Example::
161176

162177
.. testcode::

‎sphinx/ext/doctest.py‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def run(self) -> List[Node]:
9191
# convert <BLANKLINE>s to ordinary blank lines for presentation
9292
test = code
9393
code = blankline_re.sub('', code)
94-
if doctestopt_re.search(code):
94+
if doctestopt_re.search(code) and 'no-trim-doctest-flags' not in self.options:
9595
if not test:
9696
test = code
9797
code = doctestopt_re.sub('', code)
@@ -151,6 +151,10 @@ def run(self) -> List[Node]:
151151
line=self.lineno)
152152
if 'skipif' in self.options:
153153
node['skipif'] = self.options['skipif']
154+
if 'trim-doctest-flags' in self.options:
155+
node['trim_flags'] = True
156+
elif 'no-trim-doctest-flags' in self.options:
157+
node['trim_flags'] = False
154158
return [node]
155159

156160

@@ -165,26 +169,32 @@ class TestcleanupDirective(TestDirective):
165169
class DoctestDirective(TestDirective):
166170
option_spec = {
167171
'hide': directives.flag,
172+
'no-trim-doctest-flags': directives.flag,
168173
'options': directives.unchanged,
169174
'pyversion': directives.unchanged_required,
170175
'skipif': directives.unchanged_required,
176+
'trim-doctest-flags': directives.flag,
171177
}
172178

173179

174180
class TestcodeDirective(TestDirective):
175181
option_spec = {
176182
'hide': directives.flag,
183+
'no-trim-doctest-flags': directives.flag,
177184
'pyversion': directives.unchanged_required,
178185
'skipif': directives.unchanged_required,
186+
'trim-doctest-flags': directives.flag,
179187
}
180188

181189

182190
class TestoutputDirective(TestDirective):
183191
option_spec = {
184192
'hide': directives.flag,
193+
'no-trim-doctest-flags': directives.flag,
185194
'options': directives.unchanged,
186195
'pyversion': directives.unchanged_required,
187196
'skipif': directives.unchanged_required,
197+
'trim-doctest-flags': directives.flag,
188198
}
189199

190200

‎sphinx/transforms/post_transforms/code.py‎

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
"""
1010

1111
import sys
12-
from typing import Any, Dict, List, NamedTuple, Union
12+
from typing import Any, Dict, List, NamedTuple
1313

1414
from docutils import nodes
15-
from docutils.nodes import Node
15+
from docutils.nodes import Node, TextElement
1616
from pygments.lexers import PythonConsoleLexer, guess_lexer
1717

1818
from sphinx import addnodes
@@ -93,18 +93,17 @@ class TrimDoctestFlagsTransform(SphinxTransform):
9393
default_priority = HighlightLanguageTransform.default_priority + 1
9494

9595
def apply(self, **kwargs: Any) -> None:
96-
if not self.config.trim_doctest_flags:
97-
return
98-
9996
for lbnode in self.document.traverse(nodes.literal_block): # type: nodes.literal_block
10097
if self.is_pyconsole(lbnode):
10198
self.strip_doctest_flags(lbnode)
10299

103100
for dbnode in self.document.traverse(nodes.doctest_block): # type: nodes.doctest_block
104101
self.strip_doctest_flags(dbnode)
105102

106-
@staticmethod
107-
def strip_doctest_flags(node: Union[nodes.literal_block, nodes.doctest_block]) -> None:
103+
def strip_doctest_flags(self, node: TextElement) -> None:
104+
if not node.get('trim_flags', self.config.trim_doctest_flags):
105+
return
106+
108107
source = node.rawsource
109108
source = doctest.blankline_re.sub('', source)
110109
source = doctest.doctestopt_re.sub('', source)

‎tests/roots/test-trim_doctest_flags/index.rst‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,19 @@ test-trim_doctest_flags
2222
>>> datetime.date.now() # doctest: +QUX
2323
datetime.date(2008, 1, 1)
2424

25-
.. doctest_block::
25+
.. doctest::
2626

2727
>>> datetime.date.now() # doctest: +QUUX
2828
datetime.date(2008, 1, 1)
29+
30+
.. doctest::
31+
:trim-doctest-flags:
32+
33+
>>> datetime.date.now() # doctest: +CORGE
34+
datetime.date(2008, 1, 1)
35+
36+
.. doctest::
37+
:no-trim-doctest-flags:
38+
39+
>>> datetime.date.now() # doctest: +GRAULT
40+
datetime.date(2008, 1, 1)

‎tests/test_transforms_post_transforms_code.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,23 @@ def test_trim_doctest_flags_html(app, status, warning):
1919
assert 'BAZ' not in result
2020
assert 'QUX' not in result
2121
assert 'QUUX' not in result
22+
assert 'CORGE' not in result
23+
assert 'GRAULT' in result
24+
25+
26+
@pytest.mark.sphinx('html', testroot='trim_doctest_flags',
27+
confoverrides={'trim_doctest_flags': False})
28+
def test_trim_doctest_flags_disabled(app, status, warning):
29+
app.build()
30+
31+
result = (app.outdir / 'index.html').read_text()
32+
assert 'FOO' in result
33+
assert 'BAR' in result
34+
assert 'BAZ' in result
35+
assert 'QUX' in result
36+
assert 'QUUX' not in result
37+
assert 'CORGE' not in result
38+
assert 'GRAULT' in result
2239

2340

2441
@pytest.mark.sphinx('latex', testroot='trim_doctest_flags')
@@ -31,3 +48,5 @@ def test_trim_doctest_flags_latex(app, status, warning):
3148
assert 'BAZ' not in result
3249
assert 'QUX' not in result
3350
assert 'QUUX' not in result
51+
assert 'CORGE' not in result
52+
assert 'GRAULT' in result

0 commit comments

Comments
 (0)