diff --git a/kwant/_common.py b/kwant/_common.py index 76e952cf6c0d2ffc437d42ca5c093a5825aac0e9..48c45eaac9cb1e4ed4a2971c3bd58e0cebcb1c43 100644 --- a/kwant/_common.py +++ b/kwant/_common.py @@ -6,10 +6,12 @@ # the file AUTHORS.rst at the top-level directory of this distribution and at # http://kwant-project.org/authors. +import sys import numpy as np import numbers import inspect import warnings +import importlib from contextlib import contextmanager __all__ = ['KwantDeprecationWarning', 'UserCodeError'] @@ -123,3 +125,26 @@ def get_parameters(func): takes_kwargs = any(i.kind is inspect.Parameter.VAR_KEYWORD for i in pars.values()) return required_params, default_params, takes_kwargs + + +class lazy_import: + def __init__(self, module, package='kwant', deprecation_warning=False): + if module.startswith('.') and not package: + raise ValueError('Cannot import a relative module without a package.') + self.__module = module + self.__package = package + self.__deprecation_warning = deprecation_warning + + def __getattr__(self, name): + if self.__deprecation_warning: + absolute_module = '.'.join((self.__package, self.__module)) + msg = ("Accessing {0} without an explicit import is deprecated. " + "Instead, explicitly 'import {0}'." + ).format('.'.join((self.__package, self.__module))) + warnings.warn(msg, KwantDeprecationWarning, stacklevel=2) + relative_module = '.' + self.__module + mod = importlib.import_module(relative_module, self.__package) + # Replace this _LazyModuleProxy with an actual module + package = sys.modules[self.__package] + setattr(package, self.__module, mod) + return getattr(mod, name)