Repository: NeurodataWithoutBorders/nwbinspector (language: python)

Issue:
Swap to pyproject.toml setup
Modern Pythonic practice has moved away from `setup.py` +/- `.cfg` towards `pyproject.toml`

This updates the package accordingly


Discussion / hints:
This will take a bit more work - will splinter a few items into smaller PRs

Fix patch:
diff --git a/.github/workflows/assess-file-changes.yml b/.github/workflows/assess-file-changes.yml
index 38fa258bb..dbf9661ef 100644
--- a/.github/workflows/assess-file-changes.yml
+++ b/.github/workflows/assess-file-changes.yml
@@ -7,9 +7,6 @@ on:
       SOURCE_CHANGED:
         description: "Whether or not the files under /src/ were changed."
         value: ${{ jobs.build.outputs.SOURCE_CHANGED }}
-      TESTING_CHANGED:
-        description: "Whether or not to regenerate the testing files and reupload them to DANI staging."
-        value: ${{ jobs.build.outputs.TESTING_CHANGED }}
 
 jobs:
   build:
@@ -17,7 +14,6 @@ jobs:
     # Map the job outputs to step outputs
     outputs:
       SOURCE_CHANGED: ${{ steps.flagged-changes.outputs.SOURCE_CHANGED }}
-      TESTING_CHANGED: ${{ steps.flagged-changes.outputs.TESTING_CHANGED }}
 
     name: Test changed-files
     steps:
@@ -33,7 +29,6 @@ jobs:
         id: flagged-changes
         run: |
           echo "::set-output name=SOURCE_CHANGED::false"
-          echo "::set-output name=TESTING_CHANGED::false"
           for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
             echo $file
             if [[ $file == "src/nwbinspector/"* || $file == "requirements.txt" || $file == "setup.py" || $file == "tests/"* ]]
@@ -43,11 +38,4 @@ jobs:
             else
               echo "Source not changed"
             fi
-            if [[ $file == "src/nwbinspector/testing.py" ]]
-            then
-              echo "Testing changed"
-              echo "::set-output name=TESTING_CHANGED::true"
-            else
-              echo "Testing not changed"
-            fi
           done
diff --git a/.github/workflows/dev-gallery.yml b/.github/workflows/dev-gallery.yml
index de828e651..5ed12a86c 100644
--- a/.github/workflows/dev-gallery.yml
+++ b/.github/workflows/dev-gallery.yml
@@ -1,6 +1,9 @@
 name: Development Version Gallery
 on: workflow_call
 
+env:
+  TESTING_FILES_FOLDER_PATH: ./204919/testing_files/
+
 jobs:
   build-and-test:
     name: Testing against dev PyNWB version
@@ -16,8 +19,6 @@ jobs:
       - uses: actions/checkout@v3
       - run: git fetch --prune --unshallow --tags
 
-      - name: Install ROS3
-        run: conda install -c conda-forge h5py
       - name: Install pytest
         run: |
           pip install pytest
@@ -26,10 +27,9 @@ jobs:
         run: |
           pip install -e ".[dandi]"
           pip install git+https://github.com/neurodatawithoutborders/pynwb@dev
+
       - name: Download testing data and set config path
-        run: |
-          dandi download "https://gui-staging.dandiarchive.org/#/dandiset/204919"
-          python -c "from nwbinspector.testing import update_testing_config; update_testing_config(key='LOCAL_PATH', value='./204919/testing_files/')"
+        run: dandi download "https://gui-staging.dandiarchive.org/#/dandiset/204919"
 
-      - name: Run pytest with coverage
+      - name: Run pytest
         run: pytest -rsx
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6681ca522..e4c52d994 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
 
 ### Improvements
 * Removed the `robust_ros3_read` utility helper. [#506](https://github.com/NeurodataWithoutBorders/nwbinspector/pull/506)
+* Simplified the `nwbinspector.testing` configuration framework. [#509](https://github.com/NeurodataWithoutBorders/nwbinspector/pull/509)
 
 
 # v0.5.2
diff --git a/setup.py b/setup.py
index 75c9ddd60..8a8b8253e 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,4 @@
 from pathlib import Path
-from shutil import copy
 
 from setuptools import find_packages, setup
 
@@ -11,14 +10,6 @@
 with open(root / "src" / "nwbinspector" / "_version.py") as f:
     version = f.read()
 
-# Instantiate the testing configuration file from the base file `base_test_config.json`
-# This requires the current working directory to be the top level
-# of a local copy of the NWB Inspector GitHub repository
-BASE_CONFIG_FILE_PATH = Path.cwd() / "base_test_config.json"
-TESTING_CONFIG_FILE_PATH = Path.cwd() / "tests" / "testing_config.json"
-if not TESTING_CONFIG_FILE_PATH.exists():
-    copy(src=str(BASE_CONFIG_FILE_PATH), dst=str(TESTING_CONFIG_FILE_PATH))
-
 setup(
     name="nwbinspector",
     version=version.split('"')[1],


Test patch:
diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml
index a6b26df7a..86336f379 100644
--- a/.github/workflows/testing.yml
+++ b/.github/workflows/testing.yml
@@ -5,6 +5,9 @@ on:
       CODECOV_TOKEN:
         required: true
 
+env:
+  TESTING_FILES_FOLDER_PATH: ./204919/testing_files/
+
 jobs:
   build-and-test:
     name: Testing using ${{ matrix.os }} with ${{ matrix.python-version }}
@@ -33,9 +36,7 @@ jobs:
       - name: Install package
         run: pip install ".[dandi]"
       - name: Download testing data and set config path
-        run: |
-          dandi download "https://gui-staging.dandiarchive.org/#/dandiset/204919"
-          python -c "from nwbinspector.testing import update_testing_config; update_testing_config(key='LOCAL_PATH', value='./204919/testing_files/')"
+        run: dandi download "https://gui-staging.dandiarchive.org/#/dandiset/204919"
 
       - name: Run pytest with coverage
         run: pytest -rsx --cov=nwbinspector --cov-report xml:./coverage.xml
diff --git a/.github/workflows/update-testing-files.yml b/.github/workflows/update-testing-files.yml
deleted file mode 100644
index 2753c1b1d..000000000
--- a/.github/workflows/update-testing-files.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: Generate and Upload Testing Files
-on:
-  workflow_dispatch:
-  workflow_call:
-    secrets:
-      DANDI_API_KEY:
-        required: true
-
-env:
-  DANDI_API_KEY: ${{ secrets.DANDI_API_KEY }}
-
-jobs:
-  build-and-test:
-    name: Generate and Upload Testing Files
-    runs-on: ubuntu-latest
-    strategy:
-      fail-fast: false
-    steps:
-      - uses: actions/checkout@v3
-      - run: git fetch --prune --unshallow --tags
-      - name: Setup Python
-        uses: actions/setup-python@v2
-        with:
-          python-version: 3.9
-
-      - name: Install DANDI
-        run: pip install -e .[dandi]
-      - name: Install older PyNWB version to generate example invalid files
-        run: |
-          pip uninstall pynwb
-          pip install pynwb==2.1.0
-      - name: Update testing configuration path
-        run: python -c "from nwbinspector.testing import update_testing_config; update_testing_config(key='LOCAL_PATH', value='./testing_files/')"
-      - name: Generate testing files
-        run: python -c "from nwbinspector.testing import generate_testing_files; generate_testing_files()"
-      - name: Upload to DANDI
-        run: |
-          dandi download 'https://gui-staging.dandiarchive.org/#/dandiset/204919' --download dandiset.yaml
-          cd 204919
-          mv ../testing_files .
-          dandi upload -i dandi-staging --validation skip  # These are purposefully invalid files
diff --git a/base_test_config.json b/base_test_config.json
deleted file mode 100644
index 442057399..000000000
--- a/base_test_config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-    "LOCAL_PATH": "/shared/catalystneuro/"
-}
diff --git a/src/nwbinspector/testing/__init__.py b/src/nwbinspector/testing/__init__.py
index bdbed455a..633ac4877 100644
--- a/src/nwbinspector/testing/__init__.py
+++ b/src/nwbinspector/testing/__init__.py
@@ -1,14 +1,11 @@
 from ._testing import (
-    TESTING_CONFIG_FILE_PATH,
     check_hdf5_io_open,
     check_streaming_enabled,
     check_streaming_tests_enabled,
     check_zarr_io_open,
     generate_image_series_testing_files,
     generate_testing_files,
-    load_testing_config,
     make_minimal_nwbfile,
-    update_testing_config,
 )
 
 __all__ = [
@@ -16,10 +13,7 @@
     "check_streaming_enabled",
     "check_hdf5_io_open",
     "check_zarr_io_open",
-    "load_testing_config",
-    "update_testing_config",
     "generate_testing_files",
     "generate_image_series_testing_files",
     "make_minimal_nwbfile",
-    "TESTING_CONFIG_FILE_PATH",
 ]
diff --git a/src/nwbinspector/testing/_testing.py b/src/nwbinspector/testing/_testing.py
index 2c649ec1b..68b7629ef 100644
--- a/src/nwbinspector/testing/_testing.py
+++ b/src/nwbinspector/testing/_testing.py
@@ -1,6 +1,5 @@
 """Helper functions for internal use across the testing suite."""
 
-import json
 import os
 from datetime import datetime
 from pathlib import Path
@@ -16,9 +15,6 @@
 
 from ..utils import get_package_version, is_module_installed, strtobool
 
-# The tests must be invoked at the outer level of the repository
-TESTING_CONFIG_FILE_PATH = Path.cwd() / "tests" / "testing_config.json"
-
 
 def check_streaming_tests_enabled() -> tuple[bool, Optional[str]]:
     """
@@ -52,34 +48,6 @@ def check_streaming_tests_enabled() -> tuple[bool, Optional[str]]:
     return streaming_enabled and not environment_skip_flag_bool and have_dandi, failure_reason
 
 
-def load_testing_config() -> dict:
-    """Helper function for loading the testing configuration file as a dictionary."""
-    # This error would only occur if someone installed a previous version
-    # directly from GitHub and then updated the branch/commit in-place
-    if not TESTING_CONFIG_FILE_PATH.exists():  # pragma: no cover
-        raise FileNotFoundError(
-            f"The testing configuration file not found at the location '{TESTING_CONFIG_FILE_PATH}'! "
-            "Please try reinstalling the package."
-        )
-
-    with open(file=TESTING_CONFIG_FILE_PATH) as file:
-        test_config = json.load(file)
-
-    return test_config
-
-
-def update_testing_config(key: str, value):
-    """Update a key/value pair in the testing configuration file through the API."""
-    testing_config = load_testing_config()
-
-    if key not in testing_config:
-        raise KeyError("Updating the testing configuration file via the API is only possible for the pre-defined keys!")
-    testing_config[key] = value
-
-    with open(file=TESTING_CONFIG_FILE_PATH, mode="w") as file:
-        json.dump(testing_config, file)
-
-
 def generate_testing_files():  # pragma: no cover
     """Generate a local copy of the NWB files required for all tests."""
     generate_image_series_testing_files()
diff --git a/tests/test_testing_module.py b/tests/test_testing_module.py
deleted file mode 100644
index ff1de7000..000000000
--- a/tests/test_testing_module.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from nwbinspector.testing import load_testing_config, update_testing_config
-
-
-def test_update_testing_config():
-    test_key = "LOCAL_PATH"
-    test_value = "/a/new/path/"
-
-    try:
-        initial_testing_config = load_testing_config()
-        NO_CONFIG = False  # Depending on the method of installation, a config may not have generated
-    except FileNotFoundError:
-        NO_CONFIG = True
-
-    if not NO_CONFIG:
-        try:
-            update_testing_config(key=test_key, value=test_value)
-            updated_testing_config = load_testing_config()
-        finally:
-            # Restore
-            update_testing_config(key=test_key, value=initial_testing_config[test_key])
-
-        assert updated_testing_config[test_key] != initial_testing_config[test_key]
-        assert updated_testing_config[test_key] == test_value
diff --git a/tests/unit_tests/test_image_series.py b/tests/unit_tests/test_image_series.py
index 4f5ea8fdc..9f6f5e91c 100644
--- a/tests/unit_tests/test_image_series.py
+++ b/tests/unit_tests/test_image_series.py
@@ -1,3 +1,4 @@
+import os
 import unittest
 from pathlib import Path
 from shutil import rmtree
@@ -14,26 +15,24 @@
     check_image_series_external_file_valid,
     check_timestamps_match_first_dimension,
 )
-from nwbinspector.testing import load_testing_config, make_minimal_nwbfile
+from nwbinspector.testing import make_minimal_nwbfile
 
-try:
-    testing_config = load_testing_config()
-    testing_file = Path(testing_config["LOCAL_PATH"]) / "image_series_testing_file.nwb"
-    NO_CONFIG = False  # Depending on the method of installation, a config may not have generated
-except FileNotFoundError:
-    testing_file = "Not found"
-    NO_CONFIG = True
+TESTING_FILES_FOLDER_PATH = os.environ.get("TESTING_FILES_FOLDER_PATH", None)
 
 
 @unittest.skipIf(
-    NO_CONFIG or not testing_file.exists(),
-    reason=f"The ImageSeries unit tests were skipped because the required file ({testing_file}) was not found!",
+    TESTING_FILES_FOLDER_PATH is None,
+    reason=(
+        f"These ImageSeries unit tests were skipped because the environment variable "
+        "'TESTING_FILES_FOLDER_PATH' was not set!"
+    ),
 )
 class TestExternalFileValid(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
-        testing_config = load_testing_config()
-        cls.testing_file = Path(testing_config["LOCAL_PATH"]) / "image_series_testing_file.nwb"
+        cls.testing_file = Path(TESTING_FILES_FOLDER_PATH) / "image_series_testing_file.nwb"
+
+        assert cls.testing_file.exists()
 
     def setUp(self):
         self.io = NWBHDF5IO(path=self.testing_file, mode="r")