Skip to content

Commit c2a5cb2

Browse files
tacaswellQuLogic
authored andcommitted
TST: fix ctrl-c tests on windows
1 parent 6abb746 commit c2a5cb2

File tree

2 files changed

+32
-17
lines changed

2 files changed

+32
-17
lines changed

lib/matplotlib/backends/qt_compat.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,14 @@ def _maybe_allow_interrupt(qapp):
228228
rsock.fileno(), _enum('QtCore.QSocketNotifier.Type').Read
229229
)
230230

231+
rsock.setblocking(False)
231232
# Clear the socket to re-arm the notifier.
232-
sn.activated.connect(lambda *args: rsock.recv(1))
233+
@sn.activated.connect
234+
def _may_clear_sock(*args):
235+
try:
236+
rsock.recv(1)
237+
except BlockingIOError:
238+
pass
233239

234240
def handle(*args):
235241
nonlocal handler_args

lib/matplotlib/tests/test_backend_qt.py

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ def test_fig_close():
5454
assert init_figs == Gcf.figs
5555

5656

57-
class InterruptiblePopen(subprocess.Popen):
57+
class WaitForStringPopen(subprocess.Popen):
5858
"""
5959
A Popen that passes flags that allow triggering KeyboardInterrupt.
6060
"""
6161

6262
def __init__(self, *args, **kwargs):
6363
if sys.platform == 'win32':
64-
kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
64+
kwargs['creationflags'] = subprocess.CREATE_NEW_CONSOLE
6565
super().__init__(
6666
*args, **kwargs,
6767
# Force Agg so that each test can switch to its desired Qt backend.
@@ -80,25 +80,35 @@ def wait_for(self, terminator):
8080
if buf.endswith(terminator):
8181
return
8282

83-
def interrupt(self):
84-
"""Interrupt process in a platform-specific way."""
85-
if sys.platform == 'win32':
86-
self.send_signal(signal.CTRL_C_EVENT)
87-
else:
88-
self.send_signal(signal.SIGINT)
89-
9083

9184
def _test_sigint_impl(backend, target_name, kwargs):
9285
import sys
9386
import matplotlib.pyplot as plt
87+
import os
88+
import threading
89+
9490
plt.switch_backend(backend)
9591
from matplotlib.backends.qt_compat import QtCore
9692

97-
target = getattr(plt, target_name)
93+
def interupter():
94+
if sys.platform == 'win32':
95+
import win32api
96+
win32api.GenerateConsoleCtrlEvent(0, 0)
97+
else:
98+
import signal
99+
os.kill(os.getpid(), signal.SIGINT)
98100

101+
target = getattr(plt, target_name)
102+
timer = threading.Timer(1, interupter)
99103
fig = plt.figure()
100-
fig.canvas.mpl_connect('draw_event',
101-
lambda *args: print('DRAW', flush=True))
104+
fig.canvas.mpl_connect(
105+
'draw_event',
106+
lambda *args: print('DRAW', flush=True)
107+
)
108+
fig.canvas.mpl_connect(
109+
'draw_event',
110+
lambda *args: timer.start()
111+
)
102112
try:
103113
target(**kwargs)
104114
except KeyboardInterrupt:
@@ -112,13 +122,12 @@ def _test_sigint_impl(backend, target_name, kwargs):
112122
])
113123
def test_sigint(target, kwargs):
114124
backend = plt.get_backend()
115-
proc = InterruptiblePopen(
125+
proc = WaitForStringPopen(
116126
[sys.executable, "-c",
117127
inspect.getsource(_test_sigint_impl) +
118128
f"\n_test_sigint_impl({backend!r}, {target!r}, {kwargs!r})"])
119129
try:
120130
proc.wait_for('DRAW')
121-
proc.interrupt()
122131
stdout, _ = proc.communicate(timeout=_test_timeout)
123132
except:
124133
proc.kill()
@@ -164,7 +173,7 @@ def custom_signal_handler(signum, frame):
164173
])
165174
def test_other_signal_before_sigint(target, kwargs):
166175
backend = plt.get_backend()
167-
proc = InterruptiblePopen(
176+
proc = WaitForStringPopen(
168177
[sys.executable, "-c",
169178
inspect.getsource(_test_other_signal_before_sigint_impl) +
170179
"\n_test_other_signal_before_sigint_impl("
@@ -173,7 +182,7 @@ def test_other_signal_before_sigint(target, kwargs):
173182
proc.wait_for('DRAW')
174183
os.kill(proc.pid, signal.SIGUSR1)
175184
proc.wait_for('SIGUSR1')
176-
proc.interrupt()
185+
os.kill(proc.pid, signal.SIGINT)
177186
stdout, _ = proc.communicate(timeout=_test_timeout)
178187
except:
179188
proc.kill()

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy