Files

146 lines
5.8 KiB
Python
Raw Permalink Normal View History

# -*- coding: utf-8 -*-
# Copyright (C) 2018-2025 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
import os
import sys
from functools import wraps
from typing import Any, Optional
from pathlib import Path
import importlib.util
from types import ModuleType
from collections.abc import Callable
def _add_openvino_libs_to_search_path() -> None:
"""Add OpenVINO libraries to the DLL search path on Windows."""
if sys.platform == "win32":
# Installer, yum, pip installs openvino dlls to the different directories
# and those paths need to be visible to the openvino modules
#
# If you're using a custom installation of openvino,
# add the location of openvino dlls to your system PATH.
openvino_libs = []
if os.path.isdir(os.path.join(os.path.dirname(__file__), "libs")):
# looking for the libs in the pip installation path.
openvino_libs.append(os.path.join(os.path.dirname(__file__), "libs"))
elif os.path.isdir(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, "Library", "bin")):
# looking for the libs in the conda installation path
openvino_libs.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, "Library", "bin"))
else:
# setupvars.bat script set all libs paths to OPENVINO_LIB_PATHS environment variable.
openvino_libs_installer = os.getenv("OPENVINO_LIB_PATHS")
if openvino_libs_installer:
openvino_libs.extend(openvino_libs_installer.split(";"))
else:
sys.exit("Error: Please set the OPENVINO_LIB_PATHS environment variable. "
"If you use an install package, please, run setupvars.bat")
for lib in openvino_libs:
lib_path = os.path.join(os.path.dirname(__file__), lib)
if os.path.isdir(lib_path):
# On Windows, with Python >= 3.8, DLLs are no longer imported from the PATH.
os.add_dll_directory(os.path.abspath(lib_path))
def get_cmake_path() -> str:
"""Searches for the directory containing CMake files within the package install directory.
:return: The path to the directory containing CMake files, if found. Otherwise, returns empty string.
:rtype: str
"""
package_path = Path(__file__).parent
cmake_file = "OpenVINOConfig.cmake"
for dirpath, _, filenames in os.walk(package_path):
if cmake_file in filenames:
return dirpath
return ""
def deprecated(name: Any = None, version: str = "", message: str = "", stacklevel: int = 2) -> Callable[..., Any]:
"""Prints deprecation warning "{function_name} is deprecated and will be removed in version {version}. {message}" and runs the function.
:param version: The version in which the code will be removed.
:param message: A message explaining why the function is deprecated and/or what to use instead.
"""
def decorator(wrapped: Callable[..., Any]) -> Callable[..., Any]:
@wraps(wrapped)
def wrapper(*args: Any, **kwargs: Any) -> Callable[..., Any]:
# it must be imported here; otherwise, there are errors with no loaded DLL for Windows
from openvino._pyopenvino.util import deprecation_warning
deprecation_warning(wrapped.__name__ if name is None else name, version, message, stacklevel)
return wrapped(*args, **kwargs)
return wrapper
return decorator
# WA method since Python 3.11 does not support @classmethod and @property chain,
# currently only read-only properties are supported.
class _ClassPropertyDescriptor(object):
def __init__(self, fget: Callable):
self.fget = fget
def __get__(self, obj: Any, cls: Any = None) -> Any:
if cls is None:
cls = type(obj)
return self.fget.__get__(obj, cls)()
def classproperty(func: Any) -> _ClassPropertyDescriptor:
if not isinstance(func, (classmethod, staticmethod)):
func = classmethod(func)
return _ClassPropertyDescriptor(func) # type: ignore
def deprecatedclassproperty(name: Any = None, version: str = "", message: str = "", stacklevel: int = 2) -> Callable[[Any], _ClassPropertyDescriptor]:
def decorator(wrapped: Any) -> _ClassPropertyDescriptor:
func = classproperty(wrapped)
# Override specific instance
def _patch(instance: _ClassPropertyDescriptor, func: Callable[..., Any]) -> None:
cls_: Any = type(instance)
class _(cls_): # noqa: N801
@func
def __get__(self, obj: Any, cls: Any = None) -> Any:
return super().__get__(obj, cls)
instance.__class__ = _
# Add `deprecated` decorator on the top of `__get__`
_patch(func, deprecated(name, version, message, stacklevel))
return func
return decorator
class LazyLoader:
"""A class to lazily load a module, importing it only when an attribute is accessed."""
def __init__(self, module_name: str):
self.module_name = module_name
self._module: Optional[ModuleType] = None
def _load_module(self) -> None:
if self._module is None:
# Import the module and update sys.modules with the loaded module
self._module = importlib.import_module(self.module_name)
# Update the LazyLoader instance's __dict__ with the module's __dict__
# This ensures that subsequent attribute accesses use the module's attributes directly (by __getattribute__() )
self.__dict__.update(self._module.__dict__)
def __getattr__(self, item: str) -> Any:
self._load_module()
return getattr(self._module, item)
def __dir__(self) -> list:
self._load_module()
return dir(self._module)
def __repr__(self) -> str:
return f"<LazyLoader for module '{self.module_name}'>"