Skip to content

force tests to use matplotlib Agg backend - #240

Merged
stefansc1 merged 2 commits into
devfrom
fix/plot_tests
Oct 12, 2026
Merged

stefansc1 merged 2 commits into
devfrom
fix/plot_tests

Conversation

@j-brendel

Copy link
Copy Markdown
Collaborator

Tests crash with _tkinter.TclError: Can't find a usable tk.tcl

Problem

Running pytest tests can fail with:

_tkinter.TclError: Can't find a usable tk.tcl in the following directories: ...
... ttk/classicTheme.tcl: couldn't read file ... no such file or directory

The traceback points into tkinter's Tk.__init__ (_tkinter.create(...)), triggered from
simba/report.py::generate_plots():

with plt.ion():  # make plotting temporarily interactive, so plt.show does not block
    plt.clf()
    plot(scenario)
    ...

plt.ion() switches matplotlib into interactive mode regardless of args.show_plots (that flag
only guards the later explicit plt.show() call). When matplotlib has no backend configured
explicitly and runs on a machine where Tk is available, it auto-selects an interactive GUI
backend (TkAgg on Windows). Creating the figure then instantiates real Tk/ttk widgets
(e.g. for the toolbar), which is what pulls in ttk::LoadThemes and tries to source the ttk
theme files. The underlying Tcl/Tk installation can be completely intact (confirmed via
python -c "import tkinter; tkinter.Tk()" and by checking the referenced file on disk) — the
real issue is that the test suite ends up creating a real GUI window at all.

This is fragile (depends on the local machine's Tk/ttk setup, antivirus/EDR file scanning, etc.)
and unnecessary: automated tests should not open interactive windows or depend on a display being
available.

Solution

Force matplotlib onto the non-interactive Agg backend for the whole test session, in
tests/conftest.py:

import matplotlib
matplotlib.use("Agg")

from pathlib import Path
...
  • conftest.py is always loaded by pytest before any test module, so this is the one place that
    reliably runs before matplotlib.pyplot gets imported anywhere (directly or via
    simba.report). Matplotlib's backend can only be set before the first pyplot import, so
    setting it per test file would be unreliable once any earlier test has already imported
    simba.report.
  • Agg still produces the .png/.pdf files via plt.savefig(...), so plot-generation tests
    keep working; only the interactive window is skipped.
  • Production/CLI usage of SimBA (generate_plots with args.show_plots = True outside of
    pytest) is unaffected, since conftest.py only applies to the test session.

Implementation (branch fix/plot_tests)

  • tests/conftest.py: added matplotlib.use("Agg") before other imports.

@j-brendel
j-brendel requested a review from stefansc1 October 12, 2026 07:49
@stefansc1
stefansc1 merged commit 8f8eb44 into dev Oct 12, 2026
4 checks passed
@stefansc1
stefansc1 deleted the fix/plot_tests branch October 12, 2026 08:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants