From c541eac62f5ad4ad9df8aca60a684a8b17ec592b Mon Sep 17 00:00:00 2001 From: Pete R Jemian Date: Tue, 29 Oct 2024 16:13:44 -0500 Subject: [PATCH 1/4] TST #1022 build a test that should pass --- .../tests/test_positioner_soft_done.py | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/apstools/devices/tests/test_positioner_soft_done.py b/apstools/devices/tests/test_positioner_soft_done.py index 51e926ce..073fa4c2 100644 --- a/apstools/devices/tests/test_positioner_soft_done.py +++ b/apstools/devices/tests/test_positioner_soft_done.py @@ -1,9 +1,11 @@ import math import time +from contextlib import nullcontext as does_not_raise import pytest from ophyd import Component from ophyd import EpicsSignal +from ophyd.sim import instantiate_fake_device from ...synApps.swait import UserCalcsDevice from ...tests import IOC_GP @@ -11,9 +13,9 @@ from ...tests import rand from ...tests import timed_pause from ...utils import run_in_thread +from ..positioner_soft_done import TARGET_UNDEFINED from ..positioner_soft_done import PVPositionerSoftDone from ..positioner_soft_done import PVPositionerSoftDoneWithStop -from ..positioner_soft_done import TARGET_UNDEFINED PV_PREFIX = f"{IOC_GP}gp:" delay_active = False @@ -365,3 +367,19 @@ def motion(p, goal): motion(calcpos, round(rand(-1.1, 0.2), 4)) # known starting position motion(calcpos, target) motion(calcpos, target) # issue #725, repeated move to same target + + +def test_issue_1022(): + """ + PVPositionerSoftDone should work with simulated fake devices. + + 'instantiate_fake_device()' produces a device that does not + have the 'setpoint' event_type. + """ + with does_not_raise(): + d = instantiate_fake_device( + PVPositionerSoftDone, + readback_pv="spam:", + setpoint_pv="eggs:", + ) + assert d is not None From 22f87fcea1c12c671434b2c3d1e962a60ef56d4e Mon Sep 17 00:00:00 2001 From: Pete R Jemian Date: Tue, 29 Oct 2024 16:14:11 -0500 Subject: [PATCH 2/4] MNT #1022 apply conditional --- apstools/devices/positioner_soft_done.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apstools/devices/positioner_soft_done.py b/apstools/devices/positioner_soft_done.py index 54367aba..e4778f04 100644 --- a/apstools/devices/positioner_soft_done.py +++ b/apstools/devices/positioner_soft_done.py @@ -138,7 +138,10 @@ def __init__( self.readback.subscribe(self.cb_readback) self.setpoint.subscribe(self.cb_setpoint) - self.setpoint.subscribe(self.cb_update_target, event_type="setpoint") + if "setpoint" in self.event_types: + self.setpoint.subscribe(self.cb_update_target, event_type="setpoint") + else: + logger.debug("Could not subscribe 'cb_update_target'. Ignoring.") # cancel subscriptions before object is garbage collected weakref.finalize(self.readback, self.readback.unsubscribe_all) From 3792b8a558d0be89839d191e2e84f442de8be61e Mon Sep 17 00:00:00 2001 From: Pete R Jemian Date: Tue, 29 Oct 2024 16:14:18 -0500 Subject: [PATCH 3/4] DOC #1022 --- CHANGES.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index d89d3cf1..1b726452 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -26,6 +26,12 @@ describe future plans. Release expected by 2024-12-31. + Fixes + ----- + + - PVPositionerSoftDone used an invalid subscription event type + in unusual cases (with fake ophyd simulated devices). + 1.7.1 ****** From 17cd75b5703a8c7bbcd5553351ccfb39ece48d52 Mon Sep 17 00:00:00 2001 From: Pete R Jemian Date: Tue, 29 Oct 2024 16:54:07 -0500 Subject: [PATCH 4/4] MNT #1022 use event_type kwarg when available --- apstools/devices/positioner_soft_done.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apstools/devices/positioner_soft_done.py b/apstools/devices/positioner_soft_done.py index e4778f04..157da42a 100644 --- a/apstools/devices/positioner_soft_done.py +++ b/apstools/devices/positioner_soft_done.py @@ -138,10 +138,10 @@ def __init__( self.readback.subscribe(self.cb_readback) self.setpoint.subscribe(self.cb_setpoint) + options = {} if "setpoint" in self.event_types: - self.setpoint.subscribe(self.cb_update_target, event_type="setpoint") - else: - logger.debug("Could not subscribe 'cb_update_target'. Ignoring.") + options["event_type"] = "setpoint" + self.setpoint.subscribe(self.cb_update_target, **options) # cancel subscriptions before object is garbage collected weakref.finalize(self.readback, self.readback.unsubscribe_all)