@@ -24,7 +24,7 @@ class _MatlabFinder(build_py):
2424 MATLAB_REL = 'R2022b'
2525
2626 # MUST_BE_UPDATED_EACH_RELEASE (Search repo for this string)
27- MATLAB_VER = '9.13.3a2 '
27+ MATLAB_VER = '9.13.3a3 '
2828
2929 # MUST_BE_UPDATED_EACH_RELEASE (Search repo for this string)
3030 SUPPORTED_PYTHON_VERSIONS = set (['3.8' , '3.9' , '3.10' ])
@@ -48,7 +48,9 @@ class _MatlabFinder(build_py):
4848 python_ver = ''
4949 platform = ''
5050 found_matlab = ''
51-
51+ found_matlab_with_wrong_arch_in_default_install = ''
52+ found_matlab_with_wrong_arch_in_path = ''
53+
5254 # ERROR MESSAGES
5355 minimum_maximum = "No compatible version of MATLAB was found. " + \
5456 "This feature supports MATLAB {min_v:s} ({min_r:s}) through {max_v:s} ({max_r:s}), inclusive."
@@ -65,6 +67,9 @@ class _MatlabFinder(build_py):
6567 "To install a compatible version, call python -m pip install matlabengine=={found:s}."
6668 invalid_version_from_matlab_ver = "Format of MATLAB version '{ver:s}' is invalid."
6769 invalid_version_from_eng = "Format of MATLAB Engine API version '{ver:s}' is invalid."
70+ next_steps = "Reinstall MATLAB, use DYLD_LIBRARY_PATH to specify a different MATLAB installation, or use a different Python interpreter."
71+ wrong_arch_in_default_install = "MATLAB installation in {path1:s} is {matlab_arch:s}, but Python interpreter is {python_arch:s}. {next_steps:s}."
72+ wrong_arch_in_path = "MATLAB installation in {path1:s}, listed in DYLD_LIBRARY_PATH, is {matlab_arch:s}, but Python interpreter is {python_arch:s}. {next_steps:s}."
6873
6974 def set_platform_and_arch (self ):
7075 """
@@ -103,7 +108,32 @@ def unix_default_install_exists(self):
103108 Determines whether MATLAB is installed in default UNIX location.
104109 """
105110 path = self .DEFAULT_INSTALLS [self .platform ]
106- return os .path .exists (path )
111+ if not os .path .exists (path ):
112+ return False
113+
114+ if self .platform == 'Darwin' :
115+ # On Mac, we need to further verify that there is a 'bin/maci64' subdir if the Python is maci64
116+ # or a 'bin/maca64' subdir if the Python is maca64.
117+ path_to_bin = os .path .join (path , 'bin' , self .arch )
118+ if os .path .exists (path_to_bin ):
119+ # The path exists, and we don't need to do anything further.
120+ return True
121+
122+ if self .arch == 'maci64' :
123+ alternate_arch = 'maca64'
124+ else :
125+ alternate_arch = 'maci64'
126+
127+ if os .path .exists (os .path .join (path , 'bin' , alternate_arch )):
128+ # There is a default install, but its arch doesn't match the Python arch. Save this info
129+ # so that if we don't find an install with a valid arch in DYLD_LIBRARY_PATH, we can
130+ # issue an error message that says that there is a Mac installation in the default
131+ # location that has the wrong arch. The user can choose whether to change the
132+ # Python interpreter or the MATLAB installation so that the arch will match.
133+ found_matlab_with_wrong_arch_in_default_install = path
134+ return False
135+
136+ return True
107137
108138 def _create_path_list (self ):
109139 """
@@ -120,6 +150,31 @@ def _create_path_list(self):
120150
121151 return path_dirs
122152
153+ def _get_alternate_arch (self ):
154+ if self .arch == 'maci64' :
155+ return 'maca64'
156+ if self .arch == 'maca64' :
157+ return 'maci64'
158+ return self .arch
159+
160+ def _arch_in_mac_dir_is_correct (self , dir ):
161+ ARCH_LEN = 6 # == len('maci64') or len('maca64')
162+ BIN_ARCH_LEN = ARCH_LEN + 4 # == len('bin/maci64') or len('bin/maca64')
163+
164+ if len (dir ) < BIN_ARCH_LEN :
165+ return False
166+
167+ if dir [- 1 ] == os .sep :
168+ # It's safe to look at dir[[-1 * (ARCH_LEN+1)] because BIN_ARCH_LEN > ARCH_LEN + 1.
169+ possible_arch = dir [- 1 * (ARCH_LEN + 1 ) : - 1 ]
170+ else :
171+ possible_arch = dir [- 1 * ARCH_LEN ]
172+
173+ if possible_arch == self .arch :
174+ return True
175+ else :
176+ return False
177+
123178 def _get_matlab_root_from_unix_bin (self , dir ):
124179 """
125180 Searches bin directory for presence of MATLAB file. Used only for
@@ -129,7 +184,10 @@ def _get_matlab_root_from_unix_bin(self, dir):
129184 possible_root = os .path .normpath (os .path .join (dir , os .pardir , os .pardir ))
130185 matlab_root = ''
131186 if os .path .isfile (matlab_path ) and self .verify_matlab_release (possible_root ):
132- matlab_root = possible_root
187+ if self .platform == 'Darwin' and not self ._arch_in_mac_dir_is_correct (dir ):
188+ found_matlab_with_wrong_arch_in_path = possible_root
189+ else :
190+ matlab_root = possible_root
133191
134192 return matlab_root
135193
@@ -301,9 +359,24 @@ def run(self):
301359 else :
302360 path_dirs = self ._create_path_list ()
303361 matlab_root = self .search_path_for_directory_unix (self .arch , path_dirs )
304- err_msg = self ._err_msg_if_bad_matlab_root (matlab_root )
305- if err_msg :
306- raise RuntimeError (err_msg )
362+ err_msg = self ._err_msg_if_bad_matlab_root (matlab_root )
363+ if err_msg :
364+ if self .platform == 'Darwin' :
365+ if self .found_matlab_with_wrong_arch_in_default_install :
366+ raise RuntimeError (
367+ self .wrong_arch_in_default_install .format (
368+ path1 = self .found_matlab_with_wrong_arch_in_default_install ,
369+ matlab_arch = self ._get_alternate_arch (),
370+ python_arch = self .arch ,
371+ next_steps = self .next_steps ))
372+ if self .found_matlab_with_wrong_arch_in_path :
373+ raise RuntimeError (
374+ self .wrong_arch_in_path .format (
375+ path1 = self .found_matlab_with_wrong_arch_in_path ,
376+ matlab_arch = self ._get_alternate_arch (),
377+ python_arch = self .arch ,
378+ next_steps = self .next_steps ))
379+ raise RuntimeError (err_msg )
307380
308381 self .write_text_file (matlab_root )
309382 build_py .run (self )
@@ -316,7 +389,7 @@ def run(self):
316389 setup (
317390 name = "matlabengine" ,
318391 # MUST_BE_UPDATED_EACH_RELEASE (Search repo for this string)
319- version = "9.13.3a2 " ,
392+ version = "9.13.3a3 " ,
320393 description = 'A module to call MATLAB from Python' ,
321394 author = 'MathWorks' ,
322395 license = "MathWorks XSLA License" ,
0 commit comments