@requireModules¶
Gracefully handle optional dependencies with automatic fallback behavior.
xpytools.xdeco.requireModules.requireModules
¶
Python
requireModules(modules: Iterable[str], *, exc_raise: bool = False, return_none: bool = True) -> Callable[[T], T]
Decorator to ensure one or more modules are available before running a function.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
Iterable[str]
|
List of module names to xcheck (e.g., ["pandas", "numpy"]). |
required |
|
bool
|
Raise ImportError if one or more modules are missing. |
False
|
|
bool
|
If True and missing modules exist, return None instead of running the function. |
True
|
Returns:
| Type | Description |
|---|---|
Decorated function that gracefully bypasses or raises on missing dependencies.
|
|
Examples:
Python Console Session
>>> @requireModules(["pandas"])
... def df_summary(df):
... import pandas as pd
... return df.describe()
...
>>> df_summary(None) # if pandas missing -> returns None, no crash
Source code in xpytools/xdeco/requireModules.py
Python
def requireModules(
modules: Iterable[str],
*,
exc_raise: bool = False,
return_none: bool = True,
) -> Callable[[T], T]:
"""
Decorator to ensure one or more modules are available before running a function.
Parameters
----------
modules : Iterable[str]
List of module names to xcheck (e.g., ["pandas", "numpy"]).
exc_raise : bool, default=False
Raise ImportError if one or more modules are missing.
return_none : bool, default=True
If True and missing modules exist, return None instead of running the function.
Returns
-------
Decorated function that gracefully bypasses or raises on missing dependencies.
Examples
--------
>>> @requireModules(["pandas"])
... def df_summary(df):
... import pandas as pd
... return df.describe()
...
>>> df_summary(None) # if pandas missing -> returns None, no crash
"""
missing: list[str] = [
mod for mod in modules if find_spec(mod) is None
]
def decorator(func: T) -> T:
@wraps(func)
def wrapper(*args, **kwargs):
if missing:
msg = (
f"Missing required module(s): {', '.join(missing)} "
f"for function '{func.__name__}'."
)
if exc_raise:
raise ImportError(msg)
if return_none:
return None
# If not returning None, fallback to no-op
return
return func(*args, **kwargs)
return cast(T, wrapper)
return decorator