We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Tkinter easyblock does not work with `--module-only`
```
== sanity checking...
ERROR: Traceback (most recent call last):
  File "/project/def-sponsor00/ocaisa/easybuild/software/EasyBuild/4.3.4/lib/python3.8/site-packages/easybuild/main.py", line 117, in build_and_install_software
    (ec_res['success'], app_log, err) = build_and_install_one(ec, init_env)
  File "/project/def-sponsor00/ocaisa/easybuild/software/EasyBuild/4.3.4/lib/python3.8/site-packages/easybuild/framework/easyblock.py", line 3412, in build_and_install_one
    result = app.run_all_steps(run_test_cases=run_test_cases)
  File "/project/def-sponsor00/ocaisa/easybuild/software/EasyBuild/4.3.4/lib/python3.8/site-packages/easybuild/framework/easyblock.py", line 3311, in run_all_steps
    self.run_step(step_name, step_methods)
  File "/project/def-sponsor00/ocaisa/easybuild/software/EasyBuild/4.3.4/lib/python3.8/site-packages/easybuild/framework/easyblock.py", line 3166, in run_step
    step_method(self)()
  File "/project/def-sponsor00/ocaisa/easybuild/software/EasyBuild/4.3.4/lib/python3.8/site-packages/easybuild/easyblocks/t/tkinter.py", line 101, in sanity_check_step
    'files': [os.path.join(os.path.dirname(det_pylibdir()), self.tkinter_so_basename)],
AttributeError: 'EB_Tkinter' object has no attribute 'tkinter_so_basename'
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `easybuild/easyblocks/t/tkinter.py`
Content:
```
1 ##
2 # Copyright 2009-2021 Ghent University
3 #
4 # This file is part of EasyBuild,
5 # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
6 # with support of Ghent University (http://ugent.be/hpc),
7 # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
8 # Flemish Research Foundation (FWO) (http://www.fwo.be/en)
9 # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
10 #
11 # https://github.com/easybuilders/easybuild
12 #
13 # EasyBuild is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation v2.
16 #
17 # EasyBuild is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 # GNU General Public License for more details.
21 #
22 # You should have received a copy of the GNU General Public License
23 # along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
24 ##
25 """
26 EasyBuild support for building and installing Tkinter. This is the Python core
27 module to use Tcl/Tk.
28 
29 @author: Adam Huffman (The Francis Crick Institute)
30 @author: Ward Poelmans (Free University of Brussels)
31 @author: Kenneth Hoste (HPC-UGent)
32 """
33 import glob
34 import os
35 import tempfile
36 from distutils.version import LooseVersion
37 
38 import easybuild.tools.environment as env
39 from easybuild.easyblocks.generic.pythonpackage import det_pylibdir
40 from easybuild.easyblocks.python import EB_Python
41 from easybuild.tools.build_log import EasyBuildError
42 from easybuild.tools.filetools import copy, move_file, remove_dir
43 from easybuild.tools.modules import get_software_root
44 from easybuild.tools.systemtools import get_shared_lib_ext
45 
46 
47 class EB_Tkinter(EB_Python):
48     """Support for building/installing the Python Tkinter module
49     based on the normal Python module. We build a normal python
50     but only install the Tkinter bits.
51     """
52 
53     def configure_step(self):
54         """Check for Tk before configuring"""
55         tk = get_software_root('Tk')
56         if not tk:
57             raise EasyBuildError("Tk is mandatory to build Tkinter")
58 
59         # avoid that pip (ab)uses $HOME/.cache/pip
60         # cfr. https://pip.pypa.io/en/stable/reference/pip_install/#caching
61         env.setvar('XDG_CACHE_HOME', tempfile.gettempdir())
62         self.log.info("Using %s as pip cache directory", os.environ['XDG_CACHE_HOME'])
63 
64         super(EB_Tkinter, self).configure_step()
65 
66     def install_step(self):
67         """Install python but only keep the bits we need"""
68         super(EB_Tkinter, self).install_step()
69 
70         tmpdir = tempfile.mkdtemp(dir=self.builddir)
71 
72         pylibdir = os.path.join(self.installdir, os.path.dirname(det_pylibdir()))
73         shlib_ext = get_shared_lib_ext()
74         tkinter_so = os.path.join(pylibdir, 'lib-dynload', '_tkinter*.' + shlib_ext)
75         tkinter_so_hits = glob.glob(tkinter_so)
76         if len(tkinter_so_hits) != 1:
77             raise EasyBuildError("Expected to find exactly one _tkinter*.so: %s", tkinter_so_hits)
78         self.tkinter_so_basename = os.path.basename(tkinter_so_hits[0])
79         if LooseVersion(self.version) >= LooseVersion('3'):
80             tkparts = ["tkinter", os.path.join("lib-dynload", self.tkinter_so_basename)]
81         else:
82             tkparts = ["lib-tk", os.path.join("lib-dynload", self.tkinter_so_basename)]
83 
84         copy([os.path.join(pylibdir, x) for x in tkparts], tmpdir)
85 
86         remove_dir(self.installdir)
87 
88         move_file(os.path.join(tmpdir, tkparts[0]), os.path.join(pylibdir, tkparts[0]))
89         tkinter_so = os.path.basename(tkparts[1])
90         move_file(os.path.join(tmpdir, tkinter_so), os.path.join(pylibdir, tkinter_so))
91 
92     def sanity_check_step(self):
93         """Custom sanity check for Python."""
94         if LooseVersion(self.version) >= LooseVersion('3'):
95             tkinter = 'tkinter'
96         else:
97             tkinter = 'Tkinter'
98         custom_commands = ["python -c 'import %s'" % tkinter]
99 
100         custom_paths = {
101             'files': [os.path.join(os.path.dirname(det_pylibdir()), self.tkinter_so_basename)],
102             'dirs': ['lib']
103         }
104         super(EB_Python, self).sanity_check_step(custom_commands=custom_commands, custom_paths=custom_paths)
105 
106     def make_module_extra(self):
107         """Set PYTHONPATH"""
108         txt = super(EB_Tkinter, self).make_module_extra()
109         pylibdir = os.path.dirname(det_pylibdir())
110         txt += self.module_generator.prepend_paths('PYTHONPATH', pylibdir)
111 
112         return txt
113
```
--- 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/easybuild/easyblocks/t/tkinter.py b/easybuild/easyblocks/t/tkinter.py
--- a/easybuild/easyblocks/t/tkinter.py
+++ b/easybuild/easyblocks/t/tkinter.py
@@ -39,6 +39,7 @@
 from easybuild.easyblocks.generic.pythonpackage import det_pylibdir
 from easybuild.easyblocks.python import EB_Python
 from easybuild.tools.build_log import EasyBuildError
+from easybuild.tools.config import build_option
 from easybuild.tools.filetools import copy, move_file, remove_dir
 from easybuild.tools.modules import get_software_root
 from easybuild.tools.systemtools import get_shared_lib_ext
@@ -50,6 +51,11 @@
     but only install the Tkinter bits.
     """
 
+    def __init__(self, *args, **kwargs):
+        """Initialize Tkinter-specific variables."""
+        super(EB_Tkinter, self).__init__(*args, **kwargs)
+        self.tkinter_so_basename = ''
+
     def configure_step(self):
         """Check for Tk before configuring"""
         tk = get_software_root('Tk')
@@ -69,18 +75,14 @@
 
         tmpdir = tempfile.mkdtemp(dir=self.builddir)
 
-        pylibdir = os.path.join(self.installdir, os.path.dirname(det_pylibdir()))
-        shlib_ext = get_shared_lib_ext()
-        tkinter_so = os.path.join(pylibdir, 'lib-dynload', '_tkinter*.' + shlib_ext)
-        tkinter_so_hits = glob.glob(tkinter_so)
-        if len(tkinter_so_hits) != 1:
-            raise EasyBuildError("Expected to find exactly one _tkinter*.so: %s", tkinter_so_hits)
-        self.tkinter_so_basename = os.path.basename(tkinter_so_hits[0])
+        if not self.tkinter_so_basename:
+            self.tkinter_so_basename = self.get_tkinter_so_basename()
         if LooseVersion(self.version) >= LooseVersion('3'):
             tkparts = ["tkinter", os.path.join("lib-dynload", self.tkinter_so_basename)]
         else:
             tkparts = ["lib-tk", os.path.join("lib-dynload", self.tkinter_so_basename)]
 
+        pylibdir = os.path.join(self.installdir, os.path.dirname(det_pylibdir()))
         copy([os.path.join(pylibdir, x) for x in tkparts], tmpdir)
 
         remove_dir(self.installdir)
@@ -89,6 +91,21 @@
         tkinter_so = os.path.basename(tkparts[1])
         move_file(os.path.join(tmpdir, tkinter_so), os.path.join(pylibdir, tkinter_so))
 
+    def get_tkinter_so_basename(self):
+        pylibdir = os.path.join(self.installdir, os.path.dirname(det_pylibdir()))
+        shlib_ext = get_shared_lib_ext()
+        if build_option('module_only'):
+            # The build has already taken place so the file will have been moved into the final pylibdir
+            tkinter_so = os.path.join(pylibdir, '_tkinter*.' + shlib_ext)
+        else:
+            tkinter_so = os.path.join(pylibdir, 'lib-dynload', '_tkinter*.' + shlib_ext)
+        tkinter_so_hits = glob.glob(tkinter_so)
+        if len(tkinter_so_hits) != 1:
+            raise EasyBuildError("Expected to find exactly one _tkinter*.so: %s", tkinter_so_hits)
+        tkinter_so_basename = os.path.basename(tkinter_so_hits[0])
+
+        return tkinter_so_basename
+
     def sanity_check_step(self):
         """Custom sanity check for Python."""
         if LooseVersion(self.version) >= LooseVersion('3'):
@@ -97,6 +114,9 @@
             tkinter = 'Tkinter'
         custom_commands = ["python -c 'import %s'" % tkinter]
 
+        if not self.tkinter_so_basename:
+            self.tkinter_so_basename = self.get_tkinter_so_basename()
+
         custom_paths = {
             'files': [os.path.join(os.path.dirname(det_pylibdir()), self.tkinter_so_basename)],
             'dirs': ['lib']

{"golden_diff": "diff --git a/easybuild/easyblocks/t/tkinter.py b/easybuild/easyblocks/t/tkinter.py\n--- a/easybuild/easyblocks/t/tkinter.py\n+++ b/easybuild/easyblocks/t/tkinter.py\n@@ -39,6 +39,7 @@\n from easybuild.easyblocks.generic.pythonpackage import det_pylibdir\n from easybuild.easyblocks.python import EB_Python\n from easybuild.tools.build_log import EasyBuildError\n+from easybuild.tools.config import build_option\n from easybuild.tools.filetools import copy, move_file, remove_dir\n from easybuild.tools.modules import get_software_root\n from easybuild.tools.systemtools import get_shared_lib_ext\n@@ -50,6 +51,11 @@\n     but only install the Tkinter bits.\n     \"\"\"\n \n+    def __init__(self, *args, **kwargs):\n+        \"\"\"Initialize Tkinter-specific variables.\"\"\"\n+        super(EB_Tkinter, self).__init__(*args, **kwargs)\n+        self.tkinter_so_basename = ''\n+\n     def configure_step(self):\n         \"\"\"Check for Tk before configuring\"\"\"\n         tk = get_software_root('Tk')\n@@ -69,18 +75,14 @@\n \n         tmpdir = tempfile.mkdtemp(dir=self.builddir)\n \n-        pylibdir = os.path.join(self.installdir, os.path.dirname(det_pylibdir()))\n-        shlib_ext = get_shared_lib_ext()\n-        tkinter_so = os.path.join(pylibdir, 'lib-dynload', '_tkinter*.' + shlib_ext)\n-        tkinter_so_hits = glob.glob(tkinter_so)\n-        if len(tkinter_so_hits) != 1:\n-            raise EasyBuildError(\"Expected to find exactly one _tkinter*.so: %s\", tkinter_so_hits)\n-        self.tkinter_so_basename = os.path.basename(tkinter_so_hits[0])\n+        if not self.tkinter_so_basename:\n+            self.tkinter_so_basename = self.get_tkinter_so_basename()\n         if LooseVersion(self.version) >= LooseVersion('3'):\n             tkparts = [\"tkinter\", os.path.join(\"lib-dynload\", self.tkinter_so_basename)]\n         else:\n             tkparts = [\"lib-tk\", os.path.join(\"lib-dynload\", self.tkinter_so_basename)]\n \n+        pylibdir = os.path.join(self.installdir, os.path.dirname(det_pylibdir()))\n         copy([os.path.join(pylibdir, x) for x in tkparts], tmpdir)\n \n         remove_dir(self.installdir)\n@@ -89,6 +91,21 @@\n         tkinter_so = os.path.basename(tkparts[1])\n         move_file(os.path.join(tmpdir, tkinter_so), os.path.join(pylibdir, tkinter_so))\n \n+    def get_tkinter_so_basename(self):\n+        pylibdir = os.path.join(self.installdir, os.path.dirname(det_pylibdir()))\n+        shlib_ext = get_shared_lib_ext()\n+        if build_option('module_only'):\n+            # The build has already taken place so the file will have been moved into the final pylibdir\n+            tkinter_so = os.path.join(pylibdir, '_tkinter*.' + shlib_ext)\n+        else:\n+            tkinter_so = os.path.join(pylibdir, 'lib-dynload', '_tkinter*.' + shlib_ext)\n+        tkinter_so_hits = glob.glob(tkinter_so)\n+        if len(tkinter_so_hits) != 1:\n+            raise EasyBuildError(\"Expected to find exactly one _tkinter*.so: %s\", tkinter_so_hits)\n+        tkinter_so_basename = os.path.basename(tkinter_so_hits[0])\n+\n+        return tkinter_so_basename\n+\n     def sanity_check_step(self):\n         \"\"\"Custom sanity check for Python.\"\"\"\n         if LooseVersion(self.version) >= LooseVersion('3'):\n@@ -97,6 +114,9 @@\n             tkinter = 'Tkinter'\n         custom_commands = [\"python -c 'import %s'\" % tkinter]\n \n+        if not self.tkinter_so_basename:\n+            self.tkinter_so_basename = self.get_tkinter_so_basename()\n+\n         custom_paths = {\n             'files': [os.path.join(os.path.dirname(det_pylibdir()), self.tkinter_so_basename)],\n             'dirs': ['lib']\n", "issue": "Tkinter easyblock does not work with `--module-only`\n```\r\n== sanity checking...\r\nERROR: Traceback (most recent call last):\r\n  File \"/project/def-sponsor00/ocaisa/easybuild/software/EasyBuild/4.3.4/lib/python3.8/site-packages/easybuild/main.py\", line 117, in build_and_install_software\r\n    (ec_res['success'], app_log, err) = build_and_install_one(ec, init_env)\r\n  File \"/project/def-sponsor00/ocaisa/easybuild/software/EasyBuild/4.3.4/lib/python3.8/site-packages/easybuild/framework/easyblock.py\", line 3412, in build_and_install_one\r\n    result = app.run_all_steps(run_test_cases=run_test_cases)\r\n  File \"/project/def-sponsor00/ocaisa/easybuild/software/EasyBuild/4.3.4/lib/python3.8/site-packages/easybuild/framework/easyblock.py\", line 3311, in run_all_steps\r\n    self.run_step(step_name, step_methods)\r\n  File \"/project/def-sponsor00/ocaisa/easybuild/software/EasyBuild/4.3.4/lib/python3.8/site-packages/easybuild/framework/easyblock.py\", line 3166, in run_step\r\n    step_method(self)()\r\n  File \"/project/def-sponsor00/ocaisa/easybuild/software/EasyBuild/4.3.4/lib/python3.8/site-packages/easybuild/easyblocks/t/tkinter.py\", line 101, in sanity_check_step\r\n    'files': [os.path.join(os.path.dirname(det_pylibdir()), self.tkinter_so_basename)],\r\nAttributeError: 'EB_Tkinter' object has no attribute 'tkinter_so_basename'\r\n```\n", "before_files": [{"content": "##\n# Copyright 2009-2021 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n##\n\"\"\"\nEasyBuild support for building and installing Tkinter. This is the Python core\nmodule to use Tcl/Tk.\n\n@author: Adam Huffman (The Francis Crick Institute)\n@author: Ward Poelmans (Free University of Brussels)\n@author: Kenneth Hoste (HPC-UGent)\n\"\"\"\nimport glob\nimport os\nimport tempfile\nfrom distutils.version import LooseVersion\n\nimport easybuild.tools.environment as env\nfrom easybuild.easyblocks.generic.pythonpackage import det_pylibdir\nfrom easybuild.easyblocks.python import EB_Python\nfrom easybuild.tools.build_log import EasyBuildError\nfrom easybuild.tools.filetools import copy, move_file, remove_dir\nfrom easybuild.tools.modules import get_software_root\nfrom easybuild.tools.systemtools import get_shared_lib_ext\n\n\nclass EB_Tkinter(EB_Python):\n    \"\"\"Support for building/installing the Python Tkinter module\n    based on the normal Python module. We build a normal python\n    but only install the Tkinter bits.\n    \"\"\"\n\n    def configure_step(self):\n        \"\"\"Check for Tk before configuring\"\"\"\n        tk = get_software_root('Tk')\n        if not tk:\n            raise EasyBuildError(\"Tk is mandatory to build Tkinter\")\n\n        # avoid that pip (ab)uses $HOME/.cache/pip\n        # cfr. https://pip.pypa.io/en/stable/reference/pip_install/#caching\n        env.setvar('XDG_CACHE_HOME', tempfile.gettempdir())\n        self.log.info(\"Using %s as pip cache directory\", os.environ['XDG_CACHE_HOME'])\n\n        super(EB_Tkinter, self).configure_step()\n\n    def install_step(self):\n        \"\"\"Install python but only keep the bits we need\"\"\"\n        super(EB_Tkinter, self).install_step()\n\n        tmpdir = tempfile.mkdtemp(dir=self.builddir)\n\n        pylibdir = os.path.join(self.installdir, os.path.dirname(det_pylibdir()))\n        shlib_ext = get_shared_lib_ext()\n        tkinter_so = os.path.join(pylibdir, 'lib-dynload', '_tkinter*.' + shlib_ext)\n        tkinter_so_hits = glob.glob(tkinter_so)\n        if len(tkinter_so_hits) != 1:\n            raise EasyBuildError(\"Expected to find exactly one _tkinter*.so: %s\", tkinter_so_hits)\n        self.tkinter_so_basename = os.path.basename(tkinter_so_hits[0])\n        if LooseVersion(self.version) >= LooseVersion('3'):\n            tkparts = [\"tkinter\", os.path.join(\"lib-dynload\", self.tkinter_so_basename)]\n        else:\n            tkparts = [\"lib-tk\", os.path.join(\"lib-dynload\", self.tkinter_so_basename)]\n\n        copy([os.path.join(pylibdir, x) for x in tkparts], tmpdir)\n\n        remove_dir(self.installdir)\n\n        move_file(os.path.join(tmpdir, tkparts[0]), os.path.join(pylibdir, tkparts[0]))\n        tkinter_so = os.path.basename(tkparts[1])\n        move_file(os.path.join(tmpdir, tkinter_so), os.path.join(pylibdir, tkinter_so))\n\n    def sanity_check_step(self):\n        \"\"\"Custom sanity check for Python.\"\"\"\n        if LooseVersion(self.version) >= LooseVersion('3'):\n            tkinter = 'tkinter'\n        else:\n            tkinter = 'Tkinter'\n        custom_commands = [\"python -c 'import %s'\" % tkinter]\n\n        custom_paths = {\n            'files': [os.path.join(os.path.dirname(det_pylibdir()), self.tkinter_so_basename)],\n            'dirs': ['lib']\n        }\n        super(EB_Python, self).sanity_check_step(custom_commands=custom_commands, custom_paths=custom_paths)\n\n    def make_module_extra(self):\n        \"\"\"Set PYTHONPATH\"\"\"\n        txt = super(EB_Tkinter, self).make_module_extra()\n        pylibdir = os.path.dirname(det_pylibdir())\n        txt += self.module_generator.prepend_paths('PYTHONPATH', pylibdir)\n\n        return txt\n", "path": "easybuild/easyblocks/t/tkinter.py"}], "after_files": [{"content": "##\n# Copyright 2009-2021 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n##\n\"\"\"\nEasyBuild support for building and installing Tkinter. This is the Python core\nmodule to use Tcl/Tk.\n\n@author: Adam Huffman (The Francis Crick Institute)\n@author: Ward Poelmans (Free University of Brussels)\n@author: Kenneth Hoste (HPC-UGent)\n\"\"\"\nimport glob\nimport os\nimport tempfile\nfrom distutils.version import LooseVersion\n\nimport easybuild.tools.environment as env\nfrom easybuild.easyblocks.generic.pythonpackage import det_pylibdir\nfrom easybuild.easyblocks.python import EB_Python\nfrom easybuild.tools.build_log import EasyBuildError\nfrom easybuild.tools.config import build_option\nfrom easybuild.tools.filetools import copy, move_file, remove_dir\nfrom easybuild.tools.modules import get_software_root\nfrom easybuild.tools.systemtools import get_shared_lib_ext\n\n\nclass EB_Tkinter(EB_Python):\n    \"\"\"Support for building/installing the Python Tkinter module\n    based on the normal Python module. We build a normal python\n    but only install the Tkinter bits.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Initialize Tkinter-specific variables.\"\"\"\n        super(EB_Tkinter, self).__init__(*args, **kwargs)\n        self.tkinter_so_basename = ''\n\n    def configure_step(self):\n        \"\"\"Check for Tk before configuring\"\"\"\n        tk = get_software_root('Tk')\n        if not tk:\n            raise EasyBuildError(\"Tk is mandatory to build Tkinter\")\n\n        # avoid that pip (ab)uses $HOME/.cache/pip\n        # cfr. https://pip.pypa.io/en/stable/reference/pip_install/#caching\n        env.setvar('XDG_CACHE_HOME', tempfile.gettempdir())\n        self.log.info(\"Using %s as pip cache directory\", os.environ['XDG_CACHE_HOME'])\n\n        super(EB_Tkinter, self).configure_step()\n\n    def install_step(self):\n        \"\"\"Install python but only keep the bits we need\"\"\"\n        super(EB_Tkinter, self).install_step()\n\n        tmpdir = tempfile.mkdtemp(dir=self.builddir)\n\n        if not self.tkinter_so_basename:\n            self.tkinter_so_basename = self.get_tkinter_so_basename()\n        if LooseVersion(self.version) >= LooseVersion('3'):\n            tkparts = [\"tkinter\", os.path.join(\"lib-dynload\", self.tkinter_so_basename)]\n        else:\n            tkparts = [\"lib-tk\", os.path.join(\"lib-dynload\", self.tkinter_so_basename)]\n\n        pylibdir = os.path.join(self.installdir, os.path.dirname(det_pylibdir()))\n        copy([os.path.join(pylibdir, x) for x in tkparts], tmpdir)\n\n        remove_dir(self.installdir)\n\n        move_file(os.path.join(tmpdir, tkparts[0]), os.path.join(pylibdir, tkparts[0]))\n        tkinter_so = os.path.basename(tkparts[1])\n        move_file(os.path.join(tmpdir, tkinter_so), os.path.join(pylibdir, tkinter_so))\n\n    def get_tkinter_so_basename(self):\n        pylibdir = os.path.join(self.installdir, os.path.dirname(det_pylibdir()))\n        shlib_ext = get_shared_lib_ext()\n        if build_option('module_only'):\n            # The build has already taken place so the file will have been moved into the final pylibdir\n            tkinter_so = os.path.join(pylibdir, '_tkinter*.' + shlib_ext)\n        else:\n            tkinter_so = os.path.join(pylibdir, 'lib-dynload', '_tkinter*.' + shlib_ext)\n        tkinter_so_hits = glob.glob(tkinter_so)\n        if len(tkinter_so_hits) != 1:\n            raise EasyBuildError(\"Expected to find exactly one _tkinter*.so: %s\", tkinter_so_hits)\n        tkinter_so_basename = os.path.basename(tkinter_so_hits[0])\n\n        return tkinter_so_basename\n\n    def sanity_check_step(self):\n        \"\"\"Custom sanity check for Python.\"\"\"\n        if LooseVersion(self.version) >= LooseVersion('3'):\n            tkinter = 'tkinter'\n        else:\n            tkinter = 'Tkinter'\n        custom_commands = [\"python -c 'import %s'\" % tkinter]\n\n        if not self.tkinter_so_basename:\n            self.tkinter_so_basename = self.get_tkinter_so_basename()\n\n        custom_paths = {\n            'files': [os.path.join(os.path.dirname(det_pylibdir()), self.tkinter_so_basename)],\n            'dirs': ['lib']\n        }\n        super(EB_Python, self).sanity_check_step(custom_commands=custom_commands, custom_paths=custom_paths)\n\n    def make_module_extra(self):\n        \"\"\"Set PYTHONPATH\"\"\"\n        txt = super(EB_Tkinter, self).make_module_extra()\n        pylibdir = os.path.dirname(det_pylibdir())\n        txt += self.module_generator.prepend_paths('PYTHONPATH', pylibdir)\n\n        return txt\n", "path": "easybuild/easyblocks/t/tkinter.py"}]}