Category confused when a base class defines another category
A fat-free DIY Python plugin management toolkit.
Brought to you by:
tibonihoo
Given a plugin module:
1 2 3 4 5 6 7 | #!/usr/bin/env python # MyBasePluginClass extends yapsy.IPlugin.IPlugin from myapp.plugintypes import MyBasePluginClass class MyPlugin(MyBasePluginClass): pass |
What happens here is that the name MyBasePluginClass is imported into the module's namespace before MyPlugin:
{ ...other globals..., 'MyBasePluginClass': '<class myapp.plugintypes.MyBasePluginClass>', 'MyPlugin': '<class MyPlugin>' }
Python classes are considered subclasses of themselves, so 'MyBasePluginClass' and 'MyPlugin' are both subclasses of 'MyBasePluginClass'.
Since PluginManager.loadModules iterates on the module object to find the first subclass of MyBasePluginClass in the file, it will incorrectly return a '<class MyBasePluginClass>' object instead of a '<class MyPlugin>' object.
So PluginManager.loadModules should only append the last subclass of a base plugin class in a plugin module.
Anonymous
Change the title to focus more on the base problem.
Just for the record, I guess this is also related to: http://stackoverflow.com/questions/6986563/yapsy-doesnt-load-plugin-correctly
Diff:
Actually for this kind of problems there are two easy workarounds.
The main idea is make avoid that any additional child class of IPlugin appears in the (globals of the) plugin file (or __init.py file if the plugin is a directory/module).
First solution is to make sure that the base classes are defined in their own module, for instance called PluginCategories and to make the actual plugin class inherit from PluginCategories.TheRightCategoryBaseClass
The other solution is to define the actual plugin class as a mixin between IPlugin and another PluginCategoryMixin class that doesn't inherit from IPlugin, and to make sure that a given category 'A' is not associated to IPlugin but to PluginCategoryAMixin for instance.
After all this needs some doc in the advice section but probably not a refactoring.
added documentation on that in the Advice/troubleshoot section for yapsy 1.10.1