[Checkins] SVN: grok/branches/wosc-utility-subclassing/src/grok/ Fix inheritance of utility registrations.

Martijn Faassen faassen at infrae.com
Sun Jan 7 10:25:53 EST 2007


Log message for revision 71771:
  Fix inheritance of utility registrations.
  

Changed:
  U   grok/branches/wosc-utility-subclassing/src/grok/ftests/utility/subclass.py
  U   grok/branches/wosc-utility-subclassing/src/grok/meta.py

-=-
Modified: grok/branches/wosc-utility-subclassing/src/grok/ftests/utility/subclass.py
===================================================================
--- grok/branches/wosc-utility-subclassing/src/grok/ftests/utility/subclass.py	2007-01-07 15:20:06 UTC (rev 71770)
+++ grok/branches/wosc-utility-subclassing/src/grok/ftests/utility/subclass.py	2007-01-07 15:25:52 UTC (rev 71771)
@@ -44,6 +44,30 @@
   Traceback (most recent call last):
     ...
   ComponentLookupError: (<InterfaceClass grok.ftests.utility.subclass.IPainting>, '')
+
+This works various levels of inheritance deep:
+
+  >>> very_hollow = VeryHollowCave()
+  >>> getRootFolder()['very_hollow'] = very_hollow
+
+  >>> setSite(very_hollow)
+  >>> fireplace = component.getUtility(IFireplace)
+  >>> painting = component.getUtility(IPainting)
+  >>> great_painting = component.getUtility(IPainting, 'great')
+  >>> bad_painting = component.getUtility(IPainting, 'bad')
+
+And with inheritance hierarchies where a base class is inherited multiple
+times through different routes:
+
+  >>> scary = ScaryCave()
+  >>> getRootFolder()['scary'] = scary
+
+  >>> setSite(scary)
+  >>> fireplace = component.getUtility(IFireplace)
+  >>> painting = component.getUtility(IPainting)
+  >>> great_painting = component.getUtility(IPainting, 'great')
+  >>> bad_painting = component.getUtility(IPainting, 'bad')
+
 """
 import grok
 from zope import interface
@@ -71,3 +95,12 @@
 
 class HollowCave(Cave):
     grok.local_utility(Painting)
+
+class VeryHollowCave(HollowCave):
+    grok.local_utility(Painting, name='great')
+    grok.local_utility(Painting, name='bad')
+
+# this cave subclasses from Cave twice
+class ScaryCave(VeryHollowCave, Cave):
+    pass
+

Modified: grok/branches/wosc-utility-subclassing/src/grok/meta.py
===================================================================
--- grok/branches/wosc-utility-subclassing/src/grok/meta.py	2007-01-07 15:20:06 UTC (rev 71770)
+++ grok/branches/wosc-utility-subclassing/src/grok/meta.py	2007-01-07 15:25:52 UTC (rev 71771)
@@ -285,23 +285,26 @@
 
                 util.check_implements_one_from_list(provides, info.factory)
                 info.provides = provides[0]
-        
-        subscriber = LocalUtilityRegistrationSubscriber(infos)
+
+        # store infos on site class
+        factory.__grok_utilities_to_install__ = infos
+        subscriber = LocalUtilityRegistrationSubscriber()
         component.provideHandler(subscriber,
                                  adapts=(factory, grok.IObjectAddedEvent))
 
 class LocalUtilityRegistrationSubscriber(object):
-    def __init__(self, infos):
-        self.infos = infos
-
+    """A subscriber that fires to set up local utilities.
+    
+    This class is deliberately stateless. This means that there
+    can be no instance variables.
+    """
     def __call__(self, site, event):
-        processed = util.class_annotation(site,
-                                          'grok.' + self.__class__.__name__, [])
-        if site.__class__ in processed:
-            import pdb; pdb.set_trace()
+        installed = getattr(site, '__grok_utilities_installed__', False)
+        if installed:
             return
-
-        for info in self.infos:
+    
+        for info in util.class_annotation(site.__class__,
+                                          'grok.utilities_to_install', []):
             utility = info.factory()
             site_manager = site.getSiteManager()
             
@@ -326,10 +329,10 @@
             site_manager.registerUtility(utility, provided=info.provides,
                                          name=info.name)
 
-        processed = processed[:]
-        processed.append(site.__class__)
-        setattr(site, '__grok_' + self.__class__.__name__ + '__', processed)
-
+        # we are done. If this subscriber gets fired again, we therefore
+        # do not register utilities anymore
+        site.__grok_utilities_installed__ = True
+        
 class DefinePermissionGrokker(grok.ModuleGrokker):
 
     def register(self, context, module_info, templates):



More information about the Checkins mailing list