| | ''' |
| | OpenCV Python binary extension loader |
| | ''' |
| | import os |
| | import importlib |
| | import sys |
| |
|
| | __all__ = [] |
| |
|
| | try: |
| | import numpy |
| | import numpy.core.multiarray |
| | except ImportError: |
| | print('OpenCV bindings requires "numpy" package.') |
| | print('Install it via command:') |
| | print(' pip install numpy') |
| | raise |
| |
|
| | |
| | |
| |
|
| |
|
| | def __load_extra_py_code_for_module(base, name, enable_debug_print=False): |
| | module_name = "{}.{}".format(__name__, name) |
| | export_module_name = "{}.{}".format(base, name) |
| | native_module = sys.modules.pop(module_name, None) |
| | try: |
| | py_module = importlib.import_module(module_name) |
| | except ImportError as err: |
| | if enable_debug_print: |
| | print("Can't load Python code for module:", module_name, |
| | ". Reason:", err) |
| | |
| | return False |
| |
|
| | if base in sys.modules and not hasattr(sys.modules[base], name): |
| | setattr(sys.modules[base], name, py_module) |
| | sys.modules[export_module_name] = py_module |
| | |
| | if native_module: |
| | setattr(py_module, "_native", native_module) |
| | for k, v in filter(lambda kv: not hasattr(py_module, kv[0]), |
| | native_module.__dict__.items()): |
| | if enable_debug_print: print(' symbol({}): {} = {}'.format(name, k, v)) |
| | setattr(py_module, k, v) |
| | return True |
| |
|
| |
|
| | def __collect_extra_submodules(enable_debug_print=False): |
| | def modules_filter(module): |
| | return all(( |
| | |
| | not module.startswith("_"), |
| | not module.startswith("python-"), |
| | |
| | os.path.isdir(os.path.join(_extra_submodules_init_path, module)) |
| | )) |
| | if sys.version_info[0] < 3: |
| | if enable_debug_print: |
| | print("Extra submodules is loaded only for Python 3") |
| | return [] |
| |
|
| | __INIT_FILE_PATH = os.path.abspath(__file__) |
| | _extra_submodules_init_path = os.path.dirname(__INIT_FILE_PATH) |
| | return filter(modules_filter, os.listdir(_extra_submodules_init_path)) |
| |
|
| |
|
| | def bootstrap(): |
| | import sys |
| |
|
| | import copy |
| | save_sys_path = copy.copy(sys.path) |
| |
|
| | if hasattr(sys, 'OpenCV_LOADER'): |
| | print(sys.path) |
| | raise ImportError('ERROR: recursion is detected during loading of "cv2" binary extensions. Check OpenCV installation.') |
| | sys.OpenCV_LOADER = True |
| |
|
| | DEBUG = False |
| | if hasattr(sys, 'OpenCV_LOADER_DEBUG'): |
| | DEBUG = True |
| |
|
| | import platform |
| | if DEBUG: print('OpenCV loader: os.name="{}" platform.system()="{}"'.format(os.name, str(platform.system()))) |
| |
|
| | LOADER_DIR = os.path.dirname(os.path.abspath(os.path.realpath(__file__))) |
| |
|
| | PYTHON_EXTENSIONS_PATHS = [] |
| | BINARIES_PATHS = [] |
| |
|
| | g_vars = globals() |
| | l_vars = locals().copy() |
| |
|
| | if sys.version_info[:2] < (3, 0): |
| | from . load_config_py2 import exec_file_wrapper |
| | else: |
| | from . load_config_py3 import exec_file_wrapper |
| |
|
| | def load_first_config(fnames, required=True): |
| | for fname in fnames: |
| | fpath = os.path.join(LOADER_DIR, fname) |
| | if not os.path.exists(fpath): |
| | if DEBUG: print('OpenCV loader: config not found, skip: {}'.format(fpath)) |
| | continue |
| | if DEBUG: print('OpenCV loader: loading config: {}'.format(fpath)) |
| | exec_file_wrapper(fpath, g_vars, l_vars) |
| | return True |
| | if required: |
| | raise ImportError('OpenCV loader: missing configuration file: {}. Check OpenCV installation.'.format(fnames)) |
| |
|
| | load_first_config(['config.py'], True) |
| | load_first_config([ |
| | 'config-{}.{}.py'.format(sys.version_info[0], sys.version_info[1]), |
| | 'config-{}.py'.format(sys.version_info[0]) |
| | ], True) |
| |
|
| | if DEBUG: print('OpenCV loader: PYTHON_EXTENSIONS_PATHS={}'.format(str(l_vars['PYTHON_EXTENSIONS_PATHS']))) |
| | if DEBUG: print('OpenCV loader: BINARIES_PATHS={}'.format(str(l_vars['BINARIES_PATHS']))) |
| |
|
| | applySysPathWorkaround = False |
| | if hasattr(sys, 'OpenCV_REPLACE_SYS_PATH_0'): |
| | applySysPathWorkaround = True |
| | else: |
| | try: |
| | BASE_DIR = os.path.dirname(LOADER_DIR) |
| | if sys.path[0] == BASE_DIR or os.path.realpath(sys.path[0]) == BASE_DIR: |
| | applySysPathWorkaround = True |
| | except: |
| | if DEBUG: print('OpenCV loader: exception during checking workaround for sys.path[0]') |
| | pass |
| |
|
| | for p in reversed(l_vars['PYTHON_EXTENSIONS_PATHS']): |
| | sys.path.insert(1 if not applySysPathWorkaround else 0, p) |
| |
|
| | if os.name == 'nt': |
| | if sys.version_info[:2] >= (3, 8): |
| | for p in l_vars['BINARIES_PATHS']: |
| | try: |
| | os.add_dll_directory(p) |
| | except Exception as e: |
| | if DEBUG: print('Failed os.add_dll_directory(): '+ str(e)) |
| | pass |
| | os.environ['PATH'] = ';'.join(l_vars['BINARIES_PATHS']) + ';' + os.environ.get('PATH', '') |
| | if DEBUG: print('OpenCV loader: PATH={}'.format(str(os.environ['PATH']))) |
| | else: |
| | |
| | os.environ['LD_LIBRARY_PATH'] = ':'.join(l_vars['BINARIES_PATHS']) + ':' + os.environ.get('LD_LIBRARY_PATH', '') |
| |
|
| | if DEBUG: print("Relink everything from native cv2 module to cv2 package") |
| |
|
| | py_module = sys.modules.pop("cv2") |
| |
|
| | native_module = importlib.import_module("cv2") |
| |
|
| | sys.modules["cv2"] = py_module |
| | setattr(py_module, "_native", native_module) |
| |
|
| | for item_name, item in filter(lambda kv: kv[0] not in ("__file__", "__loader__", "__spec__", |
| | "__name__", "__package__"), |
| | native_module.__dict__.items()): |
| | if item_name not in g_vars: |
| | g_vars[item_name] = item |
| |
|
| | sys.path = save_sys_path |
| |
|
| | try: |
| | del sys.OpenCV_LOADER |
| | except Exception as e: |
| | if DEBUG: |
| | print("Exception during delete OpenCV_LOADER:", e) |
| |
|
| | if DEBUG: print('OpenCV loader: binary extension... OK') |
| |
|
| | for submodule in __collect_extra_submodules(DEBUG): |
| | if __load_extra_py_code_for_module("cv2", submodule, DEBUG): |
| | if DEBUG: print("Extra Python code for", submodule, "is loaded") |
| |
|
| | if DEBUG: print('OpenCV loader: DONE') |
| |
|
| |
|
| | bootstrap() |
| |
|