Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't use tkinter with new venv set up with uv #7036

Open
dstansby opened this issue Sep 4, 2024 · 10 comments
Open

Can't use tkinter with new venv set up with uv #7036

dstansby opened this issue Sep 4, 2024 · 10 comments
Labels
bug Something isn't working compatibility Compatibility with a specification or another tool

Comments

@dstansby
Copy link

dstansby commented Sep 4, 2024

uv venv
source .venv/bin/activate
python -c "from tkinter import Tk; window = Tk()" 

This gives me the error message:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/dstansby/.local/share/uv/python/cpython-3.12.5-macos-aarch64-none/lib/python3.12/tkinter/__init__.py", line 2346, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_tkinter.TclError: Can't find a usable init.tcl in the following directories: 
    /tools/deps/lib/tcl8.6 /Users/dstansby/.venv/lib/tcl8.6 /Users/dstansby/lib/tcl8.6 /Users/dstansby/.venv/library /Users/dstansby/library /Users/dstansby/tcl8.6.12/library /Users/tcl8.6.12/library



This probably means that Tcl wasn't installed properly.

I can successfully run python -c "from tkinter import Tk; window = Tk()" in a fresh conda environment, but when I install python on conda it also installs tk, so maybe that's why it works? Maybe this isn't an issue with uv?, but if anyone knows how to get this working I'd be very gateful!

uv 0.4.4 (Homebrew 2024-09-04)
macOS

@zanieb
Copy link
Member

zanieb commented Sep 4, 2024

This is a python-build-standalone quirk: https://gregoryszorc.com/docs/python-build-standalone/main/quirks.html#tcl-tk-support-files

We might need to set the variable as described there. 🤔

@bluss
Copy link
Contributor

bluss commented Sep 4, 2024

For the record, rye did this astral-sh/rye#233

@charliermarsh
Copy link
Member

I'm not opposed to doing a similar thing here.

@charliermarsh charliermarsh added bug Something isn't working compatibility Compatibility with a specification or another tool labels Sep 4, 2024
@mraesener-aubex
Copy link

to maybe point others to a workaround, all you'd need to do is to export an env variable called TCL_LIBRARY pointing to the correct tcl directory.
to figure the correct one out, I did the following:

ATTENTION: this assumes that your .venv is based on the default python available to uv and also that tcl is at version 8.6, so keep that in mind

#!/bin/bash

# Get the Python path
PYTHON_PATH=$(cd ~ && uv run which python)

# Extract the base path
BASE_PATH=$(dirname "$(dirname "$PYTHON_PATH")")

# Construct the TCL_LIBRARY path
TCL_LIBRARY="$BASE_PATH/lib/tcl8.6"

# Set the environment variable
export TCL_LIBRARY

# Print the set variable (for verification)
echo "TCL_LIBRARY has been set to: $TCL_LIBRARY"

for comfort I've then just put the var in my .env file which gets automatically loaded by .envrc (direnv) - which btw would totally be an appealing feature for uv to replicate :P

@astrojuanlu
Copy link

The quirks page says

Distributions produced from this project contain tcl/tk support files

However,

$ uv --version
uv 0.4.22
$ uv venv -p 3.9
Using CPython 3.9.19
Creating virtual environment at: .venv
Activate with: source .venv/bin/activate.fish
$ find .venv -name "*tcl*"
$ # ?

What am I doing wrong?

@emcek
Copy link

emcek commented Oct 16, 2024

$ find .venv -name "tcl"
$ # ?


What am I doing wrong?

Those are in python installation directory not in virtualenv, I'm not next to linux box but under windows:

(venvflon) PS C:\Users\mplichta\Projects\venvflon> uv python list          
cpython-3.13.0-windows-x86_64-none     C:\Users\mplichta\AppData\Roaming\uv\python\cpython-3.13.0-windows-x86_64-none\python.exe
cpython-3.12.7-windows-x86_64-none     <download available>

So, path would be: C:\Users\mplichta\AppData\Roaming\uv\python\cpython-3.13.0-windows-x86_64-none\tcl\tcl8.6

As workaroud you can use tkinker like:

from os import environ
from pathlib import Path
from sys import base_prefix

environ["TCL_LIBRARY"] = str(Path(base_prefix) / "tcl" / "tcl8.6")
environ["TK_LIBRARY"] = str(Path(base_prefix) / "tcl" / "tk8.6")
import tkinter as tk

@astrojuanlu
Copy link

Oh I understand now. On macOS they're under ~/.local/share/uv/python/cpython-*-macos-aarch64-none/lib/tcl8.6 👍🏼

@giolucasd
Copy link

giolucasd commented Oct 17, 2024

This is an important issue for me and my employers. I'm currently using the workaround suggeted above.
I'm a CS major with 5 years of SWE xp in python, but no xp in rust yet. Learning rust is a current goal of mine.
Would you consider this a good first issue for me or at least one that I could get along? If so, any special precautions?

@zanieb
Copy link
Member

zanieb commented Oct 17, 2024

It'd be a stretch to say it's a good first issue, there's a lot of nuance to the possible solutions and I would have to do quite a bit of research to even understand what the trade-offs are. I think the first best step is to understand Rye's approach and if there are any alternatives. If it's the most compelling approach still, we should be able to port it over without too much difficulty.

@harrylaulau
Copy link

harrylaulau commented Oct 18, 2024

Since most people expect to use Tkinter that comes with the python, I guess including TCL_LIBRARY and TK_LIBRARY env path pointing to where uv installed python as @emcek described would be a good default solution? The uv can provide some override mechanism, like allowing use to specify custom path to these two environment variable in the .python_version file or maybe some other files? This way TCL should always work by default.

I tried @emcek method on Mac and the result is successful

from os import environ
from pathlib import Path
from sys import base_prefix

environ["TCL_LIBRARY"] = str(Path(base_prefix) / "lib" / "tcl8.6")
environ["TK_LIBRARY"] = str(Path(base_prefix) / "lib" / "tk8.6")

print(environ["TCL_LIBRARY"])
print(environ["TK_LIBRARY"])

from tkinter import *
from tkinter import ttk
root = Tk()
frm = ttk.Frame(root, padding=10)
frm.grid()
ttk.Label(frm, text="Hello World!").grid(column=0, row=0)
ttk.Button(frm, text="Quit", command=root.destroy).grid(column=1, row=0)
root.mainloop()

However I have changed the path of TCL_LIBRARY and TK_LIBRARY a bit as for mac its "lib" instead of "tcl", as pointed out by @astrojuanlu

Maybe uv can populate the two environmental variable by default?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working compatibility Compatibility with a specification or another tool
Projects
None yet
Development

No branches or pull requests

9 participants