Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/matplotlib/tests/test_backend_macosx.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,17 @@
from unittest import mock

import matplotlib as mpl
from matplotlib import _c_internal_utils
import matplotlib.pyplot as plt
from matplotlib.testing import subprocess_run_helper


pytestmark = [
pytest.mark.skipif(not _c_internal_utils.display_is_valid(),
reason="Display is unavailable")
]


_test_timeout = 60


Expand Down
5 changes: 2 additions & 3 deletions lib/matplotlib/tests/test_backend_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,8 @@ def _get_testable_qt_backends():
]:
reason = None
missing = [dep for dep in deps if not importlib.util.find_spec(dep)]
if (sys.platform == "linux" and
not _c_internal_utils.display_is_valid()):
reason = "$DISPLAY and $WAYLAND_DISPLAY are unset"
if not _c_internal_utils.display_is_valid():
reason = "Display is unavailable"
elif missing:
reason = "{} cannot be imported".format(", ".join(missing))
elif env["MPLBACKEND"] == 'macosx' and os.environ.get('TF_BUILD'):
Expand Down
4 changes: 2 additions & 2 deletions lib/matplotlib/tests/test_backend_tk.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def _isolated_tk_test(success_count, func=None):
reason="missing tkinter"
)
@pytest.mark.skipif(
sys.platform == "linux" and not _c_internal_utils.xdisplay_is_valid(),
reason="$DISPLAY is unset"
not _c_internal_utils.display_is_valid(),
reason="Display is unavailable"
)
@functools.wraps(func)
def test_func():
Expand Down
9 changes: 6 additions & 3 deletions lib/matplotlib/tests/test_backends_interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ def _get_available_interactive_backends():
not _c_internal_utils.display_is_valid())
_is_linux_and_xdisplay_invalid = (sys.platform == "linux" and
not _c_internal_utils.xdisplay_is_valid())
_is_macos_and_display_invalid = (sys.platform == "darwin" and
not _c_internal_utils.display_is_valid())
envs = []
for deps, env in [
*[([qt_api],
Expand All @@ -85,6 +87,8 @@ def _get_available_interactive_backends():
reason = "$DISPLAY is unset"
elif _is_linux_and_display_invalid:
reason = "$DISPLAY and $WAYLAND_DISPLAY are unset"
elif _is_macos_and_display_invalid:
reason = "Display is unavailable"
elif env["MPLBACKEND"] == 'macosx' and os.environ.get('TF_BUILD'):
reason = "macosx backend fails on Azure"
elif env["MPLBACKEND"].startswith('gtk'):
Expand Down Expand Up @@ -451,9 +455,8 @@ def qt5_and_qt6_pairs():
yield from ([qt5, qt6], [qt6, qt5])


@pytest.mark.skipif(
sys.platform == "linux" and not _c_internal_utils.display_is_valid(),
reason="$DISPLAY and $WAYLAND_DISPLAY are unset")
@pytest.mark.skipif(not _c_internal_utils.display_is_valid(),
reason='Display is unavailable')
@pytest.mark.parametrize('host, mpl', [*qt5_and_qt6_pairs()])
def test_cross_Qt_imports(host, mpl):
try:
Expand Down
4 changes: 1 addition & 3 deletions lib/matplotlib/tests/test_rcparams.py
Original file line number Diff line number Diff line change
Expand Up @@ -573,9 +573,7 @@ def test_backend_fallback_headless_auto_backend(tmp_path):
assert backend.strip().lower() == "agg"


@pytest.mark.skipif(
sys.platform == "linux" and not _c_internal_utils.xdisplay_is_valid(),
reason="headless")
@pytest.mark.skipif(not _c_internal_utils.display_is_valid(), reason="headless")
def test_backend_fallback_headful(tmp_path):
if parse_version(pytest.__version__) >= parse_version('8.2.0'):
pytest_kwargs = dict(exc_type=ImportError)
Expand Down
13 changes: 13 additions & 0 deletions src/_c_internal_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#include <CoreText/CoreText.h>
#include <ApplicationServices/ApplicationServices.h>
#endif

namespace py = pybind11;
Expand Down Expand Up @@ -94,6 +95,16 @@ mpl_display_is_valid(void)
}
}
return false;
#elif defined(__APPLE__)
CFDictionaryRef session_info;

session_info = CGSessionCopyCurrentDictionary();
if (session_info == NULL) {
return false;
}

CFRelease(session_info);
return true;
#else
return true;
#endif
Expand Down Expand Up @@ -258,6 +269,8 @@ PYBIND11_MODULE(_c_internal_utils, m, py::mod_gil_not_used())
succeeds, or $WAYLAND_DISPLAY is set and wl_display_connect(NULL)
succeeds.

On macOS, returns True if CGSessionCopyCurrentDictionary is not NULL.

On other platforms, always returns True.)""");
m.def(
"xdisplay_is_valid", &mpl_xdisplay_is_valid,
Expand Down
6 changes: 3 additions & 3 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ else
endif

if host_machine.system() == 'darwin'
coretext = dependency('appleframeworks', modules: 'CoreText')
appleframeworks = dependency('appleframeworks', modules: ['CoreGraphics', 'CoreText'])
else
coretext = []
appleframeworks = []
endif

extension_data = {
Expand All @@ -50,7 +50,7 @@ extension_data = {
'sources': files(
'_c_internal_utils.cpp',
),
'dependencies': [pybind11_dep, dl, ole32, shell32, user32, coretext],
'dependencies': [pybind11_dep, dl, ole32, shell32, user32, appleframeworks],
},
'ft2font': {
'subdir': 'matplotlib',
Expand Down
Loading