from typing import List, Callable
import importlib
import warnings
_MESSAGE_TEMPLATE = r"Usage of '{old_location}' is deprecated; please use '{new_location}' instead."
def lazy_deprecated_import(all: List[str], old_module: str, new_module: str) -> Callable:
r"""Import utility to lazily import deprecated packages / modules / functional.
The old_module and new_module are also used in the deprecation warning defined
by the `_MESSAGE_TEMPLATE`.
Args:
all: The list of the functions that are imported. Generally, the module's
__all__ list of the module.
old_module: Old module location
new_module: New module location / Migrated location
Returns:
Callable to asign to the `__getattr__`
Usage:
# In the `torch/nn/quantized/functional.py`
from torch.nn.utils._deprecation_utils import lazy_deprecated_import
_MIGRATED_TO = "torch.ao.nn.quantized.functional"
__getattr__ = lazy_deprecated_import(
all=__all__,
old_module=__name__,
new_module=_MIGRATED_TO)
"""
warning_message = _MESSAGE_TEMPLATE.format(
old_location=old_module,
new_location=new_module)
def getattr_dunder(name):
if name in all:
# We are using the "RuntimeWarning" to make sure it is not
# ignored by default.
warnings.warn(warning_message, RuntimeWarning)
package = importlib.import_module(new_module)
return getattr(package, name)
raise AttributeError(f"Module {new_module!r} has no attribute {name!r}.")
return getattr_dunder