Remove references to self from lambdas#1598
Conversation
|
Could most of these new methods be replaced by a use of functools.partial? For Parameters, a change in prototype of emitStateChanged def emitStateChanged(self, param, data, changeDesc):
...
self.sigOptionsChanged.connect(partial(self.emitStateChanged, changeDesc='options')) |
|
For mkChangeCallback, could the single call to self.mkChangeCallback(w) be converted to partial(self.widgetChanged, w=w)? |
|
Okay, yeah, partials would be more elegant and solve the |
Feel free to use PR #646 with a PyQt5/6 as an example. Change: self.vb.sigLogChanged.connect(self._logChanged)back to a lambda and |
|
@j9ac9k way to pick the most challenging to convert to a partial! 😁 Playing around with that, I was able to prove that partials still trigger the error. Thanks, everyone, for the ideas, but it looks like partials aren't going to be helpful here. It looks like PyQt* is doing extra work to make sure instance methods get disconnected appropriately. I could use |
|
Could you share how your partial() line looks like?
1) partial(self.method, arg='xyz')
or
2) partial(self.method, arg=self)?
(2) should cause problems. I am wondering if (1) also causes problems.
…On Mon, 22 Feb 2021, 09:56 Martin Chase, ***@***.***> wrote:
@j9ac9k <https://github.com/j9ac9k> way to pick the most challenging to
convert to a partial! 😁
Playing around with that, I was able to prove that partials still trigger
the error. Thanks, everyone, for the ideas, but it looks like partials
aren't going to be helpful here. It looks like PyQt* is doing extra work to
make sure instance methods get disconnected appropriately. I could use
functools.partialmethod to declare these one-liner methods, but we
wouldn't be much better off for it, and it still doesn't help with
mkChangeCallback.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#1598 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAUIWA5VH6KAM4Q4S5DZUMTTAG2V3ANCNFSM4X7CK2FA>
.
|
|
The first. The following fails the test: |
|
This here says that instance methods are treated specially. Mentions that lambda, partial and others don't get this special treatment. ☹ |
|
@pijyoi thanks for sharing that link, the addition of "static methods" is something I would never have thought to be applicable. I am now taking a hard look at some of my projects involving pyqtgraph... |
|
2 Questions...
Regarding the private methods, I'm just bringing this up; I'm not advocating for a change to be made here... |
|
Ooo, now that you mention it, I generally like private-ing methods that aren't useful as a public interface, yeah. This is a big library, and not having to worry about maintaining every little utility function is of great value to the maintainers. I'm changing it! No opinion on the |
a0889ac to
af82858
Compare
|
Just a note that I looked at this some more (with help from @j9ac9k) and I failed to be able to disconnect lambdas as part of object deletion. Any other ideas for improving this PR? |
|
Using the @slot decorator is beneficial. Connecting a signal to a decorated Python method also has the advantage of reducing the amount of memory used and is slightly faster. |
|
@dgoeries I've seen this talked about before, but I've never been able to test this. Every time I try and get specific with my slots... @Slot(tuple) # using tuple as an example, I haven't done exhaustive testing, but this holds for many cases...
def someSlot(self, arg1):
sender = self.sender()
isinstance(sender, QObject) # this returns False because sender is None in this case
...but when I do... @Slot(object)
def someSlot(self, arg1):
sender = self.sender()
isinstance(sender, QObject) # this returns True
...So if I'm just decorating my slots to pass This is outside the scope of this PR, but I am eager to know if this works and if we can measure the performance benefit. In the meantime, I think I'm going to merge this as is. Thanks @outofculture ! |
Lambdas used as signal responders which reference
selfprevent GC of said object. Instance methods do not suffer the same problem. I wasn't sure if theQTimerone needed to be fixed, but it doesn't hurt to be safe.I couldn't solve
pyqtgraph.WidgetGroup.WidgetGroup.mkChangeCallback, though. That case can't be rewritten as an instance method, and it needs to remain associated withself, so it can't be a static function. Maybe it would be sufficient to add the appropriatedisconnectsomehow? But what would that look like? If anyone has ideas, I'm willing to take another stab at this one.