Skip to content

Tcl/Tk in the embedded interpreter: differences between OS, simulator and Python #5

Description

@ru551n

Tkinter-based code in the embedded interpreter (the PySimpleGUI dialogs and the matplotlib plots of the embedded_python example) behaves differently depending on the OS, the simulator and where Python's Tcl/Tk comes from. This collects what is known, what #3 fixes, and what is still open or untested.

Linux: standalone Python builds (fixed by #3)

With a python-build-standalone CPython (what uv installs), tkinter failed in every simulator in two ways:

Error Cause Fix in #3
ImportError: libtcl9tk9.0.so: cannot open shared object file Tcl/Tk sit next to libpython and are only found through the RPATH of the python executable. In a simulator the executable is nvc, ghdl or vsim. The libraries have no SONAME, so preloading them from Python does not help. The package setup adds sys.base_prefix/lib to LD_LIBRARY_PATH of the VUnit process, inherited by every simulator
_tkinter.TclError: Cannot find a usable init.tcl The example set TCL_LIBRARY to tcl8.6 under sys.prefix whether it existed or not. In a virtual environment that is not the Python installation, and a Tcl 9 Python has no tcl8.6. tcl_library.py points Tcl/Tk at the scripts of the Python installation, for any version

Verified on Linux with NVC 1.23-devel and GHDL 7.0.0-dev (mcode). Distribution Pythons were not tested, but keep Tcl/Tk in system directories and should not need either fix.

Windows: two Tcl versions in one process (open)

Some simulators load a Tcl of their own into the simulator process. When the Python embedded in it uses another Tcl version, opening a matplotlib Tk window crashes the simulator:

Windows fatal exception: access violation
  File "...\PIL\ImageTk.py", line 65 in _pyimagingtkcall
  File "...\PIL\ImageTk.py", line 188 in paste
  File "...\PIL\ImageTk.py", line 132 in __init__
  File "...\matplotlib\backends\_backend_tk.py", line 546 in create_with_canvas

On Windows, Pillow (load_tkinter_funcs in src/Tk/tkImaging.c) and matplotlib (src/_tkagg.cpp) find the Tcl/Tk functions by enumerating the modules loaded in the process and taking the first one that exports them. That is the simulator's Tcl, loaded at startup, rather than the one _tkinter uses. On Linux and macOS both open the library of _tkinter itself, which is why this only happens on Windows.

Windows Simulator's Tcl Python 3.10 (Tcl 8.6) Python 3.14 Evidence
GHDL none plot tests pass plot tests pass CI
NVC 1.22.1 9.0 (tcl90.dll) crash plot tests pass CI, crash log
Questa 2025.2 8.6 (assumed) not tested crash (SIGSEGV in p_exec, reported in #3) Questa is not available in CI
Riviera-PRO, Active-HDL have their own Tcl not tested not tested

The crash needs a simulator with its own Tcl and a Python with a different Tcl version. Python 3.11 to 3.13 were not tested. The PySimpleGUI dialogs use tkinter directly rather than this lookup and are probably not affected, but that is not tested either.

Workarounds, documented above the plot tests in #3: use a Python with the Tcl version of the simulator, or a matplotlib backend without Tk (for example MPLBACKEND=QtAgg after pip install PySide6). A backend switch is not built into the example to avoid a large dependency.

The proper fix belongs in Pillow and matplotlib: on Windows, use the Tcl/Tk DLL that _tkinter loaded, as both already do on other platforms. No existing issue for this was found in either project.

Not tested

Also seen while running the example

  • The PySimpleGUI tests wait for answers to their dialogs and fail without a display or someone to answer them.
  • VUnit picks Questa/ModelSim before GHDL and NVC when vsim is on PATH, including an unlicensed Questa FSE installed with Quartus, and every test then fails. VUNIT_SIMULATOR selects the simulator.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions