Home | History | Annotate | Download | only in util
      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 
     18 from __future__ import absolute_import
     19 from __future__ import division
     20 from __future__ import print_function
     21 
     22 import importlib
     23 import types
     24 
     25 
     26 class LazyLoader(types.ModuleType):
     27   """Lazily import a module, mainly to avoid pulling in large dependencies.
     28 
     29   `contrib`, and `ffmpeg` are examples of modules that are large and not always
     30   needed, and this allows them to only be loaded when they are used.
     31   """
     32 
     33   # The lint error here is incorrect.
     34   def __init__(self, local_name, parent_module_globals, name):  # pylint: disable=super-on-old-class
     35     self._local_name = local_name
     36     self._parent_module_globals = parent_module_globals
     37 
     38     super(LazyLoader, self).__init__(name)
     39 
     40   def _load(self):
     41     # Import the target module and insert it into the parent's namespace
     42     module = importlib.import_module(self.__name__)
     43     self._parent_module_globals[self._local_name] = module
     44 
     45     # Update this object's dict so that if someone keeps a reference to the
     46     #   LazyLoader, lookups are efficient (__getattr__ is only called on lookups
     47     #   that fail).
     48     self.__dict__.update(module.__dict__)
     49 
     50     return module
     51 
     52   def __getattr__(self, item):
     53     module = self._load()
     54     return getattr(module, item)
     55 
     56   def __dir__(self):
     57     module = self._load()
     58     return dir(module)
     59