[Checkins] SVN: PluginRegistry/trunk/ Drop previously-activated plugins from the list returned from 'listPlugins' when they no longer implement the plugin interface.

Tres Seaver tseaver at palladion.com
Tue Apr 24 15:15:05 EDT 2007


Log message for revision 74716:
  Drop previously-activated plugins from the list returned from 'listPlugins' when they no longer implement the plugin interface.
  
  o See http://www.zope.org/Collectors/PAS/53
  

Changed:
  U   PluginRegistry/trunk/CHANGES.txt
  U   PluginRegistry/trunk/PluginRegistry.py
  U   PluginRegistry/trunk/tests/test_PluginRegistry.py
  U   PluginRegistry/trunk/tests/test_exportimport.py

-=-
Modified: PluginRegistry/trunk/CHANGES.txt
===================================================================
--- PluginRegistry/trunk/CHANGES.txt	2007-04-24 18:44:50 UTC (rev 74715)
+++ PluginRegistry/trunk/CHANGES.txt	2007-04-24 19:15:04 UTC (rev 74716)
@@ -2,6 +2,10 @@
 
   After PluginRegistry 1.1.1
 
+    - Drop previously-activated plugins from the list returned from
+      'listPlugins' when they no longer implement the plugin interface.
+      (http://www.zope.org/Collectors/PAS/53)
+
     - Skip adding duplicate interfaces during non-purge import.
       (http://www.zope.org/Collectors/PAS/52)
 

Modified: PluginRegistry/trunk/PluginRegistry.py
===================================================================
--- PluginRegistry/trunk/PluginRegistry.py	2007-04-24 18:44:50 UTC (rev 74715)
+++ PluginRegistry/trunk/PluginRegistry.py	2007-04-24 19:15:04 UTC (rev 74716)
@@ -16,6 +16,7 @@
 
 $Id$
 """
+import logging
 
 from Globals import Persistent
 from App.ImageFile import ImageFile
@@ -57,6 +58,8 @@
 
 from utils import _wwwdir
 
+logger = logging.getLogger('PluginRegistry')
+
 class PluginRegistry( SimpleItem ):
 
     """ Implement IPluginRegistry as an independent, ZMI-manageable object.
@@ -125,7 +128,12 @@
         for plugin_id in self._getPlugins( plugin_type ):
 
             plugin = parent._getOb( plugin_id )
-            result.append( ( plugin_id, plugin ) )
+            if not _satisfies( plugin, plugin_type ):
+                logger.debug( 'Active plugin %s no longer implements %s'
+                                % ( plugin_id, plugin_type )
+                            )
+            else:
+                result.append( ( plugin_id, plugin ) )
 
         return result
 
@@ -158,11 +166,7 @@
         parent = aq_parent( aq_inner( self ) )
         plugin = parent._getOb( plugin_id ) 
 
-        satisfies = getattr(plugin_type, 'providedBy', None)
-        if satisfies is None:
-            satisfies = plugin_type.isImplementedBy
-
-        if not satisfies(plugin):
+        if not _satisfies(plugin, plugin_type):
             raise ValueError, 'Plugin does not implement %s' % plugin_type 
         
         plugins.append( plugin_id )
@@ -311,12 +315,8 @@
         active = self._getPlugins( interface )
         available = []
 
-        satisfies = getattr(interface, 'providedBy', None)
-        if satisfies is None:
-            satisfies = interface.isImplementedBy
-
         for id, value in aq_parent( aq_inner( self ) ).objectItems():
-            if satisfies( value ):
+            if _satisfies(value, interface):
                 if id not in active:
                     available.append( id )
 
@@ -428,6 +428,13 @@
 
 InitializeClass( PluginRegistry )
 
+def _satisfies( plugin, iface ):
+    checker = getattr(iface, 'providedBy', None)
+    if checker is None: # BBB for Zope 2.7?
+        checker = iface.isImplementedBy
+
+    return checker(plugin)
+
 def emptyPluginRegistry( ignored ):
     """ Return empty registry, for filling from setup profile.
     """

Modified: PluginRegistry/trunk/tests/test_PluginRegistry.py
===================================================================
--- PluginRegistry/trunk/tests/test_PluginRegistry.py	2007-04-24 18:44:50 UTC (rev 74715)
+++ PluginRegistry/trunk/tests/test_PluginRegistry.py	2007-04-24 19:15:04 UTC (rev 74716)
@@ -69,7 +69,6 @@
 
         verifyClass( IPluginRegistry, self._getTargetClass() )
 
-
     def test_empty( self ):
 
         preg = self._makeOne()
@@ -121,15 +120,33 @@
         self.assertEqual( len( idlist ), 1 )
         self.assertEqual( idlist[0], 'foo_plugin' )
 
-        # XXX:  Note that we aren't testing 'listPlugins' here, as it
-        #       requires that we have TALES wired up.
-        #
-        #plugins = preg.listPlugins( 'foo' )
-        #self.assertEqual( len( plugins ), 1 )
-        #plugin = plugins[0]
-        #self.assertEqual( plugin[0], 'test' )
-        #self.assertEqual( plugin[1], preg.test_foo )
+        plugins = preg.listPlugins( IFoo )
+        self.assertEqual( len( plugins ), 1 )
+        plugin = plugins[0]
+        self.assertEqual( plugin[0], 'foo_plugin' )
+        self.assertEqual( plugin[1], preg.foo_plugin )
 
+    def test_activatePlugin_then_remove_interface( self ):
+
+        parent = DummyFolder()
+        foo_plugin = DummyPlugin()
+        directlyProvides( foo_plugin,  ( IFoo, ) )
+        parent._setObject( 'foo_plugin', foo_plugin )
+
+        preg = self._makeOne().__of__(parent)
+
+        preg.activatePlugin( IFoo, 'foo_plugin')
+
+        replacement = DummyPlugin()
+        parent._delObject( 'foo_plugin' )
+        parent._setObject( 'foo_plugin', replacement )
+
+        idlist = preg.listPluginIds( IFoo )
+        self.assertEqual( len( idlist ), 1 )  # note discrepancy
+
+        plugins = preg.listPlugins( IFoo )
+        self.assertEqual( len( plugins ), 0 )
+
     def test_deactivatePlugin( self ):
 
         parent = DummyFolder()

Modified: PluginRegistry/trunk/tests/test_exportimport.py
===================================================================
--- PluginRegistry/trunk/tests/test_exportimport.py	2007-04-24 18:44:50 UTC (rev 74715)
+++ PluginRegistry/trunk/tests/test_exportimport.py	2007-04-24 19:15:04 UTC (rev 74716)
@@ -33,6 +33,7 @@
     from Products.GenericSetup.utils import _getDottedName
 
     from zope.interface import Interface
+    from zope.interface import directlyProvides
     from zope.app.testing import ztapi
 
     try:
@@ -130,6 +131,9 @@
             registry._plugins = {} # it is usually lazy
 
             for plugin_type, registered in plugins.items():
+                for obj_id in registered:
+                    obj = app._getOb(obj_id)
+                    directlyProvides(obj, plugin_type)
                 registry._plugins[plugin_type] = registered
 
             app._setObject('plugin_registry', registry)
@@ -364,7 +368,9 @@
             from Products.PluginRegistry.exportimport \
                 import importPluginRegistry
 
-            app, registry = self._initRegistry()
+            app, registry = self._initRegistry(plugins={IFoo: ('foo_plugin_1',
+                                                               'foo_plugin_2')},
+                                              )
 
             self.assertEqual(len(registry.listPluginTypeInfo()), 0)
             self.assertRaises(KeyError, registry.listPlugins, IFoo)
@@ -395,7 +401,9 @@
             from Products.PluginRegistry.exportimport \
                 import importPluginRegistry
 
-            app, registry = self._initRegistry()
+            app, registry = self._initRegistry(plugins={IFoo: ('foo_plugin_1',
+                                                               'foo_plugin_2')},
+                                              )
 
             self.assertEqual(len(registry.listPluginTypeInfo()), 0)
             self.assertRaises(KeyError, registry.listPlugins, IFoo)



More information about the Checkins mailing list