Skip to content

Commit 8596fb6

Browse files
committed
TST: Add text to identify failing tests
1 parent 1fccb5c commit 8596fb6

File tree

3 files changed

+34
-33
lines changed

3 files changed

+34
-33
lines changed

lib/matplotlib/backends/_backend_tk.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ class TimerTk(TimerBase):
127127

128128
def __init__(self, parent, *args, **kwargs):
129129
self._timer = None
130-
super().__init__(*args, **kwargs)
131130
self.parent = parent
131+
super().__init__(*args, **kwargs)
132132

133133
def _timer_start(self):
134134
self._timer_stop()
@@ -178,6 +178,12 @@ def _on_timer(self):
178178
else:
179179
self._timer = None
180180

181+
def _timer_set_interval(self):
182+
self._timer_start()
183+
184+
def _timer_set_single_shot(self):
185+
self._timer_start()
186+
181187

182188
class FigureCanvasTk(FigureCanvasBase):
183189
required_interactive_framework = "tk"

lib/matplotlib/tests/test_backend_bases.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,3 +603,10 @@ def test_timer_properties():
603603
timer.single_shot = True
604604
# Make sure it wasn't called again
605605
mock.assert_called_once()
606+
607+
# A timer with <1 millisecond gets converted to int and therefore 0
608+
# milliseconds, which the mac framework interprets as singleshot.
609+
# We only want singleshot if we specify that ourselves, otherwise we want
610+
# a repeating timer, so make sure our interval is set to a minimum of 1ms.
611+
timer.interval = 0.1
612+
assert timer.interval == 1

lib/matplotlib/tests/test_backends_interactive.py

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -628,66 +628,54 @@ def _impl_test_interactive_timers():
628628
import matplotlib.pyplot as plt
629629

630630
fig = plt.figure()
631-
event_loop_time = 0.5 # in seconds
631+
event_loop_time = 1 # in seconds
632+
expected_200ms_calls = int(event_loop_time / 0.2)
632633

633-
# A timer with <1 millisecond gets converted to int and therefore 0
634-
# milliseconds, which the mac framework interprets as singleshot.
635-
# We only want singleshot if we specify that ourselves, otherwise we want
636-
# a repeating timer
637-
timer_repeating = fig.canvas.new_timer(0.1)
634+
# Start at 2s interval (would only get one firing), then update to 200ms
635+
timer_repeating = fig.canvas.new_timer(2000)
638636
mock_repeating = Mock()
639637
timer_repeating.add_callback(mock_repeating)
640638

641639
timer_single_shot = fig.canvas.new_timer(100)
642640
mock_single_shot = Mock()
643641
timer_single_shot.add_callback(mock_single_shot)
644642

645-
# 100ms timer triggers and the callback takes 75ms to run
646-
# Test that we don't drift and that we get called on every 100ms
647-
# interval and not every 175ms
648-
mock_slow_callback = Mock()
649-
mock_slow_callback.side_effect = lambda: time.sleep(0.075)
650-
timer_slow_callback = fig.canvas.new_timer(100)
651-
timer_slow_callback.add_callback(mock_slow_callback)
652-
653643
timer_repeating.start()
644+
# Test updating the interval updates a running timer
645+
timer_repeating.interval = 200
654646
# Start as a repeating timer then change to singleshot via the attribute
655647
timer_single_shot.start()
656648
timer_single_shot.single_shot = True
657-
timer_slow_callback.start()
649+
658650
fig.canvas.start_event_loop(event_loop_time)
659-
# NOTE: The timer is as fast as possible, but this is different between backends
660-
# so we can't assert on the exact number but it should be faster than 100ms
661-
expected_100ms_calls = int(event_loop_time / 0.1)
662-
assert mock_repeating.call_count > expected_100ms_calls, \
663-
f"Expected more than {expected_100ms_calls} calls, " \
651+
assert 1 < mock_repeating.call_count <= expected_200ms_calls + 1, \
652+
f"Interval update: Expected between 2 and {expected_200ms_calls + 1} calls, " \
664653
f"got {mock_repeating.call_count}"
665654
assert mock_single_shot.call_count == 1, \
666-
f"Expected 1 call, got {mock_single_shot.call_count}"
667-
assert mock_slow_callback.call_count >= expected_100ms_calls - 1, \
668-
f"Expected at least {expected_100ms_calls - 1} calls, " \
669-
f"got {mock_slow_callback.call_count}"
655+
f"Singleshot: Expected 1 call, got {mock_single_shot.call_count}"
670656

671-
# Test updating the interval updates a running timer
672-
timer_repeating.interval = 100
657+
# 200ms timer triggers and the callback takes 100ms to run
658+
# Test that we don't drift and that we get called on every 200ms
659+
# interval and not every 300ms
660+
mock_repeating.side_effect = lambda: time.sleep(0.1)
673661
mock_repeating.call_count = 0
674662
# Make sure we can start the timer after stopping a singleshot timer
675663
timer_single_shot.stop()
676664
timer_single_shot.start()
677665

678666
fig.canvas.start_event_loop(event_loop_time)
679-
assert 1 < mock_repeating.call_count <= expected_100ms_calls + 1, \
680-
f"Expected less than {expected_100ms_calls + 1} calls, " \
681-
"got {mock.call_count}"
667+
# Not exact timers, so add a little slop. We really want to make sure we are
668+
# getting more than 3 (every 300ms).
669+
assert mock_repeating.call_count >= expected_200ms_calls - 1, \
670+
f"Slow callback: Expected at least {expected_200ms_calls - 1} calls, " \
671+
f"got {mock_repeating.call_count}"
682672
assert mock_single_shot.call_count == 2, \
683-
f"Expected 2 calls, got {mock_single_shot.call_count}"
673+
f"Singleshot: Expected 2 calls, got {mock_single_shot.call_count}"
684674
plt.close("all")
685675

686676

687677
@pytest.mark.parametrize("env", _get_testable_interactive_backends())
688678
def test_interactive_timers(env):
689-
if env["MPLBACKEND"] == "gtk3cairo" and os.getenv("CI"):
690-
pytest.skip("gtk3cairo timers do not work in remote CI")
691679
if env["MPLBACKEND"] == "wx":
692680
pytest.skip("wx backend is deprecated; tests failed on appveyor")
693681
_run_helper(_impl_test_interactive_timers,

0 commit comments

Comments
 (0)