Make non-import packages lazy

6659902a73 caused a lot of importing a
lot of things in __init__ which makes loading anything, say session,
really slow. The load time for keystoneclient is really critical since
every client uses it. And having a CLI take several seconds to do
nothing is really bad user experience.

This drops the hot cache import time of keystoneclient.session down to
160ms which is about 60ms faster (down from 220ms without this patch)
for me.

Change-Id: I917503ae54c9abcff417f0a0368abb765a847b6e
Partial-Bug: #1431649
Co-Authored-By: Robert Collins <rbtcollins@hp.com>
This commit is contained in:
Joe Gordon
2015-03-12 20:43:36 -07:00
committed by Brant Knudson
parent c30cf7807c
commit c0145e5fe1

View File

@@ -27,18 +27,10 @@ Identity V2 and V3 clients can also be created directly. See
"""
import sys
import pbr.version
from keystoneclient import access
from keystoneclient import client
from keystoneclient import exceptions
from keystoneclient import generic
from keystoneclient import httpclient
from keystoneclient import service_catalog
from keystoneclient import v2_0
from keystoneclient import v3
__version__ = pbr.version.VersionInfo('python-keystoneclient').version_string()
@@ -55,3 +47,32 @@ __all__ = [
'httpclient',
'service_catalog',
]
class _LazyImporter(object):
def __init__(self, module):
self._module = module
def __getattr__(self, name):
# NB: this is only called until the import has been done.
# These submodules are part of the API without explicit importing, but
# expensive to load, so we load them on-demand rather than up-front.
lazy_submodules = [
'access',
'client',
'exceptions',
'generic',
'httpclient',
'service_catalog',
'v2_0',
'v3',
]
# __import__ rather than importlib for Python 2.6.
if name in lazy_submodules:
__import__('keystoneclient.%s' % name)
return getattr(self, name)
# Return module attributes like __all__ etc.
return getattr(self._module, name)
sys.modules[__name__] = _LazyImporter(sys.modules[__name__])