-
Notifications
You must be signed in to change notification settings - Fork 12
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
feat: emit the old value as second argument in Signals from SignalGroupDescriptor (evented dataclass) #257
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #257 +/- ##
=======================================
Coverage 99.89% 99.89%
=======================================
Files 22 22
Lines 1908 1908
=======================================
Hits 1906 1906
Misses 2 2 ☔ View full report in Codecov by Sentry. |
CodSpeed Performance ReportMerging #257 will degrade performances by 10.44%Comparing Summary
Benchmarks breakdown
|
I actually think it should be fine to simply add the second argument. psygnal works fine if the callback takes less (but not more) than the number of arguments in the signal. So, it's always a non-breaking change to pass more arguments to a signal... can you try reducing this PR down to just the change |
Well, it's true. I will keep it to a minimum then and test it.
Thanks
…On 31 January 2024 18:50:17 GMT+00:00, Talley Lambert ***@***.***> wrote:
> I put the old value in second place because it should allow to connect to slots defined with only the new value as argument.
> However, in order to not be a disturbing change, it would be better if it is opt-in.
I actually think it _should_ be find to simply add the second argument. psygnal works fine if the callback takes less (but not more) than the number of arguments in the signal. So, it's always a non-breaking change to pass more arguments to a signal.
can you try reducing this PR down to just the change `self.signal.emit(new, self._prev)` and seeing if it works for you? While also keeping all of the existing tests passing?
--
Reply to this email directly or view it on GitHub:
#257 (comment)
You are receiving this because you authored the thread.
Message ID: ***@***.***>
|
Done and I corrected the tests. |
thanks! One more change I think we should make: on line 143 in signals[name] = Signal(object if type_ is None else type_) to this: field_type = object if type_ is None else type_
signals[name] = Signal(field_type, field_type) That is where we actually construct all of the want to test out a couple other things locally, but will merge soon. Thanks a lot for your PR! |
oh, and also it looks like this does break something downstream in magicgui (which depends on psygnal). glad I run those tests here :) don't feel like you have to figure that one out, i'll also have a look into that. |
ok, the issue there is that magicgui makes use of which works fine for a single-argument signal, like this: >>> class Emitter:
... sig = Signal(int)
...
>>> class SomeObj:
... x = 1
...
>>> e = Emitter()
>>> my_obj = SomeObj()
>>> e.sig.connect_setattr(my_obj, 'x')
>>> e.sig.emit(5)
>>> assert my_obj.x == 5 However, (and I think this was probably a poor choice on my part), if the signal emits multiple arguments, it bundles them into a tuple: >>> class Emitter:
... sig = Signal(int, int)
...
>>> class SomeObj:
... x = 1
...
>>> e = Emitter()
>>> my_obj = SomeObj()
>>> e.sig.connect_setattr(my_obj, 'x')
>>> e.sig.emit(5, 2)
>>> assert my_obj.x == (5, 2) and that turns out to be a breaking change here... since the behavior of |
You can force to only accept one argument with Actually, using >>> class Emitter:
... sig = Signal(int, int)
...
>>> class SomeObj:
... x = 1
...
>>> e = Emitter()
>>> my_obj = SomeObj()
>>> e.sig.connect_setattr(my_obj, 'x', maxargs=1)
>>> e.sig.emit(5, 2)
>>> assert my_obj.x == 5 |
|
yep, I agree, that does make sense, and it would be the easiest fix. |
I made a search in github for |
I think people would naturally use What can be a breaking change is connecting the attribute change signal to a slot with one mandatory argument and one optional. Because now the attribute change signal has 2 values, the second value would be passed to the optional argument, making breaking changes... |
totally agree with this. it's less about "sensical" right at the immediate moment, and more about the safest way to get us there
Yep, I also did the search, and agree, it's unlikely to affect anyone.
Yep, good point! Anyway, please merge in main now that #258 is in, and then add the change mentioned in #257 (comment) ... and we should be good here |
thanks a lot @getzze for this PR and for helping me think through the implications of the change. merging now, and will release in the next day or two as v0.10.0 |
I'm using
SignalGroupDescriptor
(orevented
) with anattrs
dataclass and I would like the change signal to emit the old value alongside the new value when mutated.It's a minimal change to allow that, in
_evented_decorator._changes_emitted
method__exit__
, just change:self.signal.emit(new)
-->self.signal.emit(new, self._prev)
I put the old value in second place because it should allow to connect to slots defined with only the new value as argument.
However, in order to not be a disturbing change, it would be better if it is opt-in.
That is this PR. It is working, but not with subclassing.
Any idea?