Source code for shapiq.utils.modules
"""Utility functions for checking module imports and class instances."""
from __future__ import annotations
import sys
from importlib import import_module
[docs]
def safe_isinstance(
obj: object,
class_path_str: str | list[str] | tuple[str],
) -> bool:
"""Safely checks if an object is an instance of a class.
Acts as a safe version of isinstance without having to explicitly import packages which may
not exist in the user's environment. Checks if obj is an instance of type specified by
class_path_str.
Note:
This function was directly taken from the `shap` repository.
Args:
obj: Some object you want to test against
class_path_str: A string or list of strings specifying full class paths Example:
`sklearn.ensemble.RandomForestRegressor`
Returns:
True if isinstance is true and the package exists, False otherwise
"""
if isinstance(class_path_str, str):
class_path_strs = [class_path_str]
elif isinstance(class_path_str, list | tuple):
class_path_strs = list(class_path_str)
else:
class_path_strs = [""]
# try each module path in order
for _class_path_str in class_path_strs:
if "." not in _class_path_str:
msg = "class_path_str must be a string or list of strings specifying a full \
module path to a class. Eg, 'sklearn.ensemble.RandomForestRegressor'"
raise ValueError(msg)
# Splits on last occurrence of "."
module_name, class_name = _class_path_str.rsplit(".", 1)
# here we don't check further if the model is not imported, since we shouldn't have
# an object of that types passed to us if the model the type is from has never been
# imported. (and we don't want to import lots of new modules for no reason)
if module_name not in sys.modules:
continue
module = sys.modules[module_name]
# Get class
_class = getattr(module, class_name, None)
if _class is None:
continue
if isinstance(obj, _class):
return True
return False
[docs]
def check_import_module(name: str, functionality: str | None = None) -> None:
"""Check if the optional dependency is available."""
try:
import_module(name)
except ImportError as error:
message = f"Missing optional dependency '{name}'. Install '{name}'"
if functionality:
message += f" for {functionality}"
message += f". Use pip or conda to install '{name}'."
raise ImportError(message) from error