poetry: Can't use tkinter in virtual environment created by poetry

Issue

I have several python installations. Using one that I have compiled myself (*Python 3.9.6) with support of latest stable tk/tcl (8.6.11). This python when invoked directly has full support for tkinter library. However, when I create new virtual environment using:

poetry env use /path/to/my/python3.9.6
poetry shell
python -m tkinter

I get the error that python was not configured to use tkinter module.

When I manually add links lib/tcl8.6 and lib/tk8.6 to the virtual environment in ~/.cache/pypoetry/virtualenvs/mleo.../lib/, python can use tkinter afterwards.

I was expecting that poetry would add those links when creating new virtual environment.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 7
  • Comments: 18 (6 by maintainers)

Most upvoted comments

If you use pyenv to manage your Python versions (which you should), you’ll run into this issue. I was able to fix it by following these two steps.

Step 1: Installing Necessary System Packages

Using tkinter with pyenv can be tricky due to missing dependencies.

First, let’s make sure we have installed the necessary system packages for tkinter.

In most Linux systems, you can install them with the following commands:

sudo apt-get update
sudo apt-get install tk-dev

On macOS, you can use Homebrew to achieve the same:

brew install tcl-tk

Step 2: Linking the Correct Tcl/Tk Versions

Next, make sure you link the correct versions of Tcl/Tk when installing Python. pyenv builds Python in your environment, but if you don’t have the required dependencies, like the Tk/Tcl libraries, it’ll build Python without them.

If the Python version you want to use is already installed on your system, you’ll need to uninstall it before proceeding. For example:

pyenv uninstall 3.11.3

When installing a new Python version with pyenv, use the following commands:

For Linux:

sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev \
libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev python-openssl git

env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install <version>

For macOS, after installing tcl-tk with brew:

brew install openssl readline sqlite3 xz zlib

env LDFLAGS="-L$(brew --prefix openssl@1.1)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix sqlite3)/lib -L$(brew --prefix xz)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix tcl-tk)/lib" \
CPPFLAGS="-I$(brew --prefix openssl@1.1)/include -I$(brew --prefix readline)/include -I$(brew --prefix sqlite3)/include -I$(brew --prefix xz)/include -I$(brew --prefix zlib)/include -I$(brew --prefix tcl-tk)/include" \
PKG_CONFIG_PATH="$(brew --prefix openssl@1.1)/lib/pkgconfig:$(brew --prefix readline)/lib/pkgconfig:$(brew --prefix sqlite3)/lib/pkgconfig:$(brew --prefix xz)/lib/pkgconfig:$(brew --prefix zlib)/lib/pkgconfig:$(brew --prefix tcl-tk)/lib/pkgconfig" \
pyenv install <version>

Replace <version> with the version of Python you want to install. After that, you should be able to import tkinter in your pyenv Python environment.

Note that I couldn’t get tkinter to work with pyenv on Python 3.11.0, but it worked perfectly on 3.11.2.

I too have had this issue. After some testing, it seems fixed with the current version of Poetry. Try reinstalling it. Here are some fixes…

  • I had Poetry 1.1.8 installed and had this error, 1.1.12 fixed it
  • Check your virtualenv’s pyvenv.cfg and look for the virtualenv version.
    • Run poetry env info -p for the path to your virtualenv
    • The virtualenv version should look like virtualenv = 20.*.*
      • 20.7.2 was broken, while 20.10.0 was fixed
  • Ensure that Tkinter worked with other Python versions
    • You may have to rebuild / reinstall your version
    • I ran Python 3.9.6 for both broken and fixed versions

I hope this helped you. I know it is a bit late, but hopefully someone else stumbles upon this and it fixes their issue. 😄

My working version of pyvenv.cfg…

@djeikyb the issue you are facing is not a poetry issue IMHO.

This would seem that you didn’t have the required system dependencies available for the version of python used for your project virtual environment.

Once the dependencies are installed and available you can specify the use of the correct python version for your virtual environment.

If you want to use the system site installed package, you can also attempt to use https://python-poetry.org/docs/configuration/#virtualenvsoptionssystem-site-packages. However, that is also bound to the site of the python version being used.

Ok, I tracked this down to poetry seemingly ignoring poetry env use /path/to/python in some cases. That is, you can have the following (pseudo-bash):

$ readlink "$(poetry run which python)"
/path/a/python3.10

$ poetry env use /path/b/python3.10

$ readlink "$(poetry run which python)"
/path/a/python3.10

Perhaps you have to poetry env use /path/to/python before even creating the environment? If so, it’s incredibly misleading that poetry env use is a no-op once the environment has been created.