Skip to content

Commit d6179de

Browse files
committed
macOS: Check for display availability when looking for backends
1 parent 993f22d commit d6179de

File tree

8 files changed

+39
-16
lines changed

8 files changed

+39
-16
lines changed

lib/matplotlib/tests/test_backend_qt.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,8 @@ def _get_testable_qt_backends():
305305
]:
306306
reason = None
307307
missing = [dep for dep in deps if not importlib.util.find_spec(dep)]
308-
if (sys.platform == "linux" and
309-
not _c_internal_utils.display_is_valid()):
310-
reason = "$DISPLAY and $WAYLAND_DISPLAY are unset"
308+
if not _c_internal_utils.display_is_valid():
309+
reason = "Display is unavailable"
311310
elif missing:
312311
reason = "{} cannot be imported".format(", ".join(missing))
313312
elif env["MPLBACKEND"] == 'macosx' and os.environ.get('TF_BUILD'):

lib/matplotlib/tests/test_backend_tk.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ def _isolated_tk_test(success_count, func=None):
3535
reason="missing tkinter"
3636
)
3737
@pytest.mark.skipif(
38-
sys.platform == "linux" and not _c_internal_utils.display_is_valid(),
39-
reason="$DISPLAY and $WAYLAND_DISPLAY are unset"
38+
not _c_internal_utils.display_is_valid(),
39+
reason="Display is unavailable"
4040
)
4141
@pytest.mark.xfail( # https://github.com/actions/setup-python/issues/649
4242
('TF_BUILD' in os.environ or 'GITHUB_ACTION' in os.environ) and

lib/matplotlib/tests/test_backends_interactive.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,7 @@ def wait_for(self, terminator):
5555

5656
@functools.lru_cache
5757
def _get_available_interactive_backends():
58-
_is_linux_and_display_invalid = (sys.platform == "linux" and
59-
not _c_internal_utils.display_is_valid())
58+
_is_display_invalid = not _c_internal_utils.display_is_valid()
6059
envs = []
6160
for deps, env in [
6261
*[([qt_api],
@@ -74,8 +73,8 @@ def _get_available_interactive_backends():
7473
]:
7574
reason = None
7675
missing = [dep for dep in deps if not importlib.util.find_spec(dep)]
77-
if _is_linux_and_display_invalid:
78-
reason = "$DISPLAY and $WAYLAND_DISPLAY are unset"
76+
if _is_display_invalid:
77+
reason = "Display is unavailable"
7978
elif missing:
8079
reason = "{} cannot be imported".format(", ".join(missing))
8180
elif env["MPLBACKEND"] == 'macosx' and os.environ.get('TF_BUILD'):

lib/matplotlib/tests/test_rcparams.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -534,9 +534,7 @@ def test_backend_fallback_headless(tmp_path):
534534
env=env, check=True, stderr=subprocess.DEVNULL)
535535

536536

537-
@pytest.mark.skipif(
538-
sys.platform == "linux" and not _c_internal_utils.display_is_valid(),
539-
reason="headless")
537+
@pytest.mark.skipif(not _c_internal_utils.display_is_valid(), reason="headless")
540538
def test_backend_fallback_headful(tmp_path):
541539
pytest.importorskip("tkinter")
542540
env = {**os.environ, "MPLBACKEND": "", "MPLCONFIGDIR": str(tmp_path)}

meson.build

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ project(
1717

1818
cc = meson.get_compiler('c')
1919
cpp = meson.get_compiler('cpp')
20+
# Objective C is needed for the _c_internal_utils and macosx extension.
21+
if host_machine.system() == 'darwin'
22+
add_languages('objc', native: false)
23+
endif
2024

2125
# https://mesonbuild.com/Python-module.html
2226
py_mod = import('python')

src/_c_internal_utils.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
#else
1919
#define UNUSED_ON_NON_WINDOWS Py_UNUSED
2020
#endif
21+
#ifdef __APPLE__
22+
// Defined in _objc_internal_utils.m.
23+
extern "C" {
24+
int _macos_display_is_valid(void);
25+
}
26+
#endif
2127

2228
namespace py = pybind11;
2329
using namespace pybind11::literals;
@@ -69,6 +75,8 @@ mpl_display_is_valid(void)
6975
}
7076
}
7177
return false;
78+
#elif defined(__APPLE__)
79+
return _macos_display_is_valid() == 1;
7280
#else
7381
return true;
7482
#endif
@@ -180,6 +188,8 @@ PYBIND11_MODULE(_c_internal_utils, m)
180188
succeeds, or $WAYLAND_DISPLAY is set and wl_display_connect(NULL)
181189
succeeds.
182190
191+
On macOS, returns True if NSScreen::mainScreen is not nil.
192+
183193
On other platforms, always returns True.)""");
184194
m.def(
185195
"Win32_GetCurrentProcessExplicitAppUserModelID",

src/_objc_internal_utils.m

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <Cocoa/Cocoa.h>
2+
3+
int
4+
_macos_display_is_valid(void)
5+
{
6+
NSApplicationLoad();
7+
NSScreen *main = [NSScreen mainScreen];
8+
if (main != nil) {
9+
return 1;
10+
} else {
11+
return 0;
12+
}
13+
}

src/meson.build

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,10 @@ extension_data = {
8181
},
8282
'_c_internal_utils': {
8383
'subdir': 'matplotlib',
84-
'sources': files(
85-
'_c_internal_utils.cpp',
86-
),
84+
'sources': [
85+
files('_c_internal_utils.cpp'),
86+
(host_machine.system() == 'darwin') ? files('_objc_internal_utils.m') : [],
87+
],
8788
'dependencies': [pybind11_dep, dl, ole32, shell32, user32],
8889
},
8990
'ft2font': {
@@ -182,7 +183,6 @@ foreach ext, kwargs : extension_data
182183
endforeach
183184

184185
if get_option('macosx') and host_machine.system() == 'darwin'
185-
add_languages('objc', native: false)
186186
py3.extension_module(
187187
'_macosx',
188188
subdir: 'matplotlib/backends',

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