Closed canismarko closed 7 months ago
By the way, here's the implementation of how I'm using this without the change.
https://github.com/spc-group/haven/blob/mirrors/src/firefly/pydm_plugin.py
On the surface this looks unobtrusive, preserving the original usage pattern. Thanks for adding a test as well! On the whole I'm ok with this change if it helps support your use case.
It's been a while since I've looked at Typhos but I do wonder, is the SignalConnection
the only part of typhos
you're using? By sidestepping typhos' signal registry, you prevent other parts of Typhos from using those signals.
First off, thank you for opening a pull request.
I'm waffling back in forth in my head about whether an __init__
kwarg is the most appropriate place for this, or if typhos should explicitly implement an overridable get_signal
method instead. As-implemented this framework is clear and useful both for your use case and for the test suite addition, but leaves behind a bit of code that is confusing on first read, since the expected target of this is a super()
call in another library rather than any direct use of TyphosConnection
. In contrast, a dedicated overridable get_signal
or e.g. get_signal_from_registry
has very clear intent and also allows you to override and re-use the rest of this without excessive vendoring.
Any thoughts about this? Are there other cases where it is useful to directly pass in signals to SignalConnection
that I'm missing?
is the SignalConnection the only part of typhos you're using? By sidestepping typhos' signal registry, you prevent other parts of Typhos from using those signals.
Yes, just this and the accompanying SignalPlugin. I actually rolled my own at first, then learned that y'all had already solved this problem and abandoned my buggy version for yours.
Any thoughts about this? Are there other cases where it is useful to directly pass in signals to
SignalConnection
that I'm missing?
I had a similar thought, though I considered adding an attribute:
class SignalConnection(PyDMConnection):
registry = signal_registry
def __init__(self, ...):
...
self.signal = self.registry[address]
...
then for any subclasses it's just
class MySignalConnection(SignalConnection):
registry = my_registry
This does mean implementing __get__
on the ophydregistry.Registry class, but I'm fine with adding that (I might do it regardless).
I went with the init attribute because it seems more flexible, but I don't have a particular use case in mind. Like maybe somebody wants to create a signal and then the PyDMConnection directly? Not sure why you'd want that, though. I'm happy to adjust this to work either of the three ways:
1) signal as an init parameter 2) get_signal as an overridable method 3) registry as a class attribute
I think I like 2) best for the reasons you described.
Thoughts?
I like 2, it's a good point
I went with the init attribute because it seems more flexible, but I don't have a particular use case in mind. Like maybe somebody wants to create a signal and then the PyDMConnection directly? Not sure why you'd want that, though.
This is the only thing holding me back from insisting on 2 vs merging this as-is. It was clearly pretty useful for writing a succinct unit test, which implies that it could have further utility.
I implemented a find_signal()
method ("get_signal()" sounded too much like an accessor, which it isn't). I can also roll it back if we feel the flexibility of the init parameter is worth the debt of mixing concerns.
Thank you both.
Description
In the init method of
typhos.core.SignalConnection
class, it looks up the signal corresponding to its address in the signal_registry dictionary. This PR adds an optionalsignal=None
argument to the SignalConnection.init() method. If signal isNone
(default), then the behavior is the same as before. However, if a signal is provided, it will be used for the rest of the connection.Motivation and Context
This makes the SignalConnection class more flexible, and allows it to be used with other registries. In my case, I want to look up signals from the ophyd-registry package since the dictionary style registry used by Typhos doesn't meet all my use-cases. To do that, I will subclass the
SignalConnection
andSignalPlugin
classes.In its current implementation I have to vendor in the entire init method since
self.signal
is written half-way through and then used immediately. Vendoring in init is not desirable since future updates to this method will not be available making the code less maintainable.With this proposed change, I can use super() instead:
How Has This Been Tested?
To ensure existing behavior is not affected, the tests in
typhos/tests/plugins/test_core.py
were run before and after this change, passing in both cases.To test the new behavior, a new test was added to test_core.py, similar to the existing
test_metadata()
but where the signal object is not added tosignal_registry
and is instead passed in with the signal parameter.Where Has This Been Documented?
The docstring for SignalConnection has been updated to describe the new parameter. It now includes:
Pre-merge checklist
docs/pre-release-notes.sh
and created a pre-release documentation page