add padding function to imgScalePadding()
This commit is contained in:
@@ -1,190 +0,0 @@
|
||||
import importlib
|
||||
import importlib.util
|
||||
import inspect
|
||||
import os
|
||||
import sys
|
||||
import types
|
||||
|
||||
__all__ = ["attach", "_lazy_import"]
|
||||
|
||||
|
||||
def attach(module_name, submodules=None, submod_attrs=None):
|
||||
"""Attach lazily loaded submodules, and functions or other attributes.
|
||||
|
||||
Typically, modules import submodules and attributes as follows::
|
||||
|
||||
import mysubmodule
|
||||
import anothersubmodule
|
||||
|
||||
from .foo import someattr
|
||||
|
||||
The idea of this function is to replace the `__init__.py`
|
||||
module's `__getattr__`, `__dir__`, and `__all__` attributes such that
|
||||
all imports work exactly the way they normally would, except that the
|
||||
actual import is delayed until the resulting module object is first used.
|
||||
|
||||
The typical way to call this function, replacing the above imports, is::
|
||||
|
||||
__getattr__, __lazy_dir__, __all__ = lazy.attach(
|
||||
__name__,
|
||||
['mysubmodule', 'anothersubmodule'],
|
||||
{'foo': 'someattr'}
|
||||
)
|
||||
|
||||
This functionality requires Python 3.7 or higher.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
module_name : str
|
||||
Typically use __name__.
|
||||
submodules : set
|
||||
List of submodules to lazily import.
|
||||
submod_attrs : dict
|
||||
Dictionary of submodule -> list of attributes / functions.
|
||||
These attributes are imported as they are used.
|
||||
|
||||
Returns
|
||||
-------
|
||||
__getattr__, __dir__, __all__
|
||||
|
||||
"""
|
||||
if submod_attrs is None:
|
||||
submod_attrs = {}
|
||||
|
||||
if submodules is None:
|
||||
submodules = set()
|
||||
else:
|
||||
submodules = set(submodules)
|
||||
|
||||
attr_to_modules = {
|
||||
attr: mod for mod, attrs in submod_attrs.items() for attr in attrs
|
||||
}
|
||||
|
||||
__all__ = list(submodules | attr_to_modules.keys())
|
||||
|
||||
def __getattr__(name):
|
||||
if name in submodules:
|
||||
return importlib.import_module(f"{module_name}.{name}")
|
||||
elif name in attr_to_modules:
|
||||
submod = importlib.import_module(f"{module_name}.{attr_to_modules[name]}")
|
||||
return getattr(submod, name)
|
||||
else:
|
||||
raise AttributeError(f"No {module_name} attribute {name}")
|
||||
|
||||
def __dir__():
|
||||
return __all__
|
||||
|
||||
if os.environ.get("EAGER_IMPORT", ""):
|
||||
for attr in set(attr_to_modules.keys()) | submodules:
|
||||
__getattr__(attr)
|
||||
|
||||
return __getattr__, __dir__, list(__all__)
|
||||
|
||||
|
||||
class DelayedImportErrorModule(types.ModuleType):
|
||||
def __init__(self, frame_data, *args, **kwargs):
|
||||
self.__frame_data = frame_data
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __getattr__(self, x):
|
||||
if x in ("__class__", "__file__", "__frame_data"):
|
||||
super().__getattr__(x)
|
||||
else:
|
||||
fd = self.__frame_data
|
||||
raise ModuleNotFoundError(
|
||||
f"No module named '{fd['spec']}'\n\n"
|
||||
"This error is lazily reported, having originally occurred in\n"
|
||||
f' File {fd["filename"]}, line {fd["lineno"]}, in {fd["function"]}\n\n'
|
||||
f'----> {"".join(fd["code_context"]).strip()}'
|
||||
)
|
||||
|
||||
|
||||
def _lazy_import(fullname):
|
||||
"""Return a lazily imported proxy for a module or library.
|
||||
|
||||
Warning
|
||||
-------
|
||||
Importing using this function can currently cause trouble
|
||||
when the user tries to import from a subpackage of a module before
|
||||
the package is fully imported. In particular, this idiom may not work:
|
||||
|
||||
np = lazy_import("numpy")
|
||||
from numpy.lib import recfunctions
|
||||
|
||||
This is due to a difference in the way Python's LazyLoader handles
|
||||
subpackage imports compared to the normal import process. Hopefully
|
||||
we will get Python's LazyLoader to fix this, or find a workaround.
|
||||
In the meantime, this is a potential problem.
|
||||
|
||||
The workaround is to import numpy before importing from the subpackage.
|
||||
|
||||
Notes
|
||||
-----
|
||||
We often see the following pattern::
|
||||
|
||||
def myfunc():
|
||||
import scipy as sp
|
||||
sp.argmin(...)
|
||||
....
|
||||
|
||||
This is to prevent a library, in this case `scipy`, from being
|
||||
imported at function definition time, since that can be slow.
|
||||
|
||||
This function provides a proxy module that, upon access, imports
|
||||
the actual module. So the idiom equivalent to the above example is::
|
||||
|
||||
sp = lazy.load("scipy")
|
||||
|
||||
def myfunc():
|
||||
sp.argmin(...)
|
||||
....
|
||||
|
||||
The initial import time is fast because the actual import is delayed
|
||||
until the first attribute is requested. The overall import time may
|
||||
decrease as well for users that don't make use of large portions
|
||||
of the library.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fullname : str
|
||||
The full name of the package or subpackage to import. For example::
|
||||
|
||||
sp = lazy.load('scipy') # import scipy as sp
|
||||
spla = lazy.load('scipy.linalg') # import scipy.linalg as spla
|
||||
|
||||
Returns
|
||||
-------
|
||||
pm : importlib.util._LazyModule
|
||||
Proxy module. Can be used like any regularly imported module.
|
||||
Actual loading of the module occurs upon first attribute request.
|
||||
|
||||
"""
|
||||
try:
|
||||
return sys.modules[fullname]
|
||||
except:
|
||||
pass
|
||||
|
||||
# Not previously loaded -- look it up
|
||||
spec = importlib.util.find_spec(fullname)
|
||||
|
||||
if spec is None:
|
||||
try:
|
||||
parent = inspect.stack()[1]
|
||||
frame_data = {
|
||||
"spec": fullname,
|
||||
"filename": parent.filename,
|
||||
"lineno": parent.lineno,
|
||||
"function": parent.function,
|
||||
"code_context": parent.code_context,
|
||||
}
|
||||
return DelayedImportErrorModule(frame_data, "DelayedImportErrorModule")
|
||||
finally:
|
||||
del parent
|
||||
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
sys.modules[fullname] = module
|
||||
|
||||
loader = importlib.util.LazyLoader(spec.loader)
|
||||
loader.exec_module(module)
|
||||
|
||||
return module
|
||||
Reference in New Issue
Block a user