Skip to content

Using tkinter with pytest, "Can't find a usable init.tcl" ... "This probably means that Tcl wasn't installed properly." #939

@carlosperate

Description

@carlosperate

This is only an issue when trying to use tkinter inside pytest.
Related to:

With this file as a reproducer:

import tkinter as tk

class TestWindow(tk.Tk):
    pass

def test_window():
    app = TestWindow()

if __name__ == "__main__":
    test_window()

Using a Python interpreter installed in macOS via official installer it works fine (we can ignore the pytest trying to find tests in the empty tk class defined in the file):

$ python -m pytest test_issue.py
======================== test session starts =========================
platform darwin -- Python 3.13.7, pytest-9.0.2, pluggy-1.6.0
rootdir: /Users/carlos/workspace/tmp/delme
collected 1 item

test_issue.py .                                                [100%]

========================== warnings summary ==========================
test_issue.py:3
  /Users/carlos/workspace/tmp/delme/test_issue.py:3: PytestCollectionWarning: cannot collect test class 'TestWindow' because it has a __init__ constructor (from: test_issue.py)
    class TestWindow(tk.Tk):

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
==================== 1 passed, 1 warning in 0.19s ====================

Using uv with the latest 3.14.2:

$ python -m pip freeze > requirements.txt

$ uvx --python=3.14.2 --with-requirements=requirements.txt python -m pytest test_issue.py
====================================== test session starts ======================================
platform darwin -- Python 3.14.2, pytest-9.0.2, pluggy-1.6.0
rootdir: /Users/carlos/workspace/tmp/delme
collected 1 item

test_issue.py F                                                                           [100%]

=========================================== FAILURES ============================================
__________________________________________ test_window __________________________________________

    def test_window():
>       app = TestWindow()
              ^^^^^^^^^^^^

test_issue.py:7:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <test_issue.TestWindow object .>, screenName = None, baseName = '__main__'
className = 'Tk', useTk = True, sync = False, use = None

    def __init__(self, screenName=None, baseName=None, className='Tk',
                 useTk=True, sync=False, use=None):
        """Return a new top level widget on screen SCREENNAME. A new Tcl interpreter will
        be created. BASENAME will be used for the identification of the profile file (see
        readprofile).
        It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME
        is the name of the widget class."""
        self.master = None
        self.children = {}
        self._tkloaded = False
        # to avoid recursions in the getattr code in case of failure, we
        # ensure that self.tk is always _something_.
        self.tk = None
        if baseName is None:
            import os
            baseName = os.path.basename(sys.argv[0])
            baseName, ext = os.path.splitext(baseName)
            if ext not in ('.py', '.pyc'):
                baseName = baseName + ext
        interactive = False
>       self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       _tkinter.TclError: Can't find a usable init.tcl in the following directories:
E           /tools/deps/lib/tcl8.6 /Users/carlos/.cache/uv/archive-v0/KRJC-IU7K_S7tTfnyEv1J/lib/tcl8.6 /Users/carlos/.cache/uv/archive-v0/lib/tcl8.6 /Users/carlos/.cache/uv/archive-v0/KRJC-IU7K_S7tTfnyEv1J/library /Users/carlos/.cache/uv/archive-v0/library /Users/carlos/.cache/uv/archive-v0/tcl8.6.14/library /Users/carlos/.cache/uv/tcl8.6.14/library
E
E
E
E       This probably means that Tcl wasn't installed properly.

../../../.local/share/uv/python/cpython-3.14.2-macos-aarch64-none/lib/python3.14/tkinter/__init__.py:2479: TclError
======================================= warnings summary ========================================
test_issue.py:3
  /Users/carlos/workspace/tmp/delme/test_issue.py:3: PytestCollectionWarning: cannot collect test class 'TestWindow' because it has a __init__ constructor (from: test_issue.py)
    class TestWindow(tk.Tk):

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
==================================== short test summary info ====================================
FAILED test_issue.py::test_window - _tkinter.TclError: Can't find a usable init.tcl in the following directories:
================================= 1 failed, 1 warning in 0.14s ==================================

Running the file outside of pytest does work (or at least it doesn't throw any errors):

$ uvx --python=3.14.2 --with-requirements=requirements.txt python test_issue.py

I get the same error with the latest 3.14.2, 3.13.11, 3.12.12, 3.11.14, 3.10.19 from the latest release including the fix for #913:
https://github.com/astral-sh/python-build-standalone/releases/tag/20251217

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