diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0cd5b41e..7a5e7571 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -34,7 +34,7 @@ repos: - id: remove-tabs - id: forbid-tabs - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.27.4 + rev: 0.28.0 hooks: - id: check-readthedocs - id: check-dependabot diff --git a/CHANGELOG.md b/CHANGELOG.md index 7292bfe9..f34c118c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ Things to be included in the next release go here. ### Fixed - Fixed the code that detects VISA resource expressions to be able to detect SOCKET resource expressions properly. +- Fixed PI device close method to catch VisaIOErrors and throw a warning, rather than an exception, when closing a PI device connection. ______________________________________________________________________ diff --git a/src/tm_devices/drivers/pi/pi_device.py b/src/tm_devices/drivers/pi/pi_device.py index 5629815c..c1c113ef 100644 --- a/src/tm_devices/drivers/pi/pi_device.py +++ b/src/tm_devices/drivers/pi/pi_device.py @@ -4,6 +4,7 @@ import os import socket import time +import warnings from abc import ABC, abstractmethod from contextlib import contextmanager @@ -13,6 +14,7 @@ from packaging.version import Version from pyvisa import constants as visa_constants +from pyvisa import VisaIOError from tm_devices.drivers.device import Device from tm_devices.drivers.pi._ieee488_2_commands import IEEE4882Commands @@ -816,7 +818,12 @@ def _cleanup(self) -> None: def _close(self) -> None: """Close this device and all its used resources and components.""" - self._visa_resource.close() + try: + self._visa_resource.close() + except VisaIOError as error: + warnings.warn( + f"Error encountered while closing the visa resource:\n{error}", stacklevel=2 + ) self._visa_resource = None # pyright: ignore[reportAttributeAccessIssue] self._is_open = False diff --git a/tests/test_pi_device.py b/tests/test_pi_device.py index 5ac4ef71..a52aed62 100644 --- a/tests/test_pi_device.py +++ b/tests/test_pi_device.py @@ -113,3 +113,16 @@ def test_pi_device( # noqa: PLR0915 stdout = capsys.readouterr().out assert f"VISA timeout set to: {old_timeout}ms" in stdout assert scope.visa_timeout == old_timeout + + # Test closing a device that is powered off + with mock.patch( + "pyvisa.resources.resource.Resource.close", + mock.MagicMock(side_effect=visa.VisaIOError(123)), + ), pytest.warns(Warning): + scope._close() # noqa: SLF001 + assert scope._visa_resource is None # noqa: SLF001 + assert not scope._is_open # noqa: SLF001 + + # Re-open the device for device manager teardown + with mock.patch.dict("os.environ", {"TM_DEVICES_UNIT_TESTS_REBOOT_ALLOW": "true"}, clear=True): + assert scope._open() # noqa: SLF001