[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