|
| 1 | +import functools |
| 2 | +import os |
| 3 | +import platform |
| 4 | +import shutil |
| 5 | +from typing import Optional, NamedTuple |
| 6 | + |
| 7 | + |
| 8 | +def _get_platform_arch() -> str: |
| 9 | + system_name = platform.system() |
| 10 | + |
| 11 | + if system_name == 'Windows': |
| 12 | + return 'win64' |
| 13 | + if system_name == 'Linux': |
| 14 | + return 'glnxa64' |
| 15 | + if system_name == 'Darwin': |
| 16 | + if platform.mac_ver()[-1] == 'arm64': |
| 17 | + return 'maca64' |
| 18 | + return 'maci64' |
| 19 | + |
| 20 | + raise RuntimeError(f"{system_name} is not a supported platform.") |
| 21 | + |
| 22 | + |
| 23 | +def _get_matlab_root() -> Optional[str]: |
| 24 | + """Probe matlab root directory""" |
| 25 | + matlab_command = shutil.which('matlab') |
| 26 | + if not matlab_command: |
| 27 | + return None |
| 28 | + matlab_bin_dir = os.path.dirname(matlab_command) |
| 29 | + matlab_root = os.path.normpath(os.path.join(matlab_bin_dir, os.pardir)) |
| 30 | + return matlab_root |
| 31 | + |
| 32 | + |
| 33 | +class MatlabPathInfo(NamedTuple): |
| 34 | + arch: str |
| 35 | + bin_folder: str |
| 36 | + engine_folder: str |
| 37 | + extern_bin: str |
| 38 | + |
| 39 | + |
| 40 | +@functools.cache |
| 41 | +def get_path_info() -> MatlabPathInfo: |
| 42 | + package_folder = os.path.dirname(os.path.realpath(__file__)) |
| 43 | + arch_file = os.path.join(package_folder, 'engine', '_arch.txt') |
| 44 | + if os.path.isfile(arch_file): |
| 45 | + with open(arch_file, 'r') as root: |
| 46 | + [arch, bin_folder, engine_folder, extern_bin] = [line.strip() for line in root.readlines() if line.strip()] |
| 47 | + return MatlabPathInfo(arch, bin_folder, engine_folder, extern_bin) |
| 48 | + |
| 49 | + matlab_root = _get_matlab_root() |
| 50 | + if matlab_root: |
| 51 | + arch = _get_platform_arch() |
| 52 | + bin_folder = os.path.join(matlab_root, 'bin', arch) |
| 53 | + engine_folder = os.path.join(matlab_root, 'extern', 'engines', 'python', 'dist', 'matlab', 'engine', arch) |
| 54 | + extern_bin = os.path.join(matlab_root, 'extern', 'bin', arch) |
| 55 | + if os.path.isdir(bin_folder) and os.path.isdir(engine_folder) and os.path.isdir(extern_bin): |
| 56 | + return MatlabPathInfo(arch, bin_folder, engine_folder, extern_bin) |
| 57 | + |
| 58 | + raise RuntimeError("The MATLAB Engine for Python install is corrupted or matlab is not available. Please try to re-install.") |
0 commit comments