diff --git a/src/ophyd_async/core/_detector.py b/src/ophyd_async/core/_detector.py index f596e6351e..b2cc788ed2 100644 --- a/src/ophyd_async/core/_detector.py +++ b/src/ophyd_async/core/_detector.py @@ -312,9 +312,9 @@ async def prepare(self, value: TriggerInfo) -> None: value: TriggerInfo describing how to trigger the detector """ if value.trigger != DetectorTrigger.INTERNAL: - assert ( - value.deadtime - ), "Deadtime must be supplied when in externally triggered mode" + assert value.deadtime, ( + "Deadtime must be supplied when in externally triggered mode" + ) if value.deadtime: required = self._controller.get_deadtime(value.livetime) assert required <= value.deadtime, ( diff --git a/src/ophyd_async/core/_device.py b/src/ophyd_async/core/_device.py index 8f12607591..eee5b8b339 100644 --- a/src/ophyd_async/core/_device.py +++ b/src/ophyd_async/core/_device.py @@ -275,9 +275,10 @@ def _caller_locals(self) -> dict[str, Any]: caller_frame = tb.tb_frame while caller_frame.f_locals.get("self", None) is self: caller_frame = caller_frame.f_back - assert ( - caller_frame - ), "No previous frame to the one with self in it, this shouldn't happen" + assert caller_frame, ( + "No previous frame to the one with self in it, " + "this shouldn't happen" + ) return caller_frame.f_locals.copy() def __enter__(self) -> DeviceProcessor: diff --git a/src/ophyd_async/core/_device_filler.py b/src/ophyd_async/core/_device_filler.py index dfca58981f..754275fd98 100644 --- a/src/ophyd_async/core/_device_filler.py +++ b/src/ophyd_async/core/_device_filler.py @@ -254,9 +254,9 @@ def fill_child_device( # We need to add a new entry to a DeviceVector vector = self._ensure_device_vector(name) vector_device_type = self._vector_device_type[name] or device_type - assert issubclass( - vector_device_type, Device - ), f"{vector_device_type} is not a Device" + assert issubclass(vector_device_type, Device), ( + f"{vector_device_type} is not a Device" + ) connector = self._device_connector_factory() vector[vector_index] = vector_device_type(connector=connector) elif child := getattr(self._device, name, None): diff --git a/src/ophyd_async/core/_utils.py b/src/ophyd_async/core/_utils.py index e89131ea75..16368204a3 100644 --- a/src/ophyd_async/core/_utils.py +++ b/src/ophyd_async/core/_utils.py @@ -94,7 +94,7 @@ def _format_sub_errors(self, name: str, error: Exception, indent="") -> str: def format_error_string(self, indent="") -> str: if not isinstance(self._errors, dict) and not isinstance(self._errors, str): raise RuntimeError( - f"Unexpected type `{type(self._errors)}` " "expected `str` or `dict`" + f"Unexpected type `{type(self._errors)}` expected `str` or `dict`" ) if isinstance(self._errors, str): diff --git a/src/ophyd_async/epics/adaravis/_aravis_controller.py b/src/ophyd_async/epics/adaravis/_aravis_controller.py index e78fdf21aa..b42463a9a3 100644 --- a/src/ophyd_async/epics/adaravis/_aravis_controller.py +++ b/src/ophyd_async/epics/adaravis/_aravis_controller.py @@ -36,7 +36,7 @@ async def prepare(self, trigger_info: TriggerInfo): else: image_mode = adcore.ImageMode.MULTIPLE if (exposure := trigger_info.livetime) is not None: - asyncio.gather(self.driver.acquire_time.set(exposure)) + await self.driver.acquire_time.set(exposure) trigger_mode, trigger_source = self._get_trigger_info(trigger_info.trigger) # trigger mode must be set first and on it's own! diff --git a/src/ophyd_async/epics/adcore/_core_logic.py b/src/ophyd_async/epics/adcore/_core_logic.py index a0da204374..b35a1b962e 100644 --- a/src/ophyd_async/epics/adcore/_core_logic.py +++ b/src/ophyd_async/epics/adcore/_core_logic.py @@ -35,9 +35,9 @@ def __init__( self._arm_status: AsyncStatus | None = None async def prepare(self, trigger_info: TriggerInfo) -> None: - assert ( - trigger_info.trigger == DetectorTrigger.INTERNAL - ), "fly scanning (i.e. external triggering) is not supported for this device" + assert trigger_info.trigger == DetectorTrigger.INTERNAL, ( + "fly scanning (i.e. external triggering) is not supported for this device" + ) self.frame_timeout = ( DEFAULT_TIMEOUT + await self.driver.acquire_time.get_value() ) diff --git a/src/ophyd_async/epics/adcore/_core_writer.py b/src/ophyd_async/epics/adcore/_core_writer.py index 4102778b6f..0c131677a4 100644 --- a/src/ophyd_async/epics/adcore/_core_writer.py +++ b/src/ophyd_async/epics/adcore/_core_writer.py @@ -112,9 +112,9 @@ async def begin_capture(self) -> None: self.fileio.file_number.set(0), ) - assert ( - await self.fileio.file_path_exists.get_value() - ), f"File path {info.directory_path} for file plugin does not exist!" + assert await self.fileio.file_path_exists.get_value(), ( + f"File path {info.directory_path} for file plugin does not exist!" + ) # Overwrite num_capture to go forever await self.fileio.num_capture.set(0) diff --git a/src/ophyd_async/epics/core/_aioca.py b/src/ophyd_async/epics/core/_aioca.py index ff2fff15b5..44f0d1e5e8 100644 --- a/src/ophyd_async/epics/core/_aioca.py +++ b/src/ophyd_async/epics/core/_aioca.py @@ -322,9 +322,9 @@ async def get_setpoint(self) -> SignalDatatypeT: def set_callback(self, callback: Callback[Reading[SignalDatatypeT]] | None) -> None: if callback: - assert ( - not self.subscription - ), "Cannot set a callback when one is already set" + assert not self.subscription, ( + "Cannot set a callback when one is already set" + ) self.subscription = camonitor( self.read_pv, lambda v: callback(self._make_reading(v)), diff --git a/src/ophyd_async/epics/core/_p4p.py b/src/ophyd_async/epics/core/_p4p.py index 1f5c3acbe6..73fc919cb8 100644 --- a/src/ophyd_async/epics/core/_p4p.py +++ b/src/ophyd_async/epics/core/_p4p.py @@ -404,9 +404,9 @@ async def get_setpoint(self) -> SignalDatatypeT: def set_callback(self, callback: Callback[Reading[SignalDatatypeT]] | None) -> None: if callback: - assert ( - not self.subscription - ), "Cannot set a callback when one is already set" + assert not self.subscription, ( + "Cannot set a callback when one is already set" + ) async def async_callback(v): callback(self._make_reading(v)) diff --git a/src/ophyd_async/epics/motor.py b/src/ophyd_async/epics/motor.py index c512f4ba03..2ffd69cde2 100644 --- a/src/ophyd_async/epics/motor.py +++ b/src/ophyd_async/epics/motor.py @@ -125,9 +125,9 @@ async def prepare(self, value: FlyMotorInfo): @AsyncStatus.wrap async def kickoff(self): """Begin moving motor from prepared position to final position.""" - assert ( - self._fly_completed_position - ), "Motor must be prepared before attempting to kickoff" + assert self._fly_completed_position, ( + "Motor must be prepared before attempting to kickoff" + ) self._fly_status = self.set( self._fly_completed_position, timeout=self._fly_timeout diff --git a/src/ophyd_async/sim/_pattern_detector/_pattern_generator.py b/src/ophyd_async/sim/_pattern_detector/_pattern_generator.py index 01c54c8245..d2882726e9 100644 --- a/src/ophyd_async/sim/_pattern_detector/_pattern_generator.py +++ b/src/ophyd_async/sim/_pattern_detector/_pattern_generator.py @@ -69,9 +69,9 @@ def write_data_to_dataset(self, path: str, data_shape: tuple[int, ...], data): """Write data to named dataset, resizing to fit and flushing after.""" assert self._handle_for_h5_file, "no file has been opened!" dset = self._handle_for_h5_file[path] - assert isinstance( - dset, h5py.Dataset - ), f"Expected {path} to be dataset, got {dset}" + assert isinstance(dset, h5py.Dataset), ( + f"Expected {path} to be dataset, got {dset}" + ) dset.resize((self.image_counter + 1,) + data_shape) dset[self.image_counter] = data dset.flush() diff --git a/src/ophyd_async/tango/core/_tango_transport.py b/src/ophyd_async/tango/core/_tango_transport.py index 77394905f6..32c197a6ea 100644 --- a/src/ophyd_async/tango/core/_tango_transport.py +++ b/src/ophyd_async/tango/core/_tango_transport.py @@ -210,11 +210,11 @@ async def wait_for_reply(rd: int, to: float | None): await asyncio.sleep(A_BIT) if to and (time.time() - start_time > to): raise TimeoutError( - f"{self._name} attr put failed:" f" Timeout" + f"{self._name} attr put failed: Timeout" ) from exc else: raise RuntimeError( - f"{self._name} device failure:" f" {exc.args[0].desc}" + f"{self._name} device failure: {exc.args[0].desc}" ) from exc return AsyncStatus(wait_for_reply(rid, timeout)) @@ -422,7 +422,7 @@ async def _put(): raise TimeoutError(f"{self._name} command failed: Timeout") from te except DevFailed as de: raise RuntimeError( - f"{self._name} device" f" failure: {de.args[0].desc}" + f"{self._name} device failure: {de.args[0].desc}" ) from de else: @@ -446,8 +446,7 @@ async def wait_for_reply(rd: int, to: float | None): ) from de_exc else: raise RuntimeError( - f"{self._name} device failure:" - f" {de_exc.args[0].desc}" + f"{self._name} device failure: {de_exc.args[0].desc}" ) from de_exc return AsyncStatus(wait_for_reply(rid, timeout)) @@ -739,11 +738,11 @@ def set_callback(self, callback: Callback | None) -> None: self.proxies[self.read_trl].subscribe_callback(callback) # type: ignore except AssertionError as ae: raise RuntimeError( - "Cannot set a callback when one" " is already set" + "Cannot set a callback when one is already set" ) from ae except RuntimeError as exc: raise RuntimeError( - f"Cannot set callback" f" for {self.read_trl}. {exc}" + f"Cannot set callback for {self.read_trl}. {exc}" ) from exc else: diff --git a/src/ophyd_async/testing/_assert.py b/src/ophyd_async/testing/_assert.py index 48d8a35538..7b1623127b 100644 --- a/src/ophyd_async/testing/_assert.py +++ b/src/ophyd_async/testing/_assert.py @@ -79,12 +79,12 @@ async def assert_reading( """ actual_reading = await readable.read() - assert ( - _approx_readable_value(expected_reading) == actual_reading - ), _generate_assert_error_msg( - name=readable.name, - expected_result=expected_reading, - actual_result=actual_reading, + assert _approx_readable_value(expected_reading) == actual_reading, ( + _generate_assert_error_msg( + name=readable.name, + expected_result=expected_reading, + actual_result=actual_reading, + ) ) @@ -109,12 +109,12 @@ async def assert_configuration( """ actual_configurable = await configurable.read_configuration() - assert ( - _approx_readable_value(configuration) == actual_configurable - ), _generate_assert_error_msg( - name=configurable.name, - expected_result=configuration, - actual_result=actual_configurable, + assert _approx_readable_value(configuration) == actual_configurable, ( + _generate_assert_error_msg( + name=configurable.name, + expected_result=configuration, + actual_result=actual_configurable, + ) ) diff --git a/src/ophyd_async/testing/_mock_signal_utils.py b/src/ophyd_async/testing/_mock_signal_utils.py index 683666e6b4..b5077b637c 100644 --- a/src/ophyd_async/testing/_mock_signal_utils.py +++ b/src/ophyd_async/testing/_mock_signal_utils.py @@ -22,9 +22,9 @@ def get_mock(device: Device | Signal) -> Mock: def _get_mock_signal_backend(signal: Signal) -> MockSignalBackend: connector = signal._connector # noqa: SLF001 assert isinstance(connector, SignalConnector), f"Expected Signal, got {signal}" - assert isinstance( - connector.backend, MockSignalBackend - ), f"Signal {signal} not connected in mock mode" + assert isinstance(connector.backend, MockSignalBackend), ( + f"Signal {signal} not connected in mock mode" + ) return connector.backend diff --git a/tests/conftest.py b/tests/conftest.py index 69d4cfdf4f..bd90848e06 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -93,6 +93,7 @@ def _error_and_kill_pending_tasks( task for task in asyncio.all_tasks(loop) if (coro := task.get_coro()) is not None + and hasattr(coro, "__name__") and coro.__name__ not in _ALLOWED_PYTEST_TASKS and not task.done() } @@ -112,7 +113,7 @@ def _error_and_kill_pending_tasks( @pytest.fixture(autouse=True, scope="function") -def fail_test_on_unclosed_tasks(request: FixtureRequest): +async def fail_test_on_unclosed_tasks(request: FixtureRequest): """ Used on every test to ensure failure if there are pending tasks by the end of the test. diff --git a/tests/core/test_mock_signal_backend.py b/tests/core/test_mock_signal_backend.py index 8370e7340f..482cd6d769 100644 --- a/tests/core/test_mock_signal_backend.py +++ b/tests/core/test_mock_signal_backend.py @@ -320,9 +320,7 @@ async def test_reset_mock_put_calls(mock_signals): # Replacing spaces because they change between runners # (e.g the github actions runner has more) assert str(exc.value).replace(" ", "").replace("\n", "") == ( - "expectedcallnotfound." - "Expected:put('test_value',wait=)" - "Actual:notcalled." + "expectedcallnotfound.Expected:put('test_value',wait=)Actual:notcalled." ) diff --git a/tests/core/test_utils.py b/tests/core/test_utils.py index 7a1f07a2a9..76d334f7f4 100644 --- a/tests/core/test_utils.py +++ b/tests/core/test_utils.py @@ -284,7 +284,7 @@ async def test_combining_top_level_signal_and_child_device(): async def test_format_error_string_input(): with pytest.raises( RuntimeError, - match=("Unexpected type `` " "expected `str` or `dict`"), + match=("Unexpected type `` expected `str` or `dict`"), ): not_connected = NotConnected(123) str(not_connected) diff --git a/tests/epics/adaravis/test_aravis.py b/tests/epics/adaravis/test_aravis.py index 6382306d23..fd83f5d45e 100644 --- a/tests/epics/adaravis/test_aravis.py +++ b/tests/epics/adaravis/test_aravis.py @@ -1,4 +1,5 @@ from typing import cast +from unittest.mock import AsyncMock, patch import pytest @@ -133,17 +134,24 @@ async def test_can_decribe_collect( async def test_unsupported_trigger_excepts(test_adaravis: adaravis.AravisDetector): - with pytest.raises( - ValueError, - # str(EnumClass.value) handling changed in Python 3.11 - match=r"AravisController only supports the following trigger types: .* but", - ): - await test_adaravis.prepare( - TriggerInfo( - number_of_triggers=0, - trigger=DetectorTrigger.VARIABLE_GATE, - deadtime=1, - livetime=1, - frame_timeout=3, + with patch( + "ophyd_async.epics.adcore._hdf_writer.ADHDFWriter.open", new_callable=AsyncMock + ) as mock_open: + with pytest.raises( + ValueError, + # str(EnumClass.value) handling changed in Python 3.11 + match=( + "AravisController only supports the following trigger types: .* but" + ), + ): + await test_adaravis.prepare( + TriggerInfo( + number_of_triggers=0, + trigger=DetectorTrigger.VARIABLE_GATE, + deadtime=1, + livetime=1, + frame_timeout=3, + ) ) - ) + + mock_open.assert_called_once() diff --git a/tests/epics/adpilatus/test_pilatus.py b/tests/epics/adpilatus/test_pilatus.py index e5c8613e03..a1f3bbc5ef 100644 --- a/tests/epics/adpilatus/test_pilatus.py +++ b/tests/epics/adpilatus/test_pilatus.py @@ -1,7 +1,7 @@ import asyncio from collections.abc import Awaitable, Callable from typing import cast -from unittest.mock import patch +from unittest.mock import AsyncMock, patch import pytest @@ -103,19 +103,24 @@ async def test_hints_from_hdf_writer(test_adpilatus: adpilatus.PilatusDetector): async def test_unsupported_trigger_excepts(test_adpilatus: adpilatus.PilatusDetector): - with pytest.raises( - ValueError, - # str(EnumClass.value) handling changed in Python 3.11 - match=r"PilatusController only supports the following trigger types: .* but", - ): - await test_adpilatus.prepare( - TriggerInfo( - number_of_triggers=1, - trigger=DetectorTrigger.EDGE_TRIGGER, - deadtime=1.0, - livetime=1.0, + open = "ophyd_async.epics.adcore._hdf_writer.ADHDFWriter.open" + with patch(open, new_callable=AsyncMock) as mock_open: + with pytest.raises( + ValueError, + # str(EnumClass.value) handling changed in Python 3.11 + match=( + "PilatusController only supports the following trigger types: .* but" + ), + ): + await test_adpilatus.prepare( + TriggerInfo( + number_of_triggers=1, + trigger=DetectorTrigger.EDGE_TRIGGER, + deadtime=1.0, + livetime=1.0, + ) ) - ) + mock_open.assert_called_once() async def test_exposure_time_and_acquire_period_set( diff --git a/tests/epics/signal/test_signals.py b/tests/epics/signal/test_signals.py index e7fa6c3cbf..fdb7f44a76 100644 --- a/tests/epics/signal/test_signals.py +++ b/tests/epics/signal/test_signals.py @@ -623,7 +623,7 @@ async def test_signals_created_for_not_prec_0_float_cannot_use_int( sig = epics_signal_rw(int, ioc_devices.get_pv(protocol, "float_prec_1")) with pytest.raises( TypeError, - match="float_prec_1 with inferred datatype float" ".* cannot be coerced to int", + match="float_prec_1 with inferred datatype float.* cannot be coerced to int", ): await sig.connect() diff --git a/tests/sim/test_sim_detector.py b/tests/sim/test_sim_detector.py index 3f2e0f3557..46dd8f94c4 100644 --- a/tests/sim/test_sim_detector.py +++ b/tests/sim/test_sim_detector.py @@ -14,9 +14,9 @@ async def test_sim_pattern_detector_initialization( sim_pattern_detector: PatternDetector, ): - assert ( - sim_pattern_detector.pattern_generator - ), "PatternGenerator was not initialized correctly." + assert sim_pattern_detector.pattern_generator, ( + "PatternGenerator was not initialized correctly." + ) async def test_detector_creates_controller_and_writer(