Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e60da20

Browse filesBrowse files
committed
FIX: Add update capability to interval/singleshot timer properties
1 parent ed8131b commit e60da20
Copy full SHA for e60da20

File tree

2 files changed

+40
-4
lines changed
Filter options

2 files changed

+40
-4
lines changed

‎lib/matplotlib/tests/test_backends_interactive.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_backends_interactive.py
+22-4Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -626,29 +626,47 @@ def _impl_test_interactive_timers():
626626
# We only want singleshot if we specify that ourselves, otherwise we want
627627
# a repeating timer
628628
import os
629+
import sys
629630
from unittest.mock import Mock
630631
import matplotlib.pyplot as plt
631632
# increase pause duration on CI to let things spin up
632633
# particularly relevant for gtk3cairo
633634
pause_time = 2 if os.getenv("CI") else 0.5
635+
expected_100ms_calls = int(pause_time / 0.1)
634636
fig = plt.figure()
635637
plt.pause(pause_time)
636638
timer = fig.canvas.new_timer(0.1)
637639
mock = Mock()
638640
timer.add_callback(mock)
639641
timer.start()
640642
plt.pause(pause_time)
641-
timer.stop()
642-
assert mock.call_count > 1
643+
# NOTE: The timer is as fast as possible, but this is different between backends
644+
# so we can't assert on the exact number but it should be faster than 100ms
645+
assert mock.call_count > expected_100ms_calls, \
646+
f"Expected more than {expected_100ms_calls} calls, got {mock.call_count}"
647+
648+
# Test updating the interval updates a running timer
649+
timer.interval = 100
650+
mock.call_count = 0
651+
plt.pause(pause_time)
652+
# GTK4 on macos runners produces about 3x as many calls as expected
653+
# It works locally and on Linux though, so only skip when running on CI
654+
if not (os.getenv("CI")
655+
and "gtk4" in os.getenv("MPLBACKEND")
656+
and sys.platform == "darwin"):
657+
# Could be off due to when the timers actually get fired (especially on CI)
658+
assert 1 < mock.call_count <= expected_100ms_calls + 1, \
659+
f"Expected less than {expected_100ms_calls + 1} calls, " \
660+
"got {mock.call_count}"
643661

644662
# Now turn it into a single shot timer and verify only one gets triggered
645663
mock.call_count = 0
646664
timer.single_shot = True
647-
timer.start()
648665
plt.pause(pause_time)
649666
assert mock.call_count == 1
650667

651-
# Make sure we can start the timer a second time
668+
# Make sure we can start the timer after stopping
669+
timer.stop()
652670
timer.start()
653671
plt.pause(pause_time)
654672
assert mock.call_count == 2

‎src/_macosx.m

Copy file name to clipboardExpand all lines: src/_macosx.m
+18Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.