-
Notifications
You must be signed in to change notification settings - Fork 1.9k
PluginAPI
A number of warts have developed on the plugin API.
Stop using a namespace package for plugins. This is causing headaches because [pip-installed packages have problems with namespace packages][pipbug]. [Flask has moved away from a flaskext package][flaskfix], so it might be wise to use Armin's example there. Plugins should be called beets_X
or, for plugins distributed as part of beets, beets.plugin.X
.
__import__('beets.plug.{}'.format(...)) # built-in
modname = 'beets_{}'.format(...)
import imp
imp.find_module(modname, pluginpaths) # on path
imp.find_module(modname) # installed in Python tree
Use instances instead of classes. It's very confusing that so many aspects of plugins happen at the level of the class itself. It would be much more natural for plugins to be treated as singletons, using self
to store data. Use Trac's trick to force singleton usage -- __init__
called twice returns an existing instance.
class BeetsPlugin(object):
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = type.__new__(cls)
return _instance
plugin_classes = []
...
for obj in mod.__dict__.values():
if BeetsPlugin in obj.__mro__:
plugin_classes.append(obj)
plugin_instances = [cls() for cls in plugin_classes]
Now we can abandon decorators for events and the like. Everything should be an ordinary method on the plugin class. And stuff like commands()
should not be a method; it should be a field on the object.
... still not sure about stuff like item_fields
and template_funcs
. Decorators seem alright for them, and assigning to self.* is somewhat cumbersome... all of that would have to go in __init__
?
At the same time, I would like to move away from optparse
. In particular, Argh is a really clean-looking wrapper for the newer argparse
. To use it, however, we'll need to do something horrible to monkey-patch 2.7's argparse to support aliases. I wrote the patch that adds alias support in 3.2, but it is not backported to 2.7: http://hg.python.org/cpython/rev/4c0426261148/