tests.test_doctests
PyDRex: Run doctests for all submodules.
1"""> PyDRex: Run doctests for all submodules.""" 2 3import doctest 4import importlib 5import os 6import pkgutil 7 8import numpy as np 9import pydrex 10import pytest 11from pydrex import logger as _log 12from pydrex.exceptions import Error 13 14 15def _get_submodule_list(): 16 # Reset NumPy print options because doctests are just string matches, and typing out 17 # so many significant digits in doctests is annoying. 18 np.set_printoptions() 19 modules = ["pydrex." + m.name for m in pkgutil.iter_modules(pydrex.__path__)] 20 for module in modules: 21 try: 22 importlib.import_module(module) 23 except ModuleNotFoundError: 24 modules.remove(module) 25 return modules 26 27 28@pytest.mark.parametrize("module", _get_submodule_list()) 29def test_doctests(module, capsys, verbose): 30 """Run doctests for all submodules.""" 31 with capsys.disabled(): # Pytest output capturing messes with doctests. 32 _log.info("running doctests for %s...", module) 33 try: 34 n_fails, n_tests = doctest.testmod( 35 importlib.import_module(module), 36 raise_on_error=True, 37 verbose=verbose > 1, # Run pytest with -vv to show doctest details. 38 ) 39 if n_fails > 0: 40 raise AssertionError( 41 f"there were {n_fails} doctest failures from {module}" 42 ) 43 except doctest.DocTestFailure as e: 44 if e.test.lineno is None: 45 lineno = "" 46 else: 47 lineno = f":{e.test.lineno + 1 + e.example.lineno}" 48 raise AssertionError( 49 f"{e.test.name} ({module}{lineno}) failed with:" 50 + os.linesep 51 + os.linesep 52 + e.got 53 ) from None 54 except doctest.UnexpectedException as e: 55 if e.test.lineno is None: 56 lineno = "" 57 else: 58 lineno = f":{e.test.lineno + 1 + e.example.lineno}" 59 err_type, err, _ = e.exc_info 60 if err_type is NameError: # Raised on missing optional functions. 61 # Issue warning but let the test suite pass. 62 _log.warning( 63 "skipping doctest of missing optional symbol in %s", module 64 ) 65 elif err_type is np.core._exceptions._ArrayMemoryError: 66 # Faiures to allocate should not be fatal to the doctest test suite. 67 _log.warning( 68 "skipping doctests for module %s due to insufficient memory", module 69 ) 70 else: 71 raise Error( 72 f"{err_type.__qualname__} encountered in {e.test.name} ({module}{lineno})" 73 ) from err
@pytest.mark.parametrize('module', _get_submodule_list())
def
test_doctests(module, capsys, verbose):
29@pytest.mark.parametrize("module", _get_submodule_list()) 30def test_doctests(module, capsys, verbose): 31 """Run doctests for all submodules.""" 32 with capsys.disabled(): # Pytest output capturing messes with doctests. 33 _log.info("running doctests for %s...", module) 34 try: 35 n_fails, n_tests = doctest.testmod( 36 importlib.import_module(module), 37 raise_on_error=True, 38 verbose=verbose > 1, # Run pytest with -vv to show doctest details. 39 ) 40 if n_fails > 0: 41 raise AssertionError( 42 f"there were {n_fails} doctest failures from {module}" 43 ) 44 except doctest.DocTestFailure as e: 45 if e.test.lineno is None: 46 lineno = "" 47 else: 48 lineno = f":{e.test.lineno + 1 + e.example.lineno}" 49 raise AssertionError( 50 f"{e.test.name} ({module}{lineno}) failed with:" 51 + os.linesep 52 + os.linesep 53 + e.got 54 ) from None 55 except doctest.UnexpectedException as e: 56 if e.test.lineno is None: 57 lineno = "" 58 else: 59 lineno = f":{e.test.lineno + 1 + e.example.lineno}" 60 err_type, err, _ = e.exc_info 61 if err_type is NameError: # Raised on missing optional functions. 62 # Issue warning but let the test suite pass. 63 _log.warning( 64 "skipping doctest of missing optional symbol in %s", module 65 ) 66 elif err_type is np.core._exceptions._ArrayMemoryError: 67 # Faiures to allocate should not be fatal to the doctest test suite. 68 _log.warning( 69 "skipping doctests for module %s due to insufficient memory", module 70 ) 71 else: 72 raise Error( 73 f"{err_type.__qualname__} encountered in {e.test.name} ({module}{lineno})" 74 ) from err
Run doctests for all submodules.