root/releases/pkgcore/0.2.4/dev-notes/plugins.rst @ marienz%2540gentoo.org-20061010012239-17a7e22ee3fe384c

Revision marienz%2540gentoo.org-20061010012239-17a7e22ee3fe384c, 4.4 KB (checked in by Marien Zwart <marienz@…>, 2 years ago)

Rewrite plugins documentation.

Line 
1================
2 Plugins system
3================
4
5Goals
6=====
7
8The plugin system (``pkgcore.plugin``) is used to pick up extra code
9(potentially distributed separately from pkgcore itself) at a place
10where using the config system is not a good idea for some reason. This
11means that for a lot of things that most people would call "plugins"
12you should not actually use ``pkgcore.plugin``, you should use the
13config system. Things like extra repository types should simply be
14used as "class" value in the configuration. The plugin system is
15currently mainly used in places where handing in a ``ConfigManager``
16is too inconvenient.
17
18Using plugins
19=============
20
21Plugins are looked up based on a string "key". You can always look up
22all available plugins matching this key with
23``pkgcore.plugin.get_plugins(key)``. For some kinds of plugin (the
24ones defining a "priority" attribute) you can also get the "best"
25plugin with ``pkgcore.plugin.get_plugin(key)``. This does not make
26sense for all kinds of plugin, so not all of them define this.
27
28The plugin system does not care about what kind of object plugins are,
29this depends entirely on the key.
30
31Adding plugins
32==============
33
34Basics, caching
35---------------
36
37Plugins for pkgcore are loaded from modules inside the
38``pkgcore.plugins`` package. This package has some magic to make
39plugins in any subdirectory ``pkgcore/plugins`` under a directory on
40``sys.path`` work. So if pkgcore itself is installed in site-packages
41you can still add plugins to ``/home/you/pythonlib/pkgcore/plugins``
42if ``/home/you/pythonlib`` is in ``PYTHONPATH``. You should not put an
43``__init__.py`` in this extra plugin directory.
44
45Plugin modules should contain a ``pkgcore_plugins`` directory that
46maps the "key" strings to a sequence of plugins. This dictionary has
47to be constant, since pkgcore keeps track of what plugin module
48provides plugins for what keys in a cache file to avoid unnecessary
49imports. So this is invalid::
50
51 try:
52     import spork_package
53 except ImportError:
54     pkgcore_plugins = {}
55 else:
56     pkgcore_plugins = {'myplug': [spork_package.ThePlugin]}
57
58since if the plugin cache is generated while the package is not
59available pkgcore will cache the module as not providing any
60``myplug`` plugins, and the cache will not be updated if the package
61becomes available (only changes to the mtime of actual plugin modules
62invalidate the cache). Instead you should do something like this::
63
64 try:
65     from spork_package import ThePlugin
66 except ImportError:
67     class ThePlugin(object):
68         disabled = True
69
70 pkgcore_plugins = {'myplug': [ThePlugin]}
71
72If a plugin has a "disabled" attribute the plugin system will never
73return it from ``get_plugin`` or ``get_plugins``.
74
75Priority
76--------
77
78If you want your plugin to support ``get_plugin`` it should have a
79``priority`` attribute: an integer indicating how "preferred" this
80plugin is. The plugin with the highest priority (that is not disabled)
81is returned from ``get_plugin``.
82
83Some types of plugins need more information to determine a priority
84value. Those should not have a priority attribute. They should use
85``get_plugins`` instead and have a method that gets passed the extra
86data and returns the priority.
87
88Import behaviour
89----------------
90
91Assuming the cache is working correctly (it was generated after
92installing a plugin as root) pkgcore will import all plugin modules
93containing plugins for a requested key. No more, no less. The priority
94and disabled values are not cached (intentionally, since they may
95change without a cache invalidation), so it has to check all plugins
96for the key even if only one of them is requested (``get_plugin``, and
97the same will usually be true for ``get_plugins``).
98
99This means it makes sense to have only one kind of plugin per plugin
100module (unless the required imports overlap).
101
102The disabled and priority values are not cached by the plugin system
103after the plugin module is imported. This means they should be simple
104attributes (either completely constant or set at import time) or
105properties that do their own caching.
106
107Adding a plugin package
108=======================
109
110Both ``get_plugin`` and ``get_plugins`` take a plugin package as
111second argument. This means you can use the plugin system for external
112pkgcore-related tools without cluttering up the main pkgcore plugin
113directory. If you do this you will probably want to copy the
114``__path__`` trick from ``pkgcore/plugin/__init__.py`` to support
115plugins elsewhere on ``sys.path``.
Note: See TracBrowser for help on using the browser.