plugins.py 1.94 KB
Newer Older
xuebingbing's avatar
xuebingbing committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
"""Simple plug-in mechanism to provide replacement for setuptools plugins"""

class Plugin( object ):
    """Base class for plugins to be loaded"""
    loaded = False
    def __init__( self, name, import_path, check = None ):
        """Register the plug-in"""
        self.name = name 
        self.import_path = import_path
        self.check = check
        self.registry.append( self )
    def load( self ):
        """Attempt to load and return our entry point"""
        return importByName( self.import_path )
    @classmethod
    def match( cls, *args ):
        """Match to return the plugin which is appropriate to load"""
    @classmethod
    def all( cls ):
        """Iterate over all registered plugins"""
        return cls.registry[:]
    
def importByName( fullName ):
    """Import a class by name"""
    name = fullName.split(".")
    moduleName = name[:-1]
    className = name[-1]
    module = __import__( ".".join(moduleName), {}, {}, moduleName)
    return getattr( module, className )

        
class PlatformPlugin( Plugin ):
    """Platform-level plugin registration"""
    registry = []
    @classmethod
    def match( cls, key ):
        """Determine what platform module to load
        
        key -- (sys.platform,os.name) key to load 
        """
        for possible in key:
            # prefer sys.platform, *then* os.name
            for plugin in cls.registry:
                if plugin.name == possible:
                    return plugin
        raise KeyError( """No platform plugin registered for %s"""%(key,))

class FormatHandler( Plugin ):
    """Data-type storage-format handler"""
    registry = []
    @classmethod
    def match( cls, value ):
        """Lookup appropriate handler based on value (a type)"""
        key = '%s.%s'%( value.__module__, value.__name__ )
        for plugin in cls.registry:
            set = getattr( plugin, 'check', ())
            if set and key in set:
                return plugin
        return None