[Checkins] SVN: zope.component/trunk/ Add note to changelog

Wichert Akkerman wichert at wiggy.net
Wed Jul 23 05:32:59 EDT 2008


Log message for revision 88751:
  Add note to changelog

Changed:
  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-23 09:29:40 UTC (rev 88750)
+++ zope.component/trunk/README.txt	2008-07-23 09:32:58 UTC (rev 88751)
@@ -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-23 09:29:40 UTC (rev 88750)
+++ zope.component/trunk/src/zope/component/interfaces.py	2008-07-23 09:32:58 UTC (rev 88751)
@@ -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-23 09:29:40 UTC (rev 88750)
+++ zope.component/trunk/src/zope/component/registry.py	2008-07-23 09:32:58 UTC (rev 88751)
@@ -66,12 +66,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,12 +86,12 @@
             subscribed = self._utility_subscribers.get((provided, component),
                                                        False)
         else:
-            for ((p, _), (c,_)) in self._utility_registrations.iteritems():
-                if p == provided and c == component:
+            for ((p, _), data) in self._utility_registrations.iteritems():
+                if p == provided and data[0] == component:
                     subscribed = True
                     break
 
-        self._utility_registrations[(provided, name)] = component, info
+        self._utility_registrations[(provided, name)] = component, info, factory
         if hasattr(self, '_utility_subscribers'):
             self._utility_subscribers[(provided, component)] = True
         self.utilities.register((), provided, name, component)
@@ -96,13 +101,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))
@@ -121,8 +131,8 @@
                                                        False)
             del self._utility_subscribers[(provided, component)]
         else:
-            for ((p, _), (c,_)) in self._utility_registrations.iteritems():
-                if p == provided and c == component:
+            for ((p, _), data) in self._utility_registrations.iteritems():
+                if p == provided and data[0] == component:
                     subscribed = True
                     break
 
@@ -136,9 +146,9 @@
         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)
@@ -410,18 +420,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-23 09:29:40 UTC (rev 88750)
+++ zope.component/trunk/src/zope/component/registry.txt	2008-07-23 09:32:58 UTC (rev 88751)
@@ -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)
 
@@ -178,7 +187,7 @@
 
     >>> components.registerUtility(tests.U('ext'), 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:
 
@@ -900,7 +909,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)
@@ -908,7 +917,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)
@@ -922,14 +931,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)
 
@@ -1055,15 +1064,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-23 09:29:40 UTC (rev 88750)
+++ zope.component/trunk/src/zope/component/zcml.py	2008-07-23 09:32:58 UTC (rev 88751)
@@ -423,6 +423,7 @@
         discriminator = ('utility', provides, name),
         callable = handler,
         args = ('registerUtility', component, provides, name),
+        kwargs = dict(factory=factory), # XXX WTA: Does this work ??
         )
     _context.action(
         discriminator = None,



More information about the Checkins mailing list