Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: Disconnect the value signal when removing a listener from a connection #1208

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

jbellister-slac
Copy link
Collaborator

Context

Addresses #1186.

When calling set_channel on a PyDMWidget, the process is:

  • Call disconnect() on any channels the widget is already connected to
  • Disconnect signals/slots and decrement the listener count on the PyDMConnection associated with the address
  • If the listener count hits 0, close out the PyDMConnection for that address entirely
  • Then establish the new channel for the widget

The problem in #1186 seems to be that the value_signal is not disconnected, so if there is still an active listener such that the connection is not closed out entirely, that signal remains active and will continue to send even though the channel should have been replaced.

This should fix it by ensuring the value_signal is disconnected as part of remove_listener along with all the other signals.

Testing

Made a display that reproduced #1186. Manually verified that the problem went away after this PR. Added new unit tests, including one that does fail prior to this PR and passes now.

@@ -214,6 +217,25 @@ def remove_listener(self, channel, destroying: Optional[bool] = False) -> None:
except (KeyError, TypeError):
pass

if channel.value_signal is not None and hasattr(self, "put_value"):
Copy link
Collaborator

@nstelter-slac nstelter-slac Mar 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we can't guarantee the value_signal exists for all the types we call in 'value_signal[<type>]', i think we need catch KeyError here? (and could catch IndexError too for pyside6 support, since has diff internal structure for it)

also if u want, can be made into a shorter equivalent for-loop. i recently changed some other similar instances to a loop here: https://github.com/slaclab/pydm/pull/1197/files#diff-122f4c6562ac7f62ec92c020c468fc0994e5b4de3170b2556ce1249d892f316aR207

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BUG: PyDMPushButton.set_channel causes multiple callbacks if reassigning
2 participants