1
1
import functools
2
- import inspect
2
+ import importlib
3
3
import os
4
4
import platform
5
- import re
6
5
import subprocess
7
6
import sys
8
7
9
8
import pytest
10
9
10
+ from matplotlib .testing import subprocess_run_helper
11
+ from matplotlib import _c_internal_utils
12
+
11
13
_test_timeout = 60 # A reasonably safe value for slower architectures.
12
14
13
15
@@ -20,28 +22,24 @@ def _isolated_tk_test(success_count, func=None):
20
22
in a subprocess. See GH#18261
21
23
22
24
The decorated function must be fully self-contained, and thus perform
23
- all the imports it needs. Because its source is extracted and run by
24
- itself, coverage will consider it as not being run, so it should be marked
25
- with ``# pragma: no cover``
25
+ all the imports it needs.
26
26
"""
27
27
28
28
if func is None :
29
29
return functools .partial (_isolated_tk_test , success_count )
30
30
31
- # Remove decorators.
32
- source = re .search (r"(?ms)^def .*" , inspect .getsource (func )).group (0 )
33
-
34
31
@functools .wraps (func )
35
32
def test_func ():
33
+ if (sys .platform == "linux" and
34
+ not _c_internal_utils .display_is_valid ()):
35
+ pytest .skip ("$DISPLAY and $WAYLAND_DISPLAY are unset" )
36
+ elif not importlib .util .find_spec ('tkinter' ):
37
+ pytest .skip ("missing tkinter" )
36
38
try :
37
- proc = subprocess .run (
38
- [sys .executable , "-c" , f"{ source } \n { func .__name__ } ()" ],
39
- env = {** os .environ , "MPLBACKEND" : "TkAgg" },
40
- timeout = _test_timeout ,
41
- stdout = subprocess .PIPE ,
42
- stderr = subprocess .PIPE ,
43
- check = True ,
44
- universal_newlines = True ,
39
+ proc = subprocess_run_helper (
40
+ __name__ , func , timeout = _test_timeout ,
41
+ MPLBACKEND = "TkAgg" ,
42
+ MPL_TEST_ESCAPE_HATCH = "1"
45
43
)
46
44
except subprocess .TimeoutExpired :
47
45
pytest .fail ("Subprocess timed out" )
@@ -55,13 +53,14 @@ def test_func():
55
53
assert not [line for line in proc .stderr .splitlines ()
56
54
if "OpenGL" not in line ]
57
55
assert proc .stdout .count ("success" ) == success_count
58
-
59
- return test_func
56
+ if "MPL_TEST_ESCAPE_HATCH" in os .environ :
57
+ return func
58
+ else :
59
+ return test_func
60
60
61
61
62
- @pytest .mark .backend ('TkAgg' , skip_on_importerror = True )
63
62
@_isolated_tk_test (success_count = 6 ) # len(bad_boxes)
64
- def test_blit (): # pragma: no cover
63
+ def test_blit ():
65
64
import matplotlib .pyplot as plt
66
65
import numpy as np
67
66
import matplotlib .backends .backend_tkagg # noqa
@@ -88,9 +87,8 @@ def test_blit(): # pragma: no cover
88
87
print ("success" )
89
88
90
89
91
- @pytest .mark .backend ('TkAgg' , skip_on_importerror = True )
92
90
@_isolated_tk_test (success_count = 1 )
93
- def test_figuremanager_preserves_host_mainloop (): # pragma: no cover
91
+ def test_figuremanager_preserves_host_mainloop ():
94
92
import tkinter
95
93
import matplotlib .pyplot as plt
96
94
success = []
@@ -116,10 +114,9 @@ def legitimate_quit():
116
114
@pytest .mark .skipif (platform .python_implementation () != 'CPython' ,
117
115
reason = 'PyPy does not support Tkinter threading: '
118
116
'https://foss.heptapod.net/pypy/pypy/-/issues/1929' )
119
- @pytest .mark .backend ('TkAgg' , skip_on_importerror = True )
120
117
@pytest .mark .flaky (reruns = 3 )
121
118
@_isolated_tk_test (success_count = 1 )
122
- def test_figuremanager_cleans_own_mainloop (): # pragma: no cover
119
+ def test_figuremanager_cleans_own_mainloop ():
123
120
import tkinter
124
121
import time
125
122
import matplotlib .pyplot as plt
@@ -144,10 +141,9 @@ def target():
144
141
thread .join ()
145
142
146
143
147
- @pytest .mark .backend ('TkAgg' , skip_on_importerror = True )
148
144
@pytest .mark .flaky (reruns = 3 )
149
145
@_isolated_tk_test (success_count = 0 )
150
- def test_never_update (): # pragma: no cover
146
+ def test_never_update ():
151
147
import tkinter
152
148
del tkinter .Misc .update
153
149
del tkinter .Misc .update_idletasks
@@ -171,9 +167,8 @@ def test_never_update(): # pragma: no cover
171
167
# checks them.
172
168
173
169
174
- @pytest .mark .backend ('TkAgg' , skip_on_importerror = True )
175
170
@_isolated_tk_test (success_count = 2 )
176
- def test_missing_back_button (): # pragma: no cover
171
+ def test_missing_back_button ():
177
172
import matplotlib .pyplot as plt
178
173
from matplotlib .backends .backend_tkagg import NavigationToolbar2Tk
179
174
0 commit comments