Menu

#8 Category confused when a base class defines another category

Not a bug
closed
nobody
None
9
2013-01-13
2011-12-31
Anonymous
No

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.

Discussion

  • Thibauld Nion

    Thibauld Nion - 2011-12-31

    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

     
  • Thibauld Nion

    Thibauld Nion - 2012-11-02
    • milestone: --> Next Major Release
     
  • Thibauld Nion

    Thibauld Nion - 2012-11-02
    • status: open --> accepted
     
  • Thibauld Nion

    Thibauld Nion - 2012-12-18
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,15 +1,19 @@
     Given a plugin module:
    -```
    -# MyBasePluginClass extends yapsy.IPlugin.IPlugin
    
    -from myapp.plugintypes import MyBasePluginClass
    +    #!/usr/bin/env python
    +    # MyBasePluginClass extends yapsy.IPlugin.IPlugin
    
    -class MyPlugin(MyBasePluginClass):
    -    pass
    -```
    +    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>'  }
    +
    +> { ...other globals..., 'MyBasePluginClass': '&lt;class myapp.plugintypes.MyBasePluginClass&gt;', 'MyPlugin': '&lt;class MyPlugin&gt;'  }
    
     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.
    +
    +Since PluginManager.loadModules iterates on the module object to find the *first* subclass of MyBasePluginClass in the file, it will incorrectly return a '&lt;class MyBasePluginClass&gt;' object instead of a '&lt;class MyPlugin&gt;' object.
    +
     So PluginManager.loadModules should only append the *last* subclass of a base plugin class in a plugin module.
    
     
  • Thibauld Nion

    Thibauld Nion - 2012-12-18
    • milestone: Next Major Release --> Next Minor Release
    • priority: 5 --> 1
     
  • Thibauld Nion

    Thibauld Nion - 2012-12-19

    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.

     
  • Thibauld Nion

    Thibauld Nion - 2012-12-19
    • status: accepted --> wont-fix
    • milestone: Next Minor Release --> Not a bug
    • priority: 1 --> 9
     
  • Thibauld Nion

    Thibauld Nion - 2012-12-19

    After all this needs some doc in the advice section but probably not a refactoring.

     
  • Thibauld Nion

    Thibauld Nion - 2012-12-19
    • status: wont-fix --> pending
     
  • Thibauld Nion

    Thibauld Nion - 2013-01-13
    • status: pending --> closed
     
  • Thibauld Nion

    Thibauld Nion - 2013-01-13

    added documentation on that in the Advice/troubleshoot section for yapsy 1.10.1

     

Anonymous
Anonymous

Add attachments
Cancel