Skip to content

Commit 9a99838

Browse files
committed
FIX: Add update capability to interval/singleshot timer properties
1 parent ed8131b commit 9a99838

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

lib/matplotlib/tests/test_backends_interactive.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -631,24 +631,35 @@ def _impl_test_interactive_timers():
631631
# increase pause duration on CI to let things spin up
632632
# particularly relevant for gtk3cairo
633633
pause_time = 2 if os.getenv("CI") else 0.5
634+
expected_100ms_calls = int(pause_time / 0.1)
634635
fig = plt.figure()
635636
plt.pause(pause_time)
636637
timer = fig.canvas.new_timer(0.1)
637638
mock = Mock()
638639
timer.add_callback(mock)
639640
timer.start()
640641
plt.pause(pause_time)
641-
timer.stop()
642-
assert mock.call_count > 1
642+
# NOTE: The timer is as fast as possible, but this is different between backends
643+
# so we can't assert on the exact number but it should be faster than 100ms
644+
assert mock.call_count > expected_100ms_calls, \
645+
f"Expected more than {expected_100ms_calls} calls, got {mock.call_count}"
646+
647+
# Test updating the interval updates a running timer
648+
timer.interval = 100
649+
mock.call_count = 0
650+
plt.pause(pause_time)
651+
# Could be off due to when the timers actually get fired (especially on CI)
652+
assert 1 < mock.call_count <= expected_100ms_calls, \
653+
f"Expected less than {expected_100ms_calls} calls, got {mock.call_count}"
643654

644655
# Now turn it into a single shot timer and verify only one gets triggered
645656
mock.call_count = 0
646657
timer.single_shot = True
647-
timer.start()
648658
plt.pause(pause_time)
649659
assert mock.call_count == 1
650660

651-
# Make sure we can start the timer a second time
661+
# Make sure we can start the timer after stopping
662+
timer.stop()
652663
timer.start()
653664
plt.pause(pause_time)
654665
assert mock.call_count == 2

src/_macosx.m

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,6 +1789,18 @@ - (void)flagsChanged:(NSEvent *)event
17891789
Py_RETURN_NONE;
17901790
}
17911791

1792+
static PyObject*
1793+
Timer__timer_update(Timer* self)
1794+
{
1795+
// stop and invalidate a timer if it is already running and then create a new one
1796+
// where the start() method retrieves the updated interval internally
1797+
if (self->timer) {
1798+
Timer__timer_stop_impl(self);
1799+
gil_call_method((PyObject*)self, "_timer_start");
1800+
}
1801+
Py_RETURN_NONE;
1802+
}
1803+
17921804
static void
17931805
Timer_dealloc(Timer* self)
17941806
{
@@ -1815,6 +1827,12 @@ - (void)flagsChanged:(NSEvent *)event
18151827
{"_timer_stop",
18161828
(PyCFunction)Timer__timer_stop,
18171829
METH_NOARGS},
1830+
{"_timer_set_interval",
1831+
(PyCFunction)Timer__timer_update,
1832+
METH_NOARGS},
1833+
{"_timer_set_single_shot",
1834+
(PyCFunction)Timer__timer_update,
1835+
METH_NOARGS},
18181836
{} // sentinel
18191837
},
18201838
};

0 commit comments

Comments
 (0)