Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Don't bother disconnecting signals in TimerQt.__del__. #8450

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

Conversation

anntzer
Copy link
Contributor

@anntzer anntzer commented Apr 9, 2017

The current implementation sometimes raises an error at exit. For
example, run examples/animations/animate_decay.py (under the
Qt5Agg backend) and wait after the x-axis has been updated at least
once; then close the window. Occasionally, the following error will
be printed at exit:

Exception ignored in: <bound method TimerQT.__del__ of <matplotlib.backends.backend_qt5.TimerQT object at 0x7f74a65f5668>>
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/matplotlib/backends/backend_qt5.py", line 202, in __del__
    self._timer.timeout.disconnect(self._on_timer)
TypeError: 'method' object is not connected

As far as I can tell there is no real rationale for bothering to
explicitly disconnect the callback -- the C++-level QTimer object is
about to be garbage-collected anyways.

The current implementation sometimes raises an error at exit.  For
example, run `examples/animations/animate_decay.py` (under the
Qt5Agg backend) and wait after the x-axis has been updated at least
once; then close the window.  *Occasionally*, the following error will
be printed at exit:
```
Exception ignored in: <bound method TimerQT.__del__ of <matplotlib.backends.backend_qt5.TimerQT object at 0x7f74a65f5668>>
Traceback (most recent call last):
  File "/usr/lib/python3.6/site-packages/matplotlib/backends/backend_qt5.py", line 202, in __del__
    self._timer.timeout.disconnect(self._on_timer)
TypeError: 'method' object is not connected
```

As far as I can tell there is no real rationale for bothering to
explicitly disconnect the callback -- the C++-level QTimer object is
about to be garbage-collected anyways.
@anntzer anntzer added the GUI: Qt label Apr 9, 2017
@tacaswell tacaswell added this to the 2.1 (next point release) milestone Apr 12, 2017
@tacaswell
Copy link
Member

Does this prevent a circular set of references?

Nominally 👍 but want to think a bit more.

@anntzer
Copy link
Contributor Author

anntzer commented Apr 12, 2017

The C++-level QTimer object keeps a reference to self._on_timer whereas the Python-level TimerQt object keeps a reference to the QTimer, so there is already a circular ref in the way the class is designed. If we manage to reach a point where __del__ is invoked, that can only happen through the cyclic GC. And GC'ing the Python-level TimerQt (what this does) will then allow GC'ing the C++-level QTimer.
Overall it looks safe.

@WeatherGod
Copy link
Member

Hurray for GC race-conditions!

I am leaning a bit towards simply swallowing the TypeError exception. What if we redesign the class to no longer have the cyclic reference? Then we would need the __del__, wouldn't we?

@WeatherGod
Copy link
Member

note, I am not suggesting that we redesign the class, just simply saying that if in the future the class gets redesigned, one may forget to add back the __del__.

@anntzer
Copy link
Contributor Author

anntzer commented Apr 13, 2017

I don't understand the insistence on keeping del.
There is already a circular reference (timerqt -> qtimer (as attribute) -> timerqt method (as callback) -> timerqt (bound member)) and this del does not change anything about it. In fact, on old pythons, it prevents garbage collection of the loop (as is standard in presence of custom __del__s).

@dopplershift
Copy link
Contributor

There's no need to disconnect here, I think I was just being way overly cautious. Qt disconnects in destructors at the C++ level.

@tacaswell tacaswell merged commit 3dc4467 into matplotlib:master Apr 13, 2017
@tacaswell tacaswell modified the milestones: 2.0.1 (next bug fix release), 2.1 (next point release) Apr 13, 2017
@tacaswell
Copy link
Member

Going to backport this

@anntzer anntzer deleted the dont-bother-disconnecting-on-timerqt-__del__ branch April 13, 2017 23:57
tacaswell added a commit that referenced this pull request Apr 14, 2017
…merqt-__del__

MNT: Don't bother disconnecting signals in TimerQt.__del__.
@tacaswell
Copy link
Member

backported to v2.0.x as b160593

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

Successfully merging this pull request may close these issues.

4 participants