Skip to content

Commit 5e1a479

Browse files
authored
Merge pull request #281 from bsipocz/doctest-remote-data-all
ENH: adding doctest-remote-data-all directive
2 parents d620c96 + a7213fb commit 5e1a479

File tree

5 files changed

+73
-4
lines changed

5 files changed

+73
-4
lines changed

CHANGES.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
doctests in narrative documentations based on availability of
88
dependencies. [#280]
99

10+
- Adding new directive ``doctest-remote-data-all`` to conditionally skip all
11+
doctests in narrative documentations based on availability of
12+
remote-data. [#281]
13+
1014
- Versions of Python <3.9 are no longer supported. [#274]
1115

1216
1.3.0 (2024-11-25)

pytest_doctestplus/plugin.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,9 @@ class DocTestParserPlus(doctest.DocTestParser):
397397
398398
- ``.. doctest-remote-data::``: Skip the next doctest chunk if
399399
--remote-data is not passed.
400+
401+
- ``.. doctest-remote-data-all::``: Skip all subsequent doctest
402+
chunks if --remote-data is not passed.
400403
"""
401404

402405
def parse(self, s, name=None):
@@ -429,15 +432,24 @@ def parse(self, s, name=None):
429432
required_all = []
430433
skip_next = False
431434
lines = entry.strip().splitlines()
435+
432436
requires_all_match = [re.match(
433437
fr'{comment_char}\s+doctest-requires-all\s*::\s+(.*)', x) for x in lines]
434438
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-
439+
required_all = [re.split(r'\s*[,\s]\s*', match.group(1))
440+
for match in requires_all_match if match][0]
437441
required_modules_all = DocTestFinderPlus.check_required_modules(required_all)
442+
if not required_modules_all:
443+
skip_all = True
444+
continue
445+
446+
if config.getoption('remote_data', 'none') != 'any':
447+
if any(re.match(fr'{comment_char}\s+doctest-remote-data-all\s*::', x.strip())
448+
for x in lines):
449+
skip_all = True
450+
continue
438451

439-
if any(re.match(
440-
f'{comment_char} doctest-skip-all', x.strip()) for x in lines) or not required_modules_all:
452+
if any(re.match(f'{comment_char} doctest-skip-all', x.strip()) for x in lines):
441453
skip_all = True
442454
continue
443455

pytest_doctestplus/sphinx/doctestplus.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def setup(app):
4848
app.add_directive('doctest-skip-all', DoctestSkipDirective)
4949
app.add_directive('doctest', DoctestSkipDirective, override=True)
5050
app.add_directive('doctest-remote-data', DoctestSkipDirective)
51+
app.add_directive('doctest-remote-data-all', DoctestSkipDirective)
5152
# Code blocks that use this directive will not appear in the generated
5253
# documentation. This is intended to hide boilerplate code that is only
5354
# useful for testing documentation using doctest, but does not actually

tests/docs/skip_some_remote_data.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,20 @@ This should be skipped otherwise the test should fail::
7878
3
7979
>>> import warnings
8080
>>> warnings.warn('A warning occurred', UserWarning) # doctest: +IGNORE_WARNINGS
81+
82+
83+
Remote data all followed by code cell
84+
=====================================
85+
86+
This codeblock should fail, but is skipped:
87+
88+
.. doctest-remote-data-all::
89+
90+
>>> 1 + 1
91+
3
92+
93+
The this following block should be executed with the simple remote data, but
94+
should be skipped with the all version.
95+
96+
>>> 1 + 2
97+
5

tests/test_doctestplus.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,41 @@ def test_doctest_skip(testdir):
940940
testdir.inline_run(p, '--doctest-plus', '--doctest-rst').assertoutcome(skipped=1)
941941

942942

943+
def test_remote_data_all(testdir):
944+
testdir.makeini(
945+
"""
946+
[pytest]
947+
doctestplus = enabled
948+
""")
949+
950+
p = testdir.makefile(
951+
'.rst',
952+
"""
953+
This is a narrative docs, which some of the lines requiring remote-data access.
954+
The first code block always passes, the second is skipped without remote data and the
955+
last section is skipped due to the all option.
956+
957+
>>> print("Test")
958+
Test
959+
960+
.. doctest-remote-data-all::
961+
962+
>>> from contextlib import closing
963+
>>> from urllib.request import urlopen
964+
>>> with closing(urlopen('https://www.astropy.org')) as remote:
965+
... remote.read() # doctest: +IGNORE_OUTPUT
966+
967+
Narrative before a codeblock that should fail normally but with the all option in the
968+
directive it is skipped over thus producing a passing status.
969+
970+
>>> print(123)
971+
"""
972+
)
973+
974+
testdir.inline_run(p, '--doctest-plus', '--doctest-rst', '--remote-data').assertoutcome(failed=1)
975+
testdir.inline_run(p, '--doctest-plus', '--doctest-rst').assertoutcome(passed=1)
976+
977+
943978
# We repeat all testst including remote data with and without it opted in
944979
def test_remote_data_url(testdir):
945980
testdir.makeini(

0 commit comments

Comments
 (0)