Skip to content

Commit d9b5ba4

Browse files
added remote data directive
more descriptive comments in skip_some.rst Update tests/test_doctestplus.py Co-authored-by: Brigitta Sipőcz <[email protected]> added pytest-remotedata as a requirement to be installed by tox added version to pytest-remotedata composite directive test fails latest commit removed test for ignore warning directive test cleanup removed extra marker updated README and added changelog entry review corrections added vscode setting to .gitignore removed .vscode splitted test functions review corrections
1 parent ed6bb0c commit d9b5ba4

File tree

9 files changed

+240
-26
lines changed

9 files changed

+240
-26
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,8 @@ venv
5959
# PyCharm
6060
.idea
6161

62+
# VS code
63+
.vscode
64+
6265
pytest_doctestplus/version.py
6366
pip-wheel-metadata/

.vscode/settings.json

Lines changed: 0 additions & 3 deletions
This file was deleted.

CHANGES.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
0.9.0 (2021-01-14)
88
==================
99

10+
- Added ``..doctest-remote-data::`` directive to control remote data
11+
access for a chunk of code [#137]
12+
1013
- Declare ``setuptools`` runtime dependency [#93]
1114

1215
- Add ``SHOW_WARNINGS`` flag to show warnings. [#136]

README.rst

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,17 @@ marked:
273273
274274
The ``+REMOTE_DATA`` directive indicates that the marked statement should only
275275
be executed if the ``--remote-data`` option is given. By default, all
276-
statements marked with ``--remote-data`` will be skipped.
276+
statements marked with the remote data directive will be skipped.
277+
278+
Whole code example blocks can also be marked to control access to data from the internet
279+
this way:
280+
281+
.. code-block:: python
282+
283+
.. doctest-remote-data::
284+
285+
>>> import requests
286+
>>> r = requests.get('https://www.astropy.org')
277287
278288
.. _pytest-remotedata: https://github.com/astropy/pytest-remotedata
279289
__ pytest-remotedata_

pytest_doctestplus/plugin.py

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ def pytest_addoption(parser):
8989

9090
parser.addoption("--text-file-format", action="store",
9191
help=(
92-
"Text file format for narrative documentation. "
93-
"Options accepted are 'txt', 'tex', and 'rst'. "
94-
"This is no longer recommended, use --doctest-glob instead."
92+
"Text file format for narrative documentation. "
93+
"Options accepted are 'txt', 'tex', and 'rst'. "
94+
"This is no longer recommended, use --doctest-glob instead."
9595
))
9696

9797
# Defaults to `atol` parameter from `numpy.allclose`.
@@ -139,8 +139,8 @@ def pytest_addoption(parser):
139139
default=[])
140140

141141
parser.addini("doctest_subpackage_requires",
142-
"A list of paths to skip if requirements are not satisfied. Each item in the list "
143-
"should have the syntax path=req1;req2",
142+
"A list of paths to skip if requirements are not satisfied."
143+
"Each item in the list should have the syntax path=req1;req2",
144144
type='linelist',
145145
default=[])
146146

@@ -156,7 +156,8 @@ def get_optionflags(parent):
156156
def pytest_configure(config):
157157
doctest_plugin = config.pluginmanager.getplugin('doctest')
158158
run_regular_doctest = config.option.doctestmodules and not config.option.doctest_plus
159-
use_doctest_plus = config.getini('doctest_plus') or config.option.doctest_plus or config.option.doctest_only
159+
use_doctest_plus = config.getini(
160+
'doctest_plus') or config.option.doctest_plus or config.option.doctest_only
160161
if doctest_plugin is None or run_regular_doctest or not use_doctest_plus:
161162
return
162163

@@ -301,7 +302,8 @@ class DocTestParserPlus(doctest.DocTestParser):
301302
302303
- ``.. doctest-skip-all``: Skip all subsequent doctests.
303304
304-
- ``.. doctest-remote-data::``: Skip the next doctest chunk if --remote-data is not passed.
305+
- ``.. doctest-remote-data::``: Skip the next doctest chunk if
306+
--remote-data is not passed.
305307
"""
306308

307309
def parse(self, s, name=None):
@@ -333,7 +335,8 @@ def parse(self, s, name=None):
333335
required = []
334336
skip_next = False
335337
lines = entry.strip().splitlines()
336-
if any([re.match('{} doctest-skip-all'.format(comment_char), x.strip()) for x in lines]):
338+
if any([re.match(
339+
'{} doctest-skip-all'.format(comment_char), x.strip()) for x in lines]):
337340
skip_all = True
338341
continue
339342

@@ -361,9 +364,8 @@ def parse(self, s, name=None):
361364
continue
362365

363366
if config.getoption('remote_data', 'none') != 'any':
364-
print(config.getoption('remote_data', 'none') != 'any')
365367
matches = [re.match(
366-
r'{}\s+doctest-remote-data\s*::(\s+.*)?'.format(comment_char),
368+
r'{}\s+doctest-remote-data\s*::'.format(comment_char),
367369
last_line) for last_line in last_lines]
368370

369371
if len(matches) > 1:
@@ -372,12 +374,8 @@ def parse(self, s, name=None):
372374
match = matches[0]
373375

374376
if match:
375-
marker = match.group(1)
376-
if (marker is None or
377-
(marker.strip() == 'win32' and
378-
sys.platform == 'win32')):
379-
skip_next = True
380-
continue
377+
skip_next = True
378+
continue
381379

382380
matches = [re.match(
383381
r'{}\s+doctest-requires\s*::\s+(.*)'.format(comment_char),

setup.cfg

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ install_requires =
3535
setuptools>=30.3.0
3636
packaging>=17.0
3737

38+
[options.extras_require]
39+
test =
40+
pytest-remotedata>=0.3.2
41+
3842
[options.entry_points]
3943
pytest11 =
4044
pytest_doctestplus = pytest_doctestplus.plugin

tests/docs/skip_some.rst

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,77 @@ Code in doctest should run only if version condition is satisfied:
8080
.. doctest-requires:: pytest>=1.0 pytest>=2.0
8181

8282
>>> import pytest
83+
84+
85+
Remote data block code sandwiched in block codes
86+
================================================
87+
88+
This code block should work just fine::
89+
90+
>>> 1 + 1
91+
2
92+
93+
This should be skipped when remote data is not requested
94+
otherwise the test should fail::
95+
96+
.. doctest-remote-data::
97+
98+
>>> 1 + 3
99+
2
100+
101+
This code block should work just fine::
102+
103+
>>> 1 + 1
104+
2
105+
106+
107+
Remote data followed by plain block code
108+
========================================
109+
110+
This one should be skipped when remote data is not requested
111+
otherwise the test should fail::
112+
113+
.. doctest-remote-data::
114+
115+
>>> 1 + 3
116+
2
117+
118+
This code block should work just fine::
119+
120+
>>> 1 + 1
121+
2
122+
123+
124+
Several blocks of Remote data
125+
=============================
126+
127+
The three block codes should be skipped when remote data
128+
is not requested otherwise the tests should fail:
129+
130+
.. doctest-remote-data::
131+
132+
>>> 1 + 3
133+
2
134+
135+
.. doctest-remote-data::
136+
137+
>>> 1 + 4
138+
2
139+
140+
.. doctest-remote-data::
141+
142+
>>> 1 + 5
143+
2
144+
145+
composite directive with remote data
146+
====================================
147+
148+
This should be skipped otherwise the test should fail::
149+
150+
.. doctest-remote-data::
151+
152+
>>> 1 + 1
153+
3
154+
>>> import warnings
155+
>>> warnings.warn('A warning occurred', UserWarning) # doctest: +IGNORE_WARNINGS
156+

tests/test_doctestplus.py

Lines changed: 128 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -777,32 +777,154 @@ def test_doctest_skip(testdir):
777777
testdir.inline_run(p, '--doctest-plus', '--doctest-rst').assertoutcome(skipped=1)
778778

779779

780-
def test_remote_data(testdir):
780+
def test_remote_data_on(testdir):
781781
testdir.makeini(
782782
"""
783783
[pytest]
784784
doctestplus = enabled
785785
""")
786786

787-
# should be ignored
788787
p = testdir.makefile(
789788
'.rst',
790789
"""
790+
# This test should pass
791791
.. doctest-remote-data::
792+
792793
>>> 1 + 1
793794
2
794795
"""
795796
)
797+
testdir.inline_run(p, '--doctest-plus', '--doctest-rst',
798+
'--remote-data').assertoutcome(passed=1)
799+
800+
801+
def test_remote_data_off(testdir):
802+
testdir.makeini(
803+
"""
804+
[pytest]
805+
doctestplus = enabled
806+
""")
807+
808+
p = testdir.makefile(
809+
'.rst',
810+
"""
811+
# This test should fail, but we skip it, thus the test should be skipped.
812+
.. doctest-remote-data::
813+
814+
>>> from contextlib import closing
815+
>>> from urllib.request import urlopen
816+
>>> with closing(urlopen('https://www.astropy.org')) as remote:
817+
... remote.read() # doctest: +IGNORE_OUTPUT
818+
"""
819+
)
820+
testdir.inline_run(p, '--doctest-plus', '--doctest-rst').assertoutcome(skipped=1)
821+
822+
823+
def test_remote_data_float_cmp(testdir):
824+
testdir.makeini(
825+
"""
826+
[pytest]
827+
doctestplus = enabled
828+
""")
829+
830+
p = testdir.makefile(
831+
'.rst',
832+
"""
833+
#This test is skipped when remote data is not requested, and should
834+
#fails when remote data is requested
835+
.. doctest-remote-data::
836+
837+
>>> x = 1/3.
838+
>>> x # doctest: +FLOAT_CMP
839+
0.333333
840+
"""
841+
)
842+
testdir.inline_run(p, '--doctest-plus', '--doctest-rst').assertoutcome(skipped=1)
843+
844+
845+
def test_remote_data_ignore_whitespace(testdir):
846+
testdir.makeini(
847+
"""
848+
[pytest]
849+
doctest_optionflags = NORMALIZE_WHITESPACE
850+
doctestplus = enabled
851+
""")
852+
853+
p = testdir.makefile(
854+
'.rst',
855+
"""
856+
#This test should be skipped when remote data is not requested, and should
857+
#pass when remote data is requested
858+
.. doctest-remote-data::
859+
860+
>>> a = "foo "
861+
>>> print(a)
862+
foo
863+
"""
864+
)
865+
testdir.inline_run(p, '--doctest-plus', '--doctest-rst').assertoutcome(skipped=1)
866+
867+
868+
def test_remote_data_ellipsis(testdir):
869+
testdir.makeini(
870+
"""
871+
[pytest]
872+
doctest_optionflags = ELLIPSIS
873+
doctestplus = enabled
874+
""")
875+
876+
p = testdir.makefile(
877+
'.rst',
878+
"""
879+
#This test should be skipped when remote data is not requested, and should
880+
#pass when remote data is requested
881+
.. doctest-remote-data::
882+
883+
>>> a = "freedom at last"
884+
>>> print(a)
885+
freedom ...
886+
"""
887+
)
796888
testdir.inline_run(p, '--doctest-plus', '--doctest-rst').assertoutcome(skipped=1)
797889

798-
# should run
890+
891+
def test_remote_data_requires(testdir):
892+
testdir.makeini(
893+
"""
894+
[pytest]
895+
doctestplus = enabled
896+
""")
897+
799898
p = testdir.makefile(
800899
'.rst',
801900
"""
901+
#This test should be skipped even if remote data is requested because
902+
#the module required does not exist
802903
.. doctest-remote-data::
904+
.. doctest-requires:: does-not-exist
905+
803906
>>> 1 + 1
804-
2
907+
3
805908
"""
806909
)
807-
testdir.inline_run(p, '--doctest-plus', '--doctest-rst',
808-
'--remote-data').assertoutcome(passed=1)
910+
testdir.inline_run(p, '--doctest-plus', '--doctest-rst').assertoutcome(skipped=1)
911+
912+
913+
def test_remote_data_ignore_warnings(testdir):
914+
testdir.makeini(
915+
"""
916+
[pytest]
917+
doctestplus = enabled
918+
""")
919+
920+
p = testdir.makefile(
921+
'.rst',
922+
"""
923+
#This test should be skipped if remote data is not requested.
924+
.. doctest-remote-data::
925+
926+
>>> import warnings
927+
>>> warnings.warn('A warning occurred', UserWarning) # doctest: +IGNORE_WARNINGS
928+
"""
929+
)
930+
testdir.inline_run(p, '--doctest-plus', '--doctest-rst').assertoutcome(skipped=1)

tox.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ deps =
2020
pytest61: pytest==6.1.*
2121
pytestdev: git+https://github.com/pytest-dev/pytest#egg=pytest
2222

23+
extras =
24+
test
25+
2326
commands =
2427
pip freeze
2528
pytest {toxinidir}/tests {posargs}

0 commit comments

Comments
 (0)