cloud-init/cloudinit/plugin_finder.py

55 lines
1.5 KiB
Python

# Copyright 2015 Canonical Ltd.
# This file is part of cloud-init. See LICENCE file for license information.
#
# vi: ts=4 expandtab
"""Various base classes and implementations for finding *plugins*."""
import abc
import pkgutil
import six
from cloudinit import logging
LOG = logging.getLogger(__name__)
@six.add_metaclass(abc.ABCMeta)
class BaseModuleIterator(object):
"""Base class for describing a *module iterator*
A module iterator is a class that's capable of listing
modules or packages from a specific location, which are
already loaded.
"""
def __init__(self, search_paths):
self._search_paths = search_paths
@abc.abstractmethod
def list_modules(self):
"""List all the modules that this finder knows about."""
class PkgutilModuleIterator(BaseModuleIterator):
"""A class based on the *pkgutil* module for discovering modules."""
@staticmethod
def _find_module(finder, module):
"""Delegate to the *finder* for finding the given module."""
return finder.find_module(module).load_module(module)
def list_modules(self):
"""List all modules that this class knows about."""
for finder, name, _ in pkgutil.walk_packages(self._search_paths):
try:
module = self._find_module(finder, name)
except ImportError:
LOG.debug('Could not import the module %r using the '
'search path %r', name, finder.path)
continue
yield module