Repository: matplotlib/matplotlib
File: lib/matplotlib/backends/backend_gtk3.py (Python)

Code before:
import functools
import logging
import os
from pathlib import Path

import matplotlib as mpl
from matplotlib import _api, backend_tools, cbook
from matplotlib.backend_bases import (
    ToolContainerBase, MouseButton,
    CloseEvent, KeyEvent, LocationEvent, MouseEvent, ResizeEvent)

try:
    import gi
except ImportError as err:
    raise ImportError("The GTK3 backends require PyGObject") from err

try:
    gi.require_version
except AttributeError as err:
    raise ImportError("The GTK3 backends require PyGObject") from err

try:
    # :raises ValueError: If module/version is already loaded, already
    # required, or unavailable.
    gi.require_version("Gtk", "3.0")
    # Also require GioUnix to avoid PyGIWarning when Gio is imported
    # GioUnix is platform-specific and may not be available on all systems
    try:
        gi.require_version("GioUnix", "2.0")
    except ValueError:
        # GioUnix is not available on this platform, which is fine
        pass
except ValueError as e:
    # in this case we want to re-raise as ImportError so the
    # auto-backend selection logic correctly skips.
    raise ImportError(e) from e

from gi.repository import Gio, GLib, GObject, Gtk, Gdk
from . import _backend_gtk
from ._backend_gtk import (  # noqa: F401 # pylint: disable=W0611
    _BackendGTK, _FigureCanvasGTK, _FigureManagerGTK, _NavigationToolbar2GTK,
    TimerGTK as TimerGTK3,
)



Review comment (suggestion):
Does the error message above need to be corrected then?  I do not fully understand how PyGObject / gobject introspection splits itself up in either and upstream sense or the downstream packaging sense (which I assume different packagers make different choices?).

"No, this is the right error message in both cases" is perfectly good answer, but if we can make this a bit more precise that would be good.

Code after:
import functools
import logging
import os
from pathlib import Path

import matplotlib as mpl
from matplotlib import _api, backend_tools, cbook
from matplotlib.backend_bases import (
    ToolContainerBase, MouseButton,
    CloseEvent, KeyEvent, LocationEvent, MouseEvent, ResizeEvent)

try:
    from gi import require_version as gi_require_version
except ImportError as err:
    raise ImportError("The GTK3 backends require PyGObject") from err

try:
    # :raises ValueError: If module/version is already loaded, already
    # required, or unavailable.
    gi_require_version("Gtk", "3.0")
    # Also require GioUnix to avoid PyGIWarning when Gio is imported
    # GioUnix is platform-specific and may not be available on all systems
    try:
        gi_require_version("GioUnix", "2.0")
    except ValueError:
        # GioUnix is not available on this platform, which is fine
        pass
except ValueError as e:
    # in this case we want to re-raise as ImportError so the
    # auto-backend selection logic correctly skips.
    raise ImportError(e) from e

from gi.repository import Gio, GLib, GObject, Gtk, Gdk
from . import _backend_gtk
from ._backend_gtk import (  # noqa: F401 # pylint: disable=W0611
    _BackendGTK, _FigureCanvasGTK, _FigureManagerGTK, _NavigationToolbar2GTK,
    TimerGTK as TimerGTK3,
)


_log = logging.getLogger(__name__)


@functools.cache
def _mpl_to_gtk_cursor(mpl_cursor):