We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Matlab fails to build with Python 3
Trying to build `matlab-2020b` with system version `Python 3.6` fails to configure the build.

The error is caused by [reading a non-ascii character](https://github.com/ComputeCanada/easybuild-easyconfigs/blob/computecanada-master/easybuild/easyconfigs/m/MATLAB/MATLAB-2020a-remove-idiotic-non-ascii-character.patch). 

--- 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/m/matlab.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 installing MATLAB, implemented as an easyblock
27 
28 @author: Stijn De Weirdt (Ghent University)
29 @author: Dries Verdegem (Ghent University)
30 @author: Kenneth Hoste (Ghent University)
31 @author: Pieter De Baets (Ghent University)
32 @author: Jens Timmerman (Ghent University)
33 @author: Fotis Georgatos (Uni.Lu, NTUA)
34 """
35 import re
36 import os
37 import shutil
38 import stat
39 import tempfile
40 
41 from distutils.version import LooseVersion
42 
43 from easybuild.easyblocks.generic.packedbinary import PackedBinary
44 from easybuild.framework.easyconfig import CUSTOM
45 from easybuild.tools.build_log import EasyBuildError
46 from easybuild.tools.filetools import adjust_permissions, change_dir, read_file, write_file
47 from easybuild.tools.py2vs3 import string_type
48 from easybuild.tools.run import run_cmd
49 
50 
51 class EB_MATLAB(PackedBinary):
52     """Support for installing MATLAB."""
53 
54     def __init__(self, *args, **kwargs):
55         """Add extra config options specific to MATLAB."""
56         super(EB_MATLAB, self).__init__(*args, **kwargs)
57         self.comp_fam = None
58         self.configfile = os.path.join(self.builddir, 'my_installer_input.txt')
59 
60     @staticmethod
61     def extra_options():
62         extra_vars = {
63             'java_options': ['-Xmx256m', "$_JAVA_OPTIONS value set for install and in module file.", CUSTOM],
64             'key': [None, "Installation key(s), make one install for each key. Single key or a list of keys", CUSTOM],
65         }
66         return PackedBinary.extra_options(extra_vars)
67 
68     def configure_step(self):
69         """Configure MATLAB installation: create license file."""
70 
71         licfile = self.cfg['license_file']
72         if licfile is None:
73             licserv = self.cfg['license_server']
74             if licserv is None:
75                 licserv = os.getenv('EB_MATLAB_LICENSE_SERVER', 'license.example.com')
76             licport = self.cfg['license_server_port']
77             if licport is None:
78                 licport = os.getenv('EB_MATLAB_LICENSE_SERVER_PORT', '00000')
79             # create license file
80             lictxt = '\n'.join([
81                 "SERVER %s 000000000000 %s" % (licserv, licport),
82                 "USE_SERVER",
83             ])
84 
85             licfile = os.path.join(self.builddir, 'matlab.lic')
86             write_file(licfile, lictxt)
87 
88         try:
89             shutil.copyfile(os.path.join(self.cfg['start_dir'], 'installer_input.txt'), self.configfile)
90             config = read_file(self.configfile)
91 
92             regdest = re.compile(r"^# destinationFolder=.*", re.M)
93             regagree = re.compile(r"^# agreeToLicense=.*", re.M)
94             regmode = re.compile(r"^# mode=.*", re.M)
95             reglicpath = re.compile(r"^# licensePath=.*", re.M)
96 
97             config = regdest.sub("destinationFolder=%s" % self.installdir, config)
98             config = regagree.sub("agreeToLicense=Yes", config)
99             config = regmode.sub("mode=silent", config)
100             config = reglicpath.sub("licensePath=%s" % licfile, config)
101 
102             write_file(self.configfile, config)
103 
104         except IOError as err:
105             raise EasyBuildError("Failed to create installation config file %s: %s", self.configfile, err)
106 
107         self.log.debug('configuration file written to %s:\n %s', self.configfile, config)
108 
109     def install_step(self):
110         """MATLAB install procedure using 'install' command."""
111 
112         src = os.path.join(self.cfg['start_dir'], 'install')
113 
114         # make sure install script is executable
115         adjust_permissions(src, stat.S_IXUSR)
116 
117         if LooseVersion(self.version) >= LooseVersion('2016b'):
118             jdir = os.path.join(self.cfg['start_dir'], 'sys', 'java', 'jre', 'glnxa64', 'jre', 'bin')
119             for perm_dir in [os.path.join(self.cfg['start_dir'], 'bin', 'glnxa64'), jdir]:
120                 adjust_permissions(perm_dir, stat.S_IXUSR)
121 
122         # make sure $DISPLAY is not defined, which may lead to (hard to trace) problems
123         # this is a workaround for not being able to specify --nodisplay to the install scripts
124         if 'DISPLAY' in os.environ:
125             os.environ.pop('DISPLAY')
126 
127         if '_JAVA_OPTIONS' not in self.cfg['preinstallopts']:
128             java_opts = 'export _JAVA_OPTIONS="%s" && ' % self.cfg['java_options']
129             self.cfg['preinstallopts'] = java_opts + self.cfg['preinstallopts']
130         if LooseVersion(self.version) >= LooseVersion('2016b'):
131             change_dir(self.builddir)
132 
133         # Build the cmd string
134         cmdlist = [
135             self.cfg['preinstallopts'],
136             src,
137             '-inputFile',
138             self.configfile,
139         ]
140         if LooseVersion(self.version) < LooseVersion('2020a'):
141             # MATLAB installers < 2020a ignore $TMPDIR (always use /tmp) and might need a large tmpdir
142             tmpdir = tempfile.mkdtemp()
143             cmdlist.extend([
144                 '-v',
145                 '-tmpdir',
146                 tmpdir,
147             ])
148         cmdlist.append(self.cfg['installopts'])
149         cmd = ' '.join(cmdlist)
150 
151         keys = self.cfg['key']
152         if keys is None:
153             keys = os.getenv('EB_MATLAB_KEY', '00000-00000-00000-00000-00000-00000-00000-00000-00000-00000')
154         if isinstance(keys, string_type):
155             keys = keys.split(',')
156 
157         # Compile the installation key regex outside of the loop
158         regkey = re.compile(r"^(# )?fileInstallationKey=.*", re.M)
159 
160         # Run an install for each key
161         for i, key in enumerate(keys):
162 
163             self.log.info('Installing MATLAB with key %s of %s', i + 1, len(keys))
164 
165             try:
166                 config = read_file(self.configfile)
167                 config = regkey.sub("fileInstallationKey=%s" % key, config)
168                 write_file(self.configfile, config)
169 
170             except IOError as err:
171                 raise EasyBuildError("Failed to update config file %s: %s", self.configfile, err)
172 
173             (out, _) = run_cmd(cmd, log_all=True, simple=False)
174 
175             # check installer output for known signs of trouble
176             patterns = [
177                 "Error: You have entered an invalid File Installation Key",
178             ]
179 
180             for pattern in patterns:
181                 regex = re.compile(pattern, re.I)
182                 if regex.search(out):
183                     raise EasyBuildError("Found error pattern '%s' in output of installation command '%s': %s",
184                                          regex.pattern, cmd, out)
185 
186     def sanity_check_step(self):
187         """Custom sanity check for MATLAB."""
188         custom_paths = {
189             'files': ["bin/matlab", "bin/glnxa64/MATLAB", "toolbox/local/classpath.txt"],
190             'dirs': ["java/jar"],
191         }
192         super(EB_MATLAB, self).sanity_check_step(custom_paths=custom_paths)
193 
194     def make_module_extra(self):
195         """Extend PATH and set proper _JAVA_OPTIONS (e.g., -Xmx)."""
196         txt = super(EB_MATLAB, self).make_module_extra()
197 
198         # make MATLAB runtime available
199         if LooseVersion(self.version) >= LooseVersion('2017a'):
200             for ldlibdir in ['runtime', 'bin', os.path.join('sys', 'os')]:
201                 libdir = os.path.join(ldlibdir, 'glnxa64')
202                 txt += self.module_generator.prepend_paths('LD_LIBRARY_PATH', libdir)
203         if self.cfg['java_options']:
204             txt += self.module_generator.set_environment('_JAVA_OPTIONS', self.cfg['java_options'])
205         return txt
206
```
--- 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/m/matlab.py b/easybuild/easyblocks/m/matlab.py
--- a/easybuild/easyblocks/m/matlab.py
+++ b/easybuild/easyblocks/m/matlab.py
@@ -34,7 +34,6 @@
 """
 import re
 import os
-import shutil
 import stat
 import tempfile
 
@@ -43,7 +42,7 @@
 from easybuild.easyblocks.generic.packedbinary import PackedBinary
 from easybuild.framework.easyconfig import CUSTOM
 from easybuild.tools.build_log import EasyBuildError
-from easybuild.tools.filetools import adjust_permissions, change_dir, read_file, write_file
+from easybuild.tools.filetools import adjust_permissions, change_dir, copy_file, read_file, write_file
 from easybuild.tools.py2vs3 import string_type
 from easybuild.tools.run import run_cmd
 
@@ -86,18 +85,24 @@
             write_file(licfile, lictxt)
 
         try:
-            shutil.copyfile(os.path.join(self.cfg['start_dir'], 'installer_input.txt'), self.configfile)
-            config = read_file(self.configfile)
+            copy_file(os.path.join(self.cfg['start_dir'], 'installer_input.txt'), self.configfile)
 
-            regdest = re.compile(r"^# destinationFolder=.*", re.M)
-            regagree = re.compile(r"^# agreeToLicense=.*", re.M)
-            regmode = re.compile(r"^# mode=.*", re.M)
-            reglicpath = re.compile(r"^# licensePath=.*", re.M)
+            # read file in binary mode to avoid UTF-8 encoding issues when using Python 3,
+            # due to non-UTF-8 characters...
+            config = read_file(self.configfile, mode='rb')
 
-            config = regdest.sub("destinationFolder=%s" % self.installdir, config)
-            config = regagree.sub("agreeToLicense=Yes", config)
-            config = regmode.sub("mode=silent", config)
-            config = reglicpath.sub("licensePath=%s" % licfile, config)
+            # use raw byte strings (must be 'br', not 'rb'),
+            # required when using Python 3 because file was read in binary mode
+            regdest = re.compile(br"^# destinationFolder=.*", re.M)
+            regagree = re.compile(br"^# agreeToLicense=.*", re.M)
+            regmode = re.compile(br"^# mode=.*", re.M)
+            reglicpath = re.compile(br"^# licensePath=.*", re.M)
+
+            # must use byte-strings here when using Python 3, see above
+            config = regdest.sub(b"destinationFolder=%s" % self.installdir.encode('utf-8'), config)
+            config = regagree.sub(b"agreeToLicense=Yes", config)
+            config = regmode.sub(b"mode=silent", config)
+            config = reglicpath.sub(b"licensePath=%s" % licfile.encode('utf-8'), config)
 
             write_file(self.configfile, config)
 
@@ -155,7 +160,7 @@
             keys = keys.split(',')
 
         # Compile the installation key regex outside of the loop
-        regkey = re.compile(r"^(# )?fileInstallationKey=.*", re.M)
+        regkey = re.compile(br"^(# )?fileInstallationKey=.*", re.M)
 
         # Run an install for each key
         for i, key in enumerate(keys):
@@ -163,8 +168,8 @@
             self.log.info('Installing MATLAB with key %s of %s', i + 1, len(keys))
 
             try:
-                config = read_file(self.configfile)
-                config = regkey.sub("fileInstallationKey=%s" % key, config)
+                config = read_file(self.configfile, mode='rb')
+                config = regkey.sub(b"fileInstallationKey=%s" % key.encode('utf-8'), config)
                 write_file(self.configfile, config)
 
             except IOError as err:

{"golden_diff": "diff --git a/easybuild/easyblocks/m/matlab.py b/easybuild/easyblocks/m/matlab.py\n--- a/easybuild/easyblocks/m/matlab.py\n+++ b/easybuild/easyblocks/m/matlab.py\n@@ -34,7 +34,6 @@\n \"\"\"\n import re\n import os\n-import shutil\n import stat\n import tempfile\n \n@@ -43,7 +42,7 @@\n from easybuild.easyblocks.generic.packedbinary import PackedBinary\n from easybuild.framework.easyconfig import CUSTOM\n from easybuild.tools.build_log import EasyBuildError\n-from easybuild.tools.filetools import adjust_permissions, change_dir, read_file, write_file\n+from easybuild.tools.filetools import adjust_permissions, change_dir, copy_file, read_file, write_file\n from easybuild.tools.py2vs3 import string_type\n from easybuild.tools.run import run_cmd\n \n@@ -86,18 +85,24 @@\n             write_file(licfile, lictxt)\n \n         try:\n-            shutil.copyfile(os.path.join(self.cfg['start_dir'], 'installer_input.txt'), self.configfile)\n-            config = read_file(self.configfile)\n+            copy_file(os.path.join(self.cfg['start_dir'], 'installer_input.txt'), self.configfile)\n \n-            regdest = re.compile(r\"^# destinationFolder=.*\", re.M)\n-            regagree = re.compile(r\"^# agreeToLicense=.*\", re.M)\n-            regmode = re.compile(r\"^# mode=.*\", re.M)\n-            reglicpath = re.compile(r\"^# licensePath=.*\", re.M)\n+            # read file in binary mode to avoid UTF-8 encoding issues when using Python 3,\n+            # due to non-UTF-8 characters...\n+            config = read_file(self.configfile, mode='rb')\n \n-            config = regdest.sub(\"destinationFolder=%s\" % self.installdir, config)\n-            config = regagree.sub(\"agreeToLicense=Yes\", config)\n-            config = regmode.sub(\"mode=silent\", config)\n-            config = reglicpath.sub(\"licensePath=%s\" % licfile, config)\n+            # use raw byte strings (must be 'br', not 'rb'),\n+            # required when using Python 3 because file was read in binary mode\n+            regdest = re.compile(br\"^# destinationFolder=.*\", re.M)\n+            regagree = re.compile(br\"^# agreeToLicense=.*\", re.M)\n+            regmode = re.compile(br\"^# mode=.*\", re.M)\n+            reglicpath = re.compile(br\"^# licensePath=.*\", re.M)\n+\n+            # must use byte-strings here when using Python 3, see above\n+            config = regdest.sub(b\"destinationFolder=%s\" % self.installdir.encode('utf-8'), config)\n+            config = regagree.sub(b\"agreeToLicense=Yes\", config)\n+            config = regmode.sub(b\"mode=silent\", config)\n+            config = reglicpath.sub(b\"licensePath=%s\" % licfile.encode('utf-8'), config)\n \n             write_file(self.configfile, config)\n \n@@ -155,7 +160,7 @@\n             keys = keys.split(',')\n \n         # Compile the installation key regex outside of the loop\n-        regkey = re.compile(r\"^(# )?fileInstallationKey=.*\", re.M)\n+        regkey = re.compile(br\"^(# )?fileInstallationKey=.*\", re.M)\n \n         # Run an install for each key\n         for i, key in enumerate(keys):\n@@ -163,8 +168,8 @@\n             self.log.info('Installing MATLAB with key %s of %s', i + 1, len(keys))\n \n             try:\n-                config = read_file(self.configfile)\n-                config = regkey.sub(\"fileInstallationKey=%s\" % key, config)\n+                config = read_file(self.configfile, mode='rb')\n+                config = regkey.sub(b\"fileInstallationKey=%s\" % key.encode('utf-8'), config)\n                 write_file(self.configfile, config)\n \n             except IOError as err:\n", "issue": "Matlab fails to build with Python 3\nTrying to build `matlab-2020b` with system version `Python 3.6` fails to configure the build.\r\n\r\nThe error is caused by [reading a non-ascii character](https://github.com/ComputeCanada/easybuild-easyconfigs/blob/computecanada-master/easybuild/easyconfigs/m/MATLAB/MATLAB-2020a-remove-idiotic-non-ascii-character.patch). \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 installing MATLAB, implemented as an easyblock\n\n@author: Stijn De Weirdt (Ghent University)\n@author: Dries Verdegem (Ghent University)\n@author: Kenneth Hoste (Ghent University)\n@author: Pieter De Baets (Ghent University)\n@author: Jens Timmerman (Ghent University)\n@author: Fotis Georgatos (Uni.Lu, NTUA)\n\"\"\"\nimport re\nimport os\nimport shutil\nimport stat\nimport tempfile\n\nfrom distutils.version import LooseVersion\n\nfrom easybuild.easyblocks.generic.packedbinary import PackedBinary\nfrom easybuild.framework.easyconfig import CUSTOM\nfrom easybuild.tools.build_log import EasyBuildError\nfrom easybuild.tools.filetools import adjust_permissions, change_dir, read_file, write_file\nfrom easybuild.tools.py2vs3 import string_type\nfrom easybuild.tools.run import run_cmd\n\n\nclass EB_MATLAB(PackedBinary):\n    \"\"\"Support for installing MATLAB.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Add extra config options specific to MATLAB.\"\"\"\n        super(EB_MATLAB, self).__init__(*args, **kwargs)\n        self.comp_fam = None\n        self.configfile = os.path.join(self.builddir, 'my_installer_input.txt')\n\n    @staticmethod\n    def extra_options():\n        extra_vars = {\n            'java_options': ['-Xmx256m', \"$_JAVA_OPTIONS value set for install and in module file.\", CUSTOM],\n            'key': [None, \"Installation key(s), make one install for each key. Single key or a list of keys\", CUSTOM],\n        }\n        return PackedBinary.extra_options(extra_vars)\n\n    def configure_step(self):\n        \"\"\"Configure MATLAB installation: create license file.\"\"\"\n\n        licfile = self.cfg['license_file']\n        if licfile is None:\n            licserv = self.cfg['license_server']\n            if licserv is None:\n                licserv = os.getenv('EB_MATLAB_LICENSE_SERVER', 'license.example.com')\n            licport = self.cfg['license_server_port']\n            if licport is None:\n                licport = os.getenv('EB_MATLAB_LICENSE_SERVER_PORT', '00000')\n            # create license file\n            lictxt = '\\n'.join([\n                \"SERVER %s 000000000000 %s\" % (licserv, licport),\n                \"USE_SERVER\",\n            ])\n\n            licfile = os.path.join(self.builddir, 'matlab.lic')\n            write_file(licfile, lictxt)\n\n        try:\n            shutil.copyfile(os.path.join(self.cfg['start_dir'], 'installer_input.txt'), self.configfile)\n            config = read_file(self.configfile)\n\n            regdest = re.compile(r\"^# destinationFolder=.*\", re.M)\n            regagree = re.compile(r\"^# agreeToLicense=.*\", re.M)\n            regmode = re.compile(r\"^# mode=.*\", re.M)\n            reglicpath = re.compile(r\"^# licensePath=.*\", re.M)\n\n            config = regdest.sub(\"destinationFolder=%s\" % self.installdir, config)\n            config = regagree.sub(\"agreeToLicense=Yes\", config)\n            config = regmode.sub(\"mode=silent\", config)\n            config = reglicpath.sub(\"licensePath=%s\" % licfile, config)\n\n            write_file(self.configfile, config)\n\n        except IOError as err:\n            raise EasyBuildError(\"Failed to create installation config file %s: %s\", self.configfile, err)\n\n        self.log.debug('configuration file written to %s:\\n %s', self.configfile, config)\n\n    def install_step(self):\n        \"\"\"MATLAB install procedure using 'install' command.\"\"\"\n\n        src = os.path.join(self.cfg['start_dir'], 'install')\n\n        # make sure install script is executable\n        adjust_permissions(src, stat.S_IXUSR)\n\n        if LooseVersion(self.version) >= LooseVersion('2016b'):\n            jdir = os.path.join(self.cfg['start_dir'], 'sys', 'java', 'jre', 'glnxa64', 'jre', 'bin')\n            for perm_dir in [os.path.join(self.cfg['start_dir'], 'bin', 'glnxa64'), jdir]:\n                adjust_permissions(perm_dir, stat.S_IXUSR)\n\n        # make sure $DISPLAY is not defined, which may lead to (hard to trace) problems\n        # this is a workaround for not being able to specify --nodisplay to the install scripts\n        if 'DISPLAY' in os.environ:\n            os.environ.pop('DISPLAY')\n\n        if '_JAVA_OPTIONS' not in self.cfg['preinstallopts']:\n            java_opts = 'export _JAVA_OPTIONS=\"%s\" && ' % self.cfg['java_options']\n            self.cfg['preinstallopts'] = java_opts + self.cfg['preinstallopts']\n        if LooseVersion(self.version) >= LooseVersion('2016b'):\n            change_dir(self.builddir)\n\n        # Build the cmd string\n        cmdlist = [\n            self.cfg['preinstallopts'],\n            src,\n            '-inputFile',\n            self.configfile,\n        ]\n        if LooseVersion(self.version) < LooseVersion('2020a'):\n            # MATLAB installers < 2020a ignore $TMPDIR (always use /tmp) and might need a large tmpdir\n            tmpdir = tempfile.mkdtemp()\n            cmdlist.extend([\n                '-v',\n                '-tmpdir',\n                tmpdir,\n            ])\n        cmdlist.append(self.cfg['installopts'])\n        cmd = ' '.join(cmdlist)\n\n        keys = self.cfg['key']\n        if keys is None:\n            keys = os.getenv('EB_MATLAB_KEY', '00000-00000-00000-00000-00000-00000-00000-00000-00000-00000')\n        if isinstance(keys, string_type):\n            keys = keys.split(',')\n\n        # Compile the installation key regex outside of the loop\n        regkey = re.compile(r\"^(# )?fileInstallationKey=.*\", re.M)\n\n        # Run an install for each key\n        for i, key in enumerate(keys):\n\n            self.log.info('Installing MATLAB with key %s of %s', i + 1, len(keys))\n\n            try:\n                config = read_file(self.configfile)\n                config = regkey.sub(\"fileInstallationKey=%s\" % key, config)\n                write_file(self.configfile, config)\n\n            except IOError as err:\n                raise EasyBuildError(\"Failed to update config file %s: %s\", self.configfile, err)\n\n            (out, _) = run_cmd(cmd, log_all=True, simple=False)\n\n            # check installer output for known signs of trouble\n            patterns = [\n                \"Error: You have entered an invalid File Installation Key\",\n            ]\n\n            for pattern in patterns:\n                regex = re.compile(pattern, re.I)\n                if regex.search(out):\n                    raise EasyBuildError(\"Found error pattern '%s' in output of installation command '%s': %s\",\n                                         regex.pattern, cmd, out)\n\n    def sanity_check_step(self):\n        \"\"\"Custom sanity check for MATLAB.\"\"\"\n        custom_paths = {\n            'files': [\"bin/matlab\", \"bin/glnxa64/MATLAB\", \"toolbox/local/classpath.txt\"],\n            'dirs': [\"java/jar\"],\n        }\n        super(EB_MATLAB, self).sanity_check_step(custom_paths=custom_paths)\n\n    def make_module_extra(self):\n        \"\"\"Extend PATH and set proper _JAVA_OPTIONS (e.g., -Xmx).\"\"\"\n        txt = super(EB_MATLAB, self).make_module_extra()\n\n        # make MATLAB runtime available\n        if LooseVersion(self.version) >= LooseVersion('2017a'):\n            for ldlibdir in ['runtime', 'bin', os.path.join('sys', 'os')]:\n                libdir = os.path.join(ldlibdir, 'glnxa64')\n                txt += self.module_generator.prepend_paths('LD_LIBRARY_PATH', libdir)\n        if self.cfg['java_options']:\n            txt += self.module_generator.set_environment('_JAVA_OPTIONS', self.cfg['java_options'])\n        return txt\n", "path": "easybuild/easyblocks/m/matlab.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 installing MATLAB, implemented as an easyblock\n\n@author: Stijn De Weirdt (Ghent University)\n@author: Dries Verdegem (Ghent University)\n@author: Kenneth Hoste (Ghent University)\n@author: Pieter De Baets (Ghent University)\n@author: Jens Timmerman (Ghent University)\n@author: Fotis Georgatos (Uni.Lu, NTUA)\n\"\"\"\nimport re\nimport os\nimport stat\nimport tempfile\n\nfrom distutils.version import LooseVersion\n\nfrom easybuild.easyblocks.generic.packedbinary import PackedBinary\nfrom easybuild.framework.easyconfig import CUSTOM\nfrom easybuild.tools.build_log import EasyBuildError\nfrom easybuild.tools.filetools import adjust_permissions, change_dir, copy_file, read_file, write_file\nfrom easybuild.tools.py2vs3 import string_type\nfrom easybuild.tools.run import run_cmd\n\n\nclass EB_MATLAB(PackedBinary):\n    \"\"\"Support for installing MATLAB.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Add extra config options specific to MATLAB.\"\"\"\n        super(EB_MATLAB, self).__init__(*args, **kwargs)\n        self.comp_fam = None\n        self.configfile = os.path.join(self.builddir, 'my_installer_input.txt')\n\n    @staticmethod\n    def extra_options():\n        extra_vars = {\n            'java_options': ['-Xmx256m', \"$_JAVA_OPTIONS value set for install and in module file.\", CUSTOM],\n            'key': [None, \"Installation key(s), make one install for each key. Single key or a list of keys\", CUSTOM],\n        }\n        return PackedBinary.extra_options(extra_vars)\n\n    def configure_step(self):\n        \"\"\"Configure MATLAB installation: create license file.\"\"\"\n\n        licfile = self.cfg['license_file']\n        if licfile is None:\n            licserv = self.cfg['license_server']\n            if licserv is None:\n                licserv = os.getenv('EB_MATLAB_LICENSE_SERVER', 'license.example.com')\n            licport = self.cfg['license_server_port']\n            if licport is None:\n                licport = os.getenv('EB_MATLAB_LICENSE_SERVER_PORT', '00000')\n            # create license file\n            lictxt = '\\n'.join([\n                \"SERVER %s 000000000000 %s\" % (licserv, licport),\n                \"USE_SERVER\",\n            ])\n\n            licfile = os.path.join(self.builddir, 'matlab.lic')\n            write_file(licfile, lictxt)\n\n        try:\n            copy_file(os.path.join(self.cfg['start_dir'], 'installer_input.txt'), self.configfile)\n\n            # read file in binary mode to avoid UTF-8 encoding issues when using Python 3,\n            # due to non-UTF-8 characters...\n            config = read_file(self.configfile, mode='rb')\n\n            # use raw byte strings (must be 'br', not 'rb'),\n            # required when using Python 3 because file was read in binary mode\n            regdest = re.compile(br\"^# destinationFolder=.*\", re.M)\n            regagree = re.compile(br\"^# agreeToLicense=.*\", re.M)\n            regmode = re.compile(br\"^# mode=.*\", re.M)\n            reglicpath = re.compile(br\"^# licensePath=.*\", re.M)\n\n            # must use byte-strings here when using Python 3, see above\n            config = regdest.sub(b\"destinationFolder=%s\" % self.installdir.encode('utf-8'), config)\n            config = regagree.sub(b\"agreeToLicense=Yes\", config)\n            config = regmode.sub(b\"mode=silent\", config)\n            config = reglicpath.sub(b\"licensePath=%s\" % licfile.encode('utf-8'), config)\n\n            write_file(self.configfile, config)\n\n        except IOError as err:\n            raise EasyBuildError(\"Failed to create installation config file %s: %s\", self.configfile, err)\n\n        self.log.debug('configuration file written to %s:\\n %s', self.configfile, config)\n\n    def install_step(self):\n        \"\"\"MATLAB install procedure using 'install' command.\"\"\"\n\n        src = os.path.join(self.cfg['start_dir'], 'install')\n\n        # make sure install script is executable\n        adjust_permissions(src, stat.S_IXUSR)\n\n        if LooseVersion(self.version) >= LooseVersion('2016b'):\n            jdir = os.path.join(self.cfg['start_dir'], 'sys', 'java', 'jre', 'glnxa64', 'jre', 'bin')\n            for perm_dir in [os.path.join(self.cfg['start_dir'], 'bin', 'glnxa64'), jdir]:\n                adjust_permissions(perm_dir, stat.S_IXUSR)\n\n        # make sure $DISPLAY is not defined, which may lead to (hard to trace) problems\n        # this is a workaround for not being able to specify --nodisplay to the install scripts\n        if 'DISPLAY' in os.environ:\n            os.environ.pop('DISPLAY')\n\n        if '_JAVA_OPTIONS' not in self.cfg['preinstallopts']:\n            java_opts = 'export _JAVA_OPTIONS=\"%s\" && ' % self.cfg['java_options']\n            self.cfg['preinstallopts'] = java_opts + self.cfg['preinstallopts']\n        if LooseVersion(self.version) >= LooseVersion('2016b'):\n            change_dir(self.builddir)\n\n        # Build the cmd string\n        cmdlist = [\n            self.cfg['preinstallopts'],\n            src,\n            '-inputFile',\n            self.configfile,\n        ]\n        if LooseVersion(self.version) < LooseVersion('2020a'):\n            # MATLAB installers < 2020a ignore $TMPDIR (always use /tmp) and might need a large tmpdir\n            tmpdir = tempfile.mkdtemp()\n            cmdlist.extend([\n                '-v',\n                '-tmpdir',\n                tmpdir,\n            ])\n        cmdlist.append(self.cfg['installopts'])\n        cmd = ' '.join(cmdlist)\n\n        keys = self.cfg['key']\n        if keys is None:\n            keys = os.getenv('EB_MATLAB_KEY', '00000-00000-00000-00000-00000-00000-00000-00000-00000-00000')\n        if isinstance(keys, string_type):\n            keys = keys.split(',')\n\n        # Compile the installation key regex outside of the loop\n        regkey = re.compile(br\"^(# )?fileInstallationKey=.*\", re.M)\n\n        # Run an install for each key\n        for i, key in enumerate(keys):\n\n            self.log.info('Installing MATLAB with key %s of %s', i + 1, len(keys))\n\n            try:\n                config = read_file(self.configfile, mode='rb')\n                config = regkey.sub(b\"fileInstallationKey=%s\" % key.encode('utf-8'), config)\n                write_file(self.configfile, config)\n\n            except IOError as err:\n                raise EasyBuildError(\"Failed to update config file %s: %s\", self.configfile, err)\n\n            (out, _) = run_cmd(cmd, log_all=True, simple=False)\n\n            # check installer output for known signs of trouble\n            patterns = [\n                \"Error: You have entered an invalid File Installation Key\",\n            ]\n\n            for pattern in patterns:\n                regex = re.compile(pattern, re.I)\n                if regex.search(out):\n                    raise EasyBuildError(\"Found error pattern '%s' in output of installation command '%s': %s\",\n                                         regex.pattern, cmd, out)\n\n    def sanity_check_step(self):\n        \"\"\"Custom sanity check for MATLAB.\"\"\"\n        custom_paths = {\n            'files': [\"bin/matlab\", \"bin/glnxa64/MATLAB\", \"toolbox/local/classpath.txt\"],\n            'dirs': [\"java/jar\"],\n        }\n        super(EB_MATLAB, self).sanity_check_step(custom_paths=custom_paths)\n\n    def make_module_extra(self):\n        \"\"\"Extend PATH and set proper _JAVA_OPTIONS (e.g., -Xmx).\"\"\"\n        txt = super(EB_MATLAB, self).make_module_extra()\n\n        # make MATLAB runtime available\n        if LooseVersion(self.version) >= LooseVersion('2017a'):\n            for ldlibdir in ['runtime', 'bin', os.path.join('sys', 'os')]:\n                libdir = os.path.join(ldlibdir, 'glnxa64')\n                txt += self.module_generator.prepend_paths('LD_LIBRARY_PATH', libdir)\n        if self.cfg['java_options']:\n            txt += self.module_generator.set_environment('_JAVA_OPTIONS', self.cfg['java_options'])\n        return txt\n", "path": "easybuild/easyblocks/m/matlab.py"}]}