We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Problem with hook-_tkinter.py using Python3.7 on MacOS
My application builds and runs perfectly on the same machine using Python3.6 (venv). But with Python 3.7 (installed from python.org) the following occurs:

```
14638 INFO: Excluding import 'tkinter'
14639 INFO: Import to be excluded not found: 'FixTk'
14639 INFO: Loading module hook "hook-xml.etree.cElementTree.py"...
14640 INFO: Loading module hook "hook-_tkinter.py"...
14642 ERROR: Tcl/Tk improperly installed on this system.
```

Then when I try and run the app:

```
Traceback (most recent call last):
  File "PyInstaller/loader/rthooks/pyi_rth__tkinter.py", line 28, in <module>
FileNotFoundError: Tcl data directory "/var/folders/nl/2wxh3z313l129zpzq2f8ww5m0000gn/T/_MEILUmJRc/tcl" not found.
[2195] Failed to execute script pyi_rth__tkinter
```

I suspect it is to do with the fact that Python3.7 comes with Tcl/Tk 8.6 built in and the hook script isn't properly aware of this but I don't know enough about how it all works to be able to make any contribution.
As my application doesn't actually use tkinter I can work round it using `--exclude-module tkinter` but the problem's there for those who do neeed it.

--- 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-2020, PyInstaller Development Team.
3 #
4 # Distributed under the terms of the GNU General Public License (version 2
5 # or later) with exception for distributing the bootloader.
6 #
7 # The full license is in the file COPYING.txt, distributed with this software.
8 #
9 # SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)
10 #-----------------------------------------------------------------------------
11 
12 
13 import os
14 import sys
15 import locale
16 
17 from PyInstaller.compat import is_win, is_darwin, is_unix, is_venv, \
18     base_prefix, open_file, text_read_mode
19 from PyInstaller.compat import modname_tkinter
20 from PyInstaller.depend.bindepend import selectImports, getImports
21 from PyInstaller.building.datastruct import Tree
22 from PyInstaller.utils.hooks import exec_statement, logger
23 
24 
25 def _handle_broken_tcl_tk():
26     """
27     When freezing from a Windows venv, overwrite the values of the standard
28     `${TCL_LIBRARY}`, `${TK_LIBRARY}`, and `${TIX_LIBRARY}` environment
29     variables.
30 
31     This is a workaround for broken Tcl/Tk detection in Windows virtual
32     environments. Older versions of `virtualenv` set such variables erroneously,
33     preventing PyInstaller from properly detecting Tcl/Tk. This issue has been
34     noted for `virtualenv` under Python 2.4 and Windows 7.
35 
36     See Also
37     -------
38     https://github.com/pypa/virtualenv/issues/93
39     """
40     if is_win and is_venv:
41         basedir = os.path.join(base_prefix, 'tcl')
42         files = os.listdir(basedir)
43 
44         # Detect Tcl/Tk paths.
45         for f in files:
46             abs_path = os.path.join(basedir, f)
47             if f.startswith('tcl') and os.path.isdir(abs_path):
48                 os.environ['TCL_LIBRARY'] = abs_path
49             elif f.startswith('tk') and os.path.isdir(abs_path):
50                 os.environ['TK_LIBRARY'] = abs_path
51             elif f.startswith('tix') and os.path.isdir(abs_path):
52                 os.environ['TIX_LIBRARY'] = abs_path
53 
54 
55 def _warn_if_activetcl_or_teapot_installed(tcl_root, tcltree):
56     """
57     If the current Tcl installation is a Teapot-distributed version of ActiveTcl
58     *and* the current platform is OS X, log a non-fatal warning that the
59     resulting executable will (probably) fail to run on non-host systems.
60 
61     PyInstaller does *not* freeze all ActiveTcl dependencies -- including
62     Teapot, which is typically ignorable. Since Teapot is *not* ignorable in
63     this case, this function warns of impending failure.
64 
65     See Also
66     -------
67     https://github.com/pyinstaller/pyinstaller/issues/621
68     """
69     from macholib import util
70 
71     # System libraries do not experience this problem.
72     if util.in_system_path(tcl_root):
73         return
74 
75     # Absolute path of the "init.tcl" script.
76     try:
77         init_resource = [r[1] for r in tcltree if r[1].endswith('init.tcl')][0]
78     # If such script could not be found, silently return.
79     except IndexError:
80         return
81 
82     mentions_activetcl = False
83     mentions_teapot = False
84     # TCL/TK reads files using the `system encoding <https://www.tcl.tk/doc/howto/i18n.html#system_encoding>`_.
85     with open_file(init_resource, text_read_mode,
86                    encoding=locale.getpreferredencoding()) as init_file:
87         for line in init_file.readlines():
88             line = line.strip().lower()
89             if line.startswith('#'):
90                 continue
91             if 'activetcl' in line:
92                 mentions_activetcl = True
93             if 'teapot' in line:
94                 mentions_teapot = True
95             if mentions_activetcl and mentions_teapot:
96                 break
97 
98     if mentions_activetcl and mentions_teapot:
99         logger.warning(
100             """
101 You appear to be using an ActiveTcl build of Tcl/Tk, which PyInstaller has
102 difficulty freezing. To fix this, comment out all references to "teapot" in:
103 
104      %s
105 
106 See https://github.com/pyinstaller/pyinstaller/issues/621 for more information.
107             """ % init_resource)
108 
109 
110 def _find_tcl_tk_darwin_frameworks(binaries):
111     """
112     Get an OS X-specific 2-tuple of the absolute paths of the top-level
113     external data directories for both Tcl and Tk, respectively.
114 
115     Under OS X, Tcl and Tk are installed as Frameworks requiring special care.
116 
117     Returns
118     -------
119     list
120         2-tuple whose first element is the value of `${TCL_LIBRARY}` and whose
121         second element is the value of `${TK_LIBRARY}`.
122     """
123     tcl_root = tk_root = None
124     for nm, fnm in binaries:
125         if nm == 'Tcl':
126             tcl_root = os.path.join(os.path.dirname(fnm), 'Resources/Scripts')
127         elif nm == 'Tk':
128             tk_root =  os.path.join(os.path.dirname(fnm), 'Resources/Scripts')
129     return tcl_root, tk_root
130 
131 
132 def _find_tcl_tk_dir():
133     """
134     Get a platform-agnostic 2-tuple of the absolute paths of the top-level
135     external data directories for both Tcl and Tk, respectively.
136 
137     Returns
138     -------
139     list
140         2-tuple whose first element is the value of `${TCL_LIBRARY}` and whose
141         second element is the value of `${TK_LIBRARY}`.
142     """
143     # Python code to get path to TCL_LIBRARY.
144     tcl_root = exec_statement(
145         'from %s import Tcl; print(Tcl().eval("info library"))' % modname_tkinter)
146     tk_version = exec_statement(
147         'from _tkinter import TK_VERSION; print(TK_VERSION)')
148 
149     # TK_LIBRARY is in the same prefix as Tcl.
150     tk_root = os.path.join(os.path.dirname(tcl_root), 'tk%s' % tk_version)
151     return tcl_root, tk_root
152 
153 
154 def _find_tcl_tk(hook_api):
155     """
156     Get a platform-specific 2-tuple of the absolute paths of the top-level
157     external data directories for both Tcl and Tk, respectively.
158 
159     Returns
160     -------
161     list
162         2-tuple whose first element is the value of `${TCL_LIBRARY}` and whose
163         second element is the value of `${TK_LIBRARY}`.
164     """
165     bins = selectImports(hook_api.__file__)
166 
167     if is_darwin:
168         # _tkinter depends on system Tcl/Tk frameworks.
169         # For example this is the case of Python from homebrew.
170         if not bins:
171             # 'hook_api.binaries' can't be used because on Mac OS X _tkinter.so
172             # might depend on system Tcl/Tk frameworks and these are not
173             # included in 'hook_api.binaries'.
174             bins = getImports(hook_api.__file__)
175             # Reformat data structure from
176             #     set(['lib1', 'lib2', 'lib3'])
177             # to
178             #     [('Tcl', '/path/to/Tcl'), ('Tk', '/path/to/Tk')]
179             mapping = {}
180             for l in bins:
181                 mapping[os.path.basename(l)] = l
182             bins = [
183                 ('Tcl', mapping['Tcl']),
184                 ('Tk', mapping['Tk']),
185             ]
186 
187         # _tkinter depends on Tcl/Tk compiled as frameworks.
188         path_to_tcl = bins[0][1]
189         if 'Library/Frameworks' in path_to_tcl:
190             tcl_tk = _find_tcl_tk_darwin_frameworks(bins)
191         # Tcl/Tk compiled as on Linux other Unixes.
192         # For example this is the case of Tcl/Tk from macports.
193         else:
194             tcl_tk = _find_tcl_tk_dir()
195 
196     else:
197         tcl_tk = _find_tcl_tk_dir()
198 
199     return tcl_tk
200 
201 
202 def _collect_tcl_tk_files(hook_api):
203     """
204     Get a list of TOC-style 3-tuples describing all external Tcl/Tk data files.
205 
206     Returns
207     -------
208     Tree
209         Such list.
210     """
211     # Workaround for broken Tcl/Tk detection in virtualenv on Windows.
212     _handle_broken_tcl_tk()
213 
214     tcl_root, tk_root = _find_tcl_tk(hook_api)
215 
216     # TODO Shouldn't these be fatal exceptions?
217     if not tcl_root:
218         logger.error('Tcl/Tk improperly installed on this system.')
219         return []
220     if not os.path.isdir(tcl_root):
221         logger.error('Tcl data directory "%s" not found.', tcl_root)
222         return []
223     if not os.path.isdir(tk_root):
224         logger.error('Tk data directory "%s" not found.', tk_root)
225         return []
226 
227     tcltree = Tree(
228         tcl_root, prefix='tcl', excludes=['demos', '*.lib', 'tclConfig.sh'])
229     tktree = Tree(
230         tk_root, prefix='tk', excludes=['demos', '*.lib', 'tkConfig.sh'])
231 
232     # If the current Tcl installation is a Teapot-distributed version of
233     # ActiveTcl and the current platform is OS X, warn that this is bad.
234     if is_darwin:
235         _warn_if_activetcl_or_teapot_installed(tcl_root, tcltree)
236 
237     return (tcltree + tktree)
238 
239 
240 def hook(hook_api):
241     # Use a hook-function to get the module's attr:`__file__` easily.
242     """
243     Freeze all external Tcl/Tk data files if this is a supported platform *or*
244     log a non-fatal error otherwise.
245     """
246     if is_win or is_darwin or is_unix:
247         # _collect_tcl_tk_files(hook_api) returns a Tree (which is okay),
248         # so we need to store it into `hook_api.datas` to prevent
249         # `building.imphook.format_binaries_and_datas` from crashing
250         # with "too many values to unpack".
251         hook_api.add_datas(_collect_tcl_tk_files(hook_api))
252     else:
253         logger.error("... skipping Tcl/Tk handling on unsupported platform %s", sys.platform)
254
```
--- 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
@@ -107,12 +107,13 @@
             """ % init_resource)
 
 
-def _find_tcl_tk_darwin_frameworks(binaries):
+def _find_tcl_tk_darwin_system_frameworks(binaries):
     """
     Get an OS X-specific 2-tuple of the absolute paths of the top-level
     external data directories for both Tcl and Tk, respectively.
 
-    Under OS X, Tcl and Tk are installed as Frameworks requiring special care.
+    This function finds the OS X system installation of Tcl and Tk.
+    System OS X Tcl and Tk are installed as Frameworks requiring special care.
 
     Returns
     -------
@@ -186,10 +187,15 @@
 
         # _tkinter depends on Tcl/Tk compiled as frameworks.
         path_to_tcl = bins[0][1]
-        if 'Library/Frameworks' in path_to_tcl:
-            tcl_tk = _find_tcl_tk_darwin_frameworks(bins)
+        # OS X system installation of Tcl/Tk.
+        # [/System]/Library/Frameworks/Tcl.framework/Resources/Scripts/Tcl
+        if 'Library/Frameworks/Tcl.framework' in path_to_tcl:
+            tcl_tk = _find_tcl_tk_darwin_system_frameworks(bins)
         # Tcl/Tk compiled as on Linux other Unixes.
-        # For example this is the case of Tcl/Tk from macports.
+        # This is the case of Tcl/Tk from macports and Tck/Tk built into
+        # python.org OS X python distributions.
+        # python.org built-in tcl/tk is located at
+        # /Library/Frameworks/Python.framework/Versions/3.x/lib/libtcl8.6.dylib
         else:
             tcl_tk = _find_tcl_tk_dir()

{"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@@ -107,12 +107,13 @@\n             \"\"\" % init_resource)\n \n \n-def _find_tcl_tk_darwin_frameworks(binaries):\n+def _find_tcl_tk_darwin_system_frameworks(binaries):\n     \"\"\"\n     Get an OS X-specific 2-tuple of the absolute paths of the top-level\n     external data directories for both Tcl and Tk, respectively.\n \n-    Under OS X, Tcl and Tk are installed as Frameworks requiring special care.\n+    This function finds the OS X system installation of Tcl and Tk.\n+    System OS X Tcl and Tk are installed as Frameworks requiring special care.\n \n     Returns\n     -------\n@@ -186,10 +187,15 @@\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_tcl_tk_darwin_frameworks(bins)\n+        # OS X system installation of Tcl/Tk.\n+        # [/System]/Library/Frameworks/Tcl.framework/Resources/Scripts/Tcl\n+        if 'Library/Frameworks/Tcl.framework' in path_to_tcl:\n+            tcl_tk = _find_tcl_tk_darwin_system_frameworks(bins)\n         # Tcl/Tk compiled as on Linux other Unixes.\n-        # For example this is the case of Tcl/Tk from macports.\n+        # This is the case of Tcl/Tk from macports and Tck/Tk built into\n+        # python.org OS X python distributions.\n+        # python.org built-in tcl/tk is located at\n+        # /Library/Frameworks/Python.framework/Versions/3.x/lib/libtcl8.6.dylib\n         else:\n             tcl_tk = _find_tcl_tk_dir()\n", "issue": "Problem with hook-_tkinter.py using Python3.7 on MacOS\nMy application builds and runs perfectly on the same machine using Python3.6 (venv). But with Python 3.7 (installed from python.org) the following occurs:\r\n\r\n```\r\n14638 INFO: Excluding import 'tkinter'\r\n14639 INFO: Import to be excluded not found: 'FixTk'\r\n14639 INFO: Loading module hook \"hook-xml.etree.cElementTree.py\"...\r\n14640 INFO: Loading module hook \"hook-_tkinter.py\"...\r\n14642 ERROR: Tcl/Tk improperly installed on this system.\r\n```\r\n\r\nThen when I try and run the app:\r\n\r\n```\r\nTraceback (most recent call last):\r\n  File \"PyInstaller/loader/rthooks/pyi_rth__tkinter.py\", line 28, in <module>\r\nFileNotFoundError: Tcl data directory \"/var/folders/nl/2wxh3z313l129zpzq2f8ww5m0000gn/T/_MEILUmJRc/tcl\" not found.\r\n[2195] Failed to execute script pyi_rth__tkinter\r\n```\r\n\r\nI suspect it is to do with the fact that Python3.7 comes with Tcl/Tk 8.6 built in and the hook script isn't properly aware of this but I don't know enough about how it all works to be able to make any contribution.\r\nAs my application doesn't actually use tkinter I can work round it using `--exclude-module tkinter` but the problem's there for those who do neeed it.\n", "before_files": [{"content": "#-----------------------------------------------------------------------------\n# Copyright (c) 2013-2020, PyInstaller Development Team.\n#\n# Distributed under the terms of the GNU General Public License (version 2\n# or later) with exception for distributing the bootloader.\n#\n# The full license is in the file COPYING.txt, distributed with this software.\n#\n# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)\n#-----------------------------------------------------------------------------\n\n\nimport os\nimport sys\nimport locale\n\nfrom PyInstaller.compat import is_win, is_darwin, is_unix, is_venv, \\\n    base_prefix, open_file, text_read_mode\nfrom PyInstaller.compat import modname_tkinter\nfrom PyInstaller.depend.bindepend import selectImports, getImports\nfrom PyInstaller.building.datastruct import Tree\nfrom PyInstaller.utils.hooks import exec_statement, logger\n\n\ndef _handle_broken_tcl_tk():\n    \"\"\"\n    When freezing from a Windows venv, overwrite the values of the standard\n    `${TCL_LIBRARY}`, `${TK_LIBRARY}`, and `${TIX_LIBRARY}` environment\n    variables.\n\n    This is a workaround for broken Tcl/Tk detection in Windows virtual\n    environments. Older versions of `virtualenv` set such variables erroneously,\n    preventing PyInstaller from properly detecting Tcl/Tk. This issue has been\n    noted for `virtualenv` under Python 2.4 and Windows 7.\n\n    See Also\n    -------\n    https://github.com/pypa/virtualenv/issues/93\n    \"\"\"\n    if is_win and is_venv:\n        basedir = os.path.join(base_prefix, 'tcl')\n        files = os.listdir(basedir)\n\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                os.environ['TCL_LIBRARY'] = abs_path\n            elif f.startswith('tk') and os.path.isdir(abs_path):\n                os.environ['TK_LIBRARY'] = abs_path\n            elif f.startswith('tix') and os.path.isdir(abs_path):\n                os.environ['TIX_LIBRARY'] = abs_path\n\n\ndef _warn_if_activetcl_or_teapot_installed(tcl_root, tcltree):\n    \"\"\"\n    If the current Tcl installation is a Teapot-distributed version of ActiveTcl\n    *and* the current platform is OS X, log a non-fatal warning that the\n    resulting executable will (probably) fail to run on non-host systems.\n\n    PyInstaller does *not* freeze all ActiveTcl dependencies -- including\n    Teapot, which is typically ignorable. Since Teapot is *not* ignorable in\n    this case, this function warns of impending failure.\n\n    See Also\n    -------\n    https://github.com/pyinstaller/pyinstaller/issues/621\n    \"\"\"\n    from macholib import util\n\n    # System libraries do not experience this problem.\n    if util.in_system_path(tcl_root):\n        return\n\n    # Absolute path of the \"init.tcl\" script.\n    try:\n        init_resource = [r[1] for r in tcltree if r[1].endswith('init.tcl')][0]\n    # If such script could not be found, silently return.\n    except IndexError:\n        return\n\n    mentions_activetcl = False\n    mentions_teapot = False\n    # TCL/TK reads files using the `system encoding <https://www.tcl.tk/doc/howto/i18n.html#system_encoding>`_.\n    with open_file(init_resource, text_read_mode,\n                   encoding=locale.getpreferredencoding()) 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(\n            \"\"\"\nYou appear to be using an ActiveTcl build of Tcl/Tk, which PyInstaller has\ndifficulty freezing. To fix this, comment out all references to \"teapot\" in:\n\n     %s\n\nSee https://github.com/pyinstaller/pyinstaller/issues/621 for more information.\n            \"\"\" % init_resource)\n\n\ndef _find_tcl_tk_darwin_frameworks(binaries):\n    \"\"\"\n    Get an OS X-specific 2-tuple of the absolute paths of the top-level\n    external data directories for both Tcl and Tk, respectively.\n\n    Under OS X, Tcl and Tk are installed as Frameworks requiring special care.\n\n    Returns\n    -------\n    list\n        2-tuple whose first element is the value of `${TCL_LIBRARY}` and whose\n        second element is the value of `${TK_LIBRARY}`.\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        elif nm == 'Tk':\n            tk_root =  os.path.join(os.path.dirname(fnm), 'Resources/Scripts')\n    return tcl_root, tk_root\n\n\ndef _find_tcl_tk_dir():\n    \"\"\"\n    Get a platform-agnostic 2-tuple of the absolute paths of the top-level\n    external data directories for both Tcl and Tk, respectively.\n\n    Returns\n    -------\n    list\n        2-tuple whose first element is the value of `${TCL_LIBRARY}` and whose\n        second element is the value of `${TK_LIBRARY}`.\n    \"\"\"\n    # Python code to get path to TCL_LIBRARY.\n    tcl_root = exec_statement(\n        'from %s import Tcl; print(Tcl().eval(\"info library\"))' % modname_tkinter)\n    tk_version = exec_statement(\n        'from _tkinter import TK_VERSION; print(TK_VERSION)')\n\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_tcl_tk(hook_api):\n    \"\"\"\n    Get a platform-specific 2-tuple of the absolute paths of the top-level\n    external data directories for both Tcl and Tk, respectively.\n\n    Returns\n    -------\n    list\n        2-tuple whose first element is the value of `${TCL_LIBRARY}` and whose\n        second element is the value of `${TK_LIBRARY}`.\n    \"\"\"\n    bins = selectImports(hook_api.__file__)\n\n    if is_darwin:\n        # _tkinter depends on system Tcl/Tk frameworks.\n        # For example this is the case of Python from homebrew.\n        if not bins:\n            # 'hook_api.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 'hook_api.binaries'.\n            bins = getImports(hook_api.__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_tcl_tk_darwin_frameworks(bins)\n        # Tcl/Tk compiled as on Linux other Unixes.\n        # For example this is the case of Tcl/Tk from macports.\n        else:\n            tcl_tk = _find_tcl_tk_dir()\n\n    else:\n        tcl_tk = _find_tcl_tk_dir()\n\n    return tcl_tk\n\n\ndef _collect_tcl_tk_files(hook_api):\n    \"\"\"\n    Get a list of TOC-style 3-tuples describing all external Tcl/Tk data files.\n\n    Returns\n    -------\n    Tree\n        Such list.\n    \"\"\"\n    # Workaround for broken Tcl/Tk detection in virtualenv on Windows.\n    _handle_broken_tcl_tk()\n\n    tcl_root, tk_root = _find_tcl_tk(hook_api)\n\n    # TODO Shouldn't these be fatal exceptions?\n    if not tcl_root:\n        logger.error('Tcl/Tk improperly installed on this system.')\n        return []\n    if not os.path.isdir(tcl_root):\n        logger.error('Tcl data directory \"%s\" not found.', tcl_root)\n        return []\n    if not os.path.isdir(tk_root):\n        logger.error('Tk data directory \"%s\" not found.', tk_root)\n        return []\n\n    tcltree = Tree(\n        tcl_root, prefix='tcl', excludes=['demos', '*.lib', 'tclConfig.sh'])\n    tktree = Tree(\n        tk_root, prefix='tk', excludes=['demos', '*.lib', 'tkConfig.sh'])\n\n    # If the current Tcl installation is a Teapot-distributed version of\n    # ActiveTcl and the current platform is OS X, warn that this is bad.\n    if is_darwin:\n        _warn_if_activetcl_or_teapot_installed(tcl_root, tcltree)\n\n    return (tcltree + tktree)\n\n\ndef hook(hook_api):\n    # Use a hook-function to get the module's attr:`__file__` easily.\n    \"\"\"\n    Freeze all external Tcl/Tk data files if this is a supported platform *or*\n    log a non-fatal error otherwise.\n    \"\"\"\n    if is_win or is_darwin or is_unix:\n        # _collect_tcl_tk_files(hook_api) returns a Tree (which is okay),\n        # so we need to store it into `hook_api.datas` to prevent\n        # `building.imphook.format_binaries_and_datas` from crashing\n        # with \"too many values to unpack\".\n        hook_api.add_datas(_collect_tcl_tk_files(hook_api))\n    else:\n        logger.error(\"... skipping Tcl/Tk handling on unsupported platform %s\", sys.platform)\n", "path": "PyInstaller/hooks/hook-_tkinter.py"}], "after_files": [{"content": "#-----------------------------------------------------------------------------\n# Copyright (c) 2013-2020, PyInstaller Development Team.\n#\n# Distributed under the terms of the GNU General Public License (version 2\n# or later) with exception for distributing the bootloader.\n#\n# The full license is in the file COPYING.txt, distributed with this software.\n#\n# SPDX-License-Identifier: (GPL-2.0-or-later WITH Bootloader-exception)\n#-----------------------------------------------------------------------------\n\n\nimport os\nimport sys\nimport locale\n\nfrom PyInstaller.compat import is_win, is_darwin, is_unix, is_venv, \\\n    base_prefix, open_file, text_read_mode\nfrom PyInstaller.compat import modname_tkinter\nfrom PyInstaller.depend.bindepend import selectImports, getImports\nfrom PyInstaller.building.datastruct import Tree\nfrom PyInstaller.utils.hooks import exec_statement, logger\n\n\ndef _handle_broken_tcl_tk():\n    \"\"\"\n    When freezing from a Windows venv, overwrite the values of the standard\n    `${TCL_LIBRARY}`, `${TK_LIBRARY}`, and `${TIX_LIBRARY}` environment\n    variables.\n\n    This is a workaround for broken Tcl/Tk detection in Windows virtual\n    environments. Older versions of `virtualenv` set such variables erroneously,\n    preventing PyInstaller from properly detecting Tcl/Tk. This issue has been\n    noted for `virtualenv` under Python 2.4 and Windows 7.\n\n    See Also\n    -------\n    https://github.com/pypa/virtualenv/issues/93\n    \"\"\"\n    if is_win and is_venv:\n        basedir = os.path.join(base_prefix, 'tcl')\n        files = os.listdir(basedir)\n\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                os.environ['TCL_LIBRARY'] = abs_path\n            elif f.startswith('tk') and os.path.isdir(abs_path):\n                os.environ['TK_LIBRARY'] = abs_path\n            elif f.startswith('tix') and os.path.isdir(abs_path):\n                os.environ['TIX_LIBRARY'] = abs_path\n\n\ndef _warn_if_activetcl_or_teapot_installed(tcl_root, tcltree):\n    \"\"\"\n    If the current Tcl installation is a Teapot-distributed version of ActiveTcl\n    *and* the current platform is OS X, log a non-fatal warning that the\n    resulting executable will (probably) fail to run on non-host systems.\n\n    PyInstaller does *not* freeze all ActiveTcl dependencies -- including\n    Teapot, which is typically ignorable. Since Teapot is *not* ignorable in\n    this case, this function warns of impending failure.\n\n    See Also\n    -------\n    https://github.com/pyinstaller/pyinstaller/issues/621\n    \"\"\"\n    from macholib import util\n\n    # System libraries do not experience this problem.\n    if util.in_system_path(tcl_root):\n        return\n\n    # Absolute path of the \"init.tcl\" script.\n    try:\n        init_resource = [r[1] for r in tcltree if r[1].endswith('init.tcl')][0]\n    # If such script could not be found, silently return.\n    except IndexError:\n        return\n\n    mentions_activetcl = False\n    mentions_teapot = False\n    # TCL/TK reads files using the `system encoding <https://www.tcl.tk/doc/howto/i18n.html#system_encoding>`_.\n    with open_file(init_resource, text_read_mode,\n                   encoding=locale.getpreferredencoding()) 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(\n            \"\"\"\nYou appear to be using an ActiveTcl build of Tcl/Tk, which PyInstaller has\ndifficulty freezing. To fix this, comment out all references to \"teapot\" in:\n\n     %s\n\nSee https://github.com/pyinstaller/pyinstaller/issues/621 for more information.\n            \"\"\" % init_resource)\n\n\ndef _find_tcl_tk_darwin_system_frameworks(binaries):\n    \"\"\"\n    Get an OS X-specific 2-tuple of the absolute paths of the top-level\n    external data directories for both Tcl and Tk, respectively.\n\n    This function finds the OS X system installation of Tcl and Tk.\n    System OS X Tcl and Tk are installed as Frameworks requiring special care.\n\n    Returns\n    -------\n    list\n        2-tuple whose first element is the value of `${TCL_LIBRARY}` and whose\n        second element is the value of `${TK_LIBRARY}`.\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        elif nm == 'Tk':\n            tk_root =  os.path.join(os.path.dirname(fnm), 'Resources/Scripts')\n    return tcl_root, tk_root\n\n\ndef _find_tcl_tk_dir():\n    \"\"\"\n    Get a platform-agnostic 2-tuple of the absolute paths of the top-level\n    external data directories for both Tcl and Tk, respectively.\n\n    Returns\n    -------\n    list\n        2-tuple whose first element is the value of `${TCL_LIBRARY}` and whose\n        second element is the value of `${TK_LIBRARY}`.\n    \"\"\"\n    # Python code to get path to TCL_LIBRARY.\n    tcl_root = exec_statement(\n        'from %s import Tcl; print(Tcl().eval(\"info library\"))' % modname_tkinter)\n    tk_version = exec_statement(\n        'from _tkinter import TK_VERSION; print(TK_VERSION)')\n\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_tcl_tk(hook_api):\n    \"\"\"\n    Get a platform-specific 2-tuple of the absolute paths of the top-level\n    external data directories for both Tcl and Tk, respectively.\n\n    Returns\n    -------\n    list\n        2-tuple whose first element is the value of `${TCL_LIBRARY}` and whose\n        second element is the value of `${TK_LIBRARY}`.\n    \"\"\"\n    bins = selectImports(hook_api.__file__)\n\n    if is_darwin:\n        # _tkinter depends on system Tcl/Tk frameworks.\n        # For example this is the case of Python from homebrew.\n        if not bins:\n            # 'hook_api.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 'hook_api.binaries'.\n            bins = getImports(hook_api.__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        # OS X system installation of Tcl/Tk.\n        # [/System]/Library/Frameworks/Tcl.framework/Resources/Scripts/Tcl\n        if 'Library/Frameworks/Tcl.framework' in path_to_tcl:\n            tcl_tk = _find_tcl_tk_darwin_system_frameworks(bins)\n        # Tcl/Tk compiled as on Linux other Unixes.\n        # This is the case of Tcl/Tk from macports and Tck/Tk built into\n        # python.org OS X python distributions.\n        # python.org built-in tcl/tk is located at\n        # /Library/Frameworks/Python.framework/Versions/3.x/lib/libtcl8.6.dylib\n        else:\n            tcl_tk = _find_tcl_tk_dir()\n\n    else:\n        tcl_tk = _find_tcl_tk_dir()\n\n    return tcl_tk\n\n\ndef _collect_tcl_tk_files(hook_api):\n    \"\"\"\n    Get a list of TOC-style 3-tuples describing all external Tcl/Tk data files.\n\n    Returns\n    -------\n    Tree\n        Such list.\n    \"\"\"\n    # Workaround for broken Tcl/Tk detection in virtualenv on Windows.\n    _handle_broken_tcl_tk()\n\n    tcl_root, tk_root = _find_tcl_tk(hook_api)\n\n    # TODO Shouldn't these be fatal exceptions?\n    if not tcl_root:\n        logger.error('Tcl/Tk improperly installed on this system.')\n        return []\n    if not os.path.isdir(tcl_root):\n        logger.error('Tcl data directory \"%s\" not found.', tcl_root)\n        return []\n    if not os.path.isdir(tk_root):\n        logger.error('Tk data directory \"%s\" not found.', tk_root)\n        return []\n\n    tcltree = Tree(\n        tcl_root, prefix='tcl', excludes=['demos', '*.lib', 'tclConfig.sh'])\n    tktree = Tree(\n        tk_root, prefix='tk', excludes=['demos', '*.lib', 'tkConfig.sh'])\n\n    # If the current Tcl installation is a Teapot-distributed version of\n    # ActiveTcl and the current platform is OS X, warn that this is bad.\n    if is_darwin:\n        _warn_if_activetcl_or_teapot_installed(tcl_root, tcltree)\n\n    return (tcltree + tktree)\n\n\ndef hook(hook_api):\n    # Use a hook-function to get the module's attr:`__file__` easily.\n    \"\"\"\n    Freeze all external Tcl/Tk data files if this is a supported platform *or*\n    log a non-fatal error otherwise.\n    \"\"\"\n    if is_win or is_darwin or is_unix:\n        # _collect_tcl_tk_files(hook_api) returns a Tree (which is okay),\n        # so we need to store it into `hook_api.datas` to prevent\n        # `building.imphook.format_binaries_and_datas` from crashing\n        # with \"too many values to unpack\".\n        hook_api.add_datas(_collect_tcl_tk_files(hook_api))\n    else:\n        logger.error(\"... skipping Tcl/Tk handling on unsupported platform %s\", sys.platform)\n", "path": "PyInstaller/hooks/hook-_tkinter.py"}]}