libcloud-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ian Bicking <ianbick...@gmail.com>
Subject Re: [libcloud] Proposal: remove zope interfaces from libcloud.
Date Tue, 15 Dec 2009 21:41:04 GMT
On Tue, Dec 15, 2009 at 3:11 PM, Tom Davis <tom@dislocatedday.com> wrote:
> documenting libcloud with sphinx isn't so automatic when interfaces are
>> being used
>
>
> A trivial fix; a Sphinx extension for documenting interfaces already exists.
>  See: this ticket<http://bitbucket.org/birkenfeld/sphinx/issue/85/minimal-support-for-zopeinterface>(specifically
> the finished extension:
> autointerface_.py <http://bitbucket.org/m//attch/2009/02/autointerface_.py>)
>
> I can't argue that now isn't a good time, but I still feel they are (and can
> be made more) useful. For one, they can assist in getting rid of the *
> providers.py* file entirely. A simple metaclass which functions as a mount
> coupled with interface verification (we don't want to provide a driver that
> doesn't yet implement the API) fixes the need for manually listing /
> commenting drivers, not to mention the ugly static paths / names that are
> going on there.

This seems like it can be resolved anyway, and interfaces don't seem
like a particularly easy easy way to solve the problem.

First, you could just import the drivers directly instead of the
get_driver indirection.  The only thing get_driver gives you is the
ability to lazy-load something based on fixed symbols.

Second, you could have a simple reflection API, like:

def drivers():
    """Returns a list of drivers (by name)"""
    return [
        os.path.splitext(name)[0]
        for name in os.listdir(os.path.join(os.path.dirname(__file__),
'drivers')))
        if name.endswith('.py') and name != '__init__.py']

def load_driver(name):
    mod_name = 'libcloud.drivers.%s'
    __import__(mod_name)
    mod = sys.modules[mod_name]
    return getattr(mod, name.capitalize()+'Connection')

This is easier to use than the current setup, and less code to boot.

> Basically, two pretty simple things need to happen to introduce some more
> usefulness to the interfaces (besides their documentation pluses):
>
>   - Use verify module as part of the testing process
>   - Get rid of the NotImplementedError methods from the base NodeDriver as
>   this is effectively a competing method of doing the same thing (though one
>   could argue with added ambiguity: "why do I need to implement this?")
>
> Obviously I am biased for a couple reasons. One, because I almost always
> have Twisted available and it handles the interface dependency. And two,
> because I wrote the interface implementation. Run-time loading of "plugins"
> along with interface validation is a strategy I'm rather fond of. Not only
> does it remove the need to maintain a hard-coded list of available modules,
> it eases implementation. Whenever I happen to forget what a method or
> attribute is supposed to represent I just consult the interface.

A good abstract base class solves this, I think.  API verification
doesn't seem like a big win, as that's the most trivial of bugs
(simply forgetting to implement something), and all the important bugs
are when implementations are wrong, not missing.  If there are
easy-to-miss corners of the API, you can still write tests using
hasattr, like:

for method in ['host', 'request', ...]:
    assert hasattr(driver, method) and getattr(driver, method) is not
getattr(ConnectionUserAndKey, method)

-- 
Ian Bicking  |  http://blog.ianbicking.org  |  http://topplabs.org/civichacker

Mime
View raw message