Skip to content

Commit

Permalink
Refactor autogui selection to take imported backends into account bet…
Browse files Browse the repository at this point in the history
…ter (#384)
  • Loading branch information
almarklein authored Oct 23, 2023
1 parent 9221ade commit 3ad3373
Showing 1 changed file with 74 additions and 26 deletions.
100 changes: 74 additions & 26 deletions wgpu/gui/auto.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,80 @@ def is_jupyter():
return False


def _load_backend(backend_name):
"""Load a gui backend by name."""
if backend_name == "glfw":
from . import glfw as module # noqa
elif backend_name == "qt":
from . import qt as module # noqa
elif backend_name == "jupyter":
from . import jupyter as module # noqa
elif backend_name == "wx":
from . import wx as module # noqa
elif backend_name == "offscreen":
from . import offscreen as module # noqa
else: # no-cover
raise ImportError("Unknown wgpu gui backend: '{backend_name}'")
return module


def _auto_load_backend():
# Backends to auto load, ordered by preference. Maps libname -> backend_name
gui_backends = {
"glfw": "glfw",
"PySide6": "qt",
"PyQt6": "qt",
"PySide2": "qt",
"PyQt5": "qt",
}

# The module that we try to find
module = None

# Any errors we come accross as we try to import the gui backends
errors = []

# Prefer a backend for which the lib is already imported
imported = [libname for libname in gui_backends if libname in sys.modules]
for libname in imported:
try:
module = _load_backend(gui_backends[libname])
break
except Exception as err:
errors.append(err)

# If no module found yet, try importing the lib, then import the backend
if not module:
for libname in gui_backends:
try:
importlib.import_module(libname)
except ModuleNotFoundError:
continue
try:
module = _load_backend(gui_backends[libname])
except Exception as err:
errors.append(err)

# If still nothing found, raise a useful error
if not module:
msg = "\n".join(str(err) for err in errors)
msg += "\n\n Could not find either glfw or Qt framework."
msg += "\n Install glfw using e.g. ``pip install -U glfw``,"
msg += "\n or install a qt framework using e.g. ``pip install -U pyside6``."
if sys.platform.startswith("linux"):
msg += "\n You may also need to run the equivalent of ``apt install libglfw3``."
raise ImportError(msg) from None

return module


# Triage
if os.environ.get("WGPU_FORCE_OFFSCREEN") == "true":
from .offscreen import WgpuCanvas, run, call_later # noqa
module = _load_backend("offscreen")
elif is_jupyter():
from .jupyter import WgpuCanvas, run, call_later # noqa
module = _load_backend("jupyter")
else:
try:
from .glfw import WgpuCanvas, run, call_later # noqa
except ImportError as glfw_err:
qt_backends = ("PySide6", "PyQt6", "PySide2", "PyQt5")
for backend in qt_backends:
if backend in sys.modules:
break
else:
for libname in qt_backends:
try:
importlib.import_module(libname)
break
except ModuleNotFoundError:
pass
else:
msg = str(glfw_err)
msg += "\n\n Could not find either glfw or Qt framework."
msg += "\n Install glfw using e.g. ``pip install -U glfw``,"
msg += "\n or install a qt framework using e.g. ``pip install -U pyside6``."
if sys.platform.startswith("linux"):
msg += "\n You may also need to run the equivalent of ``apt install libglfw3``."
raise ImportError(msg) from None

from .qt import WgpuCanvas, run, call_later
module = _auto_load_backend()


WgpuCanvas, run, call_later = module.WgpuCanvas, module.run, module.call_later

0 comments on commit 3ad3373

Please sign in to comment.