diff --git a/docs/developer_guide.rst b/docs/developer_guide.rst index 719575981..bcf629007 100644 --- a/docs/developer_guide.rst +++ b/docs/developer_guide.rst @@ -48,7 +48,7 @@ Disable Tests That Require Network Connection Some of the tests in the suite require internet connectivity both to and from the DANDI archive S3 bucket. If this is failing for some reason, you can explicitly control all related tests by setting the environment variable -``NWBI_SKIP_NETWORK_TESTS`` to some value able to be parsed by ``distutils.util.str2tool``. For example, to disable them on +``NWBI_SKIP_NETWORK_TESTS`` to some value able to be parsed by ``nwbinspector.utils.strtotool``. For example, to disable them on a linux system, run .. code-block:: diff --git a/src/nwbinspector/nwbinspector.py b/src/nwbinspector/nwbinspector.py index 13a9ff014..2471eb3e7 100644 --- a/src/nwbinspector/nwbinspector.py +++ b/src/nwbinspector/nwbinspector.py @@ -12,7 +12,6 @@ from concurrent.futures import ProcessPoolExecutor, as_completed from types import FunctionType from warnings import filterwarnings, warn -from distutils.util import strtobool from collections import defaultdict from packaging.version import Version @@ -38,6 +37,7 @@ robust_s3_read, calculate_number_of_cpu, get_package_version, + strtobool, ) from nwbinspector import __version__ diff --git a/src/nwbinspector/testing.py b/src/nwbinspector/testing.py index f376a1314..6e7985d8f 100644 --- a/src/nwbinspector/testing.py +++ b/src/nwbinspector/testing.py @@ -3,7 +3,6 @@ import os import json from uuid import uuid4 -from distutils.util import strtobool from pathlib import Path from datetime import datetime from typing import Tuple, Optional @@ -16,7 +15,7 @@ from pynwb import NWBHDF5IO, NWBFile from pynwb.image import ImageSeries -from .utils import is_module_installed, get_package_version +from .utils import is_module_installed, get_package_version, strtobool # The tests must be invoked at the outer level of the repository TESTING_CONFIG_FILE_PATH = Path.cwd() / "tests" / "testing_config.json" diff --git a/src/nwbinspector/utils.py b/src/nwbinspector/utils.py index 75ba6c8c9..110316c3c 100644 --- a/src/nwbinspector/utils.py +++ b/src/nwbinspector/utils.py @@ -234,3 +234,22 @@ def __get_shape_helper(local_data): if hasattr(data, "__len__") and not isinstance(data, (str, bytes)): if not strict_no_data_load or isinstance(data, (list, tuple, set)): return __get_shape_helper(data) + + +def strtobool(val: str) -> bool: + """ + Convert a string representation of truth to True or False. + + True values are 'y', 'yes', 't', 'true', 'on', and '1'; + False values are 'n', 'no', 'f', 'false', 'off', and '0'. + Raises ValueError if 'val' is anything else. + """ + if not isinstance(val, str): + raise TypeError(f"Invalid type of {val!r} - must be str for `strtobool`") + val = val.lower() + if val in ("y", "yes", "t", "true", "on", "1"): + return True + elif val in ("n", "no", "f", "false", "off", "0"): + return False + else: + raise ValueError(f"Invalid truth value {val!r}") diff --git a/tests/test_utils.py b/tests/test_utils.py index 52ce0e1c4..57d58cf9e 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -11,9 +11,13 @@ get_package_version, calculate_number_of_cpu, is_ascending_series, + strtobool, ) +import pytest + + def test_format_byte_size(): assert format_byte_size(byte_size=12345) == "12.35KB" @@ -142,3 +146,21 @@ def test_is_ascending_series(): assert is_ascending_series(series=[1, 1, 1]) assert is_ascending_series(series=[1, 2, 3]) assert not is_ascending_series(series=[1, 2, 1]) + + +@pytest.mark.parametrize( + "values,target", + [ + (("y", "yes", "t", "true", "on", "1"), True), + (("n", "no", "f", "false", "off", "0"), False), + ], +) +def test_strtobool(values, target): + for v in values: + assert strtobool(v) is target + assert strtobool(v.upper()) is target + with pytest.raises(ValueError): + strtobool(v + "1") + # it is strtobool, so no bool is allowed + with pytest.raises(TypeError): + strtobool(target)