I am trying to use a library that relies on tkinter (inky, in mock mode).
My development environment consists of debian bookworm with python 3.12 (installed using asdf, a pyenv-like tool) and a virtual environment created from this runtime using python -m venv .venv
.
The python 3.12 runtime was installed after installing the tk-dev
libs so the module was compiled and if I run python -m tkinter
using that runtime, it works and I can see the tk test window.
Looking into details, the cpython bridge dynamic library is present at /home/joel/.asdf/installs/python/3.12.1/lib/python3.12/lib-dynload/_tkinter.cpython-312-x86_64-linux-gnu.so
.
Running ldd
on that file yields the libtk8.6.so file as expected, and that file is present on my system:
$ ldd ~/.asdf/installs/python/3.12.1/lib/python3.12/lib-dynload/_tkinter.cpython-312-x86_64-linux-gnu.so
linux-vdso.so.1 (0x00007fff1671e000)
libtk8.6.so => /lib/x86_64-linux-gnu/libtk8.6.so (0x00007f181edbf000)
...
Now, if I activate the virtualenv and run the same command, I am getting the following error:
$ python -m tkinter
Traceback (most recent call last):
File "<frozen runpy>", line 189, in _run_module_as_main
File "<frozen runpy>", line 148, in _get_module_details
File "<frozen runpy>", line 112, in _get_module_details
File "/home/joel/.asdf/installs/python/3.12.1/lib/python3.12/tkinter/__init__.py", line 38, in <module>
import _tkinter # If this fails your Python may not be configured for Tk
^^^^^^^^^^^^^^^
ImportError: libtk8.6.so: cannot open shared object file: No such file or directory
This makes no sense, as both the base interpreter and venv's paths are the same. With base interpreter:
$ python
Python 3.12.1 (main, Jan 14 2024, 12:18:04) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print('\n'.join(sys.path))
/home/joel/.asdf/installs/python/3.12.1/lib/python312.zip
/home/joel/.asdf/installs/python/3.12.1/lib/python3.12
/home/joel/.asdf/installs/python/3.12.1/lib/python3.12/lib-dynload
/home/joel/.asdf/installs/python/3.12.1/lib/python3.12/site-packages
With venv:
$ python
Python 3.12.1 (main, Jan 14 2024, 12:18:04) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> print('\n'.join(sys.path))
/app/packages/python
/home/joel/.asdf/installs/python/3.12.1/lib/python312.zip
/home/joel/.asdf/installs/python/3.12.1/lib/python3.12
/home/joel/.asdf/installs/python/3.12.1/lib/python3.12/lib-dynload
/home/joel/code/MiniPADD/.venv/lib/python3.12/site-packages
The only differences are:
/app/packages/python
path that comes first but there's no such path on my system.site-packages
, which is normal for a venv and should not have an impact as the base interpreter's path only contains pip
.I have no idea how to debug this further, there's nothing I can think of that explains why the static lib can be found in the case of the base interpreter but not when the virtual env is active.
How should I go to investigate this in further details?
I managed to get it working... partially.
For some reason, I had to recompile python, using the following env vars:
$ export TCLTK_LIBS="$(pkg-config tk --libs)"
$ export TCLTK_CFLAGS="$(pkg-config tk --cflags)"
$ asdf install python 3.12.1
I have no idea why this works, python was already compiled with tk enabled since it was working outside the venv, but passing those variables allowed me to make it work from inside the venv.
I still get the same error when running the code from PyCharm, although it is using the same venv as the one that works on the command line...