1# Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15 16"""A LazyLoader class.""" 17 18import importlib 19import types 20from tensorflow.python.platform import tf_logging as logging 21 22 23class LazyLoader(types.ModuleType): 24 """Lazily import a module, mainly to avoid pulling in large dependencies. 25 26 `contrib`, and `ffmpeg` are examples of modules that are large and not always 27 needed, and this allows them to only be loaded when they are used. 28 """ 29 30 # The lint error here is incorrect. 31 def __init__(self, local_name, parent_module_globals, name, warning=None): 32 self._local_name = local_name 33 self._parent_module_globals = parent_module_globals 34 self._warning = warning 35 36 super(LazyLoader, self).__init__(name) 37 38 def _load(self): 39 """Load the module and insert it into the parent's globals.""" 40 # Import the target module and insert it into the parent's namespace 41 module = importlib.import_module(self.__name__) 42 self._parent_module_globals[self._local_name] = module 43 44 # Emit a warning if one was specified 45 if self._warning: 46 logging.warning(self._warning) 47 # Make sure to only warn once. 48 self._warning = None 49 50 # Update this object's dict so that if someone keeps a reference to the 51 # LazyLoader, lookups are efficient (__getattr__ is only called on lookups 52 # that fail). 53 self.__dict__.update(module.__dict__) 54 55 return module 56 57 def __getattr__(self, item): 58 module = self._load() 59 return getattr(module, item) 60 61 def __dir__(self): 62 module = self._load() 63 return dir(module) 64