Skip to content

Commit d620c96

Browse files
authored
Merge pull request #280 from bsipocz/doctest-requires-all
ENH: adding doctest-requires-all directive
2 parents 81fe4fd + 74cebb8 commit d620c96

File tree

5 files changed

+44
-1
lines changed

5 files changed

+44
-1
lines changed

CHANGES.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33

44
- Fixing compatibility with pytest-asyncio. [#278]
55

6+
- Adding new directive ``doctest-requires-all`` to conditionally skip all
7+
doctests in narrative documentations based on availability of
8+
dependencies. [#280]
9+
610
- Versions of Python <3.9 are no longer supported. [#274]
711

812
1.3.0 (2024-11-25)

README.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,9 @@ the package's ``setup.cfg`` file. The syntax for this option is a list of
336336

337337
Multiple requirements can be specified if separated by semicolons.
338338

339+
It is also possible to conditionally skip all the doctests in a narrative
340+
documentation with ``doctest-requires-all``.
341+
339342
Remote Data
340343
~~~~~~~~~~~
341344

pytest_doctestplus/plugin.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ class DocTestParserPlus(doctest.DocTestParser):
389389
doctest chunk if the given modules/packages are not
390390
installed.
391391
392+
- ``.. doctest-requires-all:: module1, module2``: Skip all subsequent
393+
doctest chunks if the given modules/packages are not
394+
installed.
395+
392396
- ``.. doctest-skip-all``: Skip all subsequent doctests.
393397
394398
- ``.. doctest-remote-data::``: Skip the next doctest chunk if
@@ -422,10 +426,18 @@ def parse(self, s, name=None):
422426

423427
if isinstance(entry, str) and entry:
424428
required = []
429+
required_all = []
425430
skip_next = False
426431
lines = entry.strip().splitlines()
432+
requires_all_match = [re.match(
433+
fr'{comment_char}\s+doctest-requires-all\s*::\s+(.*)', x) for x in lines]
434+
if any(requires_all_match):
435+
required_all = [re.split(r'\s*[,\s]\s*', match.group(1)) for match in requires_all_match if match][0]
436+
437+
required_modules_all = DocTestFinderPlus.check_required_modules(required_all)
438+
427439
if any(re.match(
428-
f'{comment_char} doctest-skip-all', x.strip()) for x in lines):
440+
f'{comment_char} doctest-skip-all', x.strip()) for x in lines) or not required_modules_all:
429441
skip_all = True
430442
continue
431443

pytest_doctestplus/sphinx/doctestplus.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class DoctestRequiresDirective(DoctestSkipDirective):
4343
def setup(app):
4444

4545
app.add_directive('doctest-requires', DoctestRequiresDirective)
46+
app.add_directive('doctest-requires-all', DoctestRequiresDirective)
4647
app.add_directive('doctest-skip', DoctestSkipDirective)
4748
app.add_directive('doctest-skip-all', DoctestSkipDirective)
4849
app.add_directive('doctest', DoctestSkipDirective, override=True)

tests/test_doctestplus.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,29 @@ def test_requires(testdir):
435435
testdir.inline_run(p, '--doctest-plus', '--doctest-rst').assertoutcome(skipped=1)
436436

437437

438+
def test_requires_all(testdir):
439+
testdir.makeini(
440+
"""
441+
[pytest]
442+
doctestplus = enabled
443+
""")
444+
445+
# should be ignored
446+
p = testdir.makefile(
447+
'.rst',
448+
"""
449+
.. doctest-requires-all:: foobar
450+
451+
>>> import foobar
452+
453+
This is a narrative line, before another doctest snippet
454+
455+
>>> import foobar
456+
"""
457+
)
458+
testdir.inline_run(p, '--doctest-plus', '--doctest-rst').assertoutcome(skipped=1)
459+
460+
438461
def test_ignore_warnings_module(testdir):
439462

440463
# First check that we get a warning if we don't add the IGNORE_WARNINGS

0 commit comments

Comments
 (0)