Hello

This checkin contains the following change to zope.component/trunk/src/zope/component/registry.py which looks wrong to me (it's a noop). It looks to me as if the [:2] should move outside the ")" following it. I am surprised that this doesn't break any tests, as it means that reregistrations are not detected as such.


-        if (self._utility_registrations.get((provided, name))
+        if (self._utility_registrations.get((provided, name)[:2])



Wichert Akkerman wrote:
Log message for revision 88794:
  Merge wichert-utility-factories branch to trunk

Changed:
  D   zope.component/branches/wichert-utility-factories/
  U   zope.component/trunk/README.txt
  U   zope.component/trunk/src/zope/component/interfaces.py
  U   zope.component/trunk/src/zope/component/registry.py
  U   zope.component/trunk/src/zope/component/registry.txt
  U   zope.component/trunk/src/zope/component/zcml.py

-=-
Modified: zope.component/trunk/README.txt
===================================================================
--- zope.component/trunk/README.txt     2008-07-24 16:00:26 UTC (rev 88793)
+++ zope.component/trunk/README.txt     2008-07-24 16:17:58 UTC (rev 88794)
@@ -14,6 +14,10 @@
 3.5.0 (unreleased)
 ==================
+Support registration of utilities via factories through the component registry
+and return factory information in the registration information. This fixes
+https://bugs.launchpad.net/zope3/+bug/240631
+
 Optimized un/registerUtility via storing an optimized data structure for
 efficient retrieval of already registered utilities. This avoids looping over
 all utilities when registering a new one.

Modified: zope.component/trunk/src/zope/component/interfaces.py
===================================================================
--- zope.component/trunk/src/zope/component/interfaces.py       2008-07-24 
16:00:26 UTC (rev 88793)
+++ zope.component/trunk/src/zope/component/interfaces.py       2008-07-24 
16:17:58 UTC (rev 88794)
@@ -512,6 +512,7 @@
     """Information about the registration of a utility
     """
+ factory = interface.Attribute("The factory used to create the utility. Optional.")
     component = interface.Attribute("The object registered")
     provided = interface.Attribute("The interface provided by the component")
@@ -583,9 +584,12 @@
     """Register components
     """
- def registerUtility(component, provided=None, name=u'', info=u''):
+    def registerUtility(component=None, provided=None, name=u'', info=u'', 
factory=None):
         """Register a utility
+ factory
+           Factory for the component to be registerd.
+
         component
            The registered component
@@ -602,10 +606,11 @@
            An object that can be converted to a string to provide
            information about the registration.
+ Only one of component and factory can be used.
         A Registered event is generated with an IUtilityRegistration.
         """
- def unregisterUtility(component=None, provided=None, name=u''):
+    def unregisterUtility(component=None, provided=None, name=u'', 
factory=None):
         """Unregister a utility
A boolean is returned indicating whether the registry was
@@ -614,6 +619,9 @@
         None and is not registered, then the function returns
         False, otherwise it returns True.
+ factory
+           Factory for the component to be unregisterd.
+
         component
            The registered component The given component can be
            None, in which case any component registered to provide
@@ -629,6 +637,7 @@
         name
            The utility name.
+ Only one of component and factory can be used.
         An UnRegistered event is generated with an IUtilityRegistration.
         """
Modified: zope.component/trunk/src/zope/component/registry.py
===================================================================
--- zope.component/trunk/src/zope/component/registry.py 2008-07-24 16:00:26 UTC 
(rev 88793)
+++ zope.component/trunk/src/zope/component/registry.py 2008-07-24 16:17:58 UTC 
(rev 88794)
@@ -65,12 +65,17 @@
         lambda self, bases: self._setBases(bases),
         )
- def registerUtility(self, component, provided=None, name=u'', info=u'',
-                        event=True):
+    def registerUtility(self, component=None, provided=None, name=u'', 
info=u'',
+                        event=True, factory=None):
+        if factory:
+            if component:
+                raise TypeError("Can't specify factory and component.")
+            component = factory()
+
         if provided is None:
             provided = _getUtilityProvided(component)
- if (self._utility_registrations.get((provided, name))
+        if (self._utility_registrations.get((provided, name)[:2])
             == (component, info)):
             # already registered
             return
@@ -81,7 +86,7 @@
                 subscribed = True
                 break
- self._utility_registrations[(provided, name)] = component, info
+        self._utility_registrations[(provided, name)] = component, info, 
factory
         self.utilities.register((), provided, name, component)
if not subscribed:
@@ -89,13 +94,18 @@
if event:
             zope.event.notify(interfaces.Registered(
-                UtilityRegistration(self, provided, name, component, info)
+                UtilityRegistration(self, provided, name, component, info, 
factory)
                 ))
- def unregisterUtility(self, component=None, provided=None, name=u''):
+    def unregisterUtility(self, component=None, provided=None, name=u'', 
factory=None):
+        if factory:
+            if component:
+                raise TypeError("Can't specify factory and component.")
+            component = factory()
+
         if provided is None:
             if component is None:
-                raise TypeError("Must specify one of component and provided")
+                raise TypeError("Must specify one of component, factory and 
provided")
             provided = _getUtilityProvided(component)
old = self._utility_registrations.get((provided, name))
@@ -118,15 +128,15 @@
             self.utilities.unsubscribe((), provided, component)
zope.event.notify(interfaces.Unregistered(
-            UtilityRegistration(self, provided, name, component, old[1])
+            UtilityRegistration(self, provided, name, component, *old[1:])
             ))
return True def registeredUtilities(self):
-        for ((provided, name), (component, info)
+        for ((provided, name), data
              ) in self._utility_registrations.iteritems():
-            yield UtilityRegistration(self, provided, name, component, info)
+            yield UtilityRegistration(self, provided, name, *data)
def queryUtility(self, provided, name=u'', default=None):
         return self.utilities.lookup((), provided, name, default)
@@ -398,18 +408,20 @@
interface.implements(interfaces.IUtilityRegistration) - def __init__(self, registry, provided, name, component, doc):
-        (self.registry, self.provided, self.name, self.component, self.info
-         ) = registry, provided, name, component, doc
+    def __init__(self, registry, provided, name, component, doc, factory=None):
+        (self.registry, self.provided, self.name, self.component, self.info,
+         self.factory
+         ) = registry, provided, name, component, doc, factory
def __repr__(self):
-        return '%s(%r, %s, %r, %s, %r)' % (
-            self.__class__.__name__,
-            self.registry,
-            getattr(self.provided, '__name__', None), self.name,
-            getattr(self.component, '__name__', `self.component`), self.info,
-            )
-
+        return '%s(%r, %s, %r, %s, %r, %r)' % (
+                self.__class__.__name__,
+                self.registry,
+                getattr(self.provided, '__name__', None), self.name,
+                getattr(self.component, '__name__', `self.component`),
+                self.factory, self.info,
+                )
+ def __cmp__(self, other):
         return cmp(self.__repr__(), other.__repr__())
Modified: zope.component/trunk/src/zope/component/registry.txt
===================================================================
--- zope.component/trunk/src/zope/component/registry.txt        2008-07-24 
16:00:26 UTC (rev 88793)
+++ zope.component/trunk/src/zope/component/registry.txt        2008-07-24 
16:17:58 UTC (rev 88794)
@@ -35,7 +35,7 @@
>>> components.registerUtility(tests.U1(1))
     Registered event:
-    UtilityRegistration(<Components comps>, I1, u'', 1, u'')
+    UtilityRegistration(<Components comps>, I1, u'', 1, None, u'')
Here we didn't specify an interface or name. An unnamed utility was
 registered for interface I1, since that is only interface implemented
@@ -44,6 +44,15 @@
     >>> components.getUtility(tests.I1)
     U1(1)
+You can also register a utility using a factory instead of a utility instance:
+
+    >>> def factory():
+    ...    return tests.U1(1)
+    >>> components.registerUtility(factory=factory)
+    Registered event:
+    UtilityRegistration(<Components comps>, I1, u'', 1, <function factory at <SOME 
ADDRESS>>, u'')
+
+
 If a component implements other than one interface or no interface,
 then an error will be raised:
@@ -66,13 +75,13 @@ >>> components.registerUtility(tests.U12(2), tests.I2)
     Registered event:
-    UtilityRegistration(<Components comps>, I2, u'', 2, u'')
+    UtilityRegistration(<Components comps>, I2, u'', 2, None, u'')
and we can specify a name: >>> components.registerUtility(tests.U12(3), tests.I2, u'three')
     Registered event:
-    UtilityRegistration(<Components comps>, I2, u'three', 3, u'')
+    UtilityRegistration(<Components comps>, I2, u'three', 3, None, u'')
>>> components.getUtility(tests.I2)
     U12(2)
@@ -113,7 +122,7 @@
>>> components.registerUtility(tests.U1(4), info=u'use 4 now')
     Registered event:
-    UtilityRegistration(<Components comps>, I1, u'', 4, u'use 4 now')
+    UtilityRegistration(<Components comps>, I1, u'', 4, None, u'use 4 now')
     >>> components.getUtility(tests.I1)
     U1(4)
@@ -135,7 +144,7 @@ >>> components.unregisterUtility(provided=tests.I1)
     Unregistered event:
-    UtilityRegistration(<Components comps>, I1, u'', 4, u'use 4 now')
+    UtilityRegistration(<Components comps>, I1, u'', 4, None, u'use 4 now')
     True
A boolean is returned indicating whether anything changed:
@@ -155,14 +164,14 @@
     >>> u5 = tests.U1(5)
     >>> components.registerUtility(u5)
     Registered event:
-    UtilityRegistration(<Components comps>, I1, u'', 5, u'')
+    UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
     >>> components.unregisterUtility(tests.U1(6))
     False
     >>> components.queryUtility(tests.I1)
     U1(5)
     >>> components.unregisterUtility(u5)
     Unregistered event:
-    UtilityRegistration(<Components comps>, I1, u'', 5, u'')
+    UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
     True
     >>> components.queryUtility(tests.I1)
@@ -179,7 +188,7 @@
     >>> util = tests.U('ext')
     >>> components.registerUtility(util, tests.I2e)
     Registered event:
-    UtilityRegistration(<Components comps>, I2e, u'', ext, u'')
+    UtilityRegistration(<Components comps>, I2e, u'', ext, None, u'')
We don't get the new utility for getUtilitiesFor: @@ -910,7 +919,7 @@ >>> c1.registerUtility(tests.U1(1))
     Registered event:
-    UtilityRegistration(<Components 1>, I1, u'', 1, u'')
+    UtilityRegistration(<Components 1>, I1, u'', 1, None, u'')
>>> c1.queryUtility(tests.I1)
     U1(1)
@@ -918,7 +927,7 @@
     U1(1)
     >>> c1.registerUtility(tests.U1(2))
     Registered event:
-    UtilityRegistration(<Components 1>, I1, u'', 2, u'')
+    UtilityRegistration(<Components 1>, I1, u'', 2, None, u'')
>>> c2.queryUtility(tests.I1)
     U1(2)
@@ -932,14 +941,14 @@
>>> c1.registerUtility(tests.U12(1), tests.I2)
     Registered event:
-    UtilityRegistration(<Components 1>, I2, u'', 1, u'')
+    UtilityRegistration(<Components 1>, I2, u'', 1, None, u'')
>>> c4.queryUtility(tests.I2)
     U12(1)
>>> c3.registerUtility(tests.U12(3), tests.I2)
     Registered event:
-    UtilityRegistration(<Components 3>, I2, u'', 3, u'')
+    UtilityRegistration(<Components 3>, I2, u'', 3, None, u'')
     >>> c4.queryUtility(tests.I2)
     U12(3)
@@ -1065,15 +1074,15 @@
     >>> components.registerUtility(u5)
     ... # doctest: +NORMALIZE_WHITESPACE
     Double dispatch:
-      UtilityRegistration(<Components comps>, I1, u'', 5, u'')
+      UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
       Registered event:
-      UtilityRegistration(<Components comps>, I1, u'', 5, u'')
+      UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
     Double dispatch:
       U1(5)
       Registered event:
-      UtilityRegistration(<Components comps>, I1, u'', 5, u'')
+      UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
     Registered event:
-    UtilityRegistration(<Components comps>, I1, u'', 5, u'')
+    UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
>>> components.registerAdapter(tests.A12_1)
     ... # doctest: +NORMALIZE_WHITESPACE

Modified: zope.component/trunk/src/zope/component/zcml.py
===================================================================
--- zope.component/trunk/src/zope/component/zcml.py     2008-07-24 16:00:26 UTC 
(rev 88793)
+++ zope.component/trunk/src/zope/component/zcml.py     2008-07-24 16:17:58 UTC 
(rev 88794)
@@ -400,10 +400,8 @@
def utility(_context, provides=None, component=None, factory=None,
             permission=None, name=''):
-    if factory:
-        if component:
-            raise TypeError("Can't specify factory and component.")
-        component = factory()
+    if factory and component:
+        raise TypeError("Can't specify factory and component.")
if provides is None:
         provides = list(zope.interface.providedBy(component))
@@ -423,6 +421,7 @@
         discriminator = ('utility', provides, name),
         callable = handler,
         args = ('registerUtility', component, provides, name),
+        kw = dict(factory=factory),
         )
     _context.action(
         discriminator = None,

_______________________________________________
Checkins mailing list
[EMAIL PROTECTED]
http://mail.zope.org/mailman/listinfo/checkins

_______________________________________________
Zope-Dev maillist  -  Zope-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - http://mail.zope.org/mailman/listinfo/zope-announce
http://mail.zope.org/mailman/listinfo/zope )

Reply via email to