Probe QtWidgets, not QtCore: the qt backend needs the full GUI stack
QtCore's libraries (glib, icu) can load while QtWidgets/QtGui still miss libGL - matplotlib's qt backend imports all three, so the old probe could promise QtAgg and lose even the error figure at switch_backend, one library layer deeper than the NixOS fix. The regression test's mock now mirrors the real failure (bare package and QtCore import fine, GUI modules raise): both the bare-import and the QtCore-probe variants now fail it, verified by mutation. Also drop two redundant f-prefixes on placeholder-less strings in report.py.
This commit is contained in:
@@ -26,14 +26,18 @@ def _pick_backend():
|
||||
("Cannot load backend 'TkAgg' ... as 'qt' is currently running") -
|
||||
exactly what happened on macOS, whose bundled Python ships tkinter.
|
||||
|
||||
The probe must import the binding's native core, not just the
|
||||
package: on NixOS `import PySide6` succeeds (pure __init__) while
|
||||
QtCore's .so cannot find the system libraries pip wheels expect
|
||||
("libgthread-2.0.so.0: cannot open shared object file") - promising
|
||||
QtAgg then kills even the error figure at switch_backend time."""
|
||||
The probe must import QtWidgets, not just the package or QtCore:
|
||||
on NixOS `import PySide6` succeeds (pure __init__) while QtCore's
|
||||
.so cannot find the system libraries pip wheels expect
|
||||
("libgthread-2.0.so.0: cannot open shared object file"), and on a
|
||||
partially provisioned system QtCore's deps (glib, icu) can be
|
||||
present while QtWidgets/QtGui still miss libGL/libEGL. matplotlib's
|
||||
qt backend imports QtCore, QtGui and QtWidgets, so probe the widest
|
||||
one - promising QtAgg then kills even the error figure at
|
||||
switch_backend time."""
|
||||
for qt in ("PySide6", "PyQt6", "PyQt5", "PySide2"):
|
||||
try:
|
||||
__import__(qt + ".QtCore")
|
||||
__import__(qt + ".QtWidgets")
|
||||
return "QtAgg" if qt in ("PySide6", "PyQt6") else "Qt5Agg"
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
@@ -68,7 +68,7 @@ def write_summary(outdir: Path, problem: Problem, stack: RasterStack,
|
||||
f"resistivity: {problem.rho_ohm_m:.3e} ohm*m",
|
||||
f"via plating: {problem.plating_nm / 1000:.0f} um",
|
||||
"",
|
||||
(f"frequency: "
|
||||
("frequency: "
|
||||
+ (f"{result.freq_hz:g} Hz (skin depth {result.skin_depth_um:.0f} um)"
|
||||
if result.freq_hz > 0 else "DC")),
|
||||
f"RESISTANCE: {result.R_ohm * 1000:.6g} mOhm"
|
||||
@@ -127,7 +127,7 @@ def write_summary(outdir: Path, problem: Problem, stack: RasterStack,
|
||||
f"contact model: {result.contact_model}"
|
||||
+ (" (uniform orthogonal injection; R is the upper contact bound)"
|
||||
if result.contact_model == "uniform" else " (ideal bonded lug)"),
|
||||
f"terminals:",
|
||||
"terminals:",
|
||||
f" V+ ({len(problem.electrodes1)} injection area(s)):",
|
||||
*(f" {_electrode_line(e)}" for e in problem.electrodes1),
|
||||
f" V- ({len(problem.electrodes2)} injection area(s)):",
|
||||
|
||||
Reference in New Issue
Block a user