135 lines
4.8 KiB
ReStructuredText
135 lines
4.8 KiB
ReStructuredText
===================================
|
|
General advices and troubleshooting
|
|
===================================
|
|
|
|
.. contents::
|
|
:local:
|
|
|
|
|
|
Getting code samples
|
|
--------------------
|
|
|
|
Yapsy is used enough for your favorite search provider to have good
|
|
chances of finding some examples of yapsy being used in the wild.
|
|
|
|
However if you wonder how a specific functionality can be used, you
|
|
can also look at the corresponding unit test (in the test folder
|
|
packaged with yapsy's sources).
|
|
|
|
|
|
Use the logging system
|
|
----------------------
|
|
|
|
Yapsy uses Python's standard ``logging`` module to record most
|
|
important events and especially plugin loading failures.
|
|
|
|
When developping an application based on yapsy, you'll benefit from
|
|
looking at the 'debug' level logs, which can easily be done from your
|
|
application code with the following snippet::
|
|
|
|
import logging
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
|
|
Also, please note that yapsy uses a named logger for all its logs, so
|
|
that you can selectively activage debug logs for yapsy with the
|
|
following snippet::
|
|
|
|
import logging
|
|
logging.getLogger('yapsy').setLevel(logging.DEBUG)
|
|
|
|
|
|
Categorization by inheritance caveat
|
|
------------------------------------
|
|
|
|
If your application defines various categories of plugins with the yapsy's built-in mechanism for that, please keep in mind the following facts:
|
|
|
|
- a plugin instance is attributed to a given category by looking if
|
|
it is an instance, *even via a subclass*, of the class associated
|
|
to this category;
|
|
- a plugin may be attributed to several categories.
|
|
|
|
Considering this, and if you consider using several categories, you
|
|
should consider the following tips:
|
|
|
|
- **don't associate any category to ``IPlugin``** (unless you want
|
|
all plugins to be attributed to the corresponding category)
|
|
- **design a specific subclass** of ``IPlugin`` for each category
|
|
- if you want to regroup plugins of some categories into a common
|
|
category: do this by attributing a subclass of ``IPlugin`` to the
|
|
common category and attribute to the other categories specific
|
|
subclasses to this intermediate mother class so that **the plugin
|
|
class inheritance hierarchy reflects the hierarchy between
|
|
categories** (and if you want something more complex that a
|
|
hierarchy, you can consider using mixins).
|
|
|
|
|
|
Plugin class detection caveat
|
|
-----------------------------
|
|
|
|
There must be **only one plugin defined per module**. This means that
|
|
you can't have two plugin description files pointing at the same
|
|
module for instance.
|
|
|
|
Because of the "categorization by inheritance" system, you **musn't
|
|
directly import the subclass** of ``IPlugin`` in the main plugin file,
|
|
instead import its containing module and make your plugin class
|
|
inherit from ``ContainingModule.SpecificPluginClass`` as in the
|
|
following example.
|
|
|
|
The following code won't work (the class ``MyBasePluginClass`` will be
|
|
detected as the plugin's implementation instead of ``MyPlugin``)::
|
|
|
|
from myapp.plugintypes import MyBasePluginClass
|
|
|
|
class MyPlugin(MyBasePluginClass):
|
|
pass
|
|
|
|
Instead you should do the following::
|
|
|
|
import myapp.plugintypes as plugintypes
|
|
|
|
class MyPlugin(plugintypes.MyBasePluginClass):
|
|
pass
|
|
|
|
|
|
Plugin packaging
|
|
----------------
|
|
|
|
When packaging plugins in a distutils installer or as parts of an
|
|
application (like for instance with `py2exe`), you may want to take
|
|
care about the following points:
|
|
|
|
- when you set specific directories where to look for plugins with a
|
|
hardcoded path, be very carefully about the way you write these
|
|
paths because depending on the cases **using ``__file__`` or
|
|
relative paths may be unreliable**. For instance with py2exe, you
|
|
may want to follow the tips from the `Where Am I FAQ`_.
|
|
|
|
- you'd should either **package the plugins as plain Python modules or
|
|
data files** (if you want to consider you application as the only
|
|
module), either using the dedicated `setup` argument for `py2exe` or
|
|
using distutils' `MANIFEST.in`
|
|
|
|
- if you do package the plugins as data files, **make sure that their
|
|
dependencies are correctly indicated as dependencies of your
|
|
package** (or packaged with you application if you use `py2exe`).
|
|
|
|
See also a more detailed example for py2exe on `Simon on Tech's Using python plugin scripts with py2exe`_.
|
|
|
|
.. _`Where Am I FAQ`: http://www.py2exe.org/index.cgi/WhereAmI
|
|
.. _`Simon on Tech's Using python plugin scripts with py2exe`: http://notinthestars.blogspot.com.es/2011/04/using-python-plugin-scripts-with-py2exe.html
|
|
|
|
|
|
Code conventions
|
|
----------------
|
|
|
|
If you intend to modify yapsy's sources and to contribute patches
|
|
back, please respect the following conventions:
|
|
|
|
- CamelCase (upper camel case) for class names and functions
|
|
- camelCase (lower camel case) for methods
|
|
- UPPERCASE for global variables (with a few exceptions)
|
|
- tabulations are used for indentation (and not spaces !)
|
|
- unit-test each new functionality
|
|
|