|
|
|
import importlib.util
|
|
|
|
import platform
|
|
|
|
import warnings
|
|
|
|
from functools import wraps
|
|
|
|
from typing import Optional
|
|
|
|
|
|
|
|
#code is from https://github.com/pytorch/audio/blob/main/torchaudio/_internal/module_utils.py with modification.
|
|
|
|
|
|
|
|
|
|
|
|
def is_module_available(*modules: str) -> bool:
|
|
|
|
r"""Returns if a top-level module with :attr:`name` exists *without**
|
|
|
|
importing it. This is generally safer than try-catch block around a
|
|
|
|
`import X`. It avoids third party libraries breaking assumptions of some of
|
|
|
|
our tests, e.g., setting multiprocessing start method when imported
|
|
|
|
(see librosa/#747, torchvision/#544).
|
|
|
|
"""
|
|
|
|
return all(importlib.util.find_spec(m) is not None for m in modules)
|
|
|
|
|
|
|
|
|
|
|
|
def requires_module(*modules: str):
|
|
|
|
"""Decorate function to give error message if invoked without required optional modules.
|
|
|
|
This decorator is to give better error message to users rather
|
|
|
|
than raising ``NameError: name 'module' is not defined`` at random places.
|
|
|
|
"""
|
|
|
|
missing = [m for m in modules if not is_module_available(m)]
|
|
|
|
|
|
|
|
if not missing:
|
|
|
|
# fall through. If all the modules are available, no need to decorate
|
|
|
|
def decorator(func):
|
|
|
|
return func
|
|
|
|
|
|
|
|
else:
|
|
|
|
req = f"module: {missing[0]}" if len(
|
|
|
|
missing) == 1 else f"modules: {missing}"
|
|
|
|
|
|
|
|
def decorator(func):
|
|
|
|
@wraps(func)
|
|
|
|
def wrapped(*args, **kwargs):
|
|
|
|
raise RuntimeError(
|
|
|
|
f"{func.__module__}.{func.__name__} requires {req}")
|
|
|
|
|
|
|
|
return wrapped
|
|
|
|
|
|
|
|
return decorator
|
|
|
|
|
|
|
|
|
|
|
|
def deprecated(direction: str, version: Optional[str]=None):
|
|
|
|
"""Decorator to add deprecation message
|
|
|
|
Args:
|
|
|
|
direction (str): Migration steps to be given to users.
|
|
|
|
version (str or int): The version when the object will be removed
|
|
|
|
"""
|
|
|
|
|
|
|
|
def decorator(func):
|
|
|
|
@wraps(func)
|
|
|
|
def wrapped(*args, **kwargs):
|
|
|
|
message = (
|
|
|
|
f"{func.__module__}.{func.__name__} has been deprecated "
|
|
|
|
f'and will be removed from {"future" if version is None else version} release. '
|
|
|
|
f"{direction}")
|
|
|
|
warnings.warn(message, stacklevel=2)
|
|
|
|
return func(*args, **kwargs)
|
|
|
|
|
|
|
|
return wrapped
|
|
|
|
|
|
|
|
return decorator
|
|
|
|
|
|
|
|
|
|
|
|
def is_kaldi_available():
|
|
|
|
try:
|
|
|
|
from paddleaudio import _paddleaudio
|
|
|
|
return True
|
|
|
|
except Exception:
|
|
|
|
return False
|
|
|
|
|
|
|
|
def requires_kaldi():
|
|
|
|
if is_kaldi_available():
|
|
|
|
|
|
|
|
def decorator(func):
|
|
|
|
return func
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
def decorator(func):
|
|
|
|
@wraps(func)
|
|
|
|
def wrapped(*args, **kwargs):
|
|
|
|
raise RuntimeError(
|
|
|
|
f"{func.__module__}.{func.__name__} requires libpaddleaudio build with kaldi")
|
|
|
|
|
|
|
|
return wrapped
|
|
|
|
|
|
|
|
return decorator
|
|
|
|
|
|
|
|
|
|
|
|
def _check_soundfile_importable():
|
|
|
|
if not is_module_available("soundfile"):
|
|
|
|
return False
|
|
|
|
try:
|
|
|
|
import soundfile # noqa: F401
|
|
|
|
|
|
|
|
return True
|
|
|
|
except Exception:
|
|
|
|
warnings.warn(
|
|
|
|
"Failed to import soundfile. 'soundfile' backend is not available.")
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
_is_soundfile_importable = _check_soundfile_importable()
|
|
|
|
|
|
|
|
|
|
|
|
def is_soundfile_available():
|
|
|
|
return _is_soundfile_importable
|
|
|
|
|
|
|
|
|
|
|
|
def requires_soundfile():
|
|
|
|
if is_soundfile_available():
|
|
|
|
|
|
|
|
def decorator(func):
|
|
|
|
return func
|
|
|
|
else:
|
|
|
|
|
|
|
|
def decorator(func):
|
|
|
|
@wraps(func)
|
|
|
|
def wrapped(*args, **kwargs):
|
|
|
|
raise RuntimeError(
|
|
|
|
f"{func.__module__}.{func.__name__} requires soundfile")
|
|
|
|
|
|
|
|
return wrapped
|
|
|
|
|
|
|
|
return decorator
|
|
|
|
|
|
|
|
|
|
|
|
def is_sox_available():
|
|
|
|
try:
|
|
|
|
from paddleaudio import _paddleaudio
|
|
|
|
return True
|
|
|
|
except Exception:
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def requires_sox():
|
|
|
|
if is_sox_available():
|
|
|
|
|
|
|
|
def decorator(func):
|
|
|
|
return func
|
|
|
|
else:
|
|
|
|
|
|
|
|
def decorator(func):
|
|
|
|
@wraps(func)
|
|
|
|
def wrapped(*args, **kwargs):
|
|
|
|
raise RuntimeError(
|
|
|
|
f"{func.__module__}.{func.__name__} requires libpaddleaudio build with sox")
|
|
|
|
|
|
|
|
return wrapped
|
|
|
|
|
|
|
|
return decorator
|