-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Expand file tree
/
Copy pathtest_backend_registry.py
More file actions
180 lines (142 loc) · 5.81 KB
/
test_backend_registry.py
File metadata and controls
180 lines (142 loc) · 5.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
from collections.abc import Sequence
from typing import Any
import pytest
import matplotlib as mpl
from matplotlib.backends import BackendFilter, backend_registry
@pytest.fixture
def clear_backend_registry():
# Fixture that clears the singleton backend_registry before and after use
# so that the test state remains isolated.
backend_registry._clear()
yield
backend_registry._clear()
def has_duplicates(seq: Sequence[Any]) -> bool:
return len(seq) > len(set(seq))
@pytest.mark.parametrize(
'framework,expected',
[
('qt', 'qtagg'),
('gtk3', 'gtk3agg'),
('gtk4', 'gtk4agg'),
('wx', 'wxagg'),
('tk', 'tkagg'),
('macosx', 'macosx'),
('headless', 'agg'),
('does not exist', None),
]
)
def test_backend_for_gui_framework(framework, expected):
assert backend_registry.backend_for_gui_framework(framework) == expected
def test_list_builtin():
backends = backend_registry.list_builtin()
assert not has_duplicates(backends)
# Compare using sets as order is not important
assert {*backends} == {
'gtk3agg', 'gtk3cairo', 'gtk4agg', 'gtk4cairo', 'macosx', 'nbagg', 'notebook',
'qtagg', 'qtcairo', 'qt5agg', 'qt5cairo', 'tkagg',
'tkcairo', 'webagg', 'wx', 'wxagg', 'wxcairo', 'agg', 'cairo', 'pdf', 'pgf',
'ps', 'svg', 'template',
}
@pytest.mark.parametrize(
'filter,expected',
[
(BackendFilter.INTERACTIVE,
['gtk3agg', 'gtk3cairo', 'gtk4agg', 'gtk4cairo', 'macosx', 'nbagg', 'notebook',
'qtagg', 'qtcairo', 'qt5agg', 'qt5cairo', 'tkagg',
'tkcairo', 'webagg', 'wx', 'wxagg', 'wxcairo']),
(BackendFilter.NON_INTERACTIVE,
['agg', 'cairo', 'pdf', 'pgf', 'ps', 'svg', 'template']),
]
)
def test_list_builtin_with_filter(filter, expected):
backends = backend_registry.list_builtin(filter)
assert not has_duplicates(backends)
# Compare using sets as order is not important
assert {*backends} == {*expected}
def test_list_gui_frameworks():
frameworks = backend_registry.list_gui_frameworks()
assert not has_duplicates(frameworks)
# Compare using sets as order is not important
assert {*frameworks} == {
"gtk3", "gtk4", "macosx", "qt", "qt5", "qt6", "tk", "wx",
}
@pytest.mark.parametrize("backend, is_valid", [
("agg", True),
("QtAgg", True),
("module://anything", True),
("made-up-name", False),
])
def test_is_valid_backend(backend, is_valid):
assert backend_registry.is_valid_backend(backend) == is_valid
@pytest.mark.parametrize("backend, normalized", [
("agg", "matplotlib.backends.backend_agg"),
("QtAgg", "matplotlib.backends.backend_qtagg"),
("module://Anything", "Anything"),
])
def test_backend_normalization(backend, normalized):
assert backend_registry._backend_module_name(backend) == normalized
def test_deprecated_rcsetup_attributes():
match = "was deprecated in Matplotlib 3.9"
with pytest.warns(mpl.MatplotlibDeprecationWarning, match=match):
mpl.rcsetup.interactive_bk
with pytest.warns(mpl.MatplotlibDeprecationWarning, match=match):
mpl.rcsetup.non_interactive_bk
with pytest.warns(mpl.MatplotlibDeprecationWarning, match=match):
mpl.rcsetup.all_backends
def test_entry_points_inline():
pytest.importorskip('matplotlib_inline')
backends = backend_registry.list_all()
assert 'inline' in backends
def test_entry_points_ipympl():
pytest.importorskip('ipympl')
backends = backend_registry.list_all()
assert 'ipympl' in backends
assert 'widget' in backends
def test_entry_point_name_shadows_builtin(clear_backend_registry):
with pytest.raises(RuntimeError):
backend_registry._validate_and_store_entry_points(
[('qtagg', 'module1')])
def test_entry_point_name_duplicate(clear_backend_registry):
with pytest.raises(RuntimeError):
backend_registry._validate_and_store_entry_points(
[('some_name', 'module1'), ('some_name', 'module2')])
def test_entry_point_identical(clear_backend_registry):
# Issue https://github.com/matplotlib/matplotlib/issues/28367
# Multiple entry points with the same name and value (value is the module)
# are acceptable.
n = len(backend_registry._name_to_module)
backend_registry._validate_and_store_entry_points(
[('some_name', 'some.module'), ('some_name', 'some.module')])
assert len(backend_registry._name_to_module) == n+1
assert backend_registry._name_to_module['some_name'] == 'module://some.module'
def test_entry_point_name_is_module(clear_backend_registry):
with pytest.raises(RuntimeError):
backend_registry._validate_and_store_entry_points(
[('module://backend.something', 'module1')])
@pytest.mark.parametrize('backend', [
'agg',
'module://matplotlib.backends.backend_agg',
])
def test_load_entry_points_only_if_needed(clear_backend_registry, backend):
assert not backend_registry._loaded_entry_points
check = backend_registry.resolve_backend(backend)
assert check == (backend, None)
assert not backend_registry._loaded_entry_points
backend_registry.list_all() # Force load of entry points
assert backend_registry._loaded_entry_points
@pytest.mark.parametrize(
'gui_or_backend, expected_backend, expected_gui',
[
('agg', 'agg', None),
('qt', 'qtagg', 'qt'),
('TkCairo', 'tkcairo', 'tk'),
]
)
def test_resolve_gui_or_backend(gui_or_backend, expected_backend, expected_gui):
backend, gui = backend_registry.resolve_gui_or_backend(gui_or_backend)
assert backend == expected_backend
assert gui == expected_gui
def test_resolve_gui_or_backend_invalid():
match = "is not a recognised GUI loop or backend name"
with pytest.raises(RuntimeError, match=match):
backend_registry.resolve_gui_or_backend('no-such-name')