Can't use tkinter in virtual environment created by poetry
- OS version and name: Ubuntu 20.04
- Poetry version: 1.1.7
- Link of a Gist with the contents of your pyproject.toml file: https://gist.github.com/vitalije/77d16343bf8f0a99ec0946f2586edf5b
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.
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 -pfor the path to your virtualenv - The virtualenv version should look like
virtualenv = 20.*.*- 20.7.2 was broken, while 20.10.0 was fixed
- Run
- 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. 😄
I think I'm having a similar issue.
$ which poetry
/Users/rben01/.local/bin/poetry
$ python --version
Python 3.10.6
$ poetry --version
Poetry (version 1.2.1)
$ poetry run python --version
Python 3.10.6
$ python -m tkinter # displays tk window, produces no output
$ poetry run python -m tkinter
Traceback (most recent call last):
File "/nix/store/8b68yhhj335ajv25iqc2cdmp78csdlcv-python3-3.10.6/lib/python3.10/runpy.py", line 187, in _run_module_as_main
mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
File "/nix/store/8b68yhhj335ajv25iqc2cdmp78csdlcv-python3-3.10.6/lib/python3.10/runpy.py", line 146, in _get_module_details
return _get_module_details(pkg_main_name, error)
File "/nix/store/8b68yhhj335ajv25iqc2cdmp78csdlcv-python3-3.10.6/lib/python3.10/runpy.py", line 110, in _get_module_details
__import__(pkg_name)
File "/nix/store/8b68yhhj335ajv25iqc2cdmp78csdlcv-python3-3.10.6/lib/python3.10/tkinter/__init__.py", line 37, in <module>
import _tkinter # If this fails your Python may not be configured for Tk
ModuleNotFoundError: No module named '_tkinter'
This does not reproduce for me in a container -- I suspect that your Python simply has not been built against TK.
docker run --rm -i --entrypoint /bin/bash python:3.10 <<-EOF
apt-get update
apt-get install -y xvfb
pip install poetry==1.2.1
poetry new foo
pushd foo
poetry run python -m tkinter
xvfb-run poetry run python -m tkinter
EOF
@neersighted But python -m tkinter works fine.
Are you sure that you are using the same interpreter? I would try to poetry env use the Python executable you have configured for TK.
$ poetry env use "$(which python)"
Using virtualenv: /Users/rben01/Library/Caches/pypoetry/virtualenvs/base-wTklQcO3-py3.10
$ poetry run python -m tkinter
Traceback (most recent call last):
File "/nix/store/8b68yhhj335ajv25iqc2cdmp78csdlcv-python3-3.10.6/lib/python3.10/runpy.py", line 187, in _run_module_as_main
mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
File "/nix/store/8b68yhhj335ajv25iqc2cdmp78csdlcv-python3-3.10.6/lib/python3.10/runpy.py", line 146, in _get_module_details
return _get_module_details(pkg_main_name, error)
File "/nix/store/8b68yhhj335ajv25iqc2cdmp78csdlcv-python3-3.10.6/lib/python3.10/runpy.py", line 110, in _get_module_details
__import__(pkg_name)
File "/nix/store/8b68yhhj335ajv25iqc2cdmp78csdlcv-python3-3.10.6/lib/python3.10/tkinter/__init__.py", line 37, in <module>
import _tkinter # If this fails your Python may not be configured for Tk
ModuleNotFoundError: No module named '_tkinter'
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.
Ran into this as well.
Looks like pyenv had a similar issue with tkinter: https://github.com/pyenv/pyenv/issues/1375
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 [email protected])/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 [email protected])/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 [email protected])/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.
If you use
pyenvto 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
tkinterwithpyenvcan 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-devOn macOS, you can use Homebrew to achieve the same:
brew install tcl-tkStep 2: Linking the Correct Tcl/Tk Versions
Next, make sure you link the correct versions of Tcl/Tk when installing Python.
pyenvbuilds 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.3When 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 [email protected])/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 [email protected])/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 [email protected])/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 importtkinterin yourpyenvPython environment.Note that I couldn't get
tkinterto work with pyenvon Python 3.11.0, but it worked perfectly on3.11.2.
Worked for me on Python 1 3.11.1 , thanks a lot!
Fwiw I got this on macos (m1, sonoma) and I checked what version of python was running inside poetry shell, then exited that shell, ran the same version, tried import tkinter as tk, got the same error, then realized that yes — I'd installed python-tk — but my poetry shell was referencing python 3.12 and I only had [email protected]. Resolved with
brew install [email protected]
@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.
Closing this issue as most of the information here is stale and maintainers cannot reproduce it to debug.
If you encounter this issue please raise a new issue with relevant details and a usable reproducer.
I am not using poetry anymore so it is not terribly important to me, but here is today's experiment that still produces the same error.
>cd /tmp
>mkdir proba
>cd proba
>poetry --version
Poetry (version 1.8.1)
>poetry init
... setting the required python version to ^3.9
...
Generated file
[tool.poetry]
name = "proba"
version = "0.1.0"
description = ""
authors = ["vitalije <[email protected]>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.9"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Do you confirm generation? (yes/no) [yes]
>poetry env use /opt/programi/Python/bin/python3.9
Creating virtualenv proba-NvBQKm7d-py3.9 in /home/vitalije/.cache/pypoetry/virtualenvs
Using virtualenv: /home/vitalije/.cache/pypoetry/virtualenvs/proba-NvBQKm7d-py3.9
>poetry shell
Spawning shell within /home/vitalije/.cache/pypoetry/virtualenvs/proba-NvBQKm7d-py3.9
. /home/vitalije/.cache/pypoetry/virtualenvs/proba-NvBQKm7d-py3.9/bin/activate
> python -m tkinter
Traceback (most recent call last):
File "/opt/programi/Python/lib/python3.9/runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/opt/programi/Python/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/opt/programi/Python/lib/python3.9/tkinter/__main__.py", line 7, in <module>
main()
File "/opt/programi/Python/lib/python3.9/tkinter/__init__.py", line 4557, in _test
root = Tk()
File "/opt/programi/Python/lib/python3.9/tkinter/__init__.py", line 2270, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: Can't find a usable tk.tcl in the following directories:
/usr/local/lib/tcl8.6/tk8.6 /usr/local/lib/tk8.6 /home/vitalije/.cache/pypoetry/virtualenvs/proba-NvBQKm7d-py3.9/lib/tk8.6 /home/vitalije/.cache/pypoetry/virtualenvs/proba-NvBQKm7d-py3.9/lib/tk8.6 /home/vitalije/.cache/pypoetry/virtualenvs/lib/tk8.6 /home/vitalije/.cache/pypoetry/virtualenvs/proba-NvBQKm7d-py3.9/library
>
However running directly python executable with -m tkinter succeeds
>/opt/programi/Python/bin/python3.9 -m tkinter
I expect that after instructing poetry to use selected interpreter with:
> poetry env use .....some/path/python
it would create environment fully compatible with the given python interpreter installation. Instead it creates environment that is missing some packages.
Maybe my expectation is not valid, but that's what I understood this command should accomplish.
Best regards.
Note that in the reported error python says it could not find tcl.tk installation in the several directories. This list of directories doesn't include lib folder of the original python installation. Poetry did not make a copy of the required files from that folder nor it did change the search path. Maybe the reason you can't reproduce the bug is that you have tcl.tk installed in some other folder mentioned in the search path. In that case python from the environment generated by poetry is not using the original tcl.tk, but some other instance possibly a different version too.
If I manually copy necessary files to the environment created by poetry, tkinter module works. Therefore I am blaming poetry for doing its job partially. The module tkinter is a part of the python standard library, so I don't think it should be listed as a dependency.
@vitalije if you can, can you please try the following?
- Using
poetry runinstead ofpoetry shell.
poetry run python -m tkinter
- Creating a virtual environment using the standard lib venv.
/opt/programi/Python/bin/python3.9 -m venv /tmp/py39-venv
/tmp/py39-venv/bin/python -m tkinter
source /tmp/py39-venv/bin/activate
python -m tkinter
deactivate
- Creating a virtual environment using the virtualenv package installed with Poetry.
poetry_python_bin=$(head -n1 $(which poetry) | sed s/'#!'//)
"$poetry_python_bin" -m virtualenv /tmp/py39-venv-poetry
/tmp/py39-venv-poetry/bin/python -m tkinter
source /tmp/py39-venv-poetry/bin/activate
python -m tkinter
deactivate
-
poetry run python -m tkinterproduces the same error - the same error
- In this case, the second line produces the following error:
bash: /usr/bin/env bash: No such file or directory > echo $poetry_python_bin /usr/bin/env bash
I guess you wished to set this variable to the python interpreter used by poetry?
So, I did the following:
>/opt/programi/Python/bin/python3.9 -m pip install poetry
>/opt/programi/Python/bin/poetry --version
Poetry (version 1.8.2)
>head -n 1 /opt/programi/Python/bin/poetry
#!/opt/programi/Python/bin/python3.9
So, I set the poetry_python_bin to this value and continued with the 3rd script you've suggested and the result is the same error.
Even, starting from the scratch using the newly installed poetry to create a new project and a new environment produced the same error.
If I manually add links lib/tcl8.6 and lib/tk8.6 pointing to the corresponding folders in /opt/programi/Python/lib/{tcl8.6,tk.86}, then afterwards, python -m tkinter works normally.
Thank you for taking the time to do that.
Based on 2 and 3, I'm fairly confident the issue lies in how venv and virtualenv creates the virtual environment on your system. The latter is what Poetry uses internally.
It could be a bug in venv/virtualenv or for some reason your environment might require some additional flags when creating the environment. If it is about missing flags, then Poetry could detect the scenario and work around the issue.
How did you install your python installation?
It would help significantly if this can be reproduced in a container so we can debug.
I also run into this. Not much to add to the discussion at the moment, will update if I ever manage to solve it on my own.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.