Skip to content

Commit

Permalink
Remove Tkl/tk caveats from quirks (#434)
Browse files Browse the repository at this point in the history
## Summary

I'm open to keeping something here, but it should just be a non-issue
for users in the future?
  • Loading branch information
charliermarsh authored Dec 18, 2024
1 parent f91adf9 commit d9ff11c
Showing 1 changed file with 0 additions and 82 deletions.
82 changes: 0 additions & 82 deletions docs/quirks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,88 +80,6 @@ at build time! So actually using this bundled terminfo database will
require custom code setting ``TERMINFO_DIRS`` before
ncurses/libedit/readline are loaded.

.. _quirk_tcl:

Tcl/tk Support Files
====================

Python functionality using tcl/tk (such as the ``tkinter`` or ``turtle``
modules) requires loading ``.tcl`` support files from the filesystem.
If these support files cannot be found, you'll get an error like
``_tkinter.TclError: Can't find a usable init.tcl in the following
directories:``.

Distributions produced from this project contain tcl/tk support files.
The paths to these files in the extracted distribution are advertised
in the ``PYTHON.json`` file.

When tcl is initialized by Python, Python and tcl attempt to locate the
``.tcl`` support files. If the ``tcl<X.Y>/init.tcl`` file cannot be found,
an error occurs.

But the mechanism for finding the ``.tcl`` files varies by platform.

On all platforms, if the ``TCL_LIBRARY`` environment variable is set,
it will be used to locate the ``.tcl`` support files. This environment
variable is processed by tcl itself and is documented at
https://wiki.tcl-lang.org/page/TCL_LIBRARY.

On Windows, CPython will attempt to locate the ``.tcl`` support files in
well-defined directories. The C code performs the equivalent of the
following:

.. code-block:: python
import os
import sys
def get_tcl_path():
# e.g. sys.prefix/tcl/tcl8.6
p = os.path.join(sys.prefix, "tcl", "tcl<X.Y>")
if os.path.exists(p):
return p
return None
If Python's code can find the support files in the well-defined location,
it calls into the tcl C API and defines the ``tcl_library`` variable to the
found path.

The most robust way to ensure Python/tcl can find the ``.tcl`` support files
is to define ``TCL_LIBRARY`` to the path to the ``.tcl`` files present in
the extracted Python distribution. It is possible to define this environment
variable from within Python. But it must be done before running any Python
code in the ``tkinter`` module. The following example should work on Linux
and macOS distributions:

.. code-block:: python
import os
import sys
os.environ["TCL_LIBRARY"] = os.path.join(os.path.dirname(sys.executable), "..", "lib", "tcl8.6")
import turtle
If you don't set ``TCL_LIBRARY`` on Linux and macOS, the default search
mechanics implemented by Tcl are used. These may pick up ``.tcl`` files from
a location outside the Python distribution. This may *just work*. This may
fail fast. Or it could result in undefined behavior. For best results,
forcefully point Tcl at the ``.tcl`` files from the Python distribution
produced by this project.

On Windows, explicitly setting ``TCL_LIBRARY`` is not required as the
default install layout of this project's Python distributions allows CPython's
filesystem probing code to find the ``.tcl`` files. As long as the
files from ``python/install/tcl`` are present (in a ``tcl`` directory
under the directory where the ``python.exe`` is), things should *just work*.

For reference, PyOxidizer's approach to this problem is to copy all the
``.tcl`` files from the Python distribution into an install location. At
run time, the ``TCL_LIBRARY`` environment variable is set from within
the process before the Python interpreter is initialized. This ensures the
``.tcl`` files from the Python distribution are used.

.. _quirk_macos_no_tix:

No tix on macOS
Expand Down

0 comments on commit d9ff11c

Please sign in to comment.