Skip to content

Commit 792ef57

Browse files
committed
ENH: add pytest_extra_requires key to DTConfig
This allows to conditionally skip/ignore paths depending on the PEP 508 requirements: pytest_extra_requires = { "path/to/file" : "cupy>=2.3.4" }
1 parent 2dd4785 commit 792ef57

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

scipy_doctest/impl.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ class DTConfig:
7979
Default is False.
8080
pytest_extra_ignore : list
8181
A list of names/modules to ignore when run under pytest plugin. This is
82-
equivalent to using `--ignore=...` cmdline switch.
82+
equivalent to using ``--ignore=...`` cmdline switch.
8383
pytest_extra_skip : dict
8484
Names/modules to skip when run under pytest plugin. This is
8585
equivalent to decorating the doctest with `@pytest.mark.skip` or adding
@@ -92,6 +92,11 @@ class DTConfig:
9292
adding `# may vary` to the outputs of all examples.
9393
Each key is a doctest name to skip, and the corresponding value is
9494
a string. If not empty, the string value is used as the skip reason.
95+
pytest_extra_requires : dict
96+
Paths to conditionally ignore unless requirements are met.
97+
The format is ``{path/or/glob/pattern: requirement}``, where the values are
98+
PEP 508 dependency specifiers. If a requirement is not met, the behavior
99+
is equivalent to using the ``--ignore=...`` command line switch.
95100
CheckerKlass : object, optional
96101
The class for the Checker object. Must mimic the ``DTChecker`` API:
97102
subclass the `doctest.OutputChecker` and make the constructor signature
@@ -125,6 +130,7 @@ def __init__(self, *, # DTChecker configuration
125130
pytest_extra_ignore=None,
126131
pytest_extra_skip=None,
127132
pytest_extra_xfail=None,
133+
pytest_extra_requires=None,
128134
):
129135
### DTChecker configuration ###
130136
self.CheckerKlass = CheckerKlass or DTChecker
@@ -217,6 +223,7 @@ def __init__(self, *, # DTChecker configuration
217223
self.pytest_extra_ignore = pytest_extra_ignore or []
218224
self.pytest_extra_skip = pytest_extra_skip or {}
219225
self.pytest_extra_xfail = pytest_extra_xfail or {}
226+
self.pytest_extra_requires = pytest_extra_requires or {}
220227

221228

222229
def try_convert_namedtuple(got):

scipy_doctest/plugin.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import warnings
66
import doctest
77

8+
from importlib.metadata import version as get_version, PackageNotFoundError
9+
from packaging.requirements import Requirement
10+
811
import pytest
912
import _pytest
1013
from _pytest import doctest as pydoctest, outcomes
@@ -83,10 +86,20 @@ def pytest_ignore_collect(collection_path, config):
8386
return True
8487

8588
fnmatch_ex = _pytest.pathlib.fnmatch_ex
89+
8690
for entry in config.dt_config.pytest_extra_ignore:
8791
if fnmatch_ex(entry, collection_path):
8892
return True
8993

94+
for entry, req_str in config.dt_config.pytest_extra_requires.items():
95+
if fnmatch_ex(entry, collection_path):
96+
# check the requirement
97+
req = Requirement(req_str)
98+
try:
99+
return not (get_version(req.name) in req.specifier)
100+
except PackageNotFoundError:
101+
return True
102+
90103

91104
def is_private(item):
92105
"""Decide if an DocTestItem `item` is private.

0 commit comments

Comments
 (0)