ap--/python-seabreeze

Refactor tests to run for each backend independently

Closed this issue · 6 comments

ap-- commented

The way this is currently done in the pytests is a bit esoteric.
No one is going to try to use both backends from the same process, and if they do, there's some serious development effort to be spent on cross-platform support for windows.

Proposed workaround:
add pytest parameters to allow running tests for each backend individually
i.e.

pytest -m cseabreeze ./tests
pytest -m pyseabreeze_libusb1 ./tests
etc...
ap-- commented

Hi @np-8

I finished refactoring the test suite.
It's now easier to test specific backends for seabreeze.
could you run the pytests on the newest develop branch?

It would be great if you could run:

# without a spectrometer attached
pytest

# with one or more spectrometers attached
pytest --seabreeze-backend cseabreeze

# with one or more spectrometers attached
pytest --seabreeze-backend pyseabreeze

and post the output here 😃

(fyi, possible options for --seabreeze-backend are any, cseabreeze, pyseabreeze, pyseabreeze:libusb0, pyseabreeze:libusb1, pyseabreeze:openusb with any being the default)

Thanks!
-Andreas

Hi,

I pulled the latest development branch. Here are the test results

`pytest` (with no spectrometer attached)
============================= test session starts =============================
platform win32 -- Python 3.7.3, pytest-5.4.3, py-1.8.2, pluggy-0.13.1 -- c:\external-git-repos\python-seabreeze\venv\scripts\python.exe
cachedir: .pytest_cache
rootdir: C:\external-git-repos\python-seabreeze, inifile: pytest.ini
collecting ... collected 28 items

tests/test_backends.py::test_seabreeze_installed PASSED                  [  3%]
tests/test_backends.py::test_seabreeze_wrong_backend_requested PASSED    [  7%]
tests/test_backends.py::test_seabreeze_any_backend_available[cseabreeze] PASSED [ 10%]
tests/test_backends.py::test_seabreeze_any_backend_available[pyseabreeze] PASSED [ 14%]
tests/test_backends.py::test_seabreeze_cseabreeze_backend_available PASSED [ 17%]
tests/test_backends.py::test_seabreeze_pyseabreeze_backend_available PASSED [ 21%]
tests/test_backends.py::test_seabreeze_cseabreeze_api_init PASSED        [ 25%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[any] PASSED  [ 28%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[openusb] SKIPPED [ 32%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb0] SKIPPED [ 35%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb1] SKIPPED [ 39%]
tests/test_backends.py::test_seabreeze_compare_backend_feature_interfaces PASSED [ 42%]
tests/test_protocol.py::test_pyseabreeze_protocol_messages PASSED        [ 46%]
tests/test_spectrometers.py::TestHardware::test_cant_find_serial[backend(any)] FAILED [ 50%]
tests/test_spectrometers.py::TestHardware::test_device_cleanup_on_exit[backend(any)] SKIPPED [ 53%]
tests/test_spectrometers.py::TestHardware::test_read_model[no-spectrometer-backend(any)] SKIPPED [ 57%]
tests/test_spectrometers.py::TestHardware::test_read_serial_number[no-spectrometer-backend(any)] SKIPPED [ 60%]
tests/test_spectrometers.py::TestHardware::test_crash_may_not_influence_following_tests[no-spectrometer-backend(any)] SKIPPED [ 64%]
tests/test_spectrometers.py::TestHardware::test_read_intensities[no-spectrometer-backend(any)] SKIPPED [ 67%]
tests/test_spectrometers.py::TestHardware::test_correct_dark_pixels[no-spectrometer-backend(any)] SKIPPED [ 71%]
tests/test_spectrometers.py::TestHardware::test_read_wavelengths[no-spectrometer-backend(any)] SKIPPED [ 75%]
tests/test_spectrometers.py::TestHardware::test_read_spectrum[no-spectrometer-backend(any)] SKIPPED [ 78%]
tests/test_spectrometers.py::TestHardware::test_max_intensity[no-spectrometer-backend(any)] SKIPPED [ 82%]
tests/test_spectrometers.py::TestHardware::test_integration_time_limits[no-spectrometer-backend(any)] SKIPPED [ 85%]
tests/test_spectrometers.py::TestHardware::test_integration_time[no-spectrometer-backend(any)] SKIPPED [ 89%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode[no-spectrometer-backend(any)] SKIPPED [ 92%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode_wrong[no-spectrometer-backend(any)] SKIPPED [ 96%]
tests/test_spectrometers.py::TestHardware::test_list_devices_dont_close_opened_devices[backend(any)] SKIPPED [100%]

================================== FAILURES ===================================
______________ TestHardware.test_cant_find_serial[backend(any)] _______________

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x000001D9932D6950>
args = {}
device_iter = <function find.<locals>.device_iter at 0x000001D99330EB70>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x000001D9932F6128>

    def test_cant_find_serial(self):
        from seabreeze.spectrometers import Spectrometer, SeaBreezeError
    
        with pytest.raises(SeaBreezeError):
>           Spectrometer.from_serial_number("i-do-not-exist")

tests\test_spectrometers.py:135: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
=========================== short test summary info ===========================
SKIPPED [1] C:\external-git-repos\python-seabreeze\tests\test_backends.py:61: pyusb_backend openusb not available
SKIPPED [1] C:\external-git-repos\python-seabreeze\tests\test_backends.py:61: pyusb_backend libusb0 not available
SKIPPED [1] C:\external-git-repos\python-seabreeze\tests\test_backends.py:61: pyusb_backend libusb1 not available
SKIPPED [1] tests\test_spectrometers.py:137: no spectrometers connected
SKIPPED [11] tests\test_spectrometers.py: unconditional skip
SKIPPED [1] tests\test_spectrometers.py:178: FIXME: TEST BREAKS OTHER TESTS ON WINDOWS
SKIPPED [1] tests\test_spectrometers.py:271: no spectrometers connected
================== 1 failed, 10 passed, 17 skipped in 1.97s ===================
pytest --seabreeze-backend cseabreeze (with a spectrometer attached)

Note: This resulted into python crashing ("Python has stopped working")

======================================================================= test session starts ========================================================================
platform win32 -- Python 3.7.3, pytest-5.4.3, py-1.8.2, pluggy-0.13.1 -- c:\external-git-repos\python-seabreeze\venv\scripts\python.exe
cachedir: .pytest_cache
rootdir: C:\external-git-repos\python-seabreeze, inifile: pytest.ini
collected 28 items                                                                                                                                                  

tests/test_backends.py::test_seabreeze_installed PASSED                                                                                                       [  3%]
tests/test_backends.py::test_seabreeze_wrong_backend_requested PASSED                                                                                         [  7%]
tests/test_backends.py::test_seabreeze_any_backend_available[cseabreeze] PASSED                                                                               [ 10%]
tests/test_backends.py::test_seabreeze_any_backend_available[pyseabreeze] PASSED                                                                              [ 14%]
tests/test_backends.py::test_seabreeze_cseabreeze_backend_available PASSED                                                                                    [ 17%]
tests/test_backends.py::test_seabreeze_pyseabreeze_backend_available PASSED                                                                                   [ 21%]
tests/test_backends.py::test_seabreeze_cseabreeze_api_init PASSED                                                                                             [ 25%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[any] PASSED                                                                                       [ 28%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[openusb] SKIPPED                                                                                  [ 32%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb0] SKIPPED                                                                                  [ 35%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb1] SKIPPED                                                                                  [ 39%]
tests/test_backends.py::test_seabreeze_compare_backend_feature_interfaces PASSED                                                                              [ 42%]
tests/test_protocol.py::test_pyseabreeze_protocol_messages PASSED                                                                                             [ 46%]
tests/test_spectrometers.py::TestHardware::test_cant_find_serial[backend(cseabreeze)] PASSED                                                                  [ 50%]
tests/test_spectrometers.py::TestHardware::test_device_cleanup_on_exit[backend(cseabreeze)] PASSED                                                            [ 53%]
tests/test_spectrometers.py::TestHardware::test_read_model[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                      [ 57%]
tests/test_spectrometers.py::TestHardware::test_read_serial_number[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                              [ 60%]
tests/test_spectrometers.py::TestHardware::test_crash_may_not_influence_following_tests[USB4000:FLMT02803-backend(cseabreeze)] SKIPPED                        [ 64%]
tests/test_spectrometers.py::TestHardware::test_read_intensities[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                [ 67%]
tests/test_spectrometers.py::TestHardware::test_correct_dark_pixels[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                             [ 71%]
tests/test_spectrometers.py::TestHardware::test_read_wavelengths[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                [ 75%]
tests/test_spectrometers.py::TestHardware::test_read_spectrum[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                   [ 78%]
tests/test_spectrometers.py::TestHardware::test_max_intensity[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                   [ 82%]
tests/test_spectrometers.py::TestHardware::test_integration_time_limits[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                         [ 85%]
tests/test_spectrometers.py::TestHardware::test_integration_time[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                [ 89%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                    [ 92%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode_wrong[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                              [ 96%]
tests/test_spectrometers.py::TestHardware::test_list_devices_dont_close_opened_devices[backend(cseabreeze)] Windows fatal exception: access violation

Current thread 0x00000b30 (most recent call first):
  File "c:\external-git-repos\python-seabreeze\src\seabreeze\spectrometers.py", line 36 in list_devices
  File "C:\external-git-repos\python-seabreeze\tests\test_spectrometers.py", line 282 in test_list_devices_dont_close_opened_devices
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\python.py", line 182 in pytest_pyfunc_call
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\callers.py", line 187 in _multicall
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 87 in <lambda>
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 93 in _hookexec
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\hooks.py", line 286 in __call__
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\python.py", line 1477 in runtest
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 135 in pytest_runtest_call
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\callers.py", line 187 in _multicall
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 87 in <lambda>
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 93 in _hookexec
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\hooks.py", line 286 in __call__
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 217 in <lambda>
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 244 in from_call
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 217 in call_runtest_hook
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 186 in call_and_report
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 100 in runtestprotocol
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 85 in pytest_runtest_protocol
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\callers.py", line 187 in _multicall
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 87 in <lambda>
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 93 in _hookexec
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\hooks.py", line 286 in __call__
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\main.py", line 272 in pytest_runtestloop
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\callers.py", line 187 in _multicall
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 87 in <lambda>
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 93 in _hookexec
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\hooks.py", line 286 in __call__
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\main.py", line 247 in _main
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\main.py", line 191 in wrap_session
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\main.py", line 240 in pytest_cmdline_main
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\callers.py", line 187 in _multicall
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 87 in <lambda>
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 93 in _hookexec
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\hooks.py", line 286 in __call__
  File "c:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\config\__init__.py", line 125 in main
  File "C:\external-git-repos\python-seabreeze\venv\Scripts\pytest.exe\__main__.py", line 9 in <module>
  File "C:\Python\Python37\lib\runpy.py", line 85 in _run_code
  File "C:\Python\Python37\lib\runpy.py", line 193 in _run_module_as_main
pytest --seabreeze-backend pyseabreeze (with a spectrometer attached)
============================= test session starts =============================
platform win32 -- Python 3.7.3, pytest-5.4.3, py-1.8.2, pluggy-0.13.1 -- c:\external-git-repos\python-seabreeze\venv\scripts\python.exe
cachedir: .pytest_cache
rootdir: C:\external-git-repos\python-seabreeze, inifile: pytest.ini
collecting ... collected 28 items

tests/test_backends.py::test_seabreeze_installed PASSED                  [  3%]
tests/test_backends.py::test_seabreeze_wrong_backend_requested PASSED    [  7%]
tests/test_backends.py::test_seabreeze_any_backend_available[cseabreeze] PASSED [ 10%]
tests/test_backends.py::test_seabreeze_any_backend_available[pyseabreeze] PASSED [ 14%]
tests/test_backends.py::test_seabreeze_cseabreeze_backend_available PASSED [ 17%]
tests/test_backends.py::test_seabreeze_pyseabreeze_backend_available PASSED [ 21%]
tests/test_backends.py::test_seabreeze_cseabreeze_api_init PASSED        [ 25%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[any] PASSED  [ 28%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[openusb] SKIPPED [ 32%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb0] SKIPPED [ 35%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb1] SKIPPED [ 39%]
tests/test_backends.py::test_seabreeze_compare_backend_feature_interfaces PASSED [ 42%]
tests/test_protocol.py::test_pyseabreeze_protocol_messages PASSED        [ 46%]
tests/test_spectrometers.py::TestHardware::test_cant_find_serial[backend(pyseabreeze)] FAILED [ 50%]
tests/test_spectrometers.py::TestHardware::test_device_cleanup_on_exit[backend(pyseabreeze)] FAILED [ 53%]
tests/test_spectrometers.py::TestHardware::test_read_model[USB4000:FLMT02803-backend(pyseabreeze)] FAILED [ 57%]
tests/test_spectrometers.py::TestHardware::test_read_serial_number[USB4000:FLMT02803-backend(pyseabreeze)] FAILED [ 60%]
tests/test_spectrometers.py::TestHardware::test_crash_may_not_influence_following_tests[USB4000:FLMT02803-backend(pyseabreeze)] SKIPPED [ 64%]
tests/test_spectrometers.py::TestHardware::test_read_intensities[USB4000:FLMT02803-backend(pyseabreeze)] FAILED [ 67%]
tests/test_spectrometers.py::TestHardware::test_correct_dark_pixels[USB4000:FLMT02803-backend(pyseabreeze)] FAILED [ 71%]
tests/test_spectrometers.py::TestHardware::test_read_wavelengths[USB4000:FLMT02803-backend(pyseabreeze)] FAILED [ 75%]
tests/test_spectrometers.py::TestHardware::test_read_spectrum[USB4000:FLMT02803-backend(pyseabreeze)] FAILED [ 78%]
tests/test_spectrometers.py::TestHardware::test_max_intensity[USB4000:FLMT02803-backend(pyseabreeze)] FAILED [ 82%]
tests/test_spectrometers.py::TestHardware::test_integration_time_limits[USB4000:FLMT02803-backend(pyseabreeze)] FAILED [ 85%]
tests/test_spectrometers.py::TestHardware::test_integration_time[USB4000:FLMT02803-backend(pyseabreeze)] FAILED [ 89%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode[USB4000:FLMT02803-backend(pyseabreeze)] FAILED [ 92%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode_wrong[USB4000:FLMT02803-backend(pyseabreeze)] FAILED [ 96%]
tests/test_spectrometers.py::TestHardware::test_list_devices_dont_close_opened_devices[backend(pyseabreeze)] FAILED [100%]

================================== FAILURES ===================================
__________ TestHardware.test_cant_find_serial[backend(pyseabreeze)] ___________

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FF8C9BF8>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FF8DFD08>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FF8D4D68>

    def test_cant_find_serial(self):
        from seabreeze.spectrometers import Spectrometer, SeaBreezeError
    
        with pytest.raises(SeaBreezeError):
>           Spectrometer.from_serial_number("i-do-not-exist")

tests\test_spectrometers.py:135: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
_______ TestHardware.test_device_cleanup_on_exit[backend(pyseabreeze)] ________

self = <test_spectrometers.TestHardware object at 0x00000229FC76DEF0>

    @pytest.mark.skipif(_SPEC_NUM == 0, reason="no spectrometers connected")
    def test_device_cleanup_on_exit(self):
        """test if opened devices cleanup correctly"""
        # noinspection PyProtectedMember
        backend_name = self.backend._backend_
        # noinspection PyProtectedMember
        from seabreeze.backends import _SeaBreezeConfig as _Config
    
        api_kwargs_str = ", ".join(
            "%s='%s'" % item for item in _Config["_api_kwargs"].items()
        )
    
        cmd = [
            sys.executable,
            "-c",
            "; ".join(
                [
                    "import seabreeze.%s as sb" % backend_name,
                    "d = sb.SeaBreezeAPI(%s).list_devices()[0]" % api_kwargs_str,
                    "d.open()",
                ]
            ),
        ]
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr = p.communicate()
>       assert p.returncode == 0, stderr
E       AssertionError: b'Traceback (most recent call last):\r
E           File "c:\\external-git-repos\\py...e 283, in list_devices\r
E             raise RuntimeError("No pyusb backend found")\r
E         RuntimeError: No pyusb backend found\r
E         '
E       assert 1 == 0
E         +1
E         -0

tests\test_spectrometers.py:162: AssertionError
____ TestHardware.test_read_model[USB4000:FLMT02803-backend(pyseabreeze)] _____

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FF947D90>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FF8F4EA0>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FC761F28>
serial_number = 'FLMT02803'

    def test_read_model(self, serial_number):
        from seabreeze.spectrometers import Spectrometer
    
>       spec = Spectrometer.from_serial_number(serial_number)

tests\test_spectrometers.py:167: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
_ TestHardware.test_read_serial_number[USB4000:FLMT02803-backend(pyseabreeze)] _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FF8F4C80>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FFA24EA0>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FF9AD3C8>
serial_number = 'FLMT02803'

    def test_read_serial_number(self, serial_number):
        from seabreeze.spectrometers import Spectrometer
    
>       spec = Spectrometer.from_serial_number(serial_number)

tests\test_spectrometers.py:174: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
_ TestHardware.test_read_intensities[USB4000:FLMT02803-backend(pyseabreeze)] __

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FFA338C8>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FFA336A8>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FF9678D0>
serial_number = 'FLMT02803'

    def test_read_intensities(self, serial_number):
        from seabreeze.spectrometers import Spectrometer
    
>       spec = Spectrometer.from_serial_number(serial_number)

tests\test_spectrometers.py:191: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
_ TestHardware.test_correct_dark_pixels[USB4000:FLMT02803-backend(pyseabreeze)] _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FFA33510>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FFA33730>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FF9415C0>
serial_number = 'FLMT02803'

    def test_correct_dark_pixels(self, serial_number):
        from seabreeze.spectrometers import SeaBreezeError, Spectrometer
    
>       spec = Spectrometer.from_serial_number(serial_number)

tests\test_spectrometers.py:198: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
_ TestHardware.test_read_wavelengths[USB4000:FLMT02803-backend(pyseabreeze)] __

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FF98EA60>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FF98EEA0>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FFA96518>
serial_number = 'FLMT02803'

    def test_read_wavelengths(self, serial_number):
        from seabreeze.spectrometers import Spectrometer
    
>       spec = Spectrometer.from_serial_number(serial_number)

tests\test_spectrometers.py:211: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
___ TestHardware.test_read_spectrum[USB4000:FLMT02803-backend(pyseabreeze)] ___

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FF98EB70>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FFA9A9D8>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FFB47080>
serial_number = 'FLMT02803'

    def test_read_spectrum(self, serial_number):
        from seabreeze.spectrometers import Spectrometer
    
>       spec = Spectrometer.from_serial_number(serial_number)

tests\test_spectrometers.py:218: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
___ TestHardware.test_max_intensity[USB4000:FLMT02803-backend(pyseabreeze)] ___

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FF98E1E0>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FF98EA60>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FF8D4EB8>
serial_number = 'FLMT02803'

    def test_max_intensity(self, serial_number):
        from seabreeze.spectrometers import Spectrometer
    
>       spec = Spectrometer.from_serial_number(serial_number)

tests\test_spectrometers.py:225: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
_ TestHardware.test_integration_time_limits[USB4000:FLMT02803-backend(pyseabreeze)] _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FF949268>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FF949048>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FF9DE198>
serial_number = 'FLMT02803'

    def test_integration_time_limits(self, serial_number):
        from seabreeze.spectrometers import Spectrometer
    
>       spec = Spectrometer.from_serial_number(serial_number)

tests\test_spectrometers.py:233: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
_ TestHardware.test_integration_time[USB4000:FLMT02803-backend(pyseabreeze)] __

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FF949BF8>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FF949EA0>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FF9AD198>
serial_number = 'FLMT02803'

    def test_integration_time(self, serial_number):
        from seabreeze.spectrometers import Spectrometer, SeaBreezeError
    
>       spec = Spectrometer.from_serial_number(serial_number)

tests\test_spectrometers.py:242: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
___ TestHardware.test_trigger_mode[USB4000:FLMT02803-backend(pyseabreeze)] ____

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FF9496A8>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FF9F0C80>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FFAA2128>
serial_number = 'FLMT02803'

    def test_trigger_mode(self, serial_number):
        from seabreeze.spectrometers import Spectrometer, SeaBreezeError
    
>       spec = Spectrometer.from_serial_number(serial_number)

tests\test_spectrometers.py:261: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
_ TestHardware.test_trigger_mode_wrong[USB4000:FLMT02803-backend(pyseabreeze)] _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FF9F08C8>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FF96D7B8>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FFA7D550>
serial_number = 'FLMT02803'

    def test_trigger_mode_wrong(self, serial_number):
        from seabreeze.spectrometers import Spectrometer, SeaBreezeError
    
>       spec = Spectrometer.from_serial_number(serial_number)

tests\test_spectrometers.py:267: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:115: in from_serial_number
    for dev in list_devices():
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
_ TestHardware.test_list_devices_dont_close_opened_devices[backend(pyseabreeze)] _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
>               backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )

src\seabreeze\pyseabreeze\transport.py:280: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

find_all = True, backend = None
custom_match = <function USBTransport.list_devices.<locals>.<lambda> at 0x00000229FF96DEA0>
args = {}
device_iter = <function find.<locals>.device_iter at 0x00000229FF96D400>
libusb1 = <module 'usb.backend.libusb1' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb1.py'>
libusb0 = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>
openusb = <module 'usb.backend.openusb' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\openusb.py'>
m = <module 'usb.backend.libusb0' from 'c:\\external-git-repos\\python-seabreeze\\venv\\lib\\site-packages\\usb\\backend\\libusb0.py'>

    def find(find_all=False, backend = None, custom_match = None, **args):
        r"""Find an USB device and return it.
    
        find() is the function used to discover USB devices.  You can pass as
        arguments any combination of the USB Device Descriptor fields to match a
        device. For example:
    
        find(idVendor=0x3f4, idProduct=0x2009)
    
        will return the Device object for the device with idVendor field equals
        to 0x3f4 and idProduct equals to 0x2009.
    
        If there is more than one device which matchs the criteria, the first one
        found will be returned. If a matching device cannot be found the function
        returns None. If you want to get all devices, you can set the parameter
        find_all to True, then find will return an iterator with all matched devices.
        If no matching device is found, it will return an empty iterator. Example:
    
        for printer in find(find_all=True, bDeviceClass=7):
            print (printer)
    
        This call will get all the USB printers connected to the system.  (actually
        may be not, because some devices put their class information in the
        Interface Descriptor).
    
        You can also use a customized match criteria:
    
        dev = find(custom_match = lambda d: d.idProduct=0x3f4 and d.idvendor=0x2009)
    
        A more accurate printer finder using a customized match would be like
        so:
    
        def is_printer(dev):
            import usb.util
            if dev.bDeviceClass == 7:
                return True
            for cfg in dev:
                if usb.util.find_descriptor(cfg, bInterfaceClass=7) is not None:
                    return True
    
        for printer in find(find_all=True, custom_match = is_printer):
            print (printer)
    
        Now even if the device class code is in the interface descriptor the
        printer will be found.
    
        You can combine a customized match with device descriptor fields. In this
        case, the fields must match and the custom_match must return True. In the
        our previous example, if we would like to get all printers belonging to the
        manufacturer 0x3f4, the code would be like so:
    
        printers = list(find(find_all=True, idVendor=0x3f4, custom_match=is_printer))
    
        If you want to use find as a 'list all devices' function, just call
        it with find_all = True:
    
        devices = list(find(find_all=True))
    
        Finally, you can pass a custom backend to the find function:
    
        find(backend = MyBackend())
    
        PyUSB has builtin backends for libusb 0.1, libusb 1.0 and OpenUSB.  If you
        do not supply a backend explicitly, find() function will select one of the
        predefineds backends according to system availability.
    
        Backends are explained in the usb.backend module.
        """
        def device_iter(**kwargs):
            for dev in backend.enumerate_devices():
                d = Device(dev, backend)
                tests = (val == getattr(d, key) for key, val in kwargs.items())
                if _interop._all(tests) and (custom_match is None or custom_match(d)):
                    yield d
    
        if backend is None:
            import usb.backend.libusb1 as libusb1
            import usb.backend.libusb0 as libusb0
            import usb.backend.openusb as openusb
    
            for m in (libusb1, openusb, libusb0):
                backend = m.get_backend()
                if backend is not None:
                    _logger.info('find(): using backend "%s"', m.__name__)
                    break
            else:
>               raise NoBackendError('No backend available')
E               usb.core.NoBackendError: No backend available

venv\lib\site-packages\usb\core.py:1263: NoBackendError

During handling of the above exception, another exception occurred:

self = <test_spectrometers.TestHardware object at 0x00000229FF8A3C88>

    @pytest.mark.skipif(_SPEC_NUM == 0, reason="no spectrometers connected")
    def test_list_devices_dont_close_opened_devices(self):
        """test list_devices() interaction with already opened devices"""
        from seabreeze.spectrometers import list_devices
    
>       devices = list_devices()

tests\test_spectrometers.py:276: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
src\seabreeze\spectrometers.py:34: in list_devices
    list_devices._api = _lib.SeaBreezeAPI(**_lib._api_kwargs)
src\seabreeze\pyseabreeze\api.py:56: in __init__
    self.initialize()
src\seabreeze\pyseabreeze\api.py:64: in initialize
    USBTransport.initialize(**self._kwargs)
src\seabreeze\pyseabreeze\transport.py:324: in initialize
    for device in cls.list_devices(**_kwargs):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'seabreeze.pyseabreeze.transport.USBTransport'>, kwargs = {}
_pyusb_backend = None

    @classmethod
    def list_devices(cls, **kwargs):
        """list pyusb devices for all available spectrometers
    
        Note: this includes spectrometers that are currently opened in other
        processes on the machine.
    
        Yields
        ------
        devices : USBTransportHandle
            unique pyusb devices for each available spectrometer
        """
        # check if a specific pyusb backend is requested
        _pyusb_backend = kwargs.get("_pyusb_backend", None)
        # get all matching devices
        try:
            pyusb_devices = usb.core.find(
                find_all=True,
                custom_match=lambda dev: (
                    dev.idVendor == cls.vendor_id and dev.idProduct in cls.product_ids
                ),
                backend=get_pyusb_backend_from_name(name=_pyusb_backend),
            )
        except usb.core.NoBackendError:
>           raise RuntimeError("No pyusb backend found")
E           RuntimeError: No pyusb backend found

src\seabreeze\pyseabreeze\transport.py:283: RuntimeError
============================== warnings summary ===============================
tests\test_spectrometers.py:62
  C:\external-git-repos\python-seabreeze\tests\test_spectrometers.py:62: PytestUnknownMarkWarning: Unknown pytest.mark.cseabreeze - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/latest/mark.html
    marks.append(pytest.mark.cseabreeze)

-- Docs: https://docs.pytest.org/en/latest/warnings.html
=========================== short test summary info ===========================
SKIPPED [1] C:\external-git-repos\python-seabreeze\tests\test_backends.py:61: pyusb_backend openusb not available
SKIPPED [1] C:\external-git-repos\python-seabreeze\tests\test_backends.py:61: pyusb_backend libusb0 not available
SKIPPED [1] C:\external-git-repos\python-seabreeze\tests\test_backends.py:61: pyusb_backend libusb1 not available
SKIPPED [1] tests\test_spectrometers.py:178: FIXME: TEST BREAKS OTHER TESTS ON WINDOWS
============= 14 failed, 10 passed, 4 skipped, 1 warning in 3.04s =============
ap-- commented

Thanks for the test output 👍 💖

Hello darkness windows my old friend... 😅

Okay, so it looks like you are missing a libusb DLL. can you copy the one that worked for you in the virtual env that you use to run the tests, and post the output again?

Notes for me:

  • The tests should output some additional info to deal with common environment setup issues.
  • The failing cseabreeze test suite is a real issue: Windows fatal exception: access violation Need to see if I can reproduce this on my machine
  • the pyseabreeze test suite is failing because of a missing DLL. This should be made obvious in the test output
  • maybe: many windows env issues could be circumvented by making seabreeze_os_setup download the correct DLLs

Hi,

You're welcome! I used libusb-1.0.dll (v.1.0.21 64-bit) and python-seabreeze version with hash a547848. Here's the output:

python -m pytest
======================================================================== test session starts ========================================================================
platform win32 -- Python 3.7.3, pytest-5.4.3, py-1.8.2, pluggy-0.13.1 -- C:\external-git-repos\python-seabreeze\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: C:\external-git-repos\python-seabreeze, inifile: pytest.ini
collected 28 items                                                                                                                                                   

tests/test_backends.py::test_seabreeze_installed PASSED                                                                                                        [  3%]
tests/test_backends.py::test_seabreeze_wrong_backend_requested PASSED                                                                                          [  7%]
tests/test_backends.py::test_seabreeze_any_backend_available[cseabreeze] PASSED                                                                                [ 10%]
tests/test_backends.py::test_seabreeze_any_backend_available[pyseabreeze] PASSED                                                                               [ 14%]
tests/test_backends.py::test_seabreeze_cseabreeze_backend_available PASSED                                                                                     [ 17%]
tests/test_backends.py::test_seabreeze_pyseabreeze_backend_available PASSED                                                                                    [ 21%]
tests/test_backends.py::test_seabreeze_cseabreeze_api_init PASSED                                                                                              [ 25%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[any] PASSED                                                                                        [ 28%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[openusb] SKIPPED                                                                                   [ 32%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb0] SKIPPED                                                                                   [ 35%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb1] PASSED                                                                                    [ 39%]
tests/test_backends.py::test_seabreeze_compare_backend_feature_interfaces PASSED                                                                               [ 42%]
tests/test_protocol.py::test_pyseabreeze_protocol_messages PASSED                                                                                              [ 46%]
tests/test_spectrometers.py::TestHardware::test_cant_find_serial[backend(any)] PASSED                                                                          [ 50%]
tests/test_spectrometers.py::TestHardware::test_device_cleanup_on_exit[backend(any)] SKIPPED                                                                   [ 53%]
tests/test_spectrometers.py::TestHardware::test_read_model[no-spectrometer-backend(any)] SKIPPED                                                               [ 57%]
tests/test_spectrometers.py::TestHardware::test_read_serial_number[no-spectrometer-backend(any)] SKIPPED                                                       [ 60%]
tests/test_spectrometers.py::TestHardware::test_crash_may_not_influence_following_tests[no-spectrometer-backend(any)] SKIPPED                                  [ 64%]
tests/test_spectrometers.py::TestHardware::test_read_intensities[no-spectrometer-backend(any)] SKIPPED                                                         [ 67%]
tests/test_spectrometers.py::TestHardware::test_correct_dark_pixels[no-spectrometer-backend(any)] SKIPPED                                                      [ 71%]
tests/test_spectrometers.py::TestHardware::test_read_wavelengths[no-spectrometer-backend(any)] SKIPPED                                                         [ 75%]
tests/test_spectrometers.py::TestHardware::test_read_spectrum[no-spectrometer-backend(any)] SKIPPED                                                            [ 78%]
tests/test_spectrometers.py::TestHardware::test_max_intensity[no-spectrometer-backend(any)] SKIPPED                                                            [ 82%]
tests/test_spectrometers.py::TestHardware::test_integration_time_limits[no-spectrometer-backend(any)] SKIPPED                                                  [ 85%]
tests/test_spectrometers.py::TestHardware::test_integration_time[no-spectrometer-backend(any)] SKIPPED                                                         [ 89%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode[no-spectrometer-backend(any)] SKIPPED                                                             [ 92%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode_wrong[no-spectrometer-backend(any)] SKIPPED                                                       [ 96%]
tests/test_spectrometers.py::TestHardware::test_list_devices_dont_close_opened_devices[backend(any)] SKIPPED                                                   [100%]

====================================================================== short test summary info ======================================================================
SKIPPED [1] C:\external-git-repos\python-seabreeze\tests\test_backends.py:61: pyusb_backend openusb not available
SKIPPED [1] C:\external-git-repos\python-seabreeze\tests\test_backends.py:61: pyusb_backend libusb0 not available
SKIPPED [1] tests\test_spectrometers.py:137: no spectrometers connected
SKIPPED [11] tests\test_spectrometers.py: unconditional skip
SKIPPED [1] tests\test_spectrometers.py:178: FIXME: TEST BREAKS OTHER TESTS ON WINDOWS
SKIPPED [1] tests\test_spectrometers.py:271: no spectrometers connected
================================================================== 12 passed, 16 skipped in 3.25s ===================================================================
python -m pytest --seabreeze-backend cseabreeze (with spectrometer attached)

Note: This resulted into python crashing ("Python has stopped working")

======================================================================== test session starts ========================================================================
platform win32 -- Python 3.7.3, pytest-5.4.3, py-1.8.2, pluggy-0.13.1 -- C:\external-git-repos\python-seabreeze\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: C:\external-git-repos\python-seabreeze, inifile: pytest.ini
collected 28 items                                                                                                                                                   

tests/test_backends.py::test_seabreeze_installed PASSED                                                                                                        [  3%]
tests/test_backends.py::test_seabreeze_wrong_backend_requested PASSED                                                                                          [  7%]
tests/test_backends.py::test_seabreeze_any_backend_available[cseabreeze] PASSED                                                                                [ 10%]
tests/test_backends.py::test_seabreeze_any_backend_available[pyseabreeze] PASSED                                                                               [ 14%]
tests/test_backends.py::test_seabreeze_cseabreeze_backend_available PASSED                                                                                     [ 17%]
tests/test_backends.py::test_seabreeze_pyseabreeze_backend_available PASSED                                                                                    [ 21%]
tests/test_backends.py::test_seabreeze_cseabreeze_api_init PASSED                                                                                              [ 25%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[any] PASSED                                                                                        [ 28%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[openusb] SKIPPED                                                                                   [ 32%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb0] SKIPPED                                                                                   [ 35%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb1] PASSED                                                                                    [ 39%]
tests/test_backends.py::test_seabreeze_compare_backend_feature_interfaces PASSED                                                                               [ 42%]
tests/test_protocol.py::test_pyseabreeze_protocol_messages PASSED                                                                                              [ 46%]
tests/test_spectrometers.py::TestHardware::test_cant_find_serial[backend(cseabreeze)] PASSED                                                                   [ 50%]
tests/test_spectrometers.py::TestHardware::test_device_cleanup_on_exit[backend(cseabreeze)] PASSED                                                             [ 53%]
tests/test_spectrometers.py::TestHardware::test_read_model[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                       [ 57%]
tests/test_spectrometers.py::TestHardware::test_read_serial_number[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                               [ 60%]
tests/test_spectrometers.py::TestHardware::test_crash_may_not_influence_following_tests[USB4000:FLMT02803-backend(cseabreeze)] SKIPPED                         [ 64%]
tests/test_spectrometers.py::TestHardware::test_read_intensities[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                 [ 67%]
tests/test_spectrometers.py::TestHardware::test_correct_dark_pixels[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                              [ 71%]
tests/test_spectrometers.py::TestHardware::test_read_wavelengths[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                 [ 75%]
tests/test_spectrometers.py::TestHardware::test_read_spectrum[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                    [ 78%]
tests/test_spectrometers.py::TestHardware::test_max_intensity[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                    [ 82%]
tests/test_spectrometers.py::TestHardware::test_integration_time_limits[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                          [ 85%]
tests/test_spectrometers.py::TestHardware::test_integration_time[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                 [ 89%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                                     [ 92%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode_wrong[USB4000:FLMT02803-backend(cseabreeze)] PASSED                                               [ 96%]
tests/test_spectrometers.py::TestHardware::test_list_devices_dont_close_opened_devices[backend(cseabreeze)] Windows fatal exception: code 0xc0000374

Current thread 0x00005844 (most recent call first):
  File "c:\external-git-repos\python-seabreeze\src\seabreeze\spectrometers.py", line 36 in list_devices
  File "C:\external-git-repos\python-seabreeze\tests\test_spectrometers.py", line 282 in test_list_devices_dont_close_opened_devices
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\python.py", line 182 in pytest_pyfunc_call
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\callers.py", line 187 in _multicall
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 87 in <lambda>
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 93 in _hookexec
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\hooks.py", line 286 in __call__
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\python.py", line 1477 in runtest
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 135 in pytest_runtest_call
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\callers.py", line 187 in _multicall
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 87 in <lambda>
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 93 in _hookexec
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\hooks.py", line 286 in __call__
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 217 in <lambda>
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 244 in from_call
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 217 in call_runtest_hook
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 186 in call_and_report
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 100 in runtestprotocol
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\runner.py", line 85 in pytest_runtest_protocol
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\callers.py", line 187 in _multicall
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 87 in <lambda>
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 93 in _hookexec
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\hooks.py", line 286 in __call__
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\main.py", line 272 in pytest_runtestloop
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\callers.py", line 187 in _multicall
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 87 in <lambda>
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 93 in _hookexec
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\hooks.py", line 286 in __call__
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\main.py", line 247 in _main
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\main.py", line 191 in wrap_session
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\main.py", line 240 in pytest_cmdline_main
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\callers.py", line 187 in _multicall
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 87 in <lambda>
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\manager.py", line 93 in _hookexec
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pluggy\hooks.py", line 286 in __call__
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\_pytest\config\__init__.py", line 125 in main
  File "C:\external-git-repos\python-seabreeze\venv\lib\site-packages\pytest\__main__.py", line 7 in <module>
  File "C:\Python\Python37\lib\runpy.py", line 85 in _run_code
  File "C:\Python\Python37\lib\runpy.py", line 193 in _run_module_as_main
python -m pytest --seabreeze-backend pyseabreeze (with spectrometer attached)
======================================================================== test session starts ========================================================================
platform win32 -- Python 3.7.3, pytest-5.4.3, py-1.8.2, pluggy-0.13.1 -- C:\external-git-repos\python-seabreeze\venv\Scripts\python.exe
cachedir: .pytest_cache
rootdir: C:\external-git-repos\python-seabreeze, inifile: pytest.ini
collected 28 items                                                                                                                                                   

tests/test_backends.py::test_seabreeze_installed PASSED                                                                                                        [  3%]
tests/test_backends.py::test_seabreeze_wrong_backend_requested PASSED                                                                                          [  7%]
tests/test_backends.py::test_seabreeze_any_backend_available[cseabreeze] PASSED                                                                                [ 10%]
tests/test_backends.py::test_seabreeze_any_backend_available[pyseabreeze] PASSED                                                                               [ 14%]
tests/test_backends.py::test_seabreeze_cseabreeze_backend_available PASSED                                                                                     [ 17%]
tests/test_backends.py::test_seabreeze_pyseabreeze_backend_available PASSED                                                                                    [ 21%]
tests/test_backends.py::test_seabreeze_cseabreeze_api_init PASSED                                                                                              [ 25%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[any] PASSED                                                                                        [ 28%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[openusb] SKIPPED                                                                                   [ 32%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb0] SKIPPED                                                                                   [ 35%]
tests/test_backends.py::test_seabreeze_pyseabreeze_api_init[libusb1] PASSED                                                                                    [ 39%]
tests/test_backends.py::test_seabreeze_compare_backend_feature_interfaces PASSED                                                                               [ 42%]
tests/test_protocol.py::test_pyseabreeze_protocol_messages PASSED                                                                                              [ 46%]
tests/test_spectrometers.py::TestHardware::test_cant_find_serial[backend(pyseabreeze)] PASSED                                                                  [ 50%]
tests/test_spectrometers.py::TestHardware::test_device_cleanup_on_exit[backend(pyseabreeze)] PASSED                                                            [ 53%]
tests/test_spectrometers.py::TestHardware::test_read_model[USB4000:FLMT02803-backend(pyseabreeze)] PASSED                                                      [ 57%]
tests/test_spectrometers.py::TestHardware::test_read_serial_number[USB4000:FLMT02803-backend(pyseabreeze)] PASSED                                              [ 60%]
tests/test_spectrometers.py::TestHardware::test_crash_may_not_influence_following_tests[USB4000:FLMT02803-backend(pyseabreeze)] SKIPPED                        [ 64%]
tests/test_spectrometers.py::TestHardware::test_read_intensities[USB4000:FLMT02803-backend(pyseabreeze)] PASSED                                                [ 67%]
tests/test_spectrometers.py::TestHardware::test_correct_dark_pixels[USB4000:FLMT02803-backend(pyseabreeze)] PASSED                                             [ 71%]
tests/test_spectrometers.py::TestHardware::test_read_wavelengths[USB4000:FLMT02803-backend(pyseabreeze)] PASSED                                                [ 75%]
tests/test_spectrometers.py::TestHardware::test_read_spectrum[USB4000:FLMT02803-backend(pyseabreeze)] PASSED                                                   [ 78%]
tests/test_spectrometers.py::TestHardware::test_max_intensity[USB4000:FLMT02803-backend(pyseabreeze)] PASSED                                                   [ 82%]
tests/test_spectrometers.py::TestHardware::test_integration_time_limits[USB4000:FLMT02803-backend(pyseabreeze)] PASSED                                         [ 85%]
tests/test_spectrometers.py::TestHardware::test_integration_time[USB4000:FLMT02803-backend(pyseabreeze)] PASSED                                                [ 89%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode[USB4000:FLMT02803-backend(pyseabreeze)] PASSED                                                    [ 92%]
tests/test_spectrometers.py::TestHardware::test_trigger_mode_wrong[USB4000:FLMT02803-backend(pyseabreeze)] PASSED                                              [ 96%]
tests/test_spectrometers.py::TestHardware::test_list_devices_dont_close_opened_devices[backend(pyseabreeze)] PASSED                                            [100%]

========================================================================= warnings summary ==========================================================================
tests\test_spectrometers.py:62
  C:\external-git-repos\python-seabreeze\tests\test_spectrometers.py:62: PytestUnknownMarkWarning: Unknown pytest.mark.cseabreeze - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/latest/mark.html
    marks.append(pytest.mark.cseabreeze)

tests\test_spectrometers.py:64
  C:\external-git-repos\python-seabreeze\tests\test_spectrometers.py:64: PytestUnknownMarkWarning: Unknown pytest.mark.pyseabreeze - is this a typo?  You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/latest/mark.html
    marks.append(pytest.mark.pyseabreeze)

tests/test_spectrometers.py::TestHardware::test_correct_dark_pixels[USB4000:FLMT02803-backend(pyseabreeze)]
  c:\external-git-repos\python-seabreeze\src\seabreeze\spectrometers.py:192: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
    dark_offset = numpy.mean(out[self._dp]) if self._dp else 0.0

-- Docs: https://docs.pytest.org/en/latest/warnings.html
====================================================================== short test summary info ======================================================================
SKIPPED [1] C:\external-git-repos\python-seabreeze\tests\test_backends.py:61: pyusb_backend openusb not available
SKIPPED [1] C:\external-git-repos\python-seabreeze\tests\test_backends.py:61: pyusb_backend libusb0 not available
SKIPPED [1] tests\test_spectrometers.py:178: FIXME: TEST BREAKS OTHER TESTS ON WINDOWS
============================================================= 25 passed, 3 skipped, 3 warnings in 5.80s =============================================================

Just a quick comment to the libusb.dlls: The automatic download could become troublesome because if I remember correctly, the newer 1.0.23 libusb dlls do not work for some reason (at least when I tested), so the dll-downloader should have some options. Of course it would be possible to bundle the dll's with the python-seabreeze (if license-wise ok), select 32 or 64 bit dll based on python version and the just try some simple function with all of the dll's, and the first dll with which everything works is the "correct one". :D I would think that a helpful error message saying "Probably missing libusb-x.x.dll" would be ok, too. And maybe some link where it can be downloaded and instructions where to put it (in the Scripts-folder). There could be some simple test to perform of the dll's are found correctly or not ("try to connect to a spectrometer"?).

ap-- commented

With version v1.2.0 the test have been completely refactored.

I'll close this issue in favour of a more specific issue.

ap-- commented

Thanks again for you help @np-8