Repository: easybuilders/easybuild-easyblocks

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). 


Discussion:
Should be solved by [#3565](https://github.com/easybuilders/easybuild-framework/pull/3565)
Turns out https://github.com/easybuilders/easybuild-framework/pull/3565 doesn't actually fix this issue, because it's a non-UTF-8 character... 🤦 

This will need some work in the MATLAB easyblock, on it...

Resolving patch:
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 @@ def configure_step(self):
             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 @@ def install_step(self):
             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 @@ def install_step(self):
             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:


Test patch: