On 01/08/2010 21:37, Tarek Ziadé wrote:
Here's a proposal to extend PEP 376 to support a basic plugins feature -- you should read PEP 376 before reading this mail
It's basically Phillip's entry points, but with an activation flag, and a per-user config file.
= adding a PLUGINS file =
A new file called 'PLUGINS' is added to the dist-info directory at install time, and contains a list of plugins for the installed distribution.
The file is a CSV file like the RECORD file, containing one plugin per line. (see the RECORD file for details on the syntax)
A plugin is defined by :
- an application name : a string containing a name of a group of
plugins. It can be the name of the application that supports plugins, or any string. The recommended value is the distutils name of the project, as it appears at PyPI. max length: 64, chars: [a-z0-9]
- a plugin type name: a string containing a name of a type of plugins.
It can be combined with the application name to create one class of plugins for a given application. 64 chars [a-z0-9] -- default value 'plugin'
- a name: a string containing a name for the plugin. Combined with the
application name and plugin type, it defines this plugin. 64 chars [a-z0-9]
a description: a string describing the plugin. 256 chars.
a state: 1 or 0. 1 means the plugin is activated, 0 means it's not activated
a code link: a link to the plugin object (whether its a module,
class, object, etc). This link is the complete import path. For example, a plugin class called "Foo" located in the "bar" module, located in the "baz" package, is noted: "baz.bar.Foo" (the project that uses plugins is responsible for iteratting, picking and loading plugins)
= PLUGINS example =
Here's an example of a PLUGINS file for a 'UnittestPlugins' project that implements 2 unitest2 plugins:
unittest2;plugin;pep8;pep8 checker;1;unittestplugins.pep8 unittest2;plugin;debugger,Cool debugger;1;unittestplugins.debug
This seems fine; I mean it isn't written directly by humans or intended to be read directly by humans I guess. :-)
(Users will specify plugins in the setup metadata and this will be written on install by distutils2 - right?.)
= per-user plugins =
A plugin can be activated or disable globally, but a user should be able to configure them differently.
A ini-like plugins.cfg file is added per-user (its location to be defined -- its discussed in another thread) and overrides the state of the installed plugin. It provides a value for each app.type.name plugin.
[plugins] unittest2.plugin.pep8 = 0 distutils2.commands.funkycommand = 0
Notice that the user can have plugins provided by distributions installed in his own per-user site packages.
I don't think that unittest would use a distutils2 (or pkgutil) supplied API for activation. unittest needs *separate* per user and per project activation (a plugin active for a project may not be needed in other projects and so won't be enabled at the user level for example). unittest also needs plugin *configuration* and it makes sense to keep configuration and activation in the same place.
The interesting part of this proposal for unittest is the plugin discovery.
unittest will use the two config file solution (location of user config still to be determined) and probably a "plugins" subcommand (eventually) to manage the config file from the command line.
On the other hand the activation is likely to be wanted by other projects that use plugins and it certainly doesn't hurt unittest.
= Implementation =
I don't want to go into great details here yet, until we get a consensus on the PLUGINS file.
But basically we will add these features in pkgutil:
- browse plugins and get their info.
- activate/disable a plugin, by writing its state
- load a plugin and return it by importing the 'code link'
and in distutils2:
- let the user configure if plugins are automatically activated when
the project is installed
- provide a end-user script to browse plugins
- provide a way to define plugins statically in setup.cfg
All sounds good to me.