|
1 | | -# Copyright 2021 MathWorks, Inc. |
| 1 | +# Copyright 2014-2015 MathWorks, Inc. |
2 | 2 | """ |
3 | 3 | Array interface between Python and MATLAB. |
4 | 4 |
|
|
9 | 9 | Modules |
10 | 10 | ------- |
11 | 11 | * mlarray - type-specific multidimensional array classes for working |
12 | | - with MATLAB, implemented in Python |
13 | | - * mcpyarray - type-specific multidimensional array classes for working |
14 | | - with MATLAB, implemented in C++ |
15 | | - * mlexceptions - exceptions raised when manipulating mlarray objects |
| 12 | + with MATLAB |
| 13 | + * mlexceptions - exceptions raised manipulating mlarray objects |
16 | 14 | """ |
17 | 15 |
|
18 | 16 | import os |
19 | 17 | import sys |
20 | | - |
21 | | -# These can be removed once we no longer use _MiniPathInitializer. |
22 | | -import platform |
23 | | -import re |
24 | | - |
25 | 18 | from pkgutil import extend_path |
26 | 19 | __path__ = extend_path(__path__, '__name__') |
27 | 20 |
|
28 | 21 | _package_folder = os.path.dirname(os.path.realpath(__file__)) |
29 | 22 | sys.path.append(_package_folder) |
30 | 23 |
|
31 | | -# This code allows us to: |
32 | | -# (1) switch from a pure Python ("mlarray") to a C++ extension ("mcpyarray") |
33 | | -# implementation by setting the environment variable USE_MCPYARRAY to 1 |
34 | | -# (2) put the proper extern/bin/<arch> directory on the Python path to avoid |
35 | | -# a situation in which some shared libraries are loaded from a MATLAB while |
36 | | -# others are loaded from a runtime. The first directory on the path that contains |
37 | | -# the string "bin/<arch>" (with the proper directory separator) |
38 | | -# will be checked. If it is "extern/bin/<arch>", it will be used as the |
39 | | -# extern/bin/<arch> directory. Otherwise, we'll go up two directories and down |
40 | | -# to extern/bin/<arch>. |
41 | | -class _MiniPathInitializer(object): |
42 | | - PLATFORM_DICT = {'Windows': 'PATH', 'Linux': 'LD_LIBRARY_PATH', 'Darwin': 'DYLD_LIBRARY_PATH'} |
43 | | - |
44 | | - def __init__(self): |
45 | | - self.arch = '' |
46 | | - self.extern_bin_dir = '' |
47 | | - self.path_var = '' |
48 | | - self.system = '' |
49 | | - self.use_mcpyarray = False |
50 | | - if os.environ.get('USE_MCPYARRAY') and os.environ['USE_MCPYARRAY'] == '1': |
51 | | - self.use_mcpyarray = True |
52 | | - |
53 | | - def get_platform_info(self): |
54 | | - """Ask Python for the platform and architecture.""" |
55 | | - # This will return 'Windows', 'Linux', or 'Darwin' (for Mac). |
56 | | - self.system = platform.system() |
57 | | - if not self.system in _MiniPathInitializer.PLATFORM_DICT: |
58 | | - raise RuntimeError('{0} is not a supported platform.'.format(self.system)) |
59 | | - else: |
60 | | - # path_var is the OS-dependent name of the path variable ('PATH', 'LD_LIBRARY_PATH', "DYLD_LIBRARY_PATH') |
61 | | - self.path_var = _MiniPathInitializer.PLATFORM_DICT[self.system] |
62 | | - |
63 | | - if self.system == 'Windows': |
64 | | - self.arch = 'win64' |
65 | | - elif self.system == 'Linux': |
66 | | - self.arch = 'glnxa64' |
67 | | - elif self.system == 'Darwin': |
68 | | - self.arch = 'maci64' |
69 | | - else: |
70 | | - raise RuntimeError('Operating system {0} is not supported.'.format(self.system)) |
71 | | - |
72 | | - def is_extern_bin_on_py_sys_path(self): |
73 | | - #Retrieve Python sys.path as a single string, and search for the substring "extern/bin/<arch>" (with |
74 | | - #the proper directory separator). If it's already present, assume it's the one we want. |
75 | | - substr_to_find = os.path.join('extern', 'bin', self.arch) |
76 | | - for item in sys.path: |
77 | | - if item.find(substr_to_find) != -1: |
78 | | - return True |
79 | | - return False |
80 | | - |
81 | | - def put_extern_bin_on_py_sys_path(self): |
82 | | - """ |
83 | | - Look through the system path for the first directory ending with "runtime/<arch>" or |
84 | | - "bin/<arch>" (with/without trailing slash). Use this to construct a new path ending |
85 | | - with "extern/bin/<arch>". |
86 | | - """ |
87 | | - |
88 | | - path_elements = [] |
89 | | - if self.path_var in os.environ: |
90 | | - path_elements_orig = os.environ[self.path_var] |
91 | | - # On Windows, some elements of the path may use forward slashes while others use backslashes. |
92 | | - # Make them all backslashes. |
93 | | - if self.system == 'Windows': |
94 | | - path_elements_orig = path_elements_orig.replace('/', '\\') |
95 | | - path_elements = path_elements_orig.split(os.pathsep) |
96 | | - if not path_elements: |
97 | | - if self.system == 'Darwin': |
98 | | - raise RuntimeError('On the Mac, you must run mwpython rather than python ' + |
99 | | - 'to start a session or script that imports your package. ' + |
100 | | - 'For more details, execute "mwpython -help" or see the package documentation.') |
101 | | - else: |
102 | | - raise RuntimeError('On {0}, you must set the environment variable "{1}" to a non-empty string. {2}'.format( |
103 | | - self.system, self.path_var, |
104 | | - 'For more details, see the package documentation.')) |
105 | | - |
106 | | - dir_to_search = os.path.join('runtime', self.arch) |
107 | | - trailing_substrings_to_find = [dir_to_search, dir_to_search + os.sep] |
108 | | - |
109 | | - dir_found = '' |
110 | | - for elem in path_elements: |
111 | | - for trailing_substring in trailing_substrings_to_find: |
112 | | - if elem.endswith(trailing_substring): |
113 | | - dir_found = elem |
114 | | - break |
115 | | - if dir_found: |
116 | | - break |
117 | | - |
118 | | - if not dir_found: |
119 | | - raise RuntimeError('Could not find an appropriate directory in {0} from which to read binaries.'.format( |
120 | | - self.path_var)) |
121 | | - |
122 | | - path_components = dir_found.split(os.sep) |
123 | | - |
124 | | - if path_components[-1]: |
125 | | - last_path_component = path_components[-1] |
126 | | - possible_extern = -3 |
127 | | - else: |
128 | | - # The directory name ended with a slash, so the last item in the list was an empty string. Go back one more. |
129 | | - last_path_component = path_components[-2] |
130 | | - possible_extern = -4 |
131 | | - |
132 | | - if last_path_component != self.arch: |
133 | | - output_str = ''.join(('To call deployed MATLAB code on a {0} machine, you must run a {0} version of Python, ', |
134 | | - 'and your {1} variable must contain an element pointing to "<MR>{2}runtime{2}{0}", ', |
135 | | - 'where "<MR>" indicates a MATLAB or MATLAB Runtime root. ', |
136 | | - 'Instead, the value found was as follows: {3}')) |
137 | | - raise RuntimeError(output_str.format(self.arch, self.path_var, os.sep, dir_found)) |
138 | | - |
139 | | - if (len(path_components) + possible_extern) >= 0 and path_components[possible_extern] == 'extern': |
140 | | - extern_bin_dir = dir_found |
141 | | - else: |
142 | | - mroot = os.path.dirname(os.path.dirname(os.path.normpath(dir_found))) |
143 | | - extern_bin_dir = os.path.join(mroot, 'extern', 'bin', self.arch) |
144 | | - if not os.path.isdir(extern_bin_dir): |
145 | | - raise RuntimeError('Could not find the directory {0}'.format(extern_bin_dir)) |
146 | | - self.extern_bin_dir = extern_bin_dir |
147 | | - sys.path.insert(0, self.extern_bin_dir) |
148 | | - |
149 | | -_mpi = _MiniPathInitializer() |
150 | | -if _mpi.use_mcpyarray: |
151 | | - _mpi.get_platform_info() |
152 | | - if not _mpi.is_extern_bin_on_py_sys_path(): |
153 | | - _mpi.put_extern_bin_on_py_sys_path() |
154 | | - from matlabmultidimarrayforpython import double, single, uint8, int8, uint16, \ |
155 | | - int16, uint32, int32, uint64, int64, logical, ShapeError, SizeError |
156 | | -else: |
157 | | - from mlarray import double, single, uint8, int8, uint16, \ |
158 | | - int16, uint32, int32, uint64, int64, logical |
159 | | - from mlexceptions import ShapeError as ShapeError |
160 | | - from mlexceptions import SizeError as SizeError |
| 24 | +from mlarray import double, single, uint8, int8, uint16, \ |
| 25 | + int16, uint32, int32, uint64, int64, logical |
| 26 | +from mlexceptions import ShapeError as ShapeError |
| 27 | +from mlexceptions import SizeError as SizeError |
0 commit comments