[Checkins] SVN: grok/trunk/src/grok/ * cannot add local utilities to non-containers

Martijn Faassen faassen at infrae.com
Mon Jan 8 18:37:30 EST 2007


Log message for revision 71836:
  * cannot add local utilities to non-containers
    (if public)
  
  * cannot register two local utilities with
     grok.local_utility in a class if interface
     and name is the same.
  

Changed:
  A   grok/trunk/src/grok/ftests/utility/multiple_class.py
  A   grok/trunk/src/grok/ftests/utility/multiple_directive.py
  A   grok/trunk/src/grok/ftests/utility/publicnoncontainer.py
  U   grok/trunk/src/grok/meta.py
  U   grok/trunk/src/grok/tests/utility/local_implementsnone2.py

-=-
Added: grok/trunk/src/grok/ftests/utility/multiple_class.py
===================================================================
--- grok/trunk/src/grok/ftests/utility/multiple_class.py	2007-01-08 22:33:52 UTC (rev 71835)
+++ grok/trunk/src/grok/ftests/utility/multiple_class.py	2007-01-08 23:37:29 UTC (rev 71836)
@@ -0,0 +1,33 @@
+"""
+When you try to register multiple classes with the same (interface, name)
+combination multiple times using grok.local_utility, we expect an error:
+
+  >>> import grok
+  >>> from zope import component
+  >>> from grok.ftests.utility.multiple_class import *
+
+  >>> grok.grok('grok.ftests.utility.multiple_class')
+  Traceback (most recent call last):
+    ...
+  GrokError: Conflicting local utility registration
+  <class 'grok.ftests.utility.multiple_class.Fireplace2'> in site
+  <class 'grok.ftests.utility.multiple_class.Cave'>.
+  Local utilities are registered multiple times for interface
+  <InterfaceClass grok.ftests.utility.multiple_class.IFireplace> and
+  name 'Foo'.  
+"""
+import grok
+from zope import interface
+
+class IFireplace(interface.Interface):
+    pass
+
+class Fireplace(grok.LocalUtility):
+    grok.implements(IFireplace)
+
+class Fireplace2(grok.LocalUtility):
+    grok.implements(IFireplace)
+    
+class Cave(grok.Model, grok.Site):
+    grok.local_utility(Fireplace, name='Foo')
+    grok.local_utility(Fireplace2, name='Foo')

Added: grok/trunk/src/grok/ftests/utility/multiple_directive.py
===================================================================
--- grok/trunk/src/grok/ftests/utility/multiple_directive.py	2007-01-08 22:33:52 UTC (rev 71835)
+++ grok/trunk/src/grok/ftests/utility/multiple_directive.py	2007-01-08 23:37:29 UTC (rev 71836)
@@ -0,0 +1,33 @@
+"""
+When you call the grok.local_utility directive multiple times specifying
+the same (interface, name) combination, we expect an error:
+
+  >>> import grok
+  >>> from zope import component
+  >>> from grok.ftests.utility.multiple_directive import *
+
+  >>> grok.grok('grok.ftests.utility.multiple_directive')
+  Traceback (most recent call last):
+    ...
+  GrokError: Conflicting local utility registration
+  <class 'grok.ftests.utility.multiple_directive.Fireplace2'> in site
+  <class 'grok.ftests.utility.multiple_directive.Cave'>.
+  Local utilities are registered multiple times for interface
+  <InterfaceClass grok.ftests.utility.multiple_directive.IFireplace> and
+  name u''.  
+"""
+import grok
+from zope import interface
+
+class IFireplace(interface.Interface):
+    pass
+
+class Fireplace(grok.LocalUtility):
+    grok.implements(IFireplace)
+
+class Fireplace2(grok.LocalUtility):
+    grok.implements(IFireplace)
+    
+class Cave(grok.Model, grok.Site):
+    grok.local_utility(Fireplace, provides=IFireplace)
+    grok.local_utility(Fireplace2, provides=IFireplace)

Added: grok/trunk/src/grok/ftests/utility/publicnoncontainer.py
===================================================================
--- grok/trunk/src/grok/ftests/utility/publicnoncontainer.py	2007-01-08 22:33:52 UTC (rev 71835)
+++ grok/trunk/src/grok/ftests/utility/publicnoncontainer.py	2007-01-08 23:37:29 UTC (rev 71836)
@@ -0,0 +1,26 @@
+"""
+You cannot use local_utility with 'public' set to True if the site class
+isn't a container:
+
+  >>> import grok
+  >>> from zope import component
+  >>> from grok.ftests.utility.publicnoncontainer import *
+  >>> grok.grok('grok.ftests.utility.publicnoncontainer')
+  Traceback (most recent call last):
+    ...
+  GrokError: Cannot set public to True with grok.local_utility as the site
+  (<class 'grok.ftests.utility.publicnoncontainer.Cave'>) is not a container.
+
+"""
+
+import grok
+from zope import interface
+
+class IFireplace(interface.Interface):
+    pass
+
+class Fireplace(grok.LocalUtility):
+    grok.implements(IFireplace)
+    
+class Cave(grok.Model, grok.Site):
+    grok.local_utility(Fireplace, public=True, name_in_container='fireplace')

Modified: grok/trunk/src/grok/meta.py
===================================================================
--- grok/trunk/src/grok/meta.py	2007-01-08 22:33:52 UTC (rev 71835)
+++ grok/trunk/src/grok/meta.py	2007-01-08 23:37:29 UTC (rev 71836)
@@ -322,17 +322,34 @@
                     if len(provides) == 0 and len(list(utilityInterfaces)) > 0:
                         raise GrokError(
                             "Cannot determine which interface to use "
-                            "for utility registration of %r. "
+                            "for utility registration of %r in site %r. "
                             "It implements an interface that is a specialization "
                             "of an interface implemented by grok.LocalUtility. "
                             "Specify the interface by either using grok.provides "
                             "on the utility or passing 'provides' to "
-                            "grok.local_utility." % info.factory, info.factory)
+                            "grok.local_utility." % (info.factory, factory),
+                            info.factory)
                 else:
                     provides = list(interface.implementedBy(info.factory))
 
                 util.check_implements_one_from_list(provides, info.factory)
                 info.provides = provides[0]
+    
+        # raise an error in case of any duplicate registrations
+        # on the class level (subclassing overrides, see below)
+        used = set()
+        class_infos = util.class_annotation(factory, 'grok.local_utility',
+                                            [])
+        for info in class_infos:
+            key = (info.provides, info.name)
+            if key in used:
+                raise GrokError(
+                    "Conflicting local utility registration %r in "
+                    "site %r. Local utilities are registered multiple "
+                    "times for interface %r and name %r." %
+                    (info.factory, factory, info.provides, info.name),
+                    factory)
+            used.add(key)
 
         # Make sure that local utilities from subclasses override
         # utilities from base classes if the registration (provided

Modified: grok/trunk/src/grok/tests/utility/local_implementsnone2.py
===================================================================
--- grok/trunk/src/grok/tests/utility/local_implementsnone2.py	2007-01-08 22:33:52 UTC (rev 71835)
+++ grok/trunk/src/grok/tests/utility/local_implementsnone2.py	2007-01-08 23:37:29 UTC (rev 71836)
@@ -3,7 +3,8 @@
   Traceback (most recent call last):
     ...
   GrokError: Cannot determine which interface to use for utility registration of
-  <class 'grok.tests.utility.local_implementsnone2.Fireplace'>. It implements
+  <class 'grok.tests.utility.local_implementsnone2.Fireplace'> in site
+  <class 'grok.tests.utility.local_implementsnone2.Cave'>. It implements
   an interface that is a specialization of an interface implemented
   by grok.LocalUtility. Specify the interface by either using grok.provides on
   the utility or passing 'provides' to grok.local_utility.



More information about the Checkins mailing list