Repository: catalystneuro/nwb-conversion-tools (language: python)

Issue:
GIN tests gap: Mac OS X for sonpy
## Description

When we added CED tests to our `test_gin.py` collection, the CI revealed some weird issue with importing the `sonpy` package seen here: https://github.com/catalystneuro/nwb-conversion-tools/runs/4358475697?check_suite_focus=true

The runner reports the package installed correctly, without issue, but still raises the lazy check for that interface only, indicating some other `ImportError`.

For now, it's simply manually disabled in the `test_gin` to ignore if running on mac.

## Steps to Reproduce

I don't have quick immediate access to a Mac device to test this right at the moment, so anyone that does is welcome to try

```
conda create -n test_sonpy python=3.7  # since that's what our CI runs  on
conda activate test_sonpy
# from nwb-conversion-tools
pip install -r requirements-full.txt
pip install -e .

python
> import sonpy
```

## Environment

Master branch of nwb-conversion-tools, full CI runner specification (`requirements-full.txt`).
    

## Checklist

- [X] Have you ensured the feature or change was not already [reported](https://github.com/catalystneuro/nwb-conversion-tools/issues)?
- [X] Have you included a brief and descriptive title?
- [X] Have you included a clear description of the problem you are trying to solve?
- [X] Have you included a minimal code snippet that reproduces the issue you are encountering?
- [X] Have you checked our [Contributing](https://nwb-conversion-tools.readthedocs.io/en/master/developer_guide.html) document?



Discussion / hints:

Fix patch:
diff --git a/nwb_conversion_tools/datainterfaces/behavior/movie/moviedatainterface.py b/nwb_conversion_tools/datainterfaces/behavior/movie/moviedatainterface.py
index 7178a910f..202fc0836 100644
--- a/nwb_conversion_tools/datainterfaces/behavior/movie/moviedatainterface.py
+++ b/nwb_conversion_tools/datainterfaces/behavior/movie/moviedatainterface.py
@@ -23,7 +23,7 @@
     HAVE_OPENCV = True
 except ImportError:
     HAVE_OPENCV = False
-INSTALL_MESSAGE = "Please install opencv to use this extractor (pip install opencv-python)!"
+INSTALL_MESSAGE = "Please install opencv to use this interface (pip install opencv-python)!"
 
 
 class MovieInterface(BaseDataInterface):
diff --git a/nwb_conversion_tools/datainterfaces/ecephys/ced/ceddatainterface.py b/nwb_conversion_tools/datainterfaces/ecephys/ced/ceddatainterface.py
index 545eb9990..0e990dd90 100644
--- a/nwb_conversion_tools/datainterfaces/ecephys/ced/ceddatainterface.py
+++ b/nwb_conversion_tools/datainterfaces/ecephys/ced/ceddatainterface.py
@@ -1,26 +1,42 @@
-"""Authors: Luiz Tauffer"""
-import spikeextractors as se
+"""Authors: Luiz Tauffer."""
+from platform import python_version
+from sys import platform
+from packaging import version
+
+from spikeextractors import CEDRecordingExtractor
 
 from ..baserecordingextractorinterface import BaseRecordingExtractorInterface
 from ....utils.json_schema import get_schema_from_method_signature, FilePathType
 
+HAVE_SONPY = True
+try:
+    import sonpy
+except ImportError:
+    HAVE_SONPY = False
+INSTALL_MESSAGE = "Please install sonpy to use this interface (pip install sonpy)!"
+if platform == "darwin" and version.parse(python_version()) < version.parse("3.8"):
+    HAVE_SONPY = False
+    INSTALL_MESSAGE = "The sonpy package (CED dependency) is not available on Mac for Python versions below 3.8!"
+
 
 class CEDRecordingInterface(BaseRecordingExtractorInterface):
     """Primary data interface class for converting a CEDRecordingExtractor."""
 
-    RX = se.CEDRecordingExtractor
+    RX = CEDRecordingExtractor
 
     @classmethod
     def get_source_schema(cls):
-        """Compile input schema for the RecordingExtractor."""
         source_schema = get_schema_from_method_signature(class_method=cls.__init__, exclude=["smrx_channel_ids"])
         source_schema.update(additionalProperties=True)
         source_schema["properties"]["file_path"].update(description="Path to CED data file.")
         return source_schema
 
-    def __init__(self, file_path: FilePathType):
-        super().__init__(file_path=file_path)
-
     @classmethod
     def get_all_channels_info(cls, file_path: FilePathType):
-        return cls.RX.get_all_channels_info(file_path)
+        """Retrieve and inspect necessary channel information prior to initialization."""
+        assert HAVE_SONPY, INSTALL_MESSAGE
+        return cls.RX.get_all_channels_info(file_path=file_path)
+
+    def __init__(self, file_path: FilePathType, smrx_channel_ids: list):
+        assert HAVE_SONPY, INSTALL_MESSAGE
+        super().__init__(file_path=file_path, smrx_channel_ids=smrx_channel_ids)
diff --git a/requirements-full.txt b/requirements-full.txt
index 12cc4ffa3..e941d0f8e 100644
--- a/requirements-full.txt
+++ b/requirements-full.txt
@@ -20,3 +20,4 @@ ndx-events==0.2.0
 parameterized==0.8.1
 pyintan==0.3.0
 pyopenephys==1.1.2
+sonpy==1.7.5


Test patch:
diff --git a/.github/workflows/full-tests-linux.yml b/.github/workflows/full-tests-linux.yml
index 0efad85a2..97aaf3f57 100644
--- a/.github/workflows/full-tests-linux.yml
+++ b/.github/workflows/full-tests-linux.yml
@@ -30,8 +30,8 @@ jobs:
         id: cache-datasets
         with:
           path: /home/runner/work/nwb-conversion-tools/nwb-conversion-tools/ephy_testing_data
-          key: ecephys-datasets-7-${{ steps.ephys.outputs.HASH_EPHY_DATASET }}
-          restore-keys: ecephys-datasets-7-${{ steps.ephys.outputs.HASH_EPHY_DATASET }}
+          key: ecephys-datasets-9-${{ steps.ephys.outputs.HASH_EPHY_DATASET }}
+          restore-keys: ecephys-datasets-9-${{ steps.ephys.outputs.HASH_EPHY_DATASET }}
       - name: Force GIN download
         if: steps.cache-datasets.outputs.cache-hit == false
         run: |
diff --git a/tests/test_internals/test_interfaces.py b/tests/test_internals/test_interfaces.py
index 7c507ec9f..72cbb4962 100644
--- a/tests/test_internals/test_interfaces.py
+++ b/tests/test_internals/test_interfaces.py
@@ -4,11 +4,15 @@
 from shutil import rmtree
 from pathlib import Path
 from itertools import product
+from platform import python_version
+from sys import platform
+from packaging import version
 
 import pytest
 import spikeextractors as se
 from spikeextractors.testing import check_recordings_equal, check_sortings_equal
 from pynwb import NWBHDF5IO
+from hdmf.testing import TestCase
 
 try:
     import cv2
@@ -24,6 +28,7 @@
     SortingTutorialInterface,
     SIPickleRecordingExtractorInterface,
     SIPickleSortingExtractorInterface,
+    CEDRecordingInterface,
     interface_list,
 )
 
@@ -32,6 +37,18 @@
 from nwb_conversion_tools.utils.conversion_tools import get_default_nwbfile_metadata
 
 
+class test(TestCase):
+    def test_import_assertions(self):
+        if platform == "darwin" and version.parse(python_version()) < version.parse("3.8"):
+            with self.assertRaisesWith(
+                exc_type=AssertionError,
+                exc_msg="The sonpy package (CED dependency) is not available on Mac for Python versions below 3.8!",
+            ):
+                CEDRecordingInterface.get_all_channels_info(file_path="does_not_matter.smrx")
+        else:
+            pytest.skip("Not testing on MacOSX with Python<3.8!")
+
+
 @pytest.mark.parametrize("data_interface", interface_list)
 def test_interface_source_schema(data_interface):
     schema = data_interface.get_source_schema()