← Back to team overview

openstack team mailing list archive

Lazy import of modules


I've heard people complain that we have lots of ways of doing lazy import of modules (i.e. loading them on demand, so that you don't need the dependency unless you're actually using the functionality) and that we should standardize on one.

So, which one should we standardize on?

To kick the conversation off, I don't like the way that nova.utils.{import_object,import_class} work today, having recently chased down a problem that was completely hidden by them.  I had an object A that was lazy-loaded using import_object, and A in turn imported B, which was missing.  import_object caught the ImportError for B, decided that it meant that A wasn't present, attempted to import it using import_class, and that failed too, and then it eventually got logged as 'Class A cannot be found'.  This was wrong firstly because A was not missing, and secondly because A wasn't a class, and thirdly because the code didn't ask to import it as a class!  There was no indication that B was missing.

This took me a long time to unpick, so if we're going to standardize around nova.utils.import_x, then we need to figure out a better way for them to work.



def import_class(import_str):
    """Returns a class from a string including module and class"""
    mod_str, _sep, class_str = import_str.rpartition('.')
        return getattr(sys.modules[mod_str], class_str)
    except (ImportError, ValueError, AttributeError), exc:
        logging.debug(_('Inner Exception: %s'), exc)
        raise exception.NotFound(_('Class %s cannot be found') % class_str)

def import_object(import_str):
    """Returns an object including a module or module and class"""
        return sys.modules[import_str]
    except ImportError:
        cls = import_class(import_str)
        return cls()