We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
_tkinter.TclError  Possible regression from ticket 540
**Original date**: 2012/10/26
**Original reporter**: _Lynn Oliver <raycores AND gmail DOT  COOM >_

When I build with pyinstaller-2.0 on OSX 10.8.2, I can run the resulting binary on the build machine without any issues.  When I run the binary on a fresh install of OSX 10.8.2, I get a _tkinter.TclError (traceback below).  I believe this is similar to the error that I reported on ticket 540.

I'm able to build successfully with a pre-2.0 dev version of pyinstaller.  I don't know of any way to identify the exact build I am using, but the files are dated 5/4/2012 at 10:20 AM (PDT).

```
Traceback (most recent call last):
  File "<string>", line 149, in <module>
  File "../axeomatic2/normal/build/pyi.darwin/aomDSP/out00-PYZ.pyz/Tkinter", line 1685, in __init__
_tkinter.TclError: Can't find a usable init.tcl in the following directories: 
    /var/folders/wr/ngmkb4s56cj4d2n1gxll358r0000gn/T/_MEIzgaAGB/_MEI/tcl /var/folders/wr/ngmkb4s56cj4d2n1gxll358r0000gn/T/_MEIzgaAGB/_MEI/tcl8.5 /Library/Frameworks/Tcl.framework/Versions/8.5/Resources/Scripts /Applications/aomDSP.app/Contents/lib/tcl8.5 /Applications/aomDSP.app/lib/tcl8.5 /Applications/aomDSP.app/Contents/library /Applications/aomDSP.app/library /Applications/aomDSP.app/tcl8.5.11/library /Applications/tcl8.5.11/library

/var/folders/wr/ngmkb4s56cj4d2n1gxll358r0000gn/T/_MEIzgaAGB/_MEI/tcl/init.tcl: can't find package activestate::teapot::link
can't find package activestate::teapot::link
    while executing
"package require activestate::teapot::link"
    invoked from within
"if {![interp issafe] && ![catch {package require platform}]} {
        package require activestate::teapot::link
        ::activestate::teapot::link::setup
..."
    (file "/var/folders/wr/ngmkb4s56cj4d2n1gxll358r0000gn/T/_MEIzgaAGB/_MEI/tcl/init.tcl" line 873)
    invoked from within
"source /var/folders/wr/ngmkb4s56cj4d2n1gxll358r0000gn/T/_MEIzgaAGB/_MEI/tcl/init.tcl"
    ("uplevel" body line 1)
    invoked from within
"uplevel #0 [list source $tclfile]"


This probably means that Tcl wasn't installed properly.
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `PyInstaller/hooks/hook-_tkinter.py`
Content:
```
1 #-----------------------------------------------------------------------------
2 # Copyright (c) 2013, PyInstaller Development Team.
3 #
4 # Distributed under the terms of the GNU General Public License with exception
5 # for distributing bootloader.
6 #
7 # The full license is in the file COPYING.txt, distributed with this software.
8 #-----------------------------------------------------------------------------
9 
10 
11 import os
12 import sys
13 
14 import PyInstaller.bindepend
15 
16 from PyInstaller.compat import is_win, is_darwin, is_unix, is_virtualenv, venv_real_prefix
17 from PyInstaller.build import Tree
18 from PyInstaller.hooks.hookutils import exec_statement, logger
19 
20 
21 def _handle_broken_tk():
22     """
23     Workaround for broken Tcl/Tk detection in virtualenv on Windows.
24 
25     There is a bug in older versions of virtualenv in setting paths
26     to Tcl/Tk properly. PyInstaller running in virtualenv is then
27     not able to find Tcl/Tk.
28 
29     This issue has been experienced in virtualenv with Python 2.4 on Win7.
30 
31     https://github.com/pypa/virtualenv/issues/93
32     """
33     if is_win and is_virtualenv:
34         basedir = os.path.join(venv_real_prefix, 'tcl')
35         files = os.listdir(basedir)
36         v = os.environ
37         # Detect Tcl/Tk paths.
38         for f in files:
39             abs_path = os.path.join(basedir, f)
40             if f.startswith('tcl') and os.path.isdir(abs_path):
41                 v['TCL_LIBRARY'] = abs_path
42             if f.startswith('tk') and os.path.isdir(abs_path):
43                 v['TK_LIBRARY'] = abs_path
44             if f.startswith('tix') and os.path.isdir(abs_path):
45                 v['TIX_LIBRARY'] = abs_path
46 
47 
48 def _find_tk_darwin_frameworks(binaries):
49     """
50     Tcl and Tk are installed as Mac OS X Frameworks.
51     """
52     tcl_root = tk_root = None
53     for nm, fnm in binaries:
54         if nm == 'Tcl':
55             tcl_root = os.path.join(os.path.dirname(fnm), 'Resources/Scripts')
56         if nm == 'Tk':
57             tk_root = os.path.join(os.path.dirname(fnm), 'Resources/Scripts')
58     return tcl_root, tk_root
59 
60 
61 def _find_tk_tclshell():
62     """
63     Get paths to Tcl/Tk from the Tcl shell command 'info library'.
64 
65     This command will return path to TCL_LIBRARY.
66     On most systems are Tcl and Tk libraries installed
67     in the same prefix.
68     """
69     tcl_root = tk_root = None
70 
71     # Python code to get path to TCL_LIBRARY.
72     code = 'from Tkinter import Tcl; t = Tcl(); print(t.eval("info library"))'
73 
74     tcl_root = exec_statement(code)
75     tk_version = exec_statement('from _tkinter import TK_VERSION as v; print(v)')
76     # TK_LIBRARY is in the same prefix as Tcl.
77     tk_root = os.path.join(os.path.dirname(tcl_root), 'tk%s' % tk_version)
78     return tcl_root, tk_root
79 
80 
81 def _find_tk(mod):
82     """
83     Find paths with Tcl and Tk data files to be bundled by PyInstaller.
84 
85     Return:
86         tcl_root  path to Tcl data files.
87         tk_root   path to Tk data files.
88     """
89     bins = PyInstaller.bindepend.selectImports(mod.__file__)
90 
91     if is_darwin:
92         # _tkinter depends on system Tcl/Tk frameworks.
93         if not bins:
94             # 'mod.pyinstaller_binaries' can't be used because on Mac OS X _tkinter.so
95             # might depend on system Tcl/Tk frameworks and these are not
96             # included in 'mod.pyinstaller_binaries'.
97             bins = PyInstaller.bindepend.getImports(mod.__file__)
98             # Reformat data structure from
99             #     set(['lib1', 'lib2', 'lib3'])
100             # to
101             #     [('Tcl', '/path/to/Tcl'), ('Tk', '/path/to/Tk')]
102             mapping = {}
103             for l in bins:
104                 mapping[os.path.basename(l)] = l
105             bins = [
106                 ('Tcl', mapping['Tcl']),
107                 ('Tk', mapping['Tk']),
108             ]
109 
110         # _tkinter depends on Tcl/Tk compiled as frameworks.
111         path_to_tcl = bins[0][1]
112         if 'Library/Frameworks' in path_to_tcl:
113             tcl_tk = _find_tk_darwin_frameworks(bins)
114         # Tcl/Tk compiled as on Linux other Unices.
115         # For example this is the case of Tcl/Tk from macports.
116         else:
117             tcl_tk = _find_tk_tclshell()
118 
119     else:
120         tcl_tk = _find_tk_tclshell()
121 
122     return tcl_tk
123 
124 
125 def _collect_tkfiles(mod):
126     # Workaround for broken Tcl/Tk detection in virtualenv on Windows.
127     _handle_broken_tk()
128 
129     tcl_root, tk_root = _find_tk(mod)
130 
131     if not tcl_root:
132         logger.error("TCL/TK seams to be not properly installed on this system")
133         return []
134 
135     tcldir = "tcl"
136     tkdir = "tk"
137 
138     tcltree = Tree(tcl_root, os.path.join('_MEI', tcldir),
139                    excludes=['demos', '*.lib', 'tclConfig.sh'])
140     tktree = Tree(tk_root, os.path.join('_MEI', tkdir),
141                   excludes=['demos', '*.lib', 'tkConfig.sh'])
142     return (tcltree + tktree)
143 
144 
145 def hook(mod):
146     # If not supported platform, skip TCL/TK detection.
147     if not (is_win or is_darwin or is_unix):
148         logger.info("... skipping TCL/TK detection on this platform (%s)",
149                 sys.platform)
150         return mod
151 
152     # Get the Tcl/Tk data files for bundling with executable.
153     #try:
154     tk_files = _collect_tkfiles(mod)
155     mod.pyinstaller_datas.extend(tk_files)
156     #except:
157     #logger.error("could not find TCL/TK")
158 
159     return mod
160
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/PyInstaller/hooks/hook-_tkinter.py b/PyInstaller/hooks/hook-_tkinter.py
--- a/PyInstaller/hooks/hook-_tkinter.py
+++ b/PyInstaller/hooks/hook-_tkinter.py
@@ -45,6 +45,58 @@
                 v['TIX_LIBRARY'] = abs_path
 
 
+def _warn_if_actvivetcl_or_teapot_install(tcl_root, tcltree):
+    """
+    Workaround ActiveTcl on OS X
+
+    PyInstaller does not package all requirements of ActiveTcl
+    (most notably teapot, which is not typically required). This
+    means packages built against ActiveTcl usually won't run on
+    non-host systems.
+
+    This method checks if ActiveTcl is being used, and if so logs
+    a warning if the problematic code is not commented out.
+
+    https://github.com/pyinstaller/pyinstaller/issues/621
+    """
+
+    from PyInstaller.lib.macholib import util
+    if util.in_system_path(tcl_root):
+        # system libraries do not experience this problem
+        return
+
+    # get the path to the 'init.tcl' script
+    try:
+        init_resource = [r[1] for r in tcltree if r[1].endswith('init.tcl')][0]
+    except IndexError:
+        # couldn't find the init script, return
+        return
+
+    mentions_activetcl = False
+    mentions_teapot = False
+    with open(init_resource, 'r') as init_file:
+        for line in init_file.readlines():
+            line = line.strip().lower()
+            if line.startswith('#'):
+                continue
+            if 'activetcl' in line:
+                mentions_activetcl = True
+            if 'teapot' in line:
+                mentions_teapot = True
+            if mentions_activetcl and mentions_teapot:
+                break
+
+    if mentions_activetcl and mentions_teapot:
+        logger.warning("""It seems you are using an ActiveTcl build of Tcl/Tk.\
+ This may not package correctly with PyInstaller.
+To fix the problem, please try commenting out all mentions of 'teapot' in:
+
+     %s
+
+See https://github.com/pyinstaller/pyinstaller/issues/621 for more information"""
+                       % init_resource)
+
+
 def _find_tk_darwin_frameworks(binaries):
     """
     Tcl and Tk are installed as Mac OS X Frameworks.
@@ -137,6 +189,11 @@
 
     tcltree = Tree(tcl_root, os.path.join('_MEI', tcldir),
                    excludes=['demos', '*.lib', 'tclConfig.sh'])
+
+    if is_darwin:
+        # handle workaround for ActiveTcl on OS X
+        _warn_if_actvivetcl_or_teapot_install(tcl_root, tcltree)
+
     tktree = Tree(tk_root, os.path.join('_MEI', tkdir),
                   excludes=['demos', '*.lib', 'tkConfig.sh'])
     return (tcltree + tktree)
@@ -146,7 +203,7 @@
     # If not supported platform, skip TCL/TK detection.
     if not (is_win or is_darwin or is_unix):
         logger.info("... skipping TCL/TK detection on this platform (%s)",
-                sys.platform)
+                    sys.platform)
         return mod
 
     # Get the Tcl/Tk data files for bundling with executable.

{"golden_diff": "diff --git a/PyInstaller/hooks/hook-_tkinter.py b/PyInstaller/hooks/hook-_tkinter.py\n--- a/PyInstaller/hooks/hook-_tkinter.py\n+++ b/PyInstaller/hooks/hook-_tkinter.py\n@@ -45,6 +45,58 @@\n                 v['TIX_LIBRARY'] = abs_path\n \n \n+def _warn_if_actvivetcl_or_teapot_install(tcl_root, tcltree):\n+    \"\"\"\n+    Workaround ActiveTcl on OS X\n+\n+    PyInstaller does not package all requirements of ActiveTcl\n+    (most notably teapot, which is not typically required). This\n+    means packages built against ActiveTcl usually won't run on\n+    non-host systems.\n+\n+    This method checks if ActiveTcl is being used, and if so logs\n+    a warning if the problematic code is not commented out.\n+\n+    https://github.com/pyinstaller/pyinstaller/issues/621\n+    \"\"\"\n+\n+    from PyInstaller.lib.macholib import util\n+    if util.in_system_path(tcl_root):\n+        # system libraries do not experience this problem\n+        return\n+\n+    # get the path to the 'init.tcl' script\n+    try:\n+        init_resource = [r[1] for r in tcltree if r[1].endswith('init.tcl')][0]\n+    except IndexError:\n+        # couldn't find the init script, return\n+        return\n+\n+    mentions_activetcl = False\n+    mentions_teapot = False\n+    with open(init_resource, 'r') as init_file:\n+        for line in init_file.readlines():\n+            line = line.strip().lower()\n+            if line.startswith('#'):\n+                continue\n+            if 'activetcl' in line:\n+                mentions_activetcl = True\n+            if 'teapot' in line:\n+                mentions_teapot = True\n+            if mentions_activetcl and mentions_teapot:\n+                break\n+\n+    if mentions_activetcl and mentions_teapot:\n+        logger.warning(\"\"\"It seems you are using an ActiveTcl build of Tcl/Tk.\\\n+ This may not package correctly with PyInstaller.\n+To fix the problem, please try commenting out all mentions of 'teapot' in:\n+\n+     %s\n+\n+See https://github.com/pyinstaller/pyinstaller/issues/621 for more information\"\"\"\n+                       % init_resource)\n+\n+\n def _find_tk_darwin_frameworks(binaries):\n     \"\"\"\n     Tcl and Tk are installed as Mac OS X Frameworks.\n@@ -137,6 +189,11 @@\n \n     tcltree = Tree(tcl_root, os.path.join('_MEI', tcldir),\n                    excludes=['demos', '*.lib', 'tclConfig.sh'])\n+\n+    if is_darwin:\n+        # handle workaround for ActiveTcl on OS X\n+        _warn_if_actvivetcl_or_teapot_install(tcl_root, tcltree)\n+\n     tktree = Tree(tk_root, os.path.join('_MEI', tkdir),\n                   excludes=['demos', '*.lib', 'tkConfig.sh'])\n     return (tcltree + tktree)\n@@ -146,7 +203,7 @@\n     # If not supported platform, skip TCL/TK detection.\n     if not (is_win or is_darwin or is_unix):\n         logger.info(\"... skipping TCL/TK detection on this platform (%s)\",\n-                sys.platform)\n+                    sys.platform)\n         return mod\n \n     # Get the Tcl/Tk data files for bundling with executable.\n", "issue": "_tkinter.TclError  Possible regression from ticket 540\n**Original date**: 2012/10/26\n**Original reporter**: _Lynn Oliver <raycores AND gmail DOT  COOM >_\n\nWhen I build with pyinstaller-2.0 on OSX 10.8.2, I can run the resulting binary on the build machine without any issues.  When I run the binary on a fresh install of OSX 10.8.2, I get a _tkinter.TclError (traceback below).  I believe this is similar to the error that I reported on ticket 540.\n\nI'm able to build successfully with a pre-2.0 dev version of pyinstaller.  I don't know of any way to identify the exact build I am using, but the files are dated 5/4/2012 at 10:20 AM (PDT).\n\n```\nTraceback (most recent call last):\n  File \"<string>\", line 149, in <module>\n  File \"../axeomatic2/normal/build/pyi.darwin/aomDSP/out00-PYZ.pyz/Tkinter\", line 1685, in __init__\n_tkinter.TclError: Can't find a usable init.tcl in the following directories: \n    /var/folders/wr/ngmkb4s56cj4d2n1gxll358r0000gn/T/_MEIzgaAGB/_MEI/tcl /var/folders/wr/ngmkb4s56cj4d2n1gxll358r0000gn/T/_MEIzgaAGB/_MEI/tcl8.5 /Library/Frameworks/Tcl.framework/Versions/8.5/Resources/Scripts /Applications/aomDSP.app/Contents/lib/tcl8.5 /Applications/aomDSP.app/lib/tcl8.5 /Applications/aomDSP.app/Contents/library /Applications/aomDSP.app/library /Applications/aomDSP.app/tcl8.5.11/library /Applications/tcl8.5.11/library\n\n/var/folders/wr/ngmkb4s56cj4d2n1gxll358r0000gn/T/_MEIzgaAGB/_MEI/tcl/init.tcl: can't find package activestate::teapot::link\ncan't find package activestate::teapot::link\n    while executing\n\"package require activestate::teapot::link\"\n    invoked from within\n\"if {![interp issafe] && ![catch {package require platform}]} {\n        package require activestate::teapot::link\n        ::activestate::teapot::link::setup\n...\"\n    (file \"/var/folders/wr/ngmkb4s56cj4d2n1gxll358r0000gn/T/_MEIzgaAGB/_MEI/tcl/init.tcl\" line 873)\n    invoked from within\n\"source /var/folders/wr/ngmkb4s56cj4d2n1gxll358r0000gn/T/_MEIzgaAGB/_MEI/tcl/init.tcl\"\n    (\"uplevel\" body line 1)\n    invoked from within\n\"uplevel #0 [list source $tclfile]\"\n\n\nThis probably means that Tcl wasn't installed properly.\n```\n\n", "before_files": [{"content": "#-----------------------------------------------------------------------------\n# Copyright (c) 2013, PyInstaller Development Team.\n#\n# Distributed under the terms of the GNU General Public License with exception\n# for distributing bootloader.\n#\n# The full license is in the file COPYING.txt, distributed with this software.\n#-----------------------------------------------------------------------------\n\n\nimport os\nimport sys\n\nimport PyInstaller.bindepend\n\nfrom PyInstaller.compat import is_win, is_darwin, is_unix, is_virtualenv, venv_real_prefix\nfrom PyInstaller.build import Tree\nfrom PyInstaller.hooks.hookutils import exec_statement, logger\n\n\ndef _handle_broken_tk():\n    \"\"\"\n    Workaround for broken Tcl/Tk detection in virtualenv on Windows.\n\n    There is a bug in older versions of virtualenv in setting paths\n    to Tcl/Tk properly. PyInstaller running in virtualenv is then\n    not able to find Tcl/Tk.\n\n    This issue has been experienced in virtualenv with Python 2.4 on Win7.\n\n    https://github.com/pypa/virtualenv/issues/93\n    \"\"\"\n    if is_win and is_virtualenv:\n        basedir = os.path.join(venv_real_prefix, 'tcl')\n        files = os.listdir(basedir)\n        v = os.environ\n        # Detect Tcl/Tk paths.\n        for f in files:\n            abs_path = os.path.join(basedir, f)\n            if f.startswith('tcl') and os.path.isdir(abs_path):\n                v['TCL_LIBRARY'] = abs_path\n            if f.startswith('tk') and os.path.isdir(abs_path):\n                v['TK_LIBRARY'] = abs_path\n            if f.startswith('tix') and os.path.isdir(abs_path):\n                v['TIX_LIBRARY'] = abs_path\n\n\ndef _find_tk_darwin_frameworks(binaries):\n    \"\"\"\n    Tcl and Tk are installed as Mac OS X Frameworks.\n    \"\"\"\n    tcl_root = tk_root = None\n    for nm, fnm in binaries:\n        if nm == 'Tcl':\n            tcl_root = os.path.join(os.path.dirname(fnm), 'Resources/Scripts')\n        if nm == 'Tk':\n            tk_root = os.path.join(os.path.dirname(fnm), 'Resources/Scripts')\n    return tcl_root, tk_root\n\n\ndef _find_tk_tclshell():\n    \"\"\"\n    Get paths to Tcl/Tk from the Tcl shell command 'info library'.\n\n    This command will return path to TCL_LIBRARY.\n    On most systems are Tcl and Tk libraries installed\n    in the same prefix.\n    \"\"\"\n    tcl_root = tk_root = None\n\n    # Python code to get path to TCL_LIBRARY.\n    code = 'from Tkinter import Tcl; t = Tcl(); print(t.eval(\"info library\"))'\n\n    tcl_root = exec_statement(code)\n    tk_version = exec_statement('from _tkinter import TK_VERSION as v; print(v)')\n    # TK_LIBRARY is in the same prefix as Tcl.\n    tk_root = os.path.join(os.path.dirname(tcl_root), 'tk%s' % tk_version)\n    return tcl_root, tk_root\n\n\ndef _find_tk(mod):\n    \"\"\"\n    Find paths with Tcl and Tk data files to be bundled by PyInstaller.\n\n    Return:\n        tcl_root  path to Tcl data files.\n        tk_root   path to Tk data files.\n    \"\"\"\n    bins = PyInstaller.bindepend.selectImports(mod.__file__)\n\n    if is_darwin:\n        # _tkinter depends on system Tcl/Tk frameworks.\n        if not bins:\n            # 'mod.pyinstaller_binaries' can't be used because on Mac OS X _tkinter.so\n            # might depend on system Tcl/Tk frameworks and these are not\n            # included in 'mod.pyinstaller_binaries'.\n            bins = PyInstaller.bindepend.getImports(mod.__file__)\n            # Reformat data structure from\n            #     set(['lib1', 'lib2', 'lib3'])\n            # to\n            #     [('Tcl', '/path/to/Tcl'), ('Tk', '/path/to/Tk')]\n            mapping = {}\n            for l in bins:\n                mapping[os.path.basename(l)] = l\n            bins = [\n                ('Tcl', mapping['Tcl']),\n                ('Tk', mapping['Tk']),\n            ]\n\n        # _tkinter depends on Tcl/Tk compiled as frameworks.\n        path_to_tcl = bins[0][1]\n        if 'Library/Frameworks' in path_to_tcl:\n            tcl_tk = _find_tk_darwin_frameworks(bins)\n        # Tcl/Tk compiled as on Linux other Unices.\n        # For example this is the case of Tcl/Tk from macports.\n        else:\n            tcl_tk = _find_tk_tclshell()\n\n    else:\n        tcl_tk = _find_tk_tclshell()\n\n    return tcl_tk\n\n\ndef _collect_tkfiles(mod):\n    # Workaround for broken Tcl/Tk detection in virtualenv on Windows.\n    _handle_broken_tk()\n\n    tcl_root, tk_root = _find_tk(mod)\n\n    if not tcl_root:\n        logger.error(\"TCL/TK seams to be not properly installed on this system\")\n        return []\n\n    tcldir = \"tcl\"\n    tkdir = \"tk\"\n\n    tcltree = Tree(tcl_root, os.path.join('_MEI', tcldir),\n                   excludes=['demos', '*.lib', 'tclConfig.sh'])\n    tktree = Tree(tk_root, os.path.join('_MEI', tkdir),\n                  excludes=['demos', '*.lib', 'tkConfig.sh'])\n    return (tcltree + tktree)\n\n\ndef hook(mod):\n    # If not supported platform, skip TCL/TK detection.\n    if not (is_win or is_darwin or is_unix):\n        logger.info(\"... skipping TCL/TK detection on this platform (%s)\",\n                sys.platform)\n        return mod\n\n    # Get the Tcl/Tk data files for bundling with executable.\n    #try:\n    tk_files = _collect_tkfiles(mod)\n    mod.pyinstaller_datas.extend(tk_files)\n    #except:\n    #logger.error(\"could not find TCL/TK\")\n\n    return mod\n", "path": "PyInstaller/hooks/hook-_tkinter.py"}], "after_files": [{"content": "#-----------------------------------------------------------------------------\n# Copyright (c) 2013, PyInstaller Development Team.\n#\n# Distributed under the terms of the GNU General Public License with exception\n# for distributing bootloader.\n#\n# The full license is in the file COPYING.txt, distributed with this software.\n#-----------------------------------------------------------------------------\n\n\nimport os\nimport sys\n\nimport PyInstaller.bindepend\n\nfrom PyInstaller.compat import is_win, is_darwin, is_unix, is_virtualenv, venv_real_prefix\nfrom PyInstaller.build import Tree\nfrom PyInstaller.hooks.hookutils import exec_statement, logger\n\n\ndef _handle_broken_tk():\n    \"\"\"\n    Workaround for broken Tcl/Tk detection in virtualenv on Windows.\n\n    There is a bug in older versions of virtualenv in setting paths\n    to Tcl/Tk properly. PyInstaller running in virtualenv is then\n    not able to find Tcl/Tk.\n\n    This issue has been experienced in virtualenv with Python 2.4 on Win7.\n\n    https://github.com/pypa/virtualenv/issues/93\n    \"\"\"\n    if is_win and is_virtualenv:\n        basedir = os.path.join(venv_real_prefix, 'tcl')\n        files = os.listdir(basedir)\n        v = os.environ\n        # Detect Tcl/Tk paths.\n        for f in files:\n            abs_path = os.path.join(basedir, f)\n            if f.startswith('tcl') and os.path.isdir(abs_path):\n                v['TCL_LIBRARY'] = abs_path\n            if f.startswith('tk') and os.path.isdir(abs_path):\n                v['TK_LIBRARY'] = abs_path\n            if f.startswith('tix') and os.path.isdir(abs_path):\n                v['TIX_LIBRARY'] = abs_path\n\n\ndef _warn_if_actvivetcl_or_teapot_install(tcl_root, tcltree):\n    \"\"\"\n    Workaround ActiveTcl on OS X\n\n    PyInstaller does not package all requirements of ActiveTcl\n    (most notably teapot, which is not typically required). This\n    means packages built against ActiveTcl usually won't run on\n    non-host systems.\n\n    This method checks if ActiveTcl is being used, and if so logs\n    a warning if the problematic code is not commented out.\n\n    https://github.com/pyinstaller/pyinstaller/issues/621\n    \"\"\"\n\n    from PyInstaller.lib.macholib import util\n    if util.in_system_path(tcl_root):\n        # system libraries do not experience this problem\n        return\n\n    # get the path to the 'init.tcl' script\n    try:\n        init_resource = [r[1] for r in tcltree if r[1].endswith('init.tcl')][0]\n    except IndexError:\n        # couldn't find the init script, return\n        return\n\n    mentions_activetcl = False\n    mentions_teapot = False\n    with open(init_resource, 'r') as init_file:\n        for line in init_file.readlines():\n            line = line.strip().lower()\n            if line.startswith('#'):\n                continue\n            if 'activetcl' in line:\n                mentions_activetcl = True\n            if 'teapot' in line:\n                mentions_teapot = True\n            if mentions_activetcl and mentions_teapot:\n                break\n\n    if mentions_activetcl and mentions_teapot:\n        logger.warning(\"\"\"It seems you are using an ActiveTcl build of Tcl/Tk.\\\n This may not package correctly with PyInstaller.\nTo fix the problem, please try commenting out all mentions of 'teapot' in:\n\n     %s\n\nSee https://github.com/pyinstaller/pyinstaller/issues/621 for more information\"\"\"\n                       % init_resource)\n\n\ndef _find_tk_darwin_frameworks(binaries):\n    \"\"\"\n    Tcl and Tk are installed as Mac OS X Frameworks.\n    \"\"\"\n    tcl_root = tk_root = None\n    for nm, fnm in binaries:\n        if nm == 'Tcl':\n            tcl_root = os.path.join(os.path.dirname(fnm), 'Resources/Scripts')\n        if nm == 'Tk':\n            tk_root = os.path.join(os.path.dirname(fnm), 'Resources/Scripts')\n    return tcl_root, tk_root\n\n\ndef _find_tk_tclshell():\n    \"\"\"\n    Get paths to Tcl/Tk from the Tcl shell command 'info library'.\n\n    This command will return path to TCL_LIBRARY.\n    On most systems are Tcl and Tk libraries installed\n    in the same prefix.\n    \"\"\"\n    tcl_root = tk_root = None\n\n    # Python code to get path to TCL_LIBRARY.\n    code = 'from Tkinter import Tcl; t = Tcl(); print(t.eval(\"info library\"))'\n\n    tcl_root = exec_statement(code)\n    tk_version = exec_statement('from _tkinter import TK_VERSION as v; print(v)')\n    # TK_LIBRARY is in the same prefix as Tcl.\n    tk_root = os.path.join(os.path.dirname(tcl_root), 'tk%s' % tk_version)\n    return tcl_root, tk_root\n\n\ndef _find_tk(mod):\n    \"\"\"\n    Find paths with Tcl and Tk data files to be bundled by PyInstaller.\n\n    Return:\n        tcl_root  path to Tcl data files.\n        tk_root   path to Tk data files.\n    \"\"\"\n    bins = PyInstaller.bindepend.selectImports(mod.__file__)\n\n    if is_darwin:\n        # _tkinter depends on system Tcl/Tk frameworks.\n        if not bins:\n            # 'mod.pyinstaller_binaries' can't be used because on Mac OS X _tkinter.so\n            # might depend on system Tcl/Tk frameworks and these are not\n            # included in 'mod.pyinstaller_binaries'.\n            bins = PyInstaller.bindepend.getImports(mod.__file__)\n            # Reformat data structure from\n            #     set(['lib1', 'lib2', 'lib3'])\n            # to\n            #     [('Tcl', '/path/to/Tcl'), ('Tk', '/path/to/Tk')]\n            mapping = {}\n            for l in bins:\n                mapping[os.path.basename(l)] = l\n            bins = [\n                ('Tcl', mapping['Tcl']),\n                ('Tk', mapping['Tk']),\n            ]\n\n        # _tkinter depends on Tcl/Tk compiled as frameworks.\n        path_to_tcl = bins[0][1]\n        if 'Library/Frameworks' in path_to_tcl:\n            tcl_tk = _find_tk_darwin_frameworks(bins)\n        # Tcl/Tk compiled as on Linux other Unices.\n        # For example this is the case of Tcl/Tk from macports.\n        else:\n            tcl_tk = _find_tk_tclshell()\n\n    else:\n        tcl_tk = _find_tk_tclshell()\n\n    return tcl_tk\n\n\ndef _collect_tkfiles(mod):\n    # Workaround for broken Tcl/Tk detection in virtualenv on Windows.\n    _handle_broken_tk()\n\n    tcl_root, tk_root = _find_tk(mod)\n\n    if not tcl_root:\n        logger.error(\"TCL/TK seams to be not properly installed on this system\")\n        return []\n\n    tcldir = \"tcl\"\n    tkdir = \"tk\"\n\n    tcltree = Tree(tcl_root, os.path.join('_MEI', tcldir),\n                   excludes=['demos', '*.lib', 'tclConfig.sh'])\n\n    if is_darwin:\n        # handle workaround for ActiveTcl on OS X\n        _warn_if_actvivetcl_or_teapot_install(tcl_root, tcltree)\n\n    tktree = Tree(tk_root, os.path.join('_MEI', tkdir),\n                  excludes=['demos', '*.lib', 'tkConfig.sh'])\n    return (tcltree + tktree)\n\n\ndef hook(mod):\n    # If not supported platform, skip TCL/TK detection.\n    if not (is_win or is_darwin or is_unix):\n        logger.info(\"... skipping TCL/TK detection on this platform (%s)\",\n                    sys.platform)\n        return mod\n\n    # Get the Tcl/Tk data files for bundling with executable.\n    #try:\n    tk_files = _collect_tkfiles(mod)\n    mod.pyinstaller_datas.extend(tk_files)\n    #except:\n    #logger.error(\"could not find TCL/TK\")\n\n    return mod\n", "path": "PyInstaller/hooks/hook-_tkinter.py"}]}