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

MAINT: Add GC tests #66

Merged
merged 36 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
f4a4af8
MAINT: Add GC tests
larsoner Oct 22, 2020
2705025
FIX: Missed one
larsoner Oct 22, 2020
c5e1cdd
FIX: Missed more
larsoner Oct 22, 2020
6cb8afe
FIX: More
larsoner Oct 22, 2020
fc01eaf
FIX: Revert deep
larsoner Oct 23, 2020
1bba575
FIX: Revert Azure addition
larsoner Oct 23, 2020
6341359
FIX: Try again?
larsoner Oct 23, 2020
82cebae
MAINT: Reorg
larsoner Oct 23, 2020
06f3fe9
FIX: Old VTK
larsoner Oct 23, 2020
d5a7101
FIX: Simplify
larsoner Oct 23, 2020
c59bf2e
FIX: Missing
larsoner Oct 23, 2020
9f8bb88
FIX: Pre
larsoner Oct 23, 2020
515627c
STY: Flake
larsoner Oct 23, 2020
f999e8c
FIX: Black
larsoner Oct 23, 2020
795e642
FIX: Sty
larsoner Oct 23, 2020
76acb42
STY: More
larsoner Oct 23, 2020
85eee8d
FIX: Just use master
larsoner Oct 23, 2020
269378a
Merge remote-tracking branch 'upstream/main' into mem
larsoner Jan 6, 2023
936e7da
FIX: Hopefully
larsoner Jan 6, 2023
dbab0de
FIX: Placeholder
larsoner Jan 6, 2023
7a44256
FIX: Rebase
larsoner Jan 6, 2023
c009a71
FIX: Order
larsoner Jan 6, 2023
39ca333
FIX: More
larsoner Jan 6, 2023
7cdde11
FIX: Flake
larsoner Jan 6, 2023
78d119c
FIX: Always bad
larsoner Jan 6, 2023
a52db70
FIX: Fixture
larsoner Jan 6, 2023
3339845
FIX: Use name
larsoner Jan 6, 2023
f363aae
FIX: Dynamic
larsoner Jan 6, 2023
c6e3b28
FIX: Pack
larsoner Jan 6, 2023
dcb59c9
FIX: Better
larsoner Jan 6, 2023
166b3a7
FIX: Revert
larsoner Jan 6, 2023
d33afea
FIX: Line
larsoner Jan 6, 2023
7b5baa9
STY: Flake
larsoner Jan 6, 2023
908330b
FIX: Del
larsoner Jan 6, 2023
a634517
FIX: Show
larsoner Jan 6, 2023
0cd0112
FIX: Skip
larsoner Jan 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .ci/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ jobs:
python.version: '3.6'
Python37:
python.version: '3.7'
Python38:
python.version: '3.8'
variables:
PYVISTA_PRE: true
GC_TEST: true

steps:
- task: UsePythonVersion@0
Expand All @@ -123,6 +128,9 @@ jobs:

- script: |
pip install wheel --upgrade
if [ "$PYVISTA_PRE" == "true" ]; then
pip install https://github.com/larsoner/pyvista/zipball/mem
fi;
python setup.py bdist_wheel
pip install dist/pyvistaqt*.whl
displayName: Build wheel and install pyvistaqt
Expand Down Expand Up @@ -369,7 +377,7 @@ jobs:
displayName: Upload Documentation to pyvistaqt-docs
env:
GH_TOKEN: $(gh.token)
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))

# don't run job on no-ci builds
condition: not(contains(variables['System.PullRequest.SourceBranch'], 'no-ci'))
7 changes: 5 additions & 2 deletions pyvistaqt/editor.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""This module contains the Qt scene editor."""

import weakref
from typing import List

import vtk
Expand Down Expand Up @@ -105,9 +106,10 @@ def _get_actor_widget(actor: vtk.vtkActor) -> QWidget:
prop = actor.GetProperty()

# visibility
sv = weakref.ref(actor.SetVisibility)
visibility = QCheckBox("Visibility")
visibility.setChecked(actor.GetVisibility())
visibility.toggled.connect(actor.SetVisibility)
visibility.toggled.connect(lambda v: sv()(v))
layout.addWidget(visibility)

if prop is not None:
Expand All @@ -116,7 +118,8 @@ def _get_actor_widget(actor: vtk.vtkActor) -> QWidget:
opacity = QDoubleSpinBox()
opacity.setMaximum(1.0)
opacity.setValue(prop.GetOpacity())
opacity.valueChanged.connect(prop.SetOpacity)
so = weakref.ref(prop.SetOpacity)
opacity.valueChanged.connect(lambda v: so()(v))
tmp_layout.addWidget(QLabel("Opacity"))
tmp_layout.addWidget(opacity)
layout.addLayout(tmp_layout)
Expand Down
32 changes: 32 additions & 0 deletions pyvistaqt/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ def close(self) -> None:
if hasattr(self, "render_timer"):
self.render_timer.stop()
BasePlotter.close(self)
BasePlotter.deep_clean(self)
larsoner marked this conversation as resolved.
Show resolved Hide resolved
QVTKRenderWindowInteractor.close(self)


Expand Down Expand Up @@ -810,6 +811,14 @@ def __del__(self) -> None: # pragma: no cover
"""Delete the qt plotter."""
if not self._closed:
self.app_window.close()
# Qt LeaveEvent requires _Iren so we use _FakeIren instead of None
# to resolve the ref to vtkGenericRenderWindowInteractor
self._Iren = _FakeEventHandler()
for key in ('_RenderWindow', 'renderer'):
try:
setattr(self, key, None)
except AttributeError:
pass

def add_callback(
self, func: Callable, interval: int = 1000, count: Optional[int] = None
Expand Down Expand Up @@ -856,3 +865,26 @@ def _create_menu_bar(parent: Any) -> QMenuBar:
if parent is not None:
parent.setMenuBar(menu_bar)
return menu_bar


class _FakeEventHandler():
def SetDPI(self, dpi):
pass

def EnterEvent(self):
pass

def MouseMoveEvent(self):
pass

def LeaveEvent(self):
pass

def SetEventInformation(self, *args, **kwargs):
pass

def SetSize(self, *args, **kwargs):
pass

def ConfigureEvent(self, *args, **kwargs):
pass
42 changes: 39 additions & 3 deletions tests/test_plotting.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import gc
import os
import platform
import weakref

import numpy as np
import pytest
Expand All @@ -20,6 +22,38 @@
NO_PLOTTING = not system_supports_plotting()


# Adapted from PyVista
def _is_vtk(obj):
try:
return obj.__class__.__name__.startswith('vtk')
except Exception: # old Python sometimes no __class__.__name__
return False


@pytest.fixture(autouse=True)
def check_gc(request):
"""Ensure that all VTK objects are garbage-collected by Python."""
if 'test_ipython' in request.node.name: # XXX this keeps a ref
yield
return
# We need https://github.com/pyvista/pyvista/pull/958 to actually run
# this test. Eventually we should use LooseVersion, but as of 2020/10/22
# 0.26.1 is the latest PyPi version and on master the version is weirdly
# 0.26.0 (as opposed to 0.26.2.dev0 or 0.27.dev0) so we can't. So for now
# let's use an env var (GC_TEST) instead of:
# if LooseVersion(pyvista.__version__) < LooseVersion('0.26.2'):
if os.getenv('GC_TEST', '').lower() != 'true':
yield
return
before = set(id(o) for o in gc.get_objects() if _is_vtk(o))
yield
pyvista.close_all()
gc.collect()
after = [o for o in gc.get_objects() if _is_vtk(o) and id(o) not in before]
after = sorted(o.__class__.__name__ for o in after)
assert len(after) == 0, 'Not all objects GCed:\n' + '\n'.join(after)


class TstWindow(MainWindow):
def __init__(self, parent=None, show=True, off_screen=True):
MainWindow.__init__(self, parent)
Expand Down Expand Up @@ -140,7 +174,8 @@ def test_editor(qtbot):

# add at least an actor
plotter.subplot(0, 0)
plotter.add_mesh(pyvista.Sphere())
pd = pyvista.Sphere()
actor = plotter.add_mesh(pd)
plotter.subplot(1, 0)
plotter.show_axes()

Expand Down Expand Up @@ -178,6 +213,7 @@ def test_editor(qtbot):

# hide the editor for coverage
editor.toggle()
plotter.remove_actor(actor)
plotter.close()

plotter = BackgroundPlotter(editor=False)
Expand Down Expand Up @@ -524,10 +560,10 @@ def test_background_plotting_menu_bar(qtbot):
def test_background_plotting_add_callback(qtbot, monkeypatch):
class CallBack(object):
def __init__(self, sphere):
self.sphere = sphere
self.sphere = weakref.ref(sphere)

def __call__(self):
self.sphere.points *= 0.5
self.sphere().points[:] = self.sphere().points * 0.5

update_count = [0]
orig_update_app_icon = BackgroundPlotter.update_app_icon
Expand Down