[Zope3-checkins] SVN: Zope3/branches/srichter-blow-services/src/zope/component/ Here is the first batch of work. I have pretty much successfully removed

Stephan Richter srichter at cosmos.phy.tufts.edu
Thu Dec 16 12:42:59 EST 2004


Log message for revision 28632:
  Here is the first batch of work. I have pretty much successfully removed 
  services and presentation components from zope.component with trying to 
  keep nackward-compatibility as much as possible. I also worked on the 
  documentation end a lot.
  
  

Changed:
  A   Zope3/branches/srichter-blow-services/src/zope/component/README.txt
  U   Zope3/branches/srichter-blow-services/src/zope/component/__init__.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/adapter.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/__init__.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/adapter.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/contextdependent.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/exceptions.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/interfaces.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/service.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/servicenames.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/__init__.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/components.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/placelesssetup.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/request.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_adapter.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_api.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_service.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_utilityservice.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/bbb/utility.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/contextdependent.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/exceptions.py
  U   Zope3/branches/srichter-blow-services/src/zope/component/interfaces.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/service.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/servicenames.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/site.py
  A   Zope3/branches/srichter-blow-services/src/zope/component/testing.py
  U   Zope3/branches/srichter-blow-services/src/zope/component/tests/__init__.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/tests/components.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/tests/placelesssetup.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/tests/request.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/tests/test_adapter.py
  U   Zope3/branches/srichter-blow-services/src/zope/component/tests/test_api.py
  U   Zope3/branches/srichter-blow-services/src/zope/component/tests/test_factory.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/tests/test_service.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/tests/test_utilityservice.py
  D   Zope3/branches/srichter-blow-services/src/zope/component/utility.py

-=-
Added: Zope3/branches/srichter-blow-services/src/zope/component/README.txt
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/README.txt	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/README.txt	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,594 @@
+=================================
+The Zope 3 Component Architecture
+=================================
+
+The component architecture provides an application framework that provides its
+functionality through loosly-connected components. A *component* can be any
+Python object and has a particular purpose associated with it. Thus, in a
+component-based applications you have many small component in contrast to
+classical object-oriented development, where yoiu have a few big objects. 
+
+Components communicate via specific APIs, which are formally defined by
+interfaces, which are provided by the `zope.interface` package. *Interfaces*
+describe the methods and properties that a component is expected to
+provide. They are also used as a primary mean to provide developer-level
+documentation for the components. For more details about interfaces see
+`zope/interface/README.txt`.
+
+The two main types of components are *adapters* and *utilities*. They will be
+discussed in detail later in this document. Both component types are managed
+by the *site manager*, with which you can register and access these
+components. However, most of the site manager's functionality is hidden behind
+the component architecture's public API, which is documented in
+`IComponentArchitecture`.
+
+
+Adapters
+--------
+
+Adapters are a well-established pattern. An *adapter* uses an object providing
+one interface to produce an object that provides another interface. Here an
+example: Imagine that you purchased an electric shaver in the US, and thus
+you require the US socket type. You are now traveling in Germany, where another
+socket style is used. You will need a device, an adapter, that converts from
+the German to the US socket style.
+
+The functionality of adapters is actually natively provided by the
+`zope.interface` package and is thus well decumented there. The `human.txt`
+file provides a gentle introduction to adapters, whereby `adapter.txt` is
+aimed at providing a comprehensive insight into adapters, but is too abstract
+for many as an inital read. Thus, we will only explain adapters in the context
+of the component architecture's API.
+
+So let's say that we have a German socket
+
+  >>> from zope.interface import Interface, implements
+
+  >>> class IGermanSocket(Interface):
+  ...     pass
+
+  >>> class Socket(object):
+  ...     def __repr__(self):
+  ...         return '<instance of %s>' %self.__class__.__name__
+
+  >>> class GermanSocket(Socket):
+  ...     """German wall socket."""
+  ...     implements(IGermanSocket)
+
+and we want to convert it to an US socket
+
+  >>> class IUSSocket(Interface):
+  ...     pass
+
+so that our shaver can be used in Germany. So we go to a German electronics
+store to look for an adapter that we can plug in the wall:
+
+  >>> class GermanToUSSocketAdapter(Socket):
+  ...     implements(IUSSocket)
+  ...     __used_by__ = IGermanSocket
+  ...     
+  ...     def __init__(self, socket):
+  ...         self.context = socket
+
+Note that I could have called the passed in socket any way I like, but
+`context` is the standard name accepted.
+
+
+Single Adapters
++++++++++++++++
+
+Before we can use the adapter, we have to buy it and make it part of our
+inventory. In the component architecture we do this by registering the adapter
+with the framework, more specifically with the global site manager:
+
+  >>> from zope import component as capi
+  >>> gsm = capi.getGlobalSiteManager()
+  
+  >>> gsm.registerAdapter((IGermanSocket,), IUSSocket, '',
+  ...                    GermanToUSSocketAdapter)
+
+`capi` is the component architecture API that is being presented by this
+file. You registered an adapter from `IGermanSocket` to `IUSSocket` having no
+name (thus the empty string).
+
+Anyways, you finally get back to your hotel room and shave, since you have not
+been able to shave in the plane. In the bathroom you discover a socket:
+
+  >>> bathroomDE = GermanSocket()
+  >>> IGermanSocket.providedBy(bathroomDE)
+  True
+
+You now insert the adapter in the German socket
+
+  >>> bathroomUS = capi.getAdapter(bathroomDE, IUSSocket, '')
+
+so that the socket now provides the US version:
+
+  >>> IUSSocket.providedBy(bathroomUS)
+  True
+
+Now you can insert your shaver and get on with your day. 
+
+After a week you travel for a couple of days to the Prague and you notice that
+the Czech have yet another socket type:
+
+  >>> class ICzechSocket(Interface):
+  ...     pass
+
+  >>> class CzechSocket(Socket):
+  ...     implements(ICzechSocket)
+
+  >>> czech = CzechSocket()
+
+You try to find an adapter for your shaver in your bag, but you fail, since
+you do not have one:
+
+  >>> capi.getAdapter(czech, IUSSocket, '') #doctest: +NORMALIZE_WHITESPACE
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: (<instance of CzechSocket>, 
+                         <InterfaceClass __builtin__.IUSSocket>)
+
+or the more graceful way:
+
+  >>> marker = object()
+  >>> socket = capi.queryAdapter(czech, IUSSocket, '', marker)
+  >>> socket is marker
+  True
+
+In the component architecture API any `get*` method will fail with a specific
+exception, if a query failed, whereby methods starting with `query*` will
+always return a `default` value after a failure.
+
+
+Named Adapters
+++++++++++++++
+
+You are finally back in Germany. You also brought your DVD player and a couple
+DVDs with you, which you would like to watch. Your shaver was able to convert
+automatically from 110 volts to 240 volts, but your DVD player cannot. So you
+have to buy another adapter that also handles converting the voltage and the
+frequency of the AC current:
+
+  >>> class GermanToUSSocketAdapterAndTransformer(object):
+  ...     implements(IUSSocket)
+  ...     __used_by__ = IGermanSocket
+  ...     
+  ...     def __init__(self, socket):
+  ...         self.context = socket
+
+Now, we need a way to keep the two adapters apart. Thus we register them with
+a name:
+
+  >>> gsm.registerAdapter((IGermanSocket,), IUSSocket, 'shaver',
+  ...                    GermanToUSSocketAdapter)
+  >>> gsm.registerAdapter((IGermanSocket,), IUSSocket, 'dvd',
+  ...                    GermanToUSSocketAdapterAndTransformer)
+
+Now we simply look up the adapters using their labels (called *name*):
+
+  >>> socket = capi.getAdapter(bathroomDE, IUSSocket, 'shaver')
+  >>> socket.__class__ is GermanToUSSocketAdapter
+  True
+
+  >>> socket = capi.getAdapter(bathroomDE, IUSSocket, 'dvd')
+  >>> socket.__class__ is GermanToUSSocketAdapterAndTransformer
+  True
+
+Clearly, we do not have an adapter for the MP3 player
+
+  >>> capi.getAdapter(bathroomDE, IUSSocket, 
+  ...                 'mp3') #doctest: +NORMALIZE_WHITESPACE
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: (<instance of GermanSocket>, 
+                         <InterfaceClass __builtin__.IUSSocket>)
+
+
+but you could use the 'dvd' adapter in this case of course. ;)
+
+Sometimes you want to know all adapters that are available. Let's say you want
+to know about all the adapters that convert a German to a US socket type:
+
+  >>> sockets = capi.getAdapters((bathroomDE,), IUSSocket)
+  >>> len(sockets)
+  3
+  >>> names = [name for name, socket in sockets]
+  >>> names.sort()
+  >>> names
+  [u'', u'dvd', u'shaver']
+
+`capi.getAdapters()` returns a list of tuples. The first entry of the tuple is
+the name of the adapter and the second is the adapter itself.
+
+
+Multi-Adapters
+++++++++++++++
+
+After watching all the DVDs you brought at least twice, you get tired of them
+and you want to listen to some music using your MP3 player. But darn, the MP3
+player plug has a ground pin and all the adapters you have do not support
+that:
+
+  >>> class IUSGroundedSocket(IUSSocket):
+  ...     pass
+
+So you go out another time to buy an adapter. This time, however, you do not
+buy yet another adapter, but a piece that provides the grounding plug:
+
+  >>> class IGrounder(Interface):
+  ...     pass
+
+  >>> class Grounder(object):
+  ...     implements(IGrounder)
+  ...     def __repr__(self):
+  ...         return '<instance of Grounder>'
+
+
+Then together they will provided a grounded us socket:
+
+  >>> class GroundedGermanToUSSocketAdapter(object):
+  ...     implements(IUSGroundedSocket)
+  ...     __used_for__ = (IGermanSocket, IGrounder)
+  ...     def __init__(self, socket, grounder):
+  ...         self.socket, self.grounder = socket, grounder
+
+You now register the combination, so that you know you can create a
+`IUSGroundedSocket`:
+
+  >>> gsm.registerAdapter((IGermanSocket, IGrounder), IUSGroundedSocket, 'mp3',
+  ...                    GroundedGermanToUSSocketAdapter)
+
+Given the grounder
+
+  >>> grounder = Grounder()
+
+and a German socket
+
+  >>> livingroom = GermanSocket()
+
+we can now get a gounded US socket:
+
+  >>> socket = capi.getMultiAdapter((livingroom, grounder), 
+  ...                               IUSGroundedSocket, 'mp3')
+
+  >>> socket.__class__ is GroundedGermanToUSSocketAdapter
+  True
+  >>> socket.socket is livingroom
+  True
+  >>> socket.grounder is grounder
+  True
+
+Of course, you do not have a 'dvd' grounded US socket available:
+
+  >>> capi.getMultiAdapter((livingroom, grounder), IUSGroundedSocket, 
+  ...                      'dvd') #doctest: +NORMALIZE_WHITESPACE
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: ((<instance of GermanSocket>, 
+                          <instance of Grounder>), 
+                         <InterfaceClass __builtin__.IUSGroundedSocket>)
+
+
+  >>> socket = capi.queryMultiAdapter((livingroom, grounder), 
+  ...                                 IUSGroundedSocket, 'dvd', marker)
+  >>> socket is marker
+  True
+
+Again, you might want to read `adapter.txt` in `zope.interface` for a more
+comprehensive coverage of multi-adapters.
+
+Subscribers
+-----------
+
+While subscribers are directly supported by the adapter registry and are
+adapters for all theoretical purposes, practically it might be better to think
+of them as separate components. Subscribers are particularly useful for
+events.
+
+Let's say one of our adapters overheated and caused a small fire:
+
+  >>> class IFire(Interface):
+  ...     pass
+
+  >>> class Fire(object):
+  ...     implements(IFire)
+
+  >>> fire = Fire()
+
+We want to use all available objects to put out the fire:
+
+  >>> class IFireExtinguisher(Interface):
+  ...     def extinguish():
+  ...         pass
+
+  >>> class FireExtinguisher(object):
+  ...     def __init__(self, fire):
+  ...         pass
+  ...     def extinguish(self):
+  ...         "Place extinguish code here."
+  ...         print 'Used ' + self.__class__.__name__ + '.'
+
+Here some specific methods to put out the fire:
+
+  >>> class PowderExtinguisher(FireExtinguisher):
+  ...     pass
+  >>> gsm.subscribe((IFire,), IFireExtinguisher, PowderExtinguisher)
+
+  >>> class Blanket(FireExtinguisher):
+  ...     pass
+  >>> gsm.subscribe((IFire,), IFireExtinguisher, Blanket)
+
+  >>> class SprinklerSystem(FireExtinguisher):
+  ...     pass
+  >>> gsm.subscribe((IFire,), IFireExtinguisher, SprinklerSystem)
+
+Now let use all these things to put out the fire:
+
+  >>> extinguishers = capi.subscribers((fire,), IFireExtinguisher)
+  >>> extinguishers.sort()
+  >>> for extinguisher in extinguishers:
+  ...     extinguisher.extinguish()
+  Used Blanket.
+  Used PowderExtinguisher.
+  Used SprinklerSystem.
+
+If no subscribers are found for a particular object, then an empty list is
+returned: 
+
+  >>> capi.subscribers((object(),), IFireExtinguisher)
+  []
+
+
+Utilities
+---------
+
+Utilities are the second type of component, the component architecture
+implements. *Utilities* are simply components that provide an interface. When
+you register an utility, you always register an instance (in cotrast to a
+factory for adapters) since the initialization and setup process of a utility
+might be complex and is not well defined. In some ways a utility is much more
+fundamental than an adapter, because an adapter cannot be used without another
+component, but a utility is always self-contained. I like to think of
+utilities as the foundation of your application and adapters as components
+extending beyond this foundation.
+
+Back to our story...
+
+After your vacation is over you fly back home to Tampa, Florida. But it is
+August now, the middle of the Hurrican season. And, believe it or not, you are
+worried that you will not be able to shave when the power goes out for several
+days. (You just hate wet shavers.)
+
+So you decide to go to your favorite hardware store and by a Diesel-powered
+electric generator. The generator provides of course a US-style socket:
+
+  >>> class Generator(object):
+  ...     implements(IUSSocket)
+  ...     def __repr__(self):
+  ...         return '<instance of Generator>'
+
+  >>> generator = Generator()
+
+Like for adapters, we now have to add the newly-acquired generator to our
+inventory by registering it as a utility:
+
+  >>> gsm.registerUtility(IUSSocket, generator)
+
+We can now get the utility using
+
+  >>> utility = capi.getUtility(IUSSocket)
+  >>> utility is generator
+  True
+
+As you can see, it is very simple to register and retrieve utilities. If a
+utility does not exsist for a particular interface, such as the German socket,
+then the lookup fails
+
+  >>> capi.getUtility(IGermanSocket)
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: (<InterfaceClass __builtin__.IGermanSocket>, '')
+
+or more gracefully when specifying a default value:
+
+  >>> default = object()
+  >>> utility = capi.queryUtility(IGermanSocket, default=default)
+  >>> utility is default
+  True
+
+Note: The only difference between `getUtility()` and `queryUtility()` is the
+fact that you can specify a default value for the latter function, so that it
+will never cause a `ComponentLookupError`.
+
+
+Named Utilities
++++++++++++++++
+
+It is often desirable to have several utilities providing the same interface
+per site. This way you can implement any sort of registry using utilities. For
+this reason, utilities -- like adapters -- can be named.
+
+In the context of our story, we might want to do the following: You really do
+not trust gas stations either. What if the roads are blocked after a hurricane
+and the gas stations run out of oil. So you look for another renewable power
+source. Then you think about solar panels! After a storm there is usually very
+nice weather, so why not? Via the Web you order a set of 110V/120W solar
+panels that provide a regular US-style socket as output:
+
+  >>> class SolarPanel(object):
+  ...     implements(IUSSocket)
+  ...     def __repr__(self):
+  ...         return '<instance of Solar Panel>'
+
+  >>> panel = SolarPanel()
+
+Once it arrives, we add it to our inventory:
+
+  >>> gsm.registerUtility(IUSSocket, panel, 'Solar Panel')
+
+You can now access the solar panel using
+
+  >>> utility = capi.getUtility(IUSSocket, 'Solar Panel')
+  >>> utility is panel
+  True
+
+Of course, if a utility is not available, then the lookup will simply fail
+
+  >>> capi.getUtility(IUSSocket, 'Wind Mill')
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: (<InterfaceClass __builtin__.IUSSocket>, 'Wind Mill')
+
+or more gracefully when specifying a default value:
+
+  >>> default = object()
+  >>> utility = capi.queryUtility(IUSSocket, 'Wind Mill', default=default)
+  >>> utility is default
+  True
+
+Now you want to look at all the utilities you have for a particular kind. The
+following API function will return a list of name/utility pairs:
+
+  >>> utils = list(capi.getUtilitiesFor(IUSSocket))
+  >>> utils.sort()
+  >>> utils #doctest: +NORMALIZE_WHITESPACE
+  [(u'', <instance of Generator>), 
+   (u'Solar Panel', <instance of Solar Panel>)]
+
+Another method of looking up all utilities is by using
+`getAllUtilitiesRegisteredFor(iface)`. This function will return an iteratable
+of utilities (without names); however, it will also return overridden
+utilities. If you are not using multiple site managers, you will not actually
+need this method.
+
+  >>> utils = list(capi.getAllUtilitiesRegisteredFor(IUSSocket))
+  >>> utils.sort()
+  >>> utils
+  [<instance of Generator>, <instance of Solar Panel>]
+
+
+Factories
++++++++++
+
+A *factory* is a special kind of utility that exists to create other
+components. A factory is always identified by a name. It also provides a title
+and description and is able to tell the developer what interfaces the created
+object will provide. The advantage of using a factory to create an object
+instead of directly isntantiating a class or executing any other callable is
+that we can refer to the factory by name. As long as the name stays fixed, the
+implementation of the callable can be renamed or moved without a breakage in
+code.
+
+Let's say that our solar panel comes in parts and they have to be
+assembled. This assembly would be done by a factory, so let's create one for
+the solar panel. To do this, we can use a standard implementation of the
+`IFactory` interface:
+
+  >>> from zope.component.factory import Factory
+  >>> factory = Factory(SolarPanel, 
+  ...                   'Solar Panel',
+  ...                   'This factory creates a solar panel.')
+
+Optionally, I could have also specifed the interfaces that the created object
+will provide, but the factory class is smart enough to determine the
+implemented interface from the class. We now register the factory:
+
+  >>> from zope.component.interfaces import IFactory
+  >>> gsm.registerUtility(IFactory, factory, 'SolarPanel')
+
+We can now get a list of interfaces the produced object will provide:
+
+  >>> ifaces = capi.getFactoryInterfaces('SolarPanel')
+  >>> IUSSocket in ifaces
+  True
+
+By the way, this is equivalent to
+
+  >>> ifaces2 = factory.getInterfaces()
+  >>> ifaces is ifaces2
+  True
+
+Of course you can also just create an object:
+
+  >>> panel = capi.createObject(None, 'SolarPanel')
+  >>> panel.__class__ is SolarPanel
+  True
+
+Note: Ignore the first argument (`None`) for now; it is the context of the
+utility lookup, which is usually an optional argument, but cannot be in this
+case, since all other arguments beside the `name` are passed in as arguments
+to the specified callable.
+
+Once you register several factories
+
+  >>> gsm.registerUtility(IFactory, Factory(Generator), 'Generator')
+
+you can also determine, which available factories will create objects
+providing a certian interface:
+
+  >>> factories = capi.getFactoriesFor(IUSSocket)
+  >>> factories = [(name, factory.__class__) for name, factory in factories]
+  >>> factories.sort()
+  >>> factories #doctest: +NORMALIZE_WHITESPACE
+  [(u'Generator', <class 'zope.component.factory.Factory'>), 
+   (u'SolarPanel', <class 'zope.component.factory.Factory'>)]
+
+
+Site Managers
+-------------
+
+Why do we need site managers? Why is the component architecture API not
+sufficient? Some applications, including Zope 3, have a concept of
+locations. It is often desireable to have different configurations for these
+location; this can be done by overwriting existing or adding new component
+registrations. Site managers in locations below the root location, should be
+able to delegate requests to their parent locations. The root site manager is
+commonly known as *global site manager*, since it is always available. You can
+always get the global site manager using the API:
+
+  >>> gsm = capi.getGlobalSiteManager()
+
+  >>> from zope.component.site import globalSiteManager
+  >>> gsm is globalSiteManager
+  True
+  >>> from zope.component.interfaces import ISiteManager
+  >>> ISiteManager.providedBy(gsm)
+  True
+  >>> from zope.component.site import IGlobalSiteManager
+  >>> IGlobalSiteManager.providedBy(gsm)
+  True
+
+You can also lookup at site manager in a given context. The only requirement
+is that the context can be adapted to a site manager. So let's create a
+special site manager:
+
+  >>> from zope.component.site import SiteManager
+  >>> sm = SiteManager()
+
+Now we create a context that adapts to the site manager via the `__conform__`
+method as specied in PEP 246.
+
+  >>> class Context(object):
+  ...     def __init__(self, sm):
+  ...         self.sm = sm
+  ...     def __conform__(self, interface):
+  ...         if interface.isOrExtends(ISiteManager):
+  ...             return self.sm
+
+We now instantiate the `Context` with our special site manager:
+
+  >>> context = Context(sm)
+  >>> context.sm is sm
+  True
+
+We can now ask for the site manager of this context:
+
+  >>> lsm = capi.getSiteManager(context)
+  >>> lsm is sm
+  True
+
+The site manager instance `lsm` is formally known as a *local site manager* of
+`context`.
+
+

Modified: Zope3/branches/srichter-blow-services/src/zope/component/__init__.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/__init__.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/__init__.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -16,16 +16,45 @@
 $Id$
 """
 import sys
-import warnings
 from zope.interface import moduleProvides, Interface, providedBy
-from zope.interface.interfaces import IInterface
-from zope.component.interfaces import IComponentArchitecture, IFactory
-from zope.component.interfaces import IServiceService
+from zope.component.interfaces import IComponentArchitecture
 from zope.component.interfaces import IDefaultViewName
-from zope.component.exceptions import ComponentLookupError
-from zope.component.service import serviceManager
-from zope.component.servicenames import Adapters, Utilities
+from zope.component.interfaces import IFactory
+from zope.component.interfaces import ISiteManager
+from zope.component.interfaces import ComponentLookupError
+from zope.component.site import globalSiteManager
 
+##############################################################################
+# BBB: Import some backward-compatibility; 12/10/2004
+from zope.component.bbb import exceptions
+sys.modules['zope.component.exceptions'] = exceptions
+from zope.component.bbb import service
+sys.modules['zope.component.service'] = service
+from zope.component.bbb import adapter
+sys.modules['zope.component.adapter'] = adapter
+from zope.component.bbb import utility
+sys.modules['zope.component.utility'] = utility
+from zope.component.bbb import servicenames
+sys.modules['zope.component.servicenames'] = servicenames
+from zope.component.bbb import contextdependent
+sys.modules['zope.component.contextdependent'] = contextdependent
+
+service.__warn__ = False
+service.serviceManager = service.GlobalServiceManager(
+    'serviceManager', __name__, globalSiteManager)
+service.__warn__ = True
+
+from zope.component.bbb import getGlobalServices, getGlobalService
+from zope.component.bbb import getServices, getService
+from zope.component.bbb import getServiceDefinitions
+from zope.component.bbb import getView, queryView
+from zope.component.bbb import getMultiView, queryMultiView
+from zope.component.bbb import getViewProviding, queryViewProviding
+from zope.component.bbb import getDefaultViewName, queryDefaultViewName
+from zope.component.bbb import getResource, queryResource
+##############################################################################
+
+
 # Try to be hookable. Do so in a try/except to avoid a hard dependency.
 try:
     from zope.hookable import hookable
@@ -36,65 +65,27 @@
 moduleProvides(IComponentArchitecture)
 __all__ = tuple(IComponentArchitecture)
 
-def warningLevel():
-    """Returns the number of the first stack frame outside of zope.component"""
-    try:
-        level = 2
-        while sys._getframe(level).f_globals['__name__'] == 'zope.component':
-            level += 1
-        return level
-    except ValueError:
-        return 2
+# SiteManager API
 
-def getGlobalServices():
-    return serviceManager
+def getGlobalSiteManager():
+    return globalSiteManager
 
-def getGlobalService(name):
-    return serviceManager.getService(name)
-
-def getServices(context=None):
+def getSiteManager(context=None):
     if context is None:
-        return serviceManager
+        return getGlobalSiteManager()
     else:
-        # Use the global service manager to adapt context to IServiceService
-        # to avoid the recursion implied by using a local getAdapter call.
+        # Use the global site manager to adapt context to `ISiteManager`
+        # to avoid the recursion implied by using a local `getAdapter()` call.
         try:
-            return IServiceService(context)
+            return ISiteManager(context)
         except TypeError, error:
             raise ComponentLookupError(*error.args)
 
-getServices = hookable(getServices)
+getSiteManager = hookable(getSiteManager)
 
-def getService(name, context=None):
-    return getServices(context).getService(name)
 
-def getServiceDefinitions(context=None):
-    return getServices(context).getServiceDefinitions()
+# Adapter API
 
-# Utility service
-
-def getUtility(interface, name='', context=None):
-    return getService(Utilities, context=context).getUtility(interface, name)
-
-def queryUtility(interface, name='', default=None, context=None):
-    return getService(Utilities, context).queryUtility(
-        interface, name, default)
-
-def getUtilitiesFor(interface, context=None):
-    if not IInterface.providedBy(interface):
-        raise TypeError("getUtilitiesFor got nonsense arguments."
-                        " Check that you are updated with the"
-                        " component API change.")
-    return getService(Utilities, context).getUtilitiesFor(interface)
-
-
-def getAllUtilitiesRegisteredFor(interface, context=None):
-    return getService(Utilities, context
-                      ).getAllUtilitiesRegisteredFor(interface)
-
-
-# Adapter service
-
 def getAdapterInContext(object, interface, context):
     adapter = queryAdapterInContext(object, interface, context)
     if adapter is None:
@@ -126,8 +117,7 @@
     if interface.providedBy(object):
         return object
 
-    adapters = getService(Adapters, context)
-    return adapters.queryAdapter(object, interface, '', default)
+    return getSiteManager(context).queryAdapter(object, interface, '', default)
 
 def getAdapter(object, interface, name, context=None):
     adapter = queryAdapter(object, interface, name, None, context)
@@ -135,24 +125,11 @@
         raise ComponentLookupError(object, interface)
     return adapter
 
-def adapter_hook(interface, object, name='', default=None):
-    try:
-        adapters = getService(Adapters)
-    except ComponentLookupError:
-        # Oh blast, no adapter service. We're probably just running
-        # from a test
-        return None
-    return adapters.queryAdapter(object, interface, name, default)
-adapter_hook = hookable(adapter_hook)
-
-import zope.interface.interface
-zope.interface.interface.adapter_hooks.append(adapter_hook)
-
 def queryAdapter(object, interface, name, default=None, context=None):
     if context is None:
         return adapter_hook(interface, object, name, default)
-    adapters = getService(Adapters, context)
-    return adapters.queryAdapter(object, interface, name, default)
+    return getSiteManager(context).queryAdapter(object, interface, name,
+                                                default)
 
 def getMultiAdapter(objects, interface, name=u'', context=None):
     adapter = queryMultiAdapter(objects, interface, name, context=context)
@@ -163,33 +140,70 @@
 def queryMultiAdapter(objects, interface, name=u'', default=None,
                       context=None):
     try:
-        adapters = getService(Adapters, context)
+        sitemanager = getSiteManager(context)
     except ComponentLookupError:
-        # Oh blast, no adapter service. We're probably just running from a test
+        # Oh blast, no site manager. This should *never* happen!
         return default
 
-    return adapters.queryMultiAdapter(objects, interface, name, default)
+    return sitemanager.queryMultiAdapter(objects, interface, name, default)
 
 def getAdapters(objects, provided, context=None):
     try:
-        adapters = getService(Adapters, context)
+        sitemanager = getSiteManager(context)
     except ComponentLookupError:
-        # Oh blast, no adapter service. We're probably just running from a test
+        # Oh blast, no site manager. This should *never* happen!
         return []
-    return [(name, adapter(*objects))
-            for name, adapter in adapters.lookupAll(map(providedBy, objects),
-                                                    provided)
-            ]
+    return sitemanager.getAdapters(objects, provided)
 
+
 def subscribers(objects, interface, context=None):
     try:
-        adapters = getService(Adapters, context=context)
+        sitemanager = getSiteManager(context)
     except ComponentLookupError:
-        # Oh blast, no adapter service. We're probably just running from a test
+        # Oh blast, no site manager. This should *never* happen!
         return []
-    return adapters.subscribers(objects, interface)
+    return sitemanager.subscribers(objects, interface)
 
+#############################################################################
+# Register the component architectures adapter hook, with the adapter hook
+# registry of the `zope.inteface` package. This way we will be able to call
+# interfaces to create adapters for objects. For example, `I1(ob)` is
+# equvalent to `getAdapterInContext(I1, ob, '')`.
+def adapter_hook(interface, object, name='', default=None):
+    try:
+        sitemanager = getSiteManager()
+    except ComponentLookupError:
+        # Oh blast, no site manager. This should *never* happen!
+        return None
+    return sitemanager.queryAdapter(object, interface, name, default)
 
+# Make the component architecture's adapter hook hookable 
+adapter_hook = hookable(adapter_hook)
+
+import zope.interface.interface
+zope.interface.interface.adapter_hooks.append(adapter_hook)
+#############################################################################
+
+
+# Utility API
+
+def getUtility(interface, name='', context=None):
+    utility = queryUtility(interface, name, context=context)
+    if utility is not None:
+        return utility
+    raise ComponentLookupError(interface, name)
+
+def queryUtility(interface, name='', default=None, context=None):
+    return getSiteManager(context).queryUtility(interface, name, default)
+
+def getUtilitiesFor(interface, context=None):
+    return getSiteManager(context).getUtilitiesFor(interface)
+
+
+def getAllUtilitiesRegisteredFor(interface, context=None):
+    return getSiteManager(context).getAllUtilitiesRegisteredFor(interface)
+
+
 # Factories
 
 def createObject(context, name, *args, **kwargs):
@@ -199,7 +213,7 @@
     return getUtility(IFactory, name, context).getInterfaces()
 
 def getFactoriesFor(interface, context=None):
-    utils = getService(Utilities, context)
+    utils = getSiteManager(context)
     for (name, factory) in utils.getUtilitiesFor(IFactory):
         interfaces = factory.getInterfaces()
         try:
@@ -210,73 +224,3 @@
                 if iface.isOrExtends(interface):
                     yield name, factory
                     break
-
-
-# Presentation API
-
-def getView(object, name, request, providing=Interface, context=None):
-    view = queryView(object, name, request, context=context,
-                     providing=providing)
-    if view is not None:
-        return view
-
-    raise ComponentLookupError("Couldn't find view",
-                               name, object, context, request, providing)
-
-def queryView(object, name, request,
-              default=None, providing=Interface, context=None):
-    return queryMultiAdapter((object, request), providing, name,
-                             default, context)
-
-queryView = hookable(queryView)
-
-def getMultiView(objects, request, providing=Interface, name='', context=None):
-    view = queryMultiView(objects, request, providing, name, context=context)
-    if view is not None:
-        return view
-
-    raise ComponentLookupError("Couldn't find view",
-                               name, objects, context, request)
-
-def queryMultiView(objects, request, providing=Interface, name='',
-                   default=None, context=None):
-    return queryMultiAdapter(objects+(request,), providing, name,
-                             default, context)
-
-def getViewProviding(object, providing, request, context=None):
-    return getView(object, '', request, providing, context)
-
-def queryViewProviding(object, providing, request, default=None, 
-                       context=None):
-    return queryView(object, '', request, default, providing, context)
-
-def getDefaultViewName(object, request, context=None):
-    view = queryDefaultViewName(object, request, context=context)
-    if view is not None:
-        return view
-
-    raise ComponentLookupError("Couldn't find default view name",
-                               context, request)
-
-def queryDefaultViewName(object, request, default=None, context=None):
-    try:
-        adapters = getService(Adapters, context)
-    except ComponentLookupError:
-        # Oh blast, no adapter service. We're probably just running from a test
-        return default
-
-    name = adapters.lookup(map(providedBy, (object, request)), IDefaultViewName)
-    if name is not None:
-        return name
-    return default
-
-def getResource(name, request, providing=Interface, context=None):
-    view = queryResource(name, request, providing=providing, context=context)
-    if view is not None:
-        return view
-
-    raise ComponentLookupError("Couldn't find resource", name, request)
-
-def queryResource(name, request, default=None, providing=Interface,
-                  context=None):
-    return queryAdapter(request, providing, name, default, context)

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/adapter.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/adapter.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/adapter.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,210 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Global Adapter Service
-
-$Id$
-"""
-import sys
-import warnings
-from types import ClassType
-
-from zope.component.exceptions import ComponentLookupError
-from zope.component.interfaces import IAdapterService, IRegistry
-from zope.component.service import GlobalService
-from zope.interface.adapter import AdapterRegistry
-from zope.interface import implements, providedBy, Interface, implementedBy
-from zope.interface.interfaces import IInterface
-
-class IGlobalAdapterService(IAdapterService, IRegistry):
-
-    def register(required, provided, name, factory, info=''):
-        """Register an adapter factory
-
-        :Parameters:
-          - `required`: a sequence of specifications for objects to be
-             adapted. 
-          - `provided`: The interface provided by the adapter
-          - `name`: The adapter name
-          - `factory`: The object used to compute the adapter
-          - `info`: Provide some info about this particular adapter.
-        """
-
-    def subscribe(required, provided, factory, info=''):
-        """Register a subscriber factory
-
-        :Parameters:
-          - `required`: a sequence of specifications for objects to be
-             adapted. 
-          - `provided`: The interface provided by the adapter
-          - `name`: The adapter name
-          - `factory`: The object used to compute the subscriber
-          - `info`: Provide some info about this particular adapter.
-        """
-
-class AdapterService(AdapterRegistry):
-    """Base implementation of an adapter service, implementing only the
-    'IAdapterService' interface.
-
-    No write-methods were implemented.
-    """
-
-    implements(IAdapterService)
-
-class GlobalAdapterService(AdapterService, GlobalService):
-    """Global Adapter Service implementation."""
-
-    implements(IGlobalAdapterService)
-
-    def __init__(self):
-        AdapterRegistry.__init__(self)
-        self._registrations = {}
-
-    def register(self, required, provided, name, factory, info=''):
-        """Register an adapter
-
-        >>> registry = GlobalAdapterService()
-        >>> class R1(Interface):
-        ...     pass
-        >>> class R2(R1):
-        ...     pass
-        >>> class P1(Interface):
-        ...     pass
-        >>> class P2(P1):
-        ...     pass
-
-        >>> registry.register((R1, ), P2, 'bob', 'c1', 'd1')
-        >>> registry.register((R1, ), P2,    '', 'c2', 'd2')
-        >>> registry.lookup((R2, ), P1, '')
-        'c2'
-
-        >>> registrations = map(repr, registry.registrations())
-        >>> registrations.sort()
-        >>> for registration in registrations:
-        ...    print registration
-        AdapterRegistration(('R1',), 'P2', '', 'c2', 'd2')
-        AdapterRegistration(('R1',), 'P2', 'bob', 'c1', 'd1')
-
-        Let's make sure that we can also register regular classes for
-        adaptation.
-
-        >>> class O1(object):
-        ...     pass
-        >>> class O2(object):
-        ...     pass
-        >>> class O3(object):
-        ...     def __init__(self, obj1, obj2=None):
-        ...         pass
-
-        >>> registry.register((O1, ), R1, '', O3)
-        >>> registry.queryAdapter(O1(), R1, '').__class__
-        <class 'zope.component.adapter.O3'>
-
-        >>> registry.register((O1, O2), R1, '', O3)
-        >>> registry.queryMultiAdapter((O1(), O2()), R1, '').__class__
-        <class 'zope.component.adapter.O3'>
-        """
-        ifaces = []
-        for iface in required:
-            if not IInterface.providedBy(iface) and iface is not None:
-                if not isinstance(iface, (type, ClassType)):
-                    raise TypeError(iface, IInterface)
-                iface = implementedBy(iface)
-
-            ifaces.append(iface)
-        required = tuple(ifaces)
-
-        self._registrations[(required, provided, name)] = AdapterRegistration(
-            required, provided, name, factory, info)
-
-        AdapterService.register(self, required, provided, name, factory)
-
-    def subscribe(self, required, provided, factory, info=''):
-        """Register an subscriptions adapter
-
-        >>> registry = GlobalAdapterService()
-        >>> class R1(Interface):
-        ...     pass
-        >>> class R2(R1):
-        ...     pass
-        >>> class P1(Interface):
-        ...     pass
-        >>> class P2(P1):
-        ...     pass
-
-        >>> registry.subscribe((R1, ), P2, 'c1', 'd1')
-        >>> registry.subscribe((R1, ), P2, 'c2', 'd2')
-        >>> subscriptions = map(str, registry.subscriptions((R2, ), P1))
-        >>> subscriptions.sort()
-        >>> subscriptions
-        ['c1', 'c2']
-
-        >>> registrations = map(repr, registry.registrations())
-        >>> registrations.sort()
-        >>> for registration in registrations:
-        ...    print registration
-        SubscriptionRegistration(('R1',), 'P2', 'c1', 'd1')
-        SubscriptionRegistration(('R1',), 'P2', 'c2', 'd2')
-
-        """
-        required = tuple(required)
-
-        registration = SubscriptionRegistration(
-            required, provided, factory, info)
-
-        self._registrations[(required, provided)] = (
-            self._registrations.get((required, provided), ())
-            +
-            (registration, )
-            )
-
-        AdapterService.subscribe(self, required, provided, factory)
-
-    def registrations(self):
-        for registration in self._registrations.itervalues():
-            if isinstance(registration, tuple):
-                for r in registration:
-                    yield r
-            else:
-                yield registration
-
-
-class AdapterRegistration(object):
-    """Registration for a simple adapter."""
-
-    def __init__(self, required, provided, name, value, doc=''):
-        (self.required, self.provided, self.name, self.value, self.doc
-         ) = required, provided, name, value, doc
-
-    def __repr__(self):
-        return '%s(%r, %r, %r, %r, %r)' % (
-            self.__class__.__name__,
-            tuple([getattr(r, '__name__', None) for r in self.required]),
-            self.provided.__name__, self.name,
-            self.value, self.doc,
-            )
-
-
-class SubscriptionRegistration(object):
-    """Registration for a subscription adapter."""
-
-    def __init__(self, required, provided, value, doc):
-        (self.required, self.provided, self.value, self.doc
-         ) = required, provided, value, doc
-
-    def __repr__(self):
-        return '%s(%r, %r, %r, %r)' % (
-            self.__class__.__name__,
-            tuple([getattr(r, '__name__', None) for r in self.required]),
-            self.provided.__name__, self.value, self.doc,
-            )

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/__init__.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/__init__.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/__init__.py	2004-12-16 17:11:13 UTC (rev 28630)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/__init__.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,236 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Component Architecture API Backward-Compatibility
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+__warn__ = True
+
+import sys
+import warnings
+
+from zope.interface import Interface, providedBy
+from zope.component.bbb.interfaces import IServiceService, IDefaultViewName
+from zope.component.bbb.service import GlobalServiceManager
+
+# Try to be hookable. Do so in a try/except to avoid a hard dependency.
+try:
+    from zope.hookable import hookable
+except ImportError:
+    def hookable(ob):
+        return ob
+
+def warningLevel():
+    """Returns the number of the first stack frame outside of zope.component"""
+    try:
+        level = 2
+        while sys._getframe(level).f_globals['__name__']=='zope.component.bbb':
+            level += 1
+        return level
+    except ValueError:
+        return 2
+
+
+def getGlobalServices():
+    if __warn__:
+        warnings.warn(
+            "The concept of services has been deprecated. You probably want to "
+            "use `getGlobalSiteManager()`.",
+            DeprecationWarning, warningLevel())
+    from zope.component import getGlobalSiteManager
+    return GlobalServiceManager('servicemanager', 'zope.component.service',
+                                getGlobalSiteManager())
+
+def getGlobalService(name):
+    if __warn__:
+        warnings.warn(
+            "The concept of services has been deprecated. You probably want to "
+            "use `getGlobalSiteManager()` or `getUtility()`.",
+            DeprecationWarning, warningLevel())
+    return getGlobalServices().getService(name)
+
+def getServices(context=None):
+    if __warn__:
+        warnings.warn(
+            "The concept of services has been deprecated. You probably want to "
+            "use `getGlobalSiteManager()` or `getUtility()`.",
+            DeprecationWarning, warningLevel())
+    if context is None:
+        return getGlobalServices()
+    else:
+        # Use the global service manager to adapt context to IServiceService
+        # to avoid the recursion implied by using a local getAdapter call.
+        try:
+            return IServiceService(context)
+        except TypeError, error:
+            from zope.component.bbb.exceptions import ComponentLookupError
+            raise ComponentLookupError(*error.args)
+
+getServices = hookable(getServices)
+
+def getService(name, context=None):
+    if __warn__:
+        warnings.warn(
+            "The concept of services has been deprecated. You probably want to "
+            "use `getGlobalSiteManager()` or `getUtility()`.",
+            DeprecationWarning, warningLevel())
+    return getServices(context).getService(name)
+
+def getServiceDefinitions(context=None):
+    if __warn__:
+        warnings.warn(
+            "The concept of services has been deprecated.",
+            DeprecationWarning, warningLevel())
+    return getServices(context).getServiceDefinitions()
+
+# Presentation API
+
+def getView(object, name, request, providing=Interface, context=None):
+    if __warn__:
+        warnings.warn(
+            "The concrete concept of a view has been deprecated. You want to "
+            "use `getMultiAdapter((object, request), providing, name, "
+            "context)`.",
+            DeprecationWarning, warningLevel())
+    view = queryView(object, name, request, context=context,
+                     providing=providing)
+    if view is not None:
+        return view
+
+    from zope.component.bbb.exceptions import ComponentLookupError
+    raise ComponentLookupError("Couldn't find view",
+                               name, object, context, request, providing)
+
+def queryView(object, name, request,
+              default=None, providing=Interface, context=None):
+    if __warn__:
+        warnings.warn(
+            "The concrete concept of a view has been deprecated. You want to "
+            "use `queryMultiAdapter((object, request), providing, name, "
+            "default, context)`.",
+            DeprecationWarning, warningLevel())
+    from zope.component import queryMultiAdapter
+    return queryMultiAdapter((object, request), providing, name,
+                             default, context)
+
+queryView = hookable(queryView)
+
+def getMultiView(objects, request, providing=Interface, name='', context=None):
+    if __warn__:
+        warnings.warn(
+            "The concrete concept of a view has been deprecated. You want to "
+            "use `getMultiAdapter(objects+(request,), providing, name, "
+            "context)`.",
+            DeprecationWarning, warningLevel())
+    view = queryMultiView(objects, request, providing, name, context=context)
+    if view is not None:
+        return view
+
+    from zope.component.bbb.exceptions import ComponentLookupError
+    raise ComponentLookupError("Couldn't find view",
+                               name, objects, context, request)
+
+def queryMultiView(objects, request, providing=Interface, name='',
+                   default=None, context=None):
+    if __warn__:
+        warnings.warn(
+            "The concrete concept of a view has been deprecated. You want to "
+            "use `getMultiAdapter(objects+(request,), providing, name, "
+            "default, context)`.",
+            DeprecationWarning, warningLevel())
+    from zope.component import queryMultiAdapter
+    return queryMultiAdapter(objects+(request,), providing, name,
+                             default, context)
+
+def getViewProviding(object, providing, request, context=None):
+    if __warn__:
+        warnings.warn(
+            "The concrete concept of a view has been deprecated. You want to "
+            "use `getMultiAdapter((object, request), providing, name, "
+            "context)`.",
+            DeprecationWarning, warningLevel())
+    return getView(object, '', request, providing, context)
+
+def queryViewProviding(object, providing, request, default=None, 
+                       context=None):
+    if __warn__:
+        warnings.warn(
+            "The concrete concept of a view has been deprecated. You want to "
+            "use `queryMultiAdapter((object, request), providing, name, "
+            "default, context)`.",
+            DeprecationWarning, warningLevel())
+    return queryView(object, '', request, default, providing, context)
+
+def getDefaultViewName(object, request, context=None):
+    if __warn__:
+        warnings.warn(
+            "The concrete concept of a view has been deprecated. You want to "
+            "use `getSiteManager(context).lookup(map(providedBy, "
+            "(object, request)), IDefaultViewName)",
+            DeprecationWarning, warningLevel())
+    view = queryDefaultViewName(object, request, context=context)
+    if view is not None:
+        return view
+
+    from zope.component.bbb.exceptions import ComponentLookupError
+    raise ComponentLookupError("Couldn't find default view name",
+                               context, request)
+
+def queryDefaultViewName(object, request, default=None, context=None):
+    if __warn__:
+        warnings.warn(
+            "The concrete concept of a view has been deprecated. You want to "
+            "use `getSiteManager(context).lookup(map(providedBy, "
+            "(object, request)), IDefaultViewName)`",
+            DeprecationWarning, warningLevel())
+    from zope.component.bbb.exceptions import ComponentLookupError
+    from zope.component import getSiteManager
+    try:
+        adapters = getSiteManager(context)
+    except ComponentLookupError:
+        # Oh blast, no adapter service. We're probably just running from a test
+        return default
+
+    name = adapters.adapters.lookup(map(providedBy, (object, request)),
+                                    IDefaultViewName)
+    if name is not None:
+        return name
+    return default
+
+def getResource(name, request, providing=Interface, context=None):
+    if __warn__:
+        warnings.warn(
+            "The concrete concept of a resource has been deprecated. You want "
+            "to use `getAdapter(request, providing, name, context)`",
+            DeprecationWarning, warningLevel())
+    view = queryResource(name, request, providing=providing, context=context)
+    if view is not None:
+        return view
+
+    from zope.component.bbb.exceptions import ComponentLookupError
+    raise ComponentLookupError("Couldn't find resource", name, request)
+
+def queryResource(name, request, default=None, providing=Interface,
+                  context=None):
+    if __warn__:
+        warnings.warn(
+            "The concrete concept of a resource has been deprecated. You want "
+            "to use `queryAdapter(request, providing, name, default, context)`",
+            DeprecationWarning, warningLevel())
+    from zope.component import queryAdapter
+    return queryAdapter(request, providing, name, default, context)
+
+

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/adapter.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/adapter.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/adapter.py	2004-12-16 17:11:13 UTC (rev 28630)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/adapter.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,165 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Global Adapter Service
+
+$Id$
+"""
+import sys
+import warnings
+from types import ClassType
+
+from zope.component.exceptions import ComponentLookupError
+from zope.component.interfaces import IAdapterService, IRegistry
+from zope.component.bbb.service import GlobalService
+from zope.component.site import AdapterRegistration, SubscriptionRegistration
+from zope.interface import implements, providedBy, Interface, implementedBy
+from zope.interface.interfaces import IInterface
+
+class IGlobalAdapterService(IAdapterService, IRegistry):
+
+    def register(required, provided, name, factory, info=''):
+        """Register an adapter factory
+
+        :Parameters:
+          - `required`: a sequence of specifications for objects to be
+             adapted. 
+          - `provided`: The interface provided by the adapter
+          - `name`: The adapter name
+          - `factory`: The object used to compute the adapter
+          - `info`: Provide some info about this particular adapter.
+        """
+
+    def subscribe(required, provided, factory, info=''):
+        """Register a subscriber factory
+
+        :Parameters:
+          - `required`: a sequence of specifications for objects to be
+             adapted. 
+          - `provided`: The interface provided by the adapter
+          - `name`: The adapter name
+          - `factory`: The object used to compute the subscriber
+          - `info`: Provide some info about this particular adapter.
+        """
+
+class AdapterService(object):
+    """Base implementation of an adapter service, implementing only the
+    'IAdapterService' interface.
+
+    No write-methods were implemented.
+    """
+
+    implements(IAdapterService)
+
+    def __init__(self, sitemanager=None):
+        if sitemanager is None:
+            from zope.component.site import GlobalSiteManager
+            sitemanager = GlobalSiteManager()
+        self.sm = sitemanager
+
+    def __getattr__(self, name):
+        attr = getattr(self.sm.adapters, name)
+        if attr is not None:
+            return attr
+        raise AttributeError, name
+
+
+class GlobalAdapterService(AdapterService, GlobalService):
+    """Global Adapter Service implementation."""
+
+    implements(IGlobalAdapterService)
+
+    def __init__(self, sitemanager=None):
+        super(GlobalAdapterService, self).__init__(sitemanager)
+
+    def register(self, required, provided, name, factory, info=''):
+        """Register an adapter
+
+        >>> registry = GlobalAdapterService()
+        >>> class R1(Interface):
+        ...     pass
+        >>> class R2(R1):
+        ...     pass
+        >>> class P1(Interface):
+        ...     pass
+        >>> class P2(P1):
+        ...     pass
+
+        >>> registry.register((R1, ), P2, 'bob', 'c1', 'd1')
+        >>> registry.register((R1, ), P2,    '', 'c2', 'd2')
+        >>> registry.lookup((R2, ), P1, '')
+        'c2'
+
+        >>> registrations = map(repr, registry.registrations())
+        >>> registrations.sort()
+        >>> for registration in registrations:
+        ...    print registration
+        AdapterRegistration(('R1',), 'P2', '', 'c2', 'd2')
+        AdapterRegistration(('R1',), 'P2', 'bob', 'c1', 'd1')
+
+        Let's make sure that we can also register regular classes for
+        adaptation.
+
+        >>> class O1(object):
+        ...     pass
+        >>> class O2(object):
+        ...     pass
+        >>> class O3(object):
+        ...     def __init__(self, obj1, obj2=None):
+        ...         pass
+
+        >>> registry.register((O1, ), R1, '', O3)
+        >>> registry.queryAdapter(O1(), R1, '').__class__
+        <class 'zope.component.bbb.adapter.O3'>
+
+        >>> registry.register((O1, O2), R1, '', O3)
+        >>> registry.queryMultiAdapter((O1(), O2()), R1, '').__class__
+        <class 'zope.component.bbb.adapter.O3'>
+        """
+        self.sm.registerAdapter(required, provided, name, factory, info)
+
+    def subscribe(self, required, provided, factory, info=''):
+        """Register an subscriptions adapter
+
+        >>> registry = GlobalAdapterService()
+        >>> class R1(Interface):
+        ...     pass
+        >>> class R2(R1):
+        ...     pass
+        >>> class P1(Interface):
+        ...     pass
+        >>> class P2(P1):
+        ...     pass
+
+        >>> registry.subscribe((R1, ), P2, 'c1', 'd1')
+        >>> registry.subscribe((R1, ), P2, 'c2', 'd2')
+        >>> subscriptions = map(str, registry.subscriptions((R2, ), P1))
+        >>> subscriptions.sort()
+        >>> subscriptions
+        ['c1', 'c2']
+
+        >>> registrations = map(repr, registry.registrations())
+        >>> registrations.sort()
+        >>> for registration in registrations:
+        ...    print registration
+        SubscriptionRegistration(('R1',), 'P2', 'c1', 'd1')
+        SubscriptionRegistration(('R1',), 'P2', 'c2', 'd2')
+
+        """
+        self.sm.subscribe(required, provided, factory, info)
+
+    def registrations(self):
+        for registration in self.sm.registrations():
+            if isinstance(registration,
+                          (AdapterRegistration, SubscriptionRegistration)):
+                yield registration

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/contextdependent.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/contextdependent.py)

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/exceptions.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/exceptions.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/exceptions.py	2004-12-16 17:11:13 UTC (rev 28630)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/exceptions.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,24 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Exceptions used by the Component Architecture
+
+$Id$
+"""
+from zope.component.interfaces import ComponentLookupError
+from zope.component.interfaces import Invalid, Misused
+
+
+__all__ = ["ComponentLookupError",
+           "Invalid",
+           "Misused"]

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/interfaces.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/interfaces.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/interfaces.py	2004-12-16 17:11:13 UTC (rev 28630)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/interfaces.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,340 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Component Architecture Interfaces kept for Backward-Compatibility.
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from zope.interface import Interface, Attribute
+
+
+class IBBBComponentArchitecture(Interface):
+    """The Component Architecture is defined by six key services,
+    all of which are managed by service managers.
+    """
+
+    # basic service manager tools
+
+    def getGlobalServices():
+        """Get the global service manager."""
+
+    def getGlobalService(name):
+        """Get a global service."""
+
+    def getServices(context=None):
+        """Get the service manager
+
+        If context is None, an application-defined policy is used to choose
+        an appropriate service manager.
+
+        If 'context' is not None, context is adapted to IServiceService, and
+        this adapter is returned.
+        """
+
+    def getService(name, context=None):
+        """Get a named service.
+
+        Returns the service defined by 'name' from the service manager.
+
+        If context is None, an application-defined policy is used to choose
+        an appropriate service manager.
+
+        If 'context' is not None, context is adapted to IServiceService, and
+        this adapter is returned.
+        """
+
+    def getServiceDefinitions(context=None):
+        """Get service definitions
+
+        Returns a dictionary of the service definitions from the service
+        manager in the format {nameString: serviceInterface}.
+
+        The default behavior of placeful service managers is to include
+        service definitions above them, but this can be overridden.
+
+        If context is None, an application-defined policy is used to choose
+        an appropriate service manager.
+
+        If 'context' is not None, context is adapted to IServiceService, and
+        this adapter is returned.
+        """
+
+    # Presentation service
+
+    def getView(object, name, request, providing=Interface, context=None):
+        """Get a named view for a given object.
+
+        The request must implement IPresentationRequest: it provides
+        the view type and the skin name.  The nearest one to the
+        object is found. If a matching view cannot be found, raises
+        ComponentLookupError.
+        """
+
+    def queryView(object, name, request,
+                  default=None, providing=Interface, context=None):
+        """Look for a named view for a given object.
+
+        The request must implement IPresentationRequest: it provides
+        the view type and the skin name.  The nearest one to the
+        object is found.  If a matching view cannot be found, returns
+        default.
+
+        If context is not specified, attempts to use object to specify
+        a context.
+        """
+
+    def getMultiView(objects, request, providing=Interface, name='',
+                     context=None):
+        """Look for a multi-view for given objects
+
+        The request must implement IPresentationRequest: it provides
+        the view type and the skin name.  The nearest one to the
+        object is found.  If a matching view cannot be found, raises
+        ComponentLookupError.
+
+        If context is not specified, attempts to use the first object
+        to specify a context.
+        """
+
+    def queryMultiView(objects, request, providing=Interface, name='',
+                       default=None, context=None):
+        """Look for a multi-view for given objects
+
+        The request must implement IPresentationRequest: it provides
+        the view type and the skin name.  The nearest one to the
+        object is found.  If a matching view cannot be found, returns
+        default.
+
+        If context is not specified, attempts to use the first object
+        to specify a context.
+        """
+
+    def getViewProviding(object, providing, request, context=None):
+        """Look for a view based on the interface it provides.
+
+        A call to this method is equivalent to:
+
+            getView(object, '', request, context, providing)
+        """
+
+    def queryViewProviding(object, providing, request,
+                           default=None, context=None):
+        """Look for a view that provides the specified interface.
+
+        A call to this method is equivalent to:
+
+            queryView(object, '', request, default, context, providing)
+        """
+
+    def getDefaultViewName(object, request, context=None):
+        """Get the name of the default view for the object and request.
+
+        The request must implement IPresentationRequest, and provides the
+        desired view type.  The nearest one to the object is found.
+        If a matching default view name cannot be found, raises
+        ComponentLookupError.
+
+        If context is not specified, attempts to use
+        object to specify a context.
+        """
+
+    def queryDefaultViewName(object, request, default=None, context=None):
+        """Look for the name of the default view for the object and request.
+
+        The request must implement IPresentationRequest, and provides
+        the desired view type.  The nearest one to the object is
+        found.  If a matching default view name cannot be found,
+        returns the default.
+
+        If context is not specified, attempts to use object to specify
+        a context.
+        """
+
+    def getResource(name, request, providing=Interface, context=None):
+        """Get a named resource for a given request
+
+        The request must implement IPresentationRequest.
+
+        The context provides a place to look for placeful resources.
+
+        A ComponentLookupError will be raised if the component can't
+        be found.
+        """
+
+    def queryResource(name, request, default=None, providing=Interface,
+                      context=None):
+        """Get a named resource for a given request
+
+        The request must implement IPresentationRequest.
+
+        The context provides a place to look for placeful resources.
+
+        If the component can't be found, the default is returned.
+        """
+
+
+class IServiceService(Interface):
+    """A service to manage Services."""
+
+    def getServiceDefinitions():
+        """Retrieve all Service Definitions
+
+        Should return a list of tuples (name, interface)
+        """
+
+    def getInterfaceFor(name):
+        """Retrieve the service interface for the given name
+        """
+
+    def getService(name):
+        """Retrieve a service implementation
+
+        Raises ComponentLookupError if the service can't be found.
+        """
+
+
+class IUtilityService(Interface):
+    """A service to manage Utilities."""
+
+    def getUtility(interface, name=''):
+        """Look up a utility that provides an interface.
+
+        If one is not found, raises ComponentLookupError.
+        """
+
+    def queryUtility(interface, name='', default=None):
+        """Look up a utility that provides an interface.
+
+        If one is not found, returns default.
+        """
+
+    def getUtilitiesFor(interface):
+        """Look up the registered utilities that provide an interface.
+
+        Returns an iterable of name-utility pairs.
+        """
+
+    def getAllUtilitiesRegisteredFor(interface):
+        """Return all registered utilities for an interface
+
+        This includes overwridden utilities.
+
+        An iterable of utility instances is returned.  No names are
+        returned.
+        """
+
+class IAdapterService(Interface):
+    """A service to manage Adapters."""
+
+    def queryAdapter(object, interface, name, default=None):
+        """Look for a named adapter to an interface for an object
+
+        If a matching adapter cannot be found, returns the default.
+
+        The name consisting of an empty string is reserved for unnamed
+        adapters. The unnamed adapter methods will often call the
+        named adapter methods with an empty string for a name.
+        """
+
+    def queryMultiAdapter(objects, interface, name, default=None):
+        """Look for a multi-adapter to an interface for an object
+
+        If a matching adapter cannot be found, returns the default.
+
+        The name consisting of an empty string is reserved for unnamed
+        adapters. The unnamed adapter methods will often call the
+        named adapter methods with an empty string for a name.
+        """
+
+    def subscribers(required, provided):
+        """Get subscribers
+
+        Subscribers are returned that provide the provided interface
+        and that depend on and are comuted from the sequence of
+        required objects.
+        """
+
+
+class IContextDependent(Interface):
+    """Components implementing this interface must have a context component.
+
+    Usually the context must be one of the arguments of the
+    constructor. Adapters and views are a primary example of context-dependent
+    components.
+    """
+
+    context = Attribute(
+        """The context of the object
+
+        This is the object being adapted, viewed, extended, etc.
+        """)
+
+
+class IPresentation(Interface):
+    """Presentation components provide interfaces to external actors
+
+    The are created for requests, which encapsulate external actors,
+    connections, etc.
+    """
+
+    request = Attribute(
+        """The request
+
+        The request is a surrogate for the user. It also provides the
+        presentation type and skin. It is of type
+        IPresentationRequest.
+        """)
+
+
+class IPresentationRequest(Interface):
+    """An IPresentationRequest provides methods for getting view meta data."""
+
+
+class IResource(IPresentation):
+    """Resources provide data to be used for presentation."""
+
+
+class IResourceFactory(Interface):
+    """A factory to create factories using the request."""
+
+    def __call__(request):
+        """Create a resource for a request
+
+        The request must be an IPresentationRequest.
+        """
+
+
+class IView(IPresentation, IContextDependent):
+    """Views provide a connection between an external actor and an object"""
+
+
+class IViewFactory(Interface):
+    """Objects for creating views"""
+
+    def __call__(context, request):
+        """Create an view (IView) object
+
+        The context aregument is the object displayed by the view. The
+        request argument is an object, such as a web request, that
+        "stands in" for the user.
+        """
+
+
+class IDefaultViewName(Interface):
+    """A string that contains the default view name
+
+    A default view name is used to select a view when a user hasn't
+    specified one.
+    """

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/service.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/service.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/service.py	2004-12-16 17:11:13 UTC (rev 28630)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/service.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,169 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Service Manager implementation
+
+$Id$
+"""
+__warn__ = True
+import warnings
+
+from zope.exceptions import DuplicationError
+from zope.component.bbb.interfaces import IServiceService
+from zope.interface import implements, Interface, directlyProvides
+
+
+class IGlobalServiceManager(IServiceService):
+
+    def defineService(name, interface):
+        """Define a new service of the given name implementing the given
+        interface.  If the name already exists, raises
+        DuplicationError"""
+
+    def provideService(name, component):
+        """Register a service component.
+
+        Provide a service component to do the work of the named
+        service.  If a service component has already been assigned to
+        this name, raise DuplicationError; if the name has not been
+        defined, raises UndefinedService; if the component does not
+        implement the registered interface for the service name,
+        raises InvalidService.
+
+        """
+
+class IService(Interface):
+    """Marker interface that is used as utility interface to simulate
+       services."""
+
+class IServiceDefinition(Interface):
+    """Marker interface that is used as utility interface to store service
+    defintions (name, interface)."""
+
+class UndefinedService(Exception):
+    """An attempt to register a service that has not been defined
+    """
+
+class InvalidService(Exception):
+    """An attempt to register a service that doesn't implement
+       the required interface
+    """
+
+class GlobalServiceManager(object):
+    """service manager"""
+
+    implements(IGlobalServiceManager)
+
+    def __init__(self, name=None, module=None, sitemanager=None):
+        if __warn__:
+            warnings.warn(
+                "The concept of services has been deprecated. You now have "
+                "only adapters and utilities, which are managed by the site "
+                "manager, which is probably the object you want.",
+                DeprecationWarning, 2)
+        if sitemanager is None:
+            from zope.component.site import GlobalSiteManager
+            sitemanager = GlobalSiteManager()
+        self.sm = sitemanager
+        self.__name__ = name
+        self.__module__ = module
+
+    def _clear(self):
+        pass
+
+    def __reduce__(self):
+        # Global service managers are pickled as global objects
+        return self.__name__
+
+    def defineService(self, name, interface):
+        """see IGlobalServiceManager interface"""
+
+        utils = self.sm.getAllUtilitiesRegisteredFor(IServiceDefinition)
+        names = [n for n, iface in utils]
+        if name in names:
+            raise DuplicationError(name)
+
+        self.sm.registerUtility(IServiceDefinition, (name, interface),
+                                name=name, strict=False)
+
+    def getServiceDefinitions(self):
+        """see IServiceService Interface"""
+        defs = list(self.sm.getAllUtilitiesRegisteredFor(IServiceDefinition))
+        return defs + [('Services', IServiceService)]
+
+    def provideService(self, name, component, force=False):
+        """see IGlobalServiceManager interface, above
+
+        The force keyword allows one to replace an existing
+        service.  This is mostly useful in testing scenarios.
+        """
+
+        if not force and self.sm.queryUtility(IService, name) is not None:
+            raise DuplicationError(name)
+
+        utils = self.sm.getAllUtilitiesRegisteredFor(IServiceDefinition)
+        if name not in [name for name, iface in utils]:
+            raise UndefinedService(name)
+
+        if not dict(self.getServiceDefinitions())[name].providedBy(component):
+            raise InvalidService(name, component,
+                                 dict(self.getServiceDefinitions())[name])
+
+        if isinstance(component, GlobalService):
+            component.__parent__ = self
+            component.__name__ = name
+
+        # Ignore the base services, since their functionality is provided by
+        # the SM.
+        if name in ('Adapters', 'Utilities', 'Services'):
+            return
+
+        directlyProvides(component, IService)
+        self.sm.registerUtility(IService, component, name)
+
+    def getService(self, name):
+        """see IServiceService interface"""
+        if name == 'Services':
+            return self
+
+        if name == 'Adapters':
+            from zope.component.bbb.adapter import GlobalAdapterService
+            return GlobalAdapterService(self.sm)
+
+        if name == 'Utilities':
+            from zope.component.bbb.utility import GlobalUtilityService
+            return GlobalUtilityService(self.sm)
+
+        service = self.sm.queryUtility(IService, name)
+        if service is None:
+            from zope.component.bbb.exceptions import ComponentLookupError
+            raise ComponentLookupError(name)
+
+        return service
+
+
+def GS(service_manager, service_name):
+    return service_manager.getService(service_name)
+
+class GlobalService(object):
+
+    def __reduce__(self):
+        return GS, (self.__parent__, self.__name__)
+
+
+def __getSM(sitemanager=None):
+    return GlobalServiceManager('serviceManager', __name__, sitemanager)
+
+def defineService(name, interface, sitemanager=None):
+    __getSM().defineService(name, interface)
+

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/servicenames.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/servicenames.py)

Added: Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/__init__.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/__init__.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/__init__.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1 @@
+# Make directory a package.

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/components.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/tests/components.py)

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/placelesssetup.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/tests/placelesssetup.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/placelesssetup.py	2004-12-16 17:11:13 UTC (rev 28630)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/placelesssetup.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,34 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Placeless Test Setup
+
+$Id$
+"""
+from zope.testing import cleanup
+
+# A mix-in class inheriting from CleanUp that also connects the CA services
+class PlacelessSetup(cleanup.CleanUp):
+
+    def setUp(self):
+        super(PlacelessSetup, self).setUp()
+
+    def tearDown(self):
+        super(PlacelessSetup, self).tearDown()
+
+
+def setUp(test):
+    cleanup.setUp()
+
+def tearDown(test):
+    cleanup.tearDown()

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/request.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/tests/request.py)

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_adapter.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/tests/test_adapter.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/test_adapter.py	2004-12-16 17:11:13 UTC (rev 28630)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_adapter.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,43 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Global Adapter Service Tests
+
+$Id$
+"""
+import unittest
+from doctest import DocTestSuite
+
+from zope.component.adapter import GlobalAdapterService
+
+class GlobalAdapterServiceTests(unittest.TestCase):
+
+    # This test does not work with the backward-compatibility code.
+    # Global adapter services are not pickled anyways.
+    def BBB_test_pickling(self):
+        from zope.component.bbb.tests.test_service import testServiceManager
+        from zope.component.interfaces import IAdapterService
+        testServiceManager.defineService('Adapters', IAdapterService)
+        adapters = GlobalAdapterService()
+        testServiceManager.provideService('Adapters', adapters)
+        import pickle
+
+        as = pickle.loads(pickle.dumps(adapters))
+        self.assert_(as.sm is adapters.sm)
+
+        testServiceManager._clear()
+
+def test_suite():
+    suite = unittest.makeSuite(GlobalAdapterServiceTests)
+    suite.addTest(DocTestSuite('zope.component.adapter'))
+    return suite

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_api.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/tests/test_api.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/test_api.py	2004-12-16 17:11:13 UTC (rev 28630)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_api.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,575 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""API tests
+
+$Id$
+"""
+import unittest
+
+from zope import component
+from zope.component import servicenames
+from zope.component import getAdapter, queryAdapter, getAdapters
+from zope.component import getAdapterInContext, queryAdapterInContext
+from zope.component import getService
+from zope.component import getUtility, queryUtility
+from zope.component import getDefaultViewName
+from zope.component import queryMultiAdapter
+from zope.component.exceptions import ComponentLookupError
+from zope.component.servicenames import Adapters
+from zope.component.tests.placelesssetup import PlacelessSetup
+from zope.component.tests.request import Request
+from zope.component.interfaces import IComponentArchitecture, IServiceService
+from zope.component.interfaces import IDefaultViewName
+
+from zope.interface import Interface, implements
+from zope.interface.verify import verifyObject
+
+class I1(Interface):
+    pass
+class I2(Interface):
+    pass
+class I3(Interface):
+    pass
+
+class Comp(object):
+    implements(I2)
+    def __init__(self, context, request=None): self.context = context
+
+class Comp2(object):
+    implements(I3)
+    def __init__(self, context, request=None): self.context = context
+
+comp = Comp(1)
+
+class Ob(object):
+    implements(I1)
+    def __conform__(self, i):
+        if i is IServiceService:
+            from zope.component.bbb import getServices
+            return getServices()
+        from zope.component.interfaces import ISiteManager
+        from zope.component import getSiteManager
+        if i is ISiteManager:
+            return getSiteManager()
+
+
+ob = Ob()
+
+class Conforming(Ob):
+    def __conform__(self, i):
+        if i is I3:
+            return Comp(self)
+        else:
+            return Ob.__conform__(self, i)
+
+class StubServiceService(object):
+    implements(IServiceService)  # This is a lie.
+
+    def __init__(self):
+        self.services = {}
+        from zope.component.site import GlobalSiteManager
+        self.sm = GlobalSiteManager()
+
+    def setService(self, name, service):
+        self.services[name] = service
+
+    def getService(self, name):
+        try:
+            return self.services[name]
+        except KeyError:
+            raise ComponentLookupError, name
+
+class ConformsToIServiceService(object):
+
+    def __init__(self, serviceservice):
+        self.serviceservice = serviceservice
+
+    def __conform__(self, interface):
+        if interface is IServiceService:
+            return self.serviceservice
+        from zope.component.interfaces import ISiteManager
+        if interface is ISiteManager:
+            return self.serviceservice.sm
+
+
+class Test(PlacelessSetup, unittest.TestCase):
+
+    def setUp(self):
+        from zope.component import bbb
+        bbb.__warn__ = False
+        bbb.service.__warn__ = False
+
+        super(Test, self).setUp()
+
+    def cleanUp(self):
+        super(Test, self).cleanUp()
+        from zope.component import bbb
+        bbb.__warn__ = True
+        bbb.service.__warn__ = True
+
+    def testInterfaces(self):
+        import zope.component
+        self.failUnless(verifyObject(IComponentArchitecture, zope.component))
+
+
+    def test_getGlobalServices(self):
+        from zope.component import getGlobalServices
+        from zope.component.service import IGlobalServiceManager
+
+        gsm = getGlobalServices()
+        self.assert_(IGlobalServiceManager.providedBy(gsm))
+        self.assert_(getGlobalServices().sm is gsm.sm)
+
+    def test_getServices(self):
+        from zope.component import getServices
+
+        # We don't know anything about the default service manager, except
+        # that it is an IServiceService.
+        self.assert_(IServiceService.providedBy(getServices()))
+
+        # Calling getServices with no args is equivalent to calling it
+        # with a context of None.
+        self.assert_(getServices().sm is getServices(None).sm)
+
+        # If the context passed to getServices is not None, it is
+        # adapted to IServiceService and this adapter returned.
+        # So, we create a context that can be adapted to IServiceService
+        # using the __conform__ API.
+        servicemanager = StubServiceService()
+        context = ConformsToIServiceService(servicemanager)
+        self.assert_(getServices(context) is servicemanager)
+
+        # Using a context that is not adaptable to IServiceService should
+        # fail.
+        self.assertRaises(ComponentLookupError, getServices, object())
+
+    def test_getService(self):
+        from zope.component import getService, getServices
+
+        # Getting the adapter service with no context given is the same
+        # as getting the adapter service from the no-context service manager.
+        self.assert_(getService(Adapters).sm is
+                     getServices().getService(Adapters).sm)
+        # And, a context of 'None' is the same as not providing a context.
+        self.assert_(getService(Adapters, None).sm is getService(Adapters).sm)
+
+        # If the context is adaptable to IServiceService then we use that
+        # adapter.
+        servicemanager = StubServiceService()
+        adapterservice = object()
+        servicemanager.setService(Adapters, adapterservice)
+        context = ConformsToIServiceService(servicemanager)
+        self.assert_(getService(Adapters, context) is adapterservice)
+
+        # Using a context that is not adaptable to IServiceService should
+        # fail.
+        self.assertRaises(ComponentLookupError,
+                          getService, Adapters, object())
+
+    def testAdapterInContext(self):
+        class I1(Interface):
+            pass
+        class I2(Interface):
+            pass
+        class C(object):
+            implements(I1)
+            def __conform__(self, iface, default=None):
+                if iface == I2:
+                    return 42
+                
+        ob = C()
+
+        servicemanager = StubServiceService()
+        context = ConformsToIServiceService(servicemanager)
+        class I3(Interface):
+            pass
+        servicemanager.sm.registerAdapter((I1,), I3, '', lambda x: 43)
+
+        # If an object implements the interface you want to adapt to,
+        # getAdapterInContext should simply return the object.
+        self.assertEquals(getAdapterInContext(ob, I1, context), ob)
+        self.assertEquals(queryAdapterInContext(ob, I1, context), ob)
+
+        # If an object conforms to the interface you want to adapt to,
+        # getAdapterInContext should simply return the conformed object.
+        self.assertEquals(getAdapterInContext(ob, I2, context), 42)
+        self.assertEquals(queryAdapterInContext(ob, I2, context), 42)
+
+        class I4(Interface):
+            pass
+        # If an adapter isn't registered for the given object and interface,
+        # and you provide no default, raise ComponentLookupError...
+        self.assertRaises(ComponentLookupError,
+                          getAdapterInContext, ob, I4, context)
+
+        # ...otherwise, you get the default
+        self.assertEquals(queryAdapterInContext(ob, I4, context, 44), 44)
+
+        # If you ask for an adapter for which something's registered
+        # you get the registered adapter
+        self.assertEquals(getAdapterInContext(ob, I3, context), 43)
+        self.assertEquals(queryAdapterInContext(ob, I3, context), 43)
+
+    def testAdapter(self):
+        # If an adapter isn't registered for the given object and interface,
+        # and you provide no default, raise ComponentLookupError...
+        self.assertRaises(ComponentLookupError, getAdapter, ob, I2, '')
+
+        # ...otherwise, you get the default
+        self.assertEquals(queryAdapter(ob, I2, '', Test), Test)
+
+        getService(Adapters).register([I1], I2, '', Comp)
+        c = getAdapter(ob, I2, '')
+        self.assertEquals(c.__class__, Comp)
+        self.assertEquals(c.context, ob)
+
+    def testInterfaceCall(self):
+        getService(Adapters).register([I1], I2, '', Comp)
+        c = I2(ob)
+        self.assertEquals(c.__class__, Comp)
+        self.assertEquals(c.context, ob)
+
+    def testNamedAdapter(self):
+        self.testAdapter()
+
+        # If an adapter isn't registered for the given object and interface,
+        # and you provide no default, raise ComponentLookupError...
+        self.assertRaises(ComponentLookupError, getAdapter, ob, I2, 'test')
+
+        # ...otherwise, you get the default
+        self.assertEquals(queryAdapter(ob, I2, 'test', Test), Test)
+
+        class Comp2(Comp): pass
+
+        getService(Adapters).register([I1], I2, 'test', Comp2)
+        c = getAdapter(ob, I2, 'test')
+        self.assertEquals(c.__class__, Comp2)
+        self.assertEquals(c.context, ob)
+
+    def testQueryMultiAdapter(self):
+        # Adapting a combination of 2 objects to an interface
+        class DoubleAdapter(object):
+            implements(I3)
+            def __init__(self, first, second):
+                self.first = first
+                self.second = second
+        class Ob2(object):
+            implements(I2)
+        ob2 = Ob2()
+        context = None
+        getService(Adapters, context).register([I1, I2], I3, '', DoubleAdapter)
+        c = queryMultiAdapter((ob, ob2), I3, context=context)
+        self.assertEquals(c.__class__, DoubleAdapter)
+        self.assertEquals(c.first, ob)
+        self.assertEquals(c.second, ob2)
+
+    def testAdapterForInterfaceNone(self):
+
+        # providing an adapter for None says that your adapter can
+        # adapt anything to I2.
+        getService(Adapters).register([None], I2, '', Comp)
+        c = I2(ob)
+        self.assertEquals(c.__class__, Comp)
+        self.assertEquals(c.context, ob)
+
+    def testgetAdapters(self):
+        getService(Adapters).register([I1], I2, '', Comp)
+        getService(Adapters).register([None], I2, 'foo', Comp)
+        c = getAdapters((ob,), I2)
+        c.sort()
+        self.assertEquals([(name, adapter.__class__, adapter.context)
+                           for name, adapter in c],
+                          [('', Comp, ob), ('foo', Comp, ob)])
+
+    def testUtility(self):
+        self.assertRaises(ComponentLookupError, getUtility, I1, context=ob)
+        self.assertRaises(ComponentLookupError, getUtility, I2, context=ob)
+        self.assertEquals(queryUtility(I2, default=Test, context=ob), Test)
+
+        getService('Utilities').provideUtility(I2, comp)
+        self.assertEquals(id(getUtility(I2, context=ob)), id(comp))
+
+    def testNamedUtility(self):
+        from zope.component import getUtility, queryUtility
+        from zope.component import getService
+        from zope.component.exceptions import ComponentLookupError
+
+        self.testUtility()
+
+        self.assertRaises(ComponentLookupError,
+                          getUtility, I1, 'test', context=ob)
+        self.assertRaises(ComponentLookupError,
+                          getUtility, I2, 'test', context=ob)
+        self.assertEquals(queryUtility(I2, 'test', Test, context=ob),
+                          Test)
+
+        getService('Utilities').provideUtility(I2, comp, 'test')
+        self.assertEquals(id(getUtility(I2, 'test', ob)), id(comp))
+
+    def test_getAllUtilitiesRegisteredFor(self):
+        class I21(I2):
+            pass
+        class Comp21(Comp):
+            implements(I21)
+        
+        compbob = Comp('bob')
+        comp21 = Comp21('21')
+        comp21bob = Comp21('21bob')
+        
+        getService('Utilities').provideUtility(I2, comp)
+        getService('Utilities').provideUtility(I21, comp21)
+        getService('Utilities').provideUtility(I2, compbob, 'bob')
+        getService('Utilities').provideUtility(I21, comp21bob, 'bob')
+
+        comps = [comp, compbob, comp21, comp21bob]
+        comps.sort()
+
+        uts = list(component.getUtilitiesFor(I2))
+        uts.sort()
+        self.assertEqual(uts, [('', comp), ('bob', compbob)])
+
+        uts = list(component.getAllUtilitiesRegisteredFor(I2))
+        uts.sort()
+        self.assertEqual(uts, comps)        
+
+    def testView(self):
+        from zope.component import getView, queryView, getService
+        from zope.component.exceptions import ComponentLookupError
+
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo', Request(I1))
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo', Request(I2))
+        self.assertEquals(queryView(ob, 'foo', Request(I2), Test), Test)
+
+        getService(Adapters).register([I1, I2], Interface, 'foo', Comp)
+        c = getView(ob, 'foo', Request(I2))
+        self.assertEquals(c.__class__, Comp)
+        self.assertEquals(c.context, ob)
+
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo2', Request(I1))
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo2', Request(I2))
+        self.assertEquals(queryView(ob, 'foo2', Request(I2), Test), Test)
+
+        self.assertEquals(queryView(ob, 'foo2', Request(I1), None), None)
+
+    def testView_w_provided(self):
+        from zope.component import getView, queryView, getService
+        from zope.component.exceptions import ComponentLookupError
+
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo', Request(I1), providing=I3)
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo', Request(I2), providing=I3)
+        self.assertEquals(
+            queryView(ob, 'foo', Request(I2), Test, providing=I3),
+            Test)
+
+        getService(Adapters).register([I1, I2], Interface, 'foo', Comp)
+
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo', Request(I1), providing=I3)
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo', Request(I2), providing=I3)
+        self.assertEquals(
+            queryView(ob, 'foo', Request(I2), Test, providing=I3),
+            Test)
+
+        getService(Adapters).register([I1, I2], I3, 'foo', Comp)
+
+        c = getView(ob, 'foo', Request(I2), providing=I3)
+        self.assertEquals(c.__class__, Comp)
+        self.assertEquals(c.context, ob)
+
+    def testMultiView(self):
+        from zope.component import queryMultiView, getService
+        from zope.component.exceptions import ComponentLookupError
+
+        class Ob2(object):
+            implements(I2)
+
+        ob2 = Ob2()
+
+        class IRequest(Interface):
+            pass
+
+        request = Request(IRequest)
+
+        class MV(object):
+            implements(I3)
+            def __init__(self, context, other, request):
+               self.context, self.other, self.request = context, other, request
+
+        self.assertEquals(
+            queryMultiView((ob, ob2), request, I3, 'foo', 42), 42)
+
+        getService(Adapters).register((I1, I2, IRequest), I3, 'foo', MV)
+
+        view = queryMultiView((ob, ob2), request, I3, 'foo')
+        self.assertEquals(view.__class__, MV)
+        self.assertEquals(view.context, ob)
+        self.assertEquals(view.other, ob2)
+        self.assertEquals(view.request, request)
+
+    def test_viewProvidingFunctions(self):        
+        # Confirm that a call to getViewProving/queryViewProviding simply 
+        # passes its arguments through to getView/queryView - here we hack
+        # getView and queryView to inspect the args passed through.
+        import zope.component
+
+        # hack zope.component.getView
+        def getView(object, name, request, context, providing):
+            self.args = [object, name, request, context, providing]
+        savedGetView = zope.component.getView
+        zope.component.bbb.getView = getView
+
+        # confirm pass through of args to getView by way of getViewProviding
+        zope.component.getViewProviding(
+            object='object', providing='providing', request='request', 
+            context='context')
+        self.assertEquals(self.args, 
+            ['object', '', 'request', 'providing', 'context'])
+
+        # hack zope.component.queryView
+        def queryView(object, name, request, default, providing, context):
+            self.args = [object, name, request, default, providing, context]
+        savedQueryView = zope.component.queryView
+        zope.component.bbb.queryView = queryView
+
+        # confirm pass through of args to queryView by way of queryViewProviding
+        zope.component.queryViewProviding(
+            object='object', providing='providing', request='request', 
+            default='default', context='context')
+        self.assertEquals(self.args, 
+            ['object', '', 'request', 'default', 'providing', 'context'])
+
+        # restore zope.component
+        zope.component.getView = savedGetView
+        zope.component.queryView = savedQueryView
+
+    def testResource(self):
+        from zope.component import getResource, queryResource, getService
+        from zope.component.exceptions import ComponentLookupError
+
+        r1 = Request(I1)
+        r2 = Request(I2)
+
+        self.assertRaises(ComponentLookupError, getResource, 'foo', r1)
+        self.assertRaises(ComponentLookupError, getResource, 'foo', r2)
+        self.assertEquals(queryResource('foo', r2, Test), Test)
+
+        getService(Adapters).register((I2,), Interface, 'foo', Comp)
+        c = getResource('foo', r2)
+        self.assertEquals(c.__class__, Comp)
+        self.assertEquals(c.context, r2)
+
+        self.assertRaises(ComponentLookupError, getResource, 'foo2', r1, ob)
+        self.assertRaises(ComponentLookupError, getResource, 'foo2', r2)
+        self.assertEquals(queryResource('foo2', r2, Test, ob), Test)
+
+        self.assertEquals(queryResource('foo2', r1, None), None)
+
+    def testResource_w_provided(self):
+        from zope.component import getResource, queryResource, getService
+        from zope.component.exceptions import ComponentLookupError
+
+        r1 = Request(I1)
+        r2 = Request(I2)
+
+        self.assertRaises(ComponentLookupError,
+                          getResource, 'foo', r1, providing=I3)
+        self.assertRaises(ComponentLookupError,
+                          getResource, 'foo', r2, providing=I3)
+        self.assertEquals(queryResource('foo', r2, Test, providing=I3),
+                          Test)
+
+        getService(Adapters).register((I2,), Interface, 'foo', Comp)
+
+        self.assertRaises(ComponentLookupError,
+                          getResource, 'foo', r1, providing=I3)
+        self.assertRaises(ComponentLookupError,
+                          getResource, 'foo', r2, providing=I3)
+        self.assertEquals(queryResource('foo', r2, Test, providing=I3),
+                          Test)
+
+        getService(Adapters).register((I2,), I3, 'foo', Comp)
+
+        c = getResource('foo', r2, providing=I3)
+        self.assertEquals(c.__class__, Comp)
+        self.assertEquals(c.context, r2)
+
+    def testViewWithContextArgument(self):
+        # Basically the same as testView, but exercising the context
+        # argument. As this only tests global views, the context
+        # argument is pretty much a no-operation.
+        from zope.component import getView, queryView, getService
+        from zope.component.exceptions import ComponentLookupError
+
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo', Request(I1), context=ob)
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo', Request(I2), context=ob)
+        self.assertEquals(queryView(ob, 'foo', Request(I2), Test, context=ob),
+                          Test)
+
+        getService(Adapters, ob).register((I1, I2), Interface, 'foo', Comp)
+
+        c = getView(ob, 'foo', Request(I2), context=ob)
+        self.assertEquals(c.__class__, Comp)
+        self.assertEquals(c.context, ob)
+
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo2', Request(I1), context=ob)
+        self.assertRaises(ComponentLookupError,
+                          getView, ob, 'foo2', Request(I2), context=ob)
+        self.assertEquals(queryView(ob, 'foo2', Request(I2), Test,
+                                    context=ob),
+                          Test)
+
+        self.assertEquals(queryView(ob, 'foo2', Request(I1), None,
+                                    context=ob),
+                          None)
+
+    def testDefaultViewName(self):
+        from zope.component import getService
+        getService(Adapters).register((I1, I2), IDefaultViewName,
+                                      '', 'sample_name')
+        self.assertRaises(ComponentLookupError,
+                          getDefaultViewName,
+                          ob, Request(I1))
+        self.assertEquals(getDefaultViewName(ob, Request(I2)),
+                          'sample_name')
+        self.assertRaises(ComponentLookupError,
+                          getDefaultViewName,
+                          ob, Request(I1))
+
+
+class TestNoSetup(unittest.TestCase):
+
+    def testNotBrokenWhenNoService(self):
+        # Both of those things emit DeprecationWarnings.
+        self.assertRaises(TypeError, I2, ob)
+        self.assertEquals(I2(ob, 42), 42)
+        pass
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(Test),
+        unittest.makeSuite(TestNoSetup),
+        ))
+
+if __name__ == "__main__":
+    unittest.TextTestRunner().run(test_suite())

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_service.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/tests/test_service.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/test_service.py	2004-12-16 17:11:13 UTC (rev 28630)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_service.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,150 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Test ServiceService component
+
+$Id$
+"""
+
+import unittest
+import pickle
+from zope.interface import Interface, implements
+
+from zope.exceptions import DuplicationError
+from zope.testing.cleanup import CleanUp
+
+from zope.component import getServiceDefinitions, getService, getGlobalServices
+from zope.component.service import UndefinedService, InvalidService
+from zope.component.service import GlobalServiceManager, GlobalService
+from zope.component.exceptions import ComponentLookupError
+from zope.component.interfaces import IServiceService
+
+class IOne(Interface):
+    pass
+
+class ITwo(Interface):
+    pass
+
+class ServiceOne(GlobalService):
+    implements(IOne)
+
+class ServiceTwo(GlobalService):
+    implements(ITwo)
+
+class Test(CleanUp, unittest.TestCase):
+
+    def setUp(self):
+        super(Test, self).setUp()
+        from zope.component import bbb
+        bbb.__warn__ = False
+        bbb.service.__warn__ = False
+
+    def cleanUp(self):
+        super(Test, self).cleanUp()
+        from zope.component import bbb
+        bbb.__warn__ = True
+        bbb.service.__warn__ = True
+
+    def testNormal(self):
+        ss = getGlobalServices()
+        ss.defineService('one', IOne)
+        c = ServiceOne()
+        ss.provideService('one', c)
+        self.assertEqual(id(getService('one',)), id(c))
+
+    def testFailedLookup(self):
+        self.assertRaises(ComponentLookupError, getService, 'two')
+
+    def testDup(self):
+        getGlobalServices().defineService('one', IOne)
+        self.assertRaises(DuplicationError,
+                          getGlobalServices().defineService,
+                          'one', ITwo)
+
+        c = ServiceOne()
+        getGlobalServices().provideService('one', c)
+
+        c2 = ServiceOne()
+        self.assertRaises(DuplicationError,
+                          getGlobalServices().provideService,
+                          'one', c2)
+
+        self.assertEqual(id(getService('one')), id(c))
+
+
+    def testUndefined(self):
+        c = ServiceOne()
+        self.assertRaises(UndefinedService,
+                          getGlobalServices().provideService,
+                          'one', c)
+
+    def testInvalid(self):
+        getGlobalServices().defineService('one', IOne)
+        getGlobalServices().defineService('two', ITwo)
+        c = ServiceOne()
+        self.assertRaises(InvalidService,
+                          getGlobalServices().provideService,
+                          'two', c)
+
+    def testGetService(self):
+        # Testing looking up a service from a service manager container that
+        # doesn't have a service manager.
+        getGlobalServices().defineService('one', IOne)
+        c = ServiceOne()
+        getGlobalServices().provideService('one', c)
+        self.assertEqual(id(getService('one')), id(c))
+
+    def testGetServiceDefinitions(self):
+        # test that the service definitions are the ones we added
+        sm = getGlobalServices()
+        sm.defineService('one', IOne)
+        c = ServiceOne()
+        sm.provideService('one', c)
+
+        sm.defineService('two', ITwo)
+        d = ServiceTwo()
+        sm.provideService('two', d)
+        defs = getServiceDefinitions()
+        defs.sort()
+        self.assertEqual(defs,
+            [('Services', IServiceService), ('one', IOne), ('two', ITwo)])
+
+    def testPickling(self):
+        self.assertEqual(testServiceManager.__reduce__(), 'testServiceManager')
+        sm = pickle.loads(pickle.dumps(testServiceManager))
+        self.assert_(sm is testServiceManager)
+
+        s2 = ServiceTwo()
+        sm.defineService('2', ITwo)
+        sm.provideService('2', s2)
+
+        self.assert_(s2.__parent__ is sm)
+        self.assertEqual(s2.__name__, '2')
+
+        s = pickle.loads(pickle.dumps(s2))
+        self.assert_(s is s2)
+        testServiceManager._clear()
+
+from zope.component import bbb
+bbb.service.__warn__ = False
+testServiceManager = GlobalServiceManager('testServiceManager', __name__)
+bbb.service.__warn__ = True
+
+
+def test_suite():
+    loader = unittest.TestLoader()
+    return loader.loadTestsFromTestCase(Test)
+
+
+if __name__ == '__main__':
+    unittest.TextTestRunner().run(test_suite())

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_utilityservice.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/tests/test_utilityservice.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/test_utilityservice.py	2004-12-16 17:11:13 UTC (rev 28630)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/tests/test_utilityservice.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,169 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Utility service tests
+
+$Id$
+"""
+from unittest import TestCase, main, makeSuite
+from zope.component import \
+     getUtility, getUtilitiesFor, getService, queryUtility, \
+     getServices, getUtilitiesFor, getGlobalServices
+from zope.component.exceptions import ComponentLookupError
+from zope.component.servicenames import Utilities
+from zope.interface import Interface, implements
+
+from zope.testing.cleanup import CleanUp # Base class w registry cleanup
+
+class IDummyUtility(Interface):
+    pass
+
+class IDummerUtility(IDummyUtility):
+    pass
+
+class DummyUtility(object):
+    __name__ = 'DummyUtility'
+    implements(IDummyUtility)
+
+class DummyUtility2(object):
+    implements(IDummyUtility)
+    __name__ = 'DummyUtility2'
+
+    def __len__(self):
+        return 0
+
+class DummerUtility(object):
+    __name__ = 'DummerUtility'
+    implements(IDummerUtility)
+
+
+dummyUtility = DummyUtility()
+dummerUtility = DummerUtility()
+dummyUtility2 = DummyUtility2()
+
+class Test(TestCase, CleanUp):
+
+    def setUp(self):
+        from zope.component import bbb
+        bbb.__warn__ = False
+        bbb.service.__warn__ = False
+
+        CleanUp.setUp(self)
+        sm = getGlobalServices()
+        defineService = sm.defineService
+        provideService = sm.provideService
+        from zope.component.interfaces import IUtilityService
+        defineService('Utilities',IUtilityService)
+        from zope.component.utility import GlobalUtilityService
+        provideService('Utilities', GlobalUtilityService())
+
+    def cleanUp(self):
+        super(Test, self).cleanUp()
+        from zope.component import bbb
+        bbb.__warn__ = True
+        bbb.service.__warn__ = True
+
+    def testGetUtility(self):
+        us = getService(Utilities)
+        self.assertRaises(
+            ComponentLookupError, getUtility, IDummyUtility)
+        us.provideUtility(IDummyUtility, dummyUtility)
+        self.assertEqual(getUtility(IDummyUtility), dummyUtility)
+
+    def testQueryUtility(self):
+        us = getService(Utilities)
+        self.assertEqual(queryUtility(IDummyUtility), None)
+        self.assertEqual(queryUtility(IDummyUtility, default=self), self)
+        us.provideUtility(IDummyUtility, dummyUtility)
+        self.assertEqual(queryUtility(IDummyUtility), dummyUtility)
+
+    def testgetUtilitiesFor(self):
+        us = getService(Utilities)
+        us.provideUtility(IDummyUtility, dummyUtility)
+        self.assertEqual(list(getUtilitiesFor(IDummyUtility)),
+                         [('',dummyUtility)])
+        self.assertEqual(list(us.getUtilitiesFor(IDummyUtility)),
+                         [('',dummyUtility)])
+
+    def testregistrations(self):
+        us = getService(Utilities)
+        us.provideUtility(IDummyUtility, dummyUtility)
+        self.assertEqual(
+            map(str, us.registrations()),
+            ["UtilityRegistration('IDummyUtility', '', 'DummyUtility', '')"])
+
+    def testOverrides(self):
+        us = getService(Utilities)
+
+        # fail if nothing registered:
+        self.assertRaises(
+            ComponentLookupError, getUtility, IDummyUtility)
+
+        # set and retiev dummy
+        us.provideUtility(IDummyUtility, dummyUtility)
+        self.assertEqual(getUtility(IDummyUtility), dummyUtility)
+
+        # dummer overrides
+        us.provideUtility(IDummerUtility, dummerUtility)
+        self.assertEqual(getUtility(IDummerUtility), dummerUtility)
+
+        # But not if we ask for dummy
+        self.assertEqual(getUtility(IDummyUtility), dummyUtility)
+
+        # same for named:
+        self.assertRaises(
+            ComponentLookupError, getUtility, IDummyUtility, 'bob')
+        us.provideUtility(IDummyUtility, dummyUtility, 'bob')
+        self.assertEqual(getUtility(IDummyUtility), dummyUtility, 'bob')
+        us.provideUtility(IDummerUtility, dummerUtility, 'bob')
+        self.assertEqual(getUtility(IDummerUtility), dummerUtility, 'bob')
+        self.assertEqual(getUtility(IDummyUtility), dummyUtility, 'bob')
+
+        # getUtilitiesFor doesn the right thing:
+        uts = list(us.getUtilitiesFor(IDummyUtility))
+        uts.sort()
+        self.assertEqual(uts, [('', dummyUtility), ('bob', dummyUtility)])
+        uts = list(us.getUtilitiesFor(IDummerUtility))
+        uts.sort()
+        self.assertEqual(uts, [('', dummerUtility), ('bob', dummerUtility)])
+
+        return us
+
+    def test_getAllUtilitiesRegisteredFor(self):
+        us = self.testOverrides()
+
+        # getAllUtilitiesRegisteredFor includes overridden
+
+        uts = list(us.getAllUtilitiesRegisteredFor(IDummerUtility))
+        self.assertEqual(uts, [dummerUtility, dummerUtility])
+
+        uts = list(us.getAllUtilitiesRegisteredFor(IDummyUtility))
+        uts.remove(dummyUtility)
+        uts.remove(dummyUtility)
+        uts.remove(dummerUtility)
+        uts.remove(dummerUtility)
+        self.assertEqual(uts, [])
+
+
+    def test_getAllUtilitiesRegisteredFor_empty(self):
+        us = getService(Utilities)
+        class IFoo(Interface):
+            pass
+        self.assertEqual(list(us.getAllUtilitiesRegisteredFor(IFoo)), [])
+
+
+def test_suite():
+    return makeSuite(Test)
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')

Copied: Zope3/branches/srichter-blow-services/src/zope/component/bbb/utility.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/utility.py)
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/utility.py	2004-12-16 17:11:13 UTC (rev 28630)
+++ Zope3/branches/srichter-blow-services/src/zope/component/bbb/utility.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,71 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""utility service
+
+$Id$
+"""
+from zope.component.exceptions import Invalid, ComponentLookupError
+from zope.component.interfaces import IUtilityService, IRegistry
+from zope.component.service import GlobalService, IService, IServiceDefinition
+from zope.component.site import UtilityRegistration
+import zope.interface
+
+class IGlobalUtilityService(IUtilityService, IRegistry):
+
+    def provideUtility(providedInterface, component, name='', info=''):
+        """Provide a utility
+
+        A utility is a component that provides an interface.
+        """
+
+class UtilityService(object):
+    """Provide IUtilityService
+
+    Mixin that superimposes utility management on adapter registery
+    implementation
+    """
+
+    def __init__(self, sitemanager=None):
+        if sitemanager is None:
+            from zope.component.site import GlobalSiteManager
+            sitemanager = GlobalSiteManager()
+        self.sm = sitemanager
+
+    def __getattr__(self, name):
+        attr = getattr(self.sm, name)
+        if attr is not None:
+            return attr
+
+        attr = getattr(self.sm.utilities, name)
+        if attr is not None:
+            return attr
+
+        raise AttributeError, name
+
+
+class GlobalUtilityService(UtilityService, GlobalService):
+
+    zope.interface.implementsOnly(IGlobalUtilityService)
+
+    def __init__(self, sitemanager=None):
+        super(GlobalUtilityService, self).__init__(sitemanager)
+
+    def provideUtility(self, providedInterface, component, name='', info=''):
+        self.sm.registerUtility(providedInterface, component, name, info)
+
+    def registrations(self):
+        for reg in self.sm.registrations():
+            if isinstance(reg, UtilityRegistration):
+                if not reg.provided in (IService, IServiceDefinition): 
+                    yield reg

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/contextdependent.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/contextdependent.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/contextdependent.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,27 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""A simple mix-in class that implements IContextDependent. 
-
-$Id$
-"""
-from zope.component.interfaces import IContextDependent
-from zope.interface import implements
-
-class ContextDependent(object):
-    """standard boilerplate for context dependent objects"""
-
-    implements(IContextDependent)
-
-    def __init__(self, context):
-        self.context = context

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/exceptions.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/exceptions.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/exceptions.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,31 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Exceptions used by the Component Architecture
-
-$Id$
-"""
-from zope.exceptions import NotFoundError
-
-__all__ = ["ComponentLookupError",
-           "Invalid",
-           "Misused"]
-
-class ComponentLookupError(NotFoundError):
-    """A component could not be found."""
-
-class Invalid(Exception):
-    """A component doesn't satisfy a promise."""
-
-class Misused(Exception):
-    """A component is being used (registered) for the wrong interface."""

Modified: Zope3/branches/srichter-blow-services/src/zope/component/interfaces.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/interfaces.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/interfaces.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -16,61 +16,30 @@
 $Id$
 """
 from zope.interface import Interface, Attribute
-from zope.component.exceptions import *
+from zope.exceptions import NotFoundError
 
-class IComponentArchitecture(Interface):
-    """The Component Architecture is defined by six key services,
-    all of which are managed by service managers.
-    """
+# BBB: Backward-compatibility; 12/05/2004
+from bbb.interfaces import *
 
-    # basic service manager tools
 
-    def getGlobalServices():
-        """Get the global service manager."""
+class ComponentLookupError(NotFoundError):
+    """A component could not be found."""
 
-    def getGlobalService(name):
-        """Get a global service."""
+class Invalid(Exception):
+    """A component doesn't satisfy a promise."""
 
-    def getServices(context=None):
-        """Get the service manager
+class Misused(Exception):
+    """A component is being used (registered) for the wrong interface."""
 
-        If context is None, an application-defined policy is used to choose
-        an appropriate service manager.
 
-        If 'context' is not None, context is adapted to IServiceService, and
-        this adapter is returned.
-        """
+class IComponentArchitecture(Interface, IBBBComponentArchitecture):
+    """The Component Architecture is defined by two key components: Adapters
+    and Utiltities. Both are managed by site managers. All other components
+    build on top of them.
+    """
 
-    def getService(name, context=None):
-        """Get a named service.
+    # Utility API
 
-        Returns the service defined by 'name' from the service manager.
-
-        If context is None, an application-defined policy is used to choose
-        an appropriate service manager.
-
-        If 'context' is not None, context is adapted to IServiceService, and
-        this adapter is returned.
-        """
-
-    def getServiceDefinitions(context=None):
-        """Get service definitions
-
-        Returns a dictionary of the service definitions from the service
-        manager in the format {nameString: serviceInterface}.
-
-        The default behavior of placeful service managers is to include
-        service definitions above them, but this can be overridden.
-
-        If context is None, an application-defined policy is used to choose
-        an appropriate service manager.
-
-        If 'context' is not None, context is adapted to IServiceService, and
-        this adapter is returned.
-        """
-
-    # Utility service
-
     def getUtility(interface, name='', context=None):
         """Get the utility that provides interface
 
@@ -101,7 +70,7 @@
         returned.
         """
 
-    # Adapter service
+    # Adapter API
 
     def getAdapter(object, interface, name, context=''):
         """Get a named adapter to an interface for an object
@@ -265,120 +234,68 @@
         create objects which implement the given interface.
         """
 
-    # Presentation service
 
-    def getView(object, name, request, providing=Interface, context=None):
-        """Get a named view for a given object.
+class ISiteManager(Interface):
+    """ """
 
-        The request must implement IPresentationRequest: it provides
-        the view type and the skin name.  The nearest one to the
-        object is found. If a matching view cannot be found, raises
-        ComponentLookupError.
-        """
+    def queryAdapter(object, interface, name, default=None):
+        """Look for a named adapter to an interface for an object
 
-    def queryView(object, name, request,
-                  default=None, providing=Interface, context=None):
-        """Look for a named view for a given object.
+        If a matching adapter cannot be found, returns the default.
 
-        The request must implement IPresentationRequest: it provides
-        the view type and the skin name.  The nearest one to the
-        object is found.  If a matching view cannot be found, returns
-        default.
-
-        If context is not specified, attempts to use object to specify
-        a context.
+        The name consisting of an empty string is reserved for unnamed
+        adapters. The unnamed adapter methods will often call the
+        named adapter methods with an empty string for a name.
         """
 
-    def getMultiView(objects, request, providing=Interface, name='',
-                     context=None):
-        """Look for a multi-view for given objects
+    def queryMultiAdapter(objects, interface, name, default=None):
+        """Look for a multi-adapter to an interface for an object
 
-        The request must implement IPresentationRequest: it provides
-        the view type and the skin name.  The nearest one to the
-        object is found.  If a matching view cannot be found, raises
-        ComponentLookupError.
+        If a matching adapter cannot be found, returns the default.
 
-        If context is not specified, attempts to use the first object
-        to specify a context.
+        The name consisting of an empty string is reserved for unnamed
+        adapters. The unnamed adapter methods will often call the
+        named adapter methods with an empty string for a name.
         """
 
-    def queryMultiView(objects, request, providing=Interface, name='',
-                       default=None, context=None):
-        """Look for a multi-view for given objects
+    def getAdapters(objects, provided):
+        """Look for all matching adapters to a provided interface for objects
 
-        The request must implement IPresentationRequest: it provides
-        the view type and the skin name.  The nearest one to the
-        object is found.  If a matching view cannot be found, returns
-        default.
-
-        If context is not specified, attempts to use the first object
-        to specify a context.
+        Return a list of adapters that match. If an adapter is named, only the
+        most specific adapter of a given name is returned.
         """
 
-    def getViewProviding(object, providing, request, context=None):
-        """Look for a view based on the interface it provides.
+    def subscribers(required, provided):
+        """Get subscribers
 
-        A call to this method is equivalent to:
-
-            getView(object, '', request, context, providing)
+        Subscribers are returned that provide the provided interface
+        and that depend on and are comuted from the sequence of
+        required objects.
         """
 
-    def queryViewProviding(object, providing, request,
-                           default=None, context=None):
-        """Look for a view that provides the specified interface.
+    def queryUtility(interface, name='', default=None):
+        """Look up a utility that provides an interface.
 
-        A call to this method is equivalent to:
-
-            queryView(object, '', request, default, context, providing)
+        If one is not found, returns default.
         """
 
-    def getDefaultViewName(object, request, context=None):
-        """Get the name of the default view for the object and request.
+    def getUtilitiesFor(interface):
+        """Look up the registered utilities that provide an interface.
 
-        The request must implement IPresentationRequest, and provides the
-        desired view type.  The nearest one to the object is found.
-        If a matching default view name cannot be found, raises
-        ComponentLookupError.
-
-        If context is not specified, attempts to use
-        object to specify a context.
+        Returns an iterable of name-utility pairs.
         """
 
-    def queryDefaultViewName(object, request, default=None, context=None):
-        """Look for the name of the default view for the object and request.
+    def getAllUtilitiesRegisteredFor(interface):
+        """Return all registered utilities for an interface
 
-        The request must implement IPresentationRequest, and provides
-        the desired view type.  The nearest one to the object is
-        found.  If a matching default view name cannot be found,
-        returns the default.
+        This includes overwridden utilities.
 
-        If context is not specified, attempts to use object to specify
-        a context.
+        An iterable of utility instances is returned.  No names are
+        returned.
         """
 
-    def getResource(name, request, providing=Interface, context=None):
-        """Get a named resource for a given request
 
-        The request must implement IPresentationRequest.
 
-        The context provides a place to look for placeful resources.
-
-        A ComponentLookupError will be raised if the component can't
-        be found.
-        """
-
-    def queryResource(name, request, default=None, providing=Interface,
-                      context=None):
-        """Get a named resource for a given request
-
-        The request must implement IPresentationRequest.
-
-        The context provides a place to look for placeful resources.
-
-        If the component can't be found, the default is returned.
-        """
-
-
 class IRegistry(Interface):
     """Object that supports component registry
     """
@@ -387,27 +304,6 @@
         """Return an iterable of component registrations
         """
 
-
-class IServiceService(Interface):
-    """A service to manage Services."""
-
-    def getServiceDefinitions():
-        """Retrieve all Service Definitions
-
-        Should return a list of tuples (name, interface)
-        """
-
-    def getInterfaceFor(name):
-        """Retrieve the service interface for the given name
-        """
-
-    def getService(name):
-        """Retrieve a service implementation
-
-        Raises ComponentLookupError if the service can't be found.
-        """
-
-
 class IFactory(Interface):
     """A factory is responsible for creating other components."""
 
@@ -426,138 +322,3 @@
         created by this factory will implement. If the callable's Implements
         instance cannot be created, an empty Implements instance is returned.
         """
-
-
-class IUtilityService(Interface):
-    """A service to manage Utilities."""
-
-    def getUtility(interface, name=''):
-        """Look up a utility that provides an interface.
-
-        If one is not found, raises ComponentLookupError.
-        """
-
-    def queryUtility(interface, name='', default=None):
-        """Look up a utility that provides an interface.
-
-        If one is not found, returns default.
-        """
-
-    def getUtilitiesFor(interface):
-        """Look up the registered utilities that provide an interface.
-
-        Returns an iterable of name-utility pairs.
-        """
-
-    def getAllUtilitiesRegisteredFor(interface):
-        """Return all registered utilities for an interface
-
-        This includes overwridden utilities.
-
-        An iterable of utility instances is returned.  No names are
-        returned.
-        """
-
-
-class IContextDependent(Interface):
-    """Components implementing this interface must have a context component.
-
-    Usually the context must be one of the arguments of the
-    constructor. Adapters and views are a primary example of context-dependent
-    components.
-    """
-
-    context = Attribute(
-        """The context of the object
-
-        This is the object being adapted, viewed, extended, etc.
-        """)
-
-
-class IAdapterService(Interface):
-    """A service to manage Adapters."""
-
-    def queryAdapter(object, interface, name, default=None):
-        """Look for a named adapter to an interface for an object
-
-        If a matching adapter cannot be found, returns the default.
-
-        The name consisting of an empty string is reserved for unnamed
-        adapters. The unnamed adapter methods will often call the
-        named adapter methods with an empty string for a name.
-        """
-
-    def queryMultiAdapter(objects, interface, name, default=None):
-        """Look for a multi-adapter to an interface for an object
-
-        If a matching adapter cannot be found, returns the default.
-
-        The name consisting of an empty string is reserved for unnamed
-        adapters. The unnamed adapter methods will often call the
-        named adapter methods with an empty string for a name.
-        """
-
-    def subscribers(required, provided):
-        """Get subscribers
-
-        Subscribers are returned that provide the provided interface
-        and that depend on and are comuted from the sequence of
-        required objects.
-        """
-
-
-class IPresentation(Interface):
-    """Presentation components provide interfaces to external actors
-
-    The are created for requests, which encapsulate external actors,
-    connections, etc.
-    """
-
-    request = Attribute(
-        """The request
-
-        The request is a surrogate for the user. It also provides the
-        presentation type and skin. It is of type
-        IPresentationRequest.
-        """)
-
-
-class IPresentationRequest(Interface):
-    """An IPresentationRequest provides methods for getting view meta data."""
-
-
-class IResource(IPresentation):
-    """Resources provide data to be used for presentation."""
-
-
-class IResourceFactory(Interface):
-    """A factory to create factories using the request."""
-
-    def __call__(request):
-        """Create a resource for a request
-
-        The request must be an IPresentationRequest.
-        """
-
-
-class IView(IPresentation, IContextDependent):
-    """Views provide a connection between an external actor and an object"""
-
-
-class IViewFactory(Interface):
-    """Objects for creating views"""
-
-    def __call__(context, request):
-        """Create an view (IView) object
-
-        The context aregument is the object displayed by the view. The
-        request argument is an object, such as a web request, that
-        "stands in" for the user.
-        """
-
-class IDefaultViewName(Interface):
-    """A string that contains the default view name
-
-    A default view name is used to select a view when a user hasn't
-    specified one.
-    """

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/service.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/service.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/service.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,133 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Service Manager implementation
-
-$Id$
-"""
-
-from zope.exceptions import DuplicationError
-from zope.component.interfaces import IServiceService
-from zope.component.exceptions import ComponentLookupError
-from zope.interface import implements
-
-
-class IGlobalServiceManager(IServiceService):
-
-    def defineService(name, interface):
-        """Define a new service of the given name implementing the given
-        interface.  If the name already exists, raises
-        DuplicationError"""
-
-    def provideService(name, component):
-        """Register a service component.
-
-        Provide a service component to do the work of the named
-        service.  If a service component has already been assigned to
-        this name, raise DuplicationError; if the name has not been
-        defined, raises UndefinedService; if the component does not
-        implement the registered interface for the service name,
-        raises InvalidService.
-
-        """
-
-class UndefinedService(Exception):
-    """An attempt to register a service that has not been defined
-    """
-
-class InvalidService(Exception):
-    """An attempt to register a service that doesn't implement
-       the required interface
-    """
-
-class GlobalServiceManager(object):
-    """service manager"""
-
-    implements(IGlobalServiceManager)
-
-    def __init__(self, name=None, module=None):
-        self._clear()
-        self.__name__ = name
-        self.__module__ = module
-
-    def _clear(self):
-        self.__defs     = {'Services': IServiceService}
-        self.__services = {'Services': self}
-
-    def __reduce__(self):
-        # Global service managers are pickled as global objects
-        return self.__name__
-
-    def defineService(self, name, interface):
-        """see IGlobalServiceManager interface"""
-
-        if name in self.__defs:
-            raise DuplicationError(name)
-
-        self.__defs[name] = interface
-
-    def getServiceDefinitions(self):
-        """see IServiceService Interface"""
-        return self.__defs.items()
-
-    def provideService(self, name, component, force=False):
-        """see IGlobalServiceManager interface, above
-
-        The force keyword allows one to replace an existing
-        service.  This is mostly useful in testing scenarios.
-        """
-
-        if not force and name in self.__services:
-            raise DuplicationError(name)
-
-        if name not in self.__defs:
-            raise UndefinedService(name)
-
-        if not self.__defs[name].providedBy(component):
-            raise InvalidService(name, component, self.__defs[name])
-
-        if isinstance(component, GlobalService):
-            component.__parent__ = self
-            component.__name__ = name
-
-        self.__services[name] = component
-
-    def getService(self, name):
-        """see IServiceService interface"""
-        service = self.__services.get(name)
-        if service is None:
-            raise ComponentLookupError(name)
-
-        return service
-
-
-def GS(service_manager, service_name):
-    return service_manager.getService(service_name)
-
-class GlobalService(object):
-
-    def __reduce__(self):
-        return GS, (self.__parent__, self.__name__)
-
-
-
-# the global service manager instance
-serviceManager = GlobalServiceManager('serviceManager', __name__)
-
-defineService = serviceManager.defineService
-
-# Register our cleanup with Testing.CleanUp to make writing unit tests
-# simpler.
-from zope.testing.cleanup import addCleanUp
-addCleanUp(serviceManager._clear)
-del addCleanUp

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/servicenames.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/servicenames.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/servicenames.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,20 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Default service names for CA core services
-
-$Id$
-"""
-Adapters = 'Adapters'
-Utilities = 'Utilities'
-Services = 'Services'

Added: Zope3/branches/srichter-blow-services/src/zope/component/site.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/site.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/site.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -0,0 +1,299 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Global Site Manager
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import types
+
+from zope.interface import implements, providedBy, implementedBy
+from zope.interface.adapter import AdapterRegistry
+from zope.interface.interfaces import IInterface
+
+from zope.component.interfaces import ISiteManager, IRegistry
+from zope.component.interfaces import ComponentLookupError
+
+
+class IGlobalSiteManager(ISiteManager, IRegistry):
+
+    def registerAdapter(required, provided, name, factory, info=''):
+        """Register an adapter factory
+
+        :Parameters:
+          - `required`: a sequence of specifications for objects to be
+             adapted. 
+          - `provided`: The interface provided by the adapter
+          - `name`: The adapter name
+          - `factory`: The object used to compute the adapter
+          - `info`: Provide some info about this particular adapter.
+        """
+
+    def subscribe(required, provided, factory, info=''):
+        """Register a subscriber factory
+
+        :Parameters:
+          - `required`: a sequence of specifications for objects to be
+             adapted. 
+          - `provided`: The interface provided by the adapter
+          - `name`: The adapter name
+          - `factory`: The object used to compute the subscriber
+          - `info`: Provide some info about this particular adapter.
+        """
+
+    def registerUtility(providedInterface, component, name='', info='',
+                        strict=True):
+        """Register a utility
+
+        If strict is true, then the specified component *must* implement the
+        `providedInterface`. Turning strict off is particularly useful for
+        tests.
+        """
+
+
+class SiteManager(object):
+    """Site Manager implementation"""
+
+    def __init__(self):
+        self.adapters = AdapterRegistry()
+        self.utilities = AdapterRegistry()
+
+    def queryAdapter(self, object, interface, name, default=None):
+        """See ISiteManager interface"""
+        return self.adapters.queryAdapter(object, interface, name, default)
+
+    def queryMultiAdapter(self, objects, interface, name='', default=None):
+        """See ISiteManager interface"""
+        return self.adapters.queryMultiAdapter(objects, interface, name,
+                                               default)
+    
+    def getAdapters(self, objects, provided):
+        """See ISiteManager interface"""
+        return [(name, adapter(*objects))
+                for name, adapter in self.adapters.lookupAll(
+                                        map(providedBy, objects), provided)]
+
+    def subscribers(self, required, provided):
+        """See ISiteManager interface"""
+        return self.adapters.subscribers(required, provided)
+    
+    def queryUtility(self, interface, name='', default=None):
+        """See ISiteManager interface"""
+
+        byname = self.utilities._null.get(interface)
+        if byname:
+            return byname.get(name, default)
+        else:
+            return default
+
+    def getUtilitiesFor(self, interface):
+        byname = self.utilities._null.get(interface)
+        if byname:
+            for item in byname.iteritems():
+                yield item
+
+    def getAllUtilitiesRegisteredFor(self, interface):
+        return iter(self.utilities._null.get(('s', interface)) or ())
+
+
+class GlobalSiteManager(SiteManager):
+    """Global Site Manager implementation."""
+
+    implements(IGlobalSiteManager)
+
+    def __init__(self):
+        super(GlobalSiteManager, self).__init__()
+        self._registrations = {}
+
+    def registerAdapter(self, required, provided, name, factory, info=''):
+        """Register an adapter
+
+        >>> from zope.interface import Interface
+        >>> registry = GlobalSiteManager()
+        >>> class R1(Interface):
+        ...     pass
+        >>> class R2(R1):
+        ...     pass
+        >>> class P1(Interface):
+        ...     pass
+        >>> class P2(P1):
+        ...     pass
+
+        >>> registry.registerAdapter((R1, ), P2, 'bob', 'c1', 'd1')
+        >>> registry.registerAdapter((R1, ), P2,    '', 'c2', 'd2')
+        >>> registry.adapters.lookup((R2, ), P1, '')
+        'c2'
+
+        >>> registrations = map(repr, registry.registrations())
+        >>> registrations.sort()
+        >>> for registration in registrations:
+        ...    print registration
+        AdapterRegistration(('R1',), 'P2', '', 'c2', 'd2')
+        AdapterRegistration(('R1',), 'P2', 'bob', 'c1', 'd1')
+
+        Let's make sure that we can also register regular classes for
+        adaptation.
+
+        >>> class O1(object):
+        ...     pass
+        >>> class O2(object):
+        ...     pass
+        >>> class O3(object):
+        ...     def __init__(self, obj1, obj2=None):
+        ...         pass
+
+        >>> registry.registerAdapter((O1, ), R1, '', O3)
+        >>> registry.queryAdapter(O1(), R1, '').__class__
+        <class 'zope.component.site.O3'>
+
+        >>> registry.registerAdapter((O1, O2), R1, '', O3)
+        >>> registry.queryMultiAdapter((O1(), O2()), R1, '').__class__
+        <class 'zope.component.site.O3'>
+        """
+        ifaces = []
+        for iface in required:
+            if not IInterface.providedBy(iface) and iface is not None:
+                if not isinstance(iface, (type, types.ClassType)):
+                    raise TypeError(iface, IInterface)
+                iface = implementedBy(iface)
+
+            ifaces.append(iface)
+        required = tuple(ifaces)
+
+        self._registrations[(required, provided, name)] = AdapterRegistration(
+            required, provided, name, factory, info)
+
+        self.adapters.register(required, provided, name, factory)
+
+    def subscribe(self, required, provided, factory, info=''):
+        """Register an subscriptions adapter
+
+        >>> from zope.interface import Interface
+        >>> registry = GlobalSiteManager()
+        >>> class R1(Interface):
+        ...     pass
+        >>> class R2(R1):
+        ...     pass
+        >>> class P1(Interface):
+        ...     pass
+        >>> class P2(P1):
+        ...     pass
+
+        >>> registry.subscribe((R1, ), P2, 'c1', 'd1')
+        >>> registry.subscribe((R1, ), P2, 'c2', 'd2')
+        >>> subscriptions = map(str,
+        ...                     registry.adapters.subscriptions((R2, ), P1))
+        >>> subscriptions.sort()
+        >>> subscriptions
+        ['c1', 'c2']
+
+        >>> registrations = map(repr, registry.registrations())
+        >>> registrations.sort()
+        >>> for registration in registrations:
+        ...    print registration
+        SubscriptionRegistration(('R1',), 'P2', 'c1', 'd1')
+        SubscriptionRegistration(('R1',), 'P2', 'c2', 'd2')
+        """
+        required = tuple(required)
+
+        registration = SubscriptionRegistration(
+            required, provided, factory, info)
+
+        self._registrations[(required, provided)] = (
+            self._registrations.get((required, provided), ())
+            +
+            (registration, )
+            )
+
+        self.adapters.subscribe(required, provided, factory)
+
+    def registerUtility(self, providedInterface, component, name='', info='',
+                        strict=True):
+
+        if strict and not providedInterface.providedBy(component):
+            raise Invalid("The registered component doesn't implement "
+                          "the promised interface.")
+
+        self.utilities.register((), providedInterface, name, component)
+
+        # Also subscribe to support getAllUtilitiesRegisteredFor:
+        self.utilities.subscribe((), providedInterface, component)
+
+        self._registrations[(providedInterface, name)] = UtilityRegistration(
+            providedInterface, name, component, info)
+
+    def registrations(self):
+        for registration in self._registrations.itervalues():
+            if isinstance(registration, tuple):
+                for r in registration:
+                    yield r
+            else:
+                yield registration
+
+
+# Global Site Manager Instance
+globalSiteManager = GlobalSiteManager()
+
+# Register our cleanup with zope.testing.cleanup to make writing unit tests
+# simpler.
+from zope.testing.cleanup import addCleanUp
+addCleanUp(globalSiteManager.__init__)
+del addCleanUp
+
+
+
+class AdapterRegistration(object):
+    """Registration for a simple adapter."""
+
+    def __init__(self, required, provided, name, value, doc=''):
+        (self.required, self.provided, self.name, self.value, self.doc
+         ) = required, provided, name, value, doc
+
+    def __repr__(self):
+        return '%s(%r, %r, %r, %r, %r)' % (
+            self.__class__.__name__,
+            tuple([getattr(r, '__name__', None) for r in self.required]),
+            self.provided.__name__, self.name,
+            self.value, self.doc,
+            )
+
+
+class SubscriptionRegistration(object):
+    """Registration for a subscription adapter."""
+
+    def __init__(self, required, provided, value, doc):
+        (self.required, self.provided, self.value, self.doc
+         ) = required, provided, value, doc
+
+    def __repr__(self):
+        return '%s(%r, %r, %r, %r)' % (
+            self.__class__.__name__,
+            tuple([getattr(r, '__name__', None) for r in self.required]),
+            self.provided.__name__, self.value, self.doc,
+            )
+
+class UtilityRegistration(object):
+
+    def __init__(self, provided, name, component, doc):
+        (self.provided, self.name, self.component, self.doc
+         ) = provided, name, component, doc
+
+    def __repr__(self):
+        return '%s(%r, %r, %r, %r)' % (
+            self.__class__.__name__,
+            self.provided.__name__, self.name,
+            getattr(self.component, '__name__', self.component), self.doc,
+            )
+
+

Copied: Zope3/branches/srichter-blow-services/src/zope/component/testing.py (from rev 28630, Zope3/branches/srichter-blow-services/src/zope/component/tests/placelesssetup.py)

Modified: Zope3/branches/srichter-blow-services/src/zope/component/tests/__init__.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/__init__.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/tests/__init__.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,2 +1,23 @@
+##############################################################################
 #
-# This file is necessary to make this directory a package.
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Testing Package for the Component Architecture
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import sys
+
+# BBB: Import some backward-compatibility; 12/10/2004
+from zope.component.bbb.tests import request
+sys.modules['zope.component.tests.request'] = request

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/tests/components.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/components.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/tests/components.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,63 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Components for testing
-
-$Id$
-"""
-from zope.interface import Interface, Attribute, implements
-
-class RecordingAdapter(object):
-
-    def __init__(self):
-        self.record = []
-
-    def __call__(self, context):
-        # Note that this sets the context rather than appending to the record
-        # so as not to assume things about adapters being cached, if this
-        # happens in the future.
-        self.context = context
-        return self
-
-    def check(self, *args):
-        record = self.record
-        if len(args) != len(record):
-            raise AssertionError('wrong number of entries in record',
-                                 args, record)
-        for arg, entry in zip(args, record):
-            if arg != entry:
-                raise AssertionError('record entry does not match',
-                                     args, record)
-
-
-class IApp(Interface):
-    a = Attribute('test attribute')
-    def f(): "test func"
-
-class IContent(Interface): pass
-
-class Content(object):
-    implements(IContent)
-
-class Comp(object):
-    __used_for__ = IContent
-    implements(IApp)
-
-    def __init__(self, *args):
-        # Ignore arguments passed to constructor
-        pass
-
-    a = 1
-    def f(): pass
-
-comp = Comp()

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/tests/placelesssetup.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/placelesssetup.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/tests/placelesssetup.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,44 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Placeless Test Setup
-
-$Id$
-"""
-from zope.testing.cleanup import CleanUp
-from zope.component import getGlobalServices
-from zope.component.servicenames import Adapters, Utilities
-
-# A mix-in class inheriting from CleanUp that also connects the CA services
-class PlacelessSetup(CleanUp):
-
-    def setUp(self):
-        CleanUp.setUp(self)
-        sm = getGlobalServices()
-        defineService = sm.defineService
-        provideService = sm.provideService
-
-        # utility service
-        from zope.component.interfaces import IUtilityService
-        defineService(Utilities, IUtilityService)
-        from zope.component.utility import GlobalUtilityService
-        provideService(Utilities, GlobalUtilityService())
-
-        # adapter service
-        from zope.component.interfaces import IAdapterService
-        defineService(Adapters, IAdapterService)
-        from zope.component.adapter import GlobalAdapterService
-        provideService(Adapters, GlobalAdapterService())
-
-    def tearDown(self):
-        CleanUp.tearDown(self)

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/tests/request.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/request.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/tests/request.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,35 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Request for tests
-
-$Id$
-"""
-import zope.interface
-
-
-class Request(object):
-
-    def __init__(self, type, skin=None):
-        zope.interface.directlyProvides(self, type)
-        # BBB goes away in 3.3
-        if skin is not None:
-            import warnings
-            warnings.warn(
-                "The skin argument is deprecated for "
-                "zope.component.tests.request.Request and will go away in "
-                "ZopeX3 3.3. Use zope.publisher.browser.TestRequest if "
-                "you need to test skins.",
-                DeprecationWarning)
-            zope.interface.directlyProvides(self, skin)
-        self._skin = skin

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/tests/test_adapter.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/test_adapter.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/tests/test_adapter.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,41 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2003 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Global Adapter Service Tests
-
-$Id$
-"""
-import unittest
-from doctest import DocTestSuite
-
-from zope.component.adapter import GlobalAdapterService
-
-class GlobalAdapterServiceTests(unittest.TestCase):
-
-    def test_pickling(self):
-        from zope.component.tests.test_service import testServiceManager
-        from zope.component.interfaces import IAdapterService
-        testServiceManager.defineService('Adapters', IAdapterService)
-        adapters = GlobalAdapterService()
-        testServiceManager.provideService('Adapters', adapters)
-        import pickle
-
-        as = pickle.loads(pickle.dumps(adapters))
-        self.assert_(as is adapters)
-
-        testServiceManager._clear()
-
-def test_suite():
-    suite = unittest.makeSuite(GlobalAdapterServiceTests)
-    suite.addTest(DocTestSuite('zope.component.adapter'))
-    return suite

Modified: Zope3/branches/srichter-blow-services/src/zope/component/tests/test_api.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/test_api.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/tests/test_api.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -17,25 +17,17 @@
 """
 import unittest
 
-from zope import component
-from zope.component import servicenames
-from zope.component import getAdapter, queryAdapter, getAdapters
-from zope.component import getAdapterInContext, queryAdapterInContext
-from zope.component import getService
-from zope.component import getUtility, queryUtility
-from zope.component import getDefaultViewName
-from zope.component import queryMultiAdapter
-from zope.component.service import serviceManager
-from zope.component.exceptions import ComponentLookupError
-from zope.component.servicenames import Adapters
-from zope.component.tests.placelesssetup import PlacelessSetup
-from zope.component.tests.request import Request
-from zope.component.interfaces import IComponentArchitecture, IServiceService
-from zope.component.interfaces import IDefaultViewName
-
 from zope.interface import Interface, implements
 from zope.interface.verify import verifyObject
+from zope.testing import doctest
 
+from zope import component as capi
+from zope.component.interfaces import ComponentLookupError
+from zope.component.interfaces import IComponentArchitecture
+from zope.component.interfaces import ISiteManager
+from zope.component.tests.placelesssetup import setUp, tearDown
+
+
 class I1(Interface):
     pass
 class I2(Interface):
@@ -43,515 +35,522 @@
 class I3(Interface):
     pass
 
+class Ob(object):
+    implements(I1)
+    def __repr__(self):
+        return '<instance Ob>'
+
+
+ob = Ob()
+
+class Ob2(object):
+    implements(I2)
+    def __repr__(self):
+        return '<instance Ob2>'
+
 class Comp(object):
     implements(I2)
-    def __init__(self, context, request=None): self.context = context
+    def __init__(self, context):
+        self.context = context
 
+comp = Comp(1)
+
 class Comp2(object):
     implements(I3)
-    def __init__(self, context, request=None): self.context = context
+    def __init__(self, context):
+        self.context = context
 
-comp = Comp(1)
 
-class Ob(object):
-    implements(I1)
-    def __conform__(self, i):
-        if i is IServiceService:
-            return serviceManager
+class ConformsToISiteManager(object):
+    """This object allows the sitemanager to conform/adapt to `ISiteManager`
+    and thus to itself."""
 
-ob = Ob()
+    def __init__(self, sitemanager):
+        self.sitemanager = sitemanager
 
-class Conforming(Ob):
-    def __conform__(self, i):
-        if i is I3:
-            return Comp(self)
-        else:
-            return Ob.__conform__(self, i)
+    def __conform__(self, interface):
+        """This method is specified by the adapter PEP to do the adaptation."""
+        if interface is ISiteManager:
+            return self.sitemanager
 
-class StubServiceService(object):
-    implements(IServiceService)  # This is a lie.
 
-    def __init__(self):
-        self.services = {}
+def testInterfaces():
+    """Ensure that the component architecture API is provided by
+    `zope.component`.
+    
+    >>> import zope.component
+    >>> verifyObject(IComponentArchitecture, zope.component)
+    True
+    """
 
-    def setService(self, name, service):
-        self.services[name] = service
+def test_getGlobalSiteManager():
+    """One of the most important functions is to get the global site manager.
+    
+      >>> from zope.component.site import IGlobalSiteManager, globalSiteManager
 
-    def getService(self, name):
-        try:
-            return self.services[name]
-        except KeyError:
-            raise ComponentLookupError, name
+    Get the global site manager via the CA API function:
 
+      >>> gsm = capi.getGlobalSiteManager()
 
-class ConformsToIServiceService(object):
+    Make sure that the global site manager implements the correct interface
+    and is the global site manager instance we expect to get.
+    
+      >>> IGlobalSiteManager.providedBy(gsm)
+      True
+      >>> globalSiteManager is gsm
+      True
 
-    def __init__(self, serviceservice):
-        self.serviceservice = serviceservice
+    Finally, ensure that we always get the same global site manager, otherwise
+    our component registry will always be reset. 
 
-    def __conform__(self, interface):
-        if interface is IServiceService:
-            return self.serviceservice
+      >>> capi.getGlobalSiteManager() is gsm
+      True
+    """
 
+def test_getSiteManager():
+    """Make sure that `getSiteManager()` always returns the correct site
+    manager instance.
+    
+    We don't know anything about the default service manager, except that it
+    is an `ISiteManager`.
 
-class Test(PlacelessSetup, unittest.TestCase):
+      >>> ISiteManager.providedBy(capi.getSiteManager())
+      True
 
-    def testInterfaces(self):
-        import zope.component
-        self.failUnless(verifyObject(IComponentArchitecture, zope.component))
+    Calling `getSiteManager()` with no args is equivalent to calling it with a
+    context of `None`.
 
+      >>> capi.getSiteManager() is capi.getSiteManager(None)
+      True
+      
+    If the context passed to `getSiteManager()` is not `None`, it is adapted
+    to `ISiteManager` and this adapter returned.  So, we create a context that
+    can be adapted to `ISiteManager` using the `__conform__` API.
 
-    def test_getGlobalServices(self):
-        from zope.component import getGlobalServices
-        from zope.component.service import IGlobalServiceManager
+    Let's create the simplest stub-implementation of a site manager possible:
 
-        gsm = getGlobalServices()
-        self.assert_(IGlobalServiceManager.providedBy(gsm))
-        self.assert_(getGlobalServices() is gsm)
+      >>> sitemanager = object()
 
-    def test_getServices(self):
-        from zope.component import getServices
+    Now create a context that knows how to adapt to our newly created site
+    manager.
+    
+      >>> context = ConformsToISiteManager(sitemanager)
 
-        # We don't know anything about the default service manager, except
-        # that it is an IServiceService.
-        self.assert_(IServiceService.providedBy(getServices()))
+    Now make sure that the `getSiteManager()` API call returns the correct
+    site manager.
 
-        # Calling getServices with no args is equivalent to calling it
-        # with a context of None.
-        self.assert_(getServices() is getServices(None))
+      >>> capi.getSiteManager(context) is sitemanager
+      True
 
-        # If the context passed to getServices is not None, it is
-        # adapted to IServiceService and this adapter returned.
-        # So, we create a context that can be adapted to IServiceService
-        # using the __conform__ API.
-        servicemanager = StubServiceService()
-        context = ConformsToIServiceService(servicemanager)
-        self.assert_(getServices(context) is servicemanager)
+    Using a context that is not adaptable to `ISiteManager` should fail.
 
-        # Using a context that is not adaptable to IServiceService should
-        # fail.
-        self.assertRaises(ComponentLookupError, getServices, object())
+      >>> capi.getSiteManager(ob) #doctest: +NORMALIZE_WHITESPACE
+      Traceback (most recent call last):
+      ...
+      ComponentLookupError: ('Could not adapt', <instance Ob>,
+      <InterfaceClass zope.component.interfaces.ISiteManager>)
+    """
+    
+def testAdapterInContext(self):
+    """The `getAdapterInContext()` and `queryAdapterInContext()` API functions
+    do not only use the site manager to look up the adapter, but first tries
+    to use the `__conform__()` method of the object to find an adapter as
+    specified by PEP 246.
 
-    def test_getService(self):
-        from zope.component import getService, getServices
+    Let's start by creating a component that support's the PEP 246's
+    `__conform__()` method:
+    
+      >>> class Component(object):
+      ...     implements(I1)
+      ...     def __conform__(self, iface, default=None):
+      ...         if iface == I2:
+      ...             return 42
+      ...     def __repr__(self):
+      ...         return '''<Component implementing 'I1'>'''
+      
+      >>> ob = Component()
+      
+    We also gave the component a custom representation, so it will be easier
+    to use in these tests.
 
-        # Getting the adapter service with no context given is the same
-        # as getting the adapter service from the no-context service manager.
-        self.assert_(getService(Adapters) is
-                     getServices().getService(Adapters))
-        # And, a context of 'None' is the same as not providing a context.
-        self.assert_(getService(Adapters, None) is getService(Adapters))
+    We now have to create a site manager (other than the default global one)
+    with which we can register adapters for `I1`.
+      
+      >>> from zope.component.site import GlobalSiteManager
+      >>> sitemanager = GlobalSiteManager()
 
-        # If the context is adaptable to IServiceService then we use that
-        # adapter.
-        servicemanager = StubServiceService()
-        adapterservice = object()
-        servicemanager.setService(Adapters, adapterservice)
-        context = ConformsToIServiceService(servicemanager)
-        self.assert_(getService(Adapters, context) is adapterservice)
+    Now we create a new `context` that knows how to get to our custom site
+    manager.
+    
+      >>> context = ConformsToISiteManager(sitemanager)
 
-        # Using a context that is not adaptable to IServiceService should
-        # fail.
-        self.assertRaises(ComponentLookupError,
-                          getService, Adapters, object())
+    We now register an adapter from `I1` to `I3`:
+      
+      >>> sitemanager.registerAdapter((I1,), I3, '', lambda x: 43)
 
-    def testAdapterInContext(self):
-        class I1(Interface):
-            pass
-        class I2(Interface):
-            pass
-        class C(object):
-            implements(I1)
-            def __conform__(self, iface, default=None):
-                if iface == I2:
-                    return 42
-                
-        ob = C()
+    If an object implements the interface you want to adapt to,
+    `getAdapterInContext()` should simply return the object.
 
-        servicemanager = StubServiceService()
-        context = ConformsToIServiceService(servicemanager)
-        class I3(Interface):
-            pass
-        class StubAdapterService(object):
-            def queryAdapter(self, ob, iface, name, default=None):
-                if iface is I3:
-                    return 43
-                return default
-        servicemanager.services[Adapters] = StubAdapterService()
+      >>> capi.getAdapterInContext(ob, I1, context)
+      <Component implementing 'I1'>
+      >>> capi.queryAdapterInContext(ob, I1, context)
+      <Component implementing 'I1'>
 
-        # If an object implements the interface you want to adapt to,
-        # getAdapterInContext should simply return the object.
-        self.assertEquals(getAdapterInContext(ob, I1, context), ob)
-        self.assertEquals(queryAdapterInContext(ob, I1, context), ob)
+    If an object conforms to the interface you want to adapt to,
+    `getAdapterInContext()` should simply return the conformed object.
 
-        # If an object conforms to the interface you want to adapt to,
-        # getAdapterInContext should simply return the conformed object.
-        self.assertEquals(getAdapterInContext(ob, I2, context), 42)
-        self.assertEquals(queryAdapterInContext(ob, I2, context), 42)
+      >>> capi.getAdapterInContext(ob, I2, context)
+      42
+      >>> capi.queryAdapterInContext(ob, I2, context)
+      42
 
-        class I4(Interface):
-            pass
-        # If an adapter isn't registered for the given object and interface,
-        # and you provide no default, raise ComponentLookupError...
-        self.assertRaises(ComponentLookupError,
-                          getAdapterInContext, ob, I4, context)
+    If an adapter isn't registered for the given object and interface, and you
+    provide no default, raise ComponentLookupError...
 
-        # ...otherwise, you get the default
-        self.assertEquals(queryAdapterInContext(ob, I4, context, 44), 44)
+      >>> class I4(Interface):
+      ...     pass
 
-        # If you ask for an adapter for which something's registered
-        # you get the registered adapter
-        self.assertEquals(getAdapterInContext(ob, I3, context), 43)
-        self.assertEquals(queryAdapterInContext(ob, I3, context), 43)
+      >>> capi.getAdapterInContext(ob, I4,
+      ...                          context) #doctest: +NORMALIZE_WHITESPACE
+      Traceback (most recent call last):
+      ...
+      ComponentLookupError: (<Component implementing 'I1'>,
+                             <InterfaceClass zope.component.tests.test_api.I4>)
 
-    def testAdapter(self):
-        # If an adapter isn't registered for the given object and interface,
-        # and you provide no default, raise ComponentLookupError...
-        self.assertRaises(ComponentLookupError, getAdapter, ob, I2, '')
+    ...otherwise, you get the default:
 
-        # ...otherwise, you get the default
-        self.assertEquals(queryAdapter(ob, I2, '', Test), Test)
+      >>> capi.queryAdapterInContext(ob, I4, context, 44)
+      44
 
-        getService(Adapters).register([I1], I2, '', Comp)
-        c = getAdapter(ob, I2, '')
-        self.assertEquals(c.__class__, Comp)
-        self.assertEquals(c.context, ob)
+    If you ask for an adapter for which something's registered you get the
+    registered adapter
 
-    def testInterfaceCall(self):
-        getService(Adapters).register([I1], I2, '', Comp)
-        c = I2(ob)
-        self.assertEquals(c.__class__, Comp)
-        self.assertEquals(c.context, ob)
+      >>> capi.getAdapterInContext(ob, I3, context)
+      43
+      >>> capi.queryAdapterInContext(ob, I3, context)
+      43
+    """
 
-    def testNamedAdapter(self):
-        self.testAdapter()
+def testAdapter():
+    """The `getAdapter()` and `queryAdapter()` API functions are similar to
+    `{get|query}AdapterInContext()` functions, except that they do not care
+    about the `__conform__()` but also handle named adapters. (Actually, the
+    name is a required argument.)
+    
+    If an adapter isn't registered for the given object and interface, and you
+    provide no default, raise `ComponentLookupError`...
 
-        # If an adapter isn't registered for the given object and interface,
-        # and you provide no default, raise ComponentLookupError...
-        self.assertRaises(ComponentLookupError, getAdapter, ob, I2, 'test')
+      >>> capi.getAdapter(ob, I2, '') #doctest: +NORMALIZE_WHITESPACE
+      Traceback (most recent call last):
+      ...
+      ComponentLookupError: (<instance Ob>,
+                             <InterfaceClass zope.component.tests.test_api.I2>)
 
-        # ...otherwise, you get the default
-        self.assertEquals(queryAdapter(ob, I2, 'test', Test), Test)
+    ...otherwise, you get the default
 
-        class Comp2(Comp): pass
+      >>> capi.queryAdapter(ob, I2, '', '<default>')
+      '<default>'
 
-        getService(Adapters).register([I1], I2, 'test', Comp2)
-        c = getAdapter(ob, I2, 'test')
-        self.assertEquals(c.__class__, Comp2)
-        self.assertEquals(c.context, ob)
+    Now get the global site manager and register an adapter from `I1` to `I2`
+    without a name:
+      
+      >>> capi.getGlobalSiteManager().registerAdapter((I1,), I2, '', Comp)
 
-    def testQueryMultiAdapter(self):
-        # Adapting a combination of 2 objects to an interface
-        class DoubleAdapter(object):
-            implements(I3)
-            def __init__(self, first, second):
-                self.first = first
-                self.second = second
-        class Ob2(object):
-            implements(I2)
-        ob2 = Ob2()
-        context = None
-        getService(Adapters, context).register([I1, I2], I3, '', DoubleAdapter)
-        c = queryMultiAdapter((ob, ob2), I3, context=context)
-        self.assertEquals(c.__class__, DoubleAdapter)
-        self.assertEquals(c.first, ob)
-        self.assertEquals(c.second, ob2)
+    You can now simply access the adapter using the `getAdapter()` API
+    function:
 
-    def testAdapterForInterfaceNone(self):
+      >>> adapter = capi.getAdapter(ob, I2, '')
+      >>> adapter.__class__ is Comp
+      True
+      >>> adapter.context is ob
+      True
+    """
 
-        # providing an adapter for None says that your adapter can
-        # adapt anything to I2.
-        getService(Adapters).register([None], I2, '', Comp)
-        c = I2(ob)
-        self.assertEquals(c.__class__, Comp)
-        self.assertEquals(c.context, ob)
+def testInterfaceCall():
+    """Here we test the `adapter_hook()` function that we registered with the
+    `zope.interface` adapter hook registry, so that we can call interfaces to
+    do adaptation.
 
-    def testgetAdapters(self):
-        getService(Adapters).register([I1], I2, '', Comp)
-        getService(Adapters).register([None], I2, 'foo', Comp)
-        c = getAdapters((ob,), I2)
-        c.sort()
-        self.assertEquals([(name, adapter.__class__, adapter.context)
-                           for name, adapter in c],
-                          [('', Comp, ob), ('foo', Comp, ob)])
+    First, we need to register an adapter:
+    
+      >>> capi.getGlobalSiteManager().registerAdapter([I1], I2, '', Comp)
 
-    def testUtility(self):
-        self.assertRaises(ComponentLookupError, getUtility, I1, context=ob)
-        self.assertRaises(ComponentLookupError, getUtility, I2, context=ob)
-        self.assertEquals(queryUtility(I2, default=Test, context=ob), Test)
+    Then we try to adapt `ob` to provide an `I2` interface by calling the `I2`
+    interface with the obejct as first argument:
 
-        getService('Utilities').provideUtility(I2, comp)
-        self.assertEquals(id(getUtility(I2, context=ob)), id(comp))
+      >>> adapter = I2(ob)
+      >>> adapter.__class__ is Comp
+      True
+      >>> adapter.context is ob
+      True
 
-    def testNamedUtility(self):
-        from zope.component import getUtility, queryUtility
-        from zope.component import getService
-        from zope.component.exceptions import ComponentLookupError
+    If no adapter is found, a `TypeError is raised...
 
-        self.testUtility()
+      >>> I1(Ob2()) #doctest: +NORMALIZE_WHITESPACE
+      Traceback (most recent call last):
+      ...
+      TypeError: ('Could not adapt', <instance Ob2>,
+                  <InterfaceClass zope.component.tests.test_api.I1>)
+      
+    ...unless we specify an alternative adapter:
 
-        self.assertRaises(ComponentLookupError,
-                          getUtility, I1, 'test', context=ob)
-        self.assertRaises(ComponentLookupError,
-                          getUtility, I2, 'test', context=ob)
-        self.assertEquals(queryUtility(I2, 'test', Test, context=ob),
-                          Test)
+      >>> marker = object()
+      >>> I2(object(), marker) is marker
+      True
+    """
 
-        getService('Utilities').provideUtility(I2, comp, 'test')
-        self.assertEquals(id(getUtility(I2, 'test', ob)), id(comp))
+def testNamedAdapter():
+    """Make sure that adapters with names are correctly selected from the
+    registry.
 
-    def test_getAllUtilitiesRegisteredFor(self):
-        class I21(I2):
-            pass
-        class Comp21(Comp):
-            implements(I21)
-        
-        compbob = Comp('bob')
-        comp21 = Comp21('21')
-        comp21bob = Comp21('21bob')
-        
-        getService('Utilities').provideUtility(I2, comp)
-        getService('Utilities').provideUtility(I21, comp21)
-        getService('Utilities').provideUtility(I2, compbob, 'bob')
-        getService('Utilities').provideUtility(I21, comp21bob, 'bob')
+    First we register some named adapter:
 
-        comps = [comp, compbob, comp21, comp21bob]
-        comps.sort()
+      >>> capi.getGlobalSiteManager().registerAdapter([I1], I2, 'foo',
+      ...                                             lambda x: 0)
 
-        uts = list(component.getUtilitiesFor(I2))
-        uts.sort()
-        self.assertEqual(uts, [('', comp), ('bob', compbob)])
+    If an adapter isn't registered for the given object and interface,
+    and you provide no default, raise `ComponentLookupError`...
 
-        uts = list(component.getAllUtilitiesRegisteredFor(I2))
-        uts.sort()
-        self.assertEqual(uts, comps)        
+      >>> capi.getAdapter(ob, I2, 'bar') #doctest: +NORMALIZE_WHITESPACE
+      Traceback (most recent call last):
+      ...
+      ComponentLookupError: 
+      (<instance Ob>, <InterfaceClass zope.component.tests.test_api.I2>)
 
-    def testView(self):
-        from zope.component import getView, queryView, getService
-        from zope.component.exceptions import ComponentLookupError
+    ...otherwise, you get the default
 
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo', Request(I1))
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo', Request(I2))
-        self.assertEquals(queryView(ob, 'foo', Request(I2), Test), Test)
+      >>> capi.queryAdapter(ob, I2, 'bar', '<default>')
+      '<default>'
 
-        getService(Adapters).register([I1, I2], Interface, 'foo', Comp)
-        c = getView(ob, 'foo', Request(I2))
-        self.assertEquals(c.__class__, Comp)
-        self.assertEquals(c.context, ob)
+    But now we register an adapter for the object having the correct name
 
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo2', Request(I1))
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo2', Request(I2))
-        self.assertEquals(queryView(ob, 'foo2', Request(I2), Test), Test)
+      >>> capi.getGlobalSiteManager().registerAdapter([I1], I2, 'bar', Comp)
 
-        self.assertEquals(queryView(ob, 'foo2', Request(I1), None), None)
+    so that the lookup succeeds:
+    
+      >>> adapter = capi.getAdapter(ob, I2, 'bar')
+      >>> adapter.__class__ is Comp
+      True
+      >>> adapter.context is ob
+      True
+    """
 
-    def testView_w_provided(self):
-        from zope.component import getView, queryView, getService
-        from zope.component.exceptions import ComponentLookupError
+def testMultiAdapter():
+    """Adapting a combination of 2 objects to an interface
 
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo', Request(I1), providing=I3)
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo', Request(I2), providing=I3)
-        self.assertEquals(
-            queryView(ob, 'foo', Request(I2), Test, providing=I3),
-            Test)
+    Multi-adapters adapt one or more objects to another interface. To make
+    this demonstration non-trivial, we need to create a second object to be
+    adapted:
+    
+      >>> ob2 = Ob2()
 
-        getService(Adapters).register([I1, I2], Interface, 'foo', Comp)
+    Like for regular adapters, if an adapter isn't registered for the given
+    objects and interface, and you provide no default, raise
+    `ComponentLookupError`...
 
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo', Request(I1), providing=I3)
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo', Request(I2), providing=I3)
-        self.assertEquals(
-            queryView(ob, 'foo', Request(I2), Test, providing=I3),
-            Test)
+      >>> capi.getMultiAdapter((ob, ob2), I3) #doctest: +NORMALIZE_WHITESPACE
+      Traceback (most recent call last):
+      ...
+      ComponentLookupError:
+      ((<instance Ob>, <instance Ob2>),
+       <InterfaceClass zope.component.tests.test_api.I3>)
 
-        getService(Adapters).register([I1, I2], I3, 'foo', Comp)
+    ...otherwise, you get the default
 
-        c = getView(ob, 'foo', Request(I2), providing=I3)
-        self.assertEquals(c.__class__, Comp)
-        self.assertEquals(c.context, ob)
+      >>> capi.queryMultiAdapter((ob, ob2), I3, default='<default>')
+      '<default>'
 
-    def testMultiView(self):
-        from zope.component import queryMultiView, getService
-        from zope.component.exceptions import ComponentLookupError
+    Note that the name is not a required attribute here.
 
-        class Ob2(object):
-            implements(I2)
+    To test multi-adapters, we also have to create an adapter class that
+    handles to context objects:
+    
+      >>> class DoubleAdapter(object):
+      ...     implements(I3)
+      ...     def __init__(self, first, second):
+      ...         self.first = first
+      ...         self.second = second
 
-        ob2 = Ob2()
+    Now we can register the multi-adapter using
+    
+      >>> capi.getGlobalSiteManager().registerAdapter((I1, I2), I3, '',
+      ...                                        DoubleAdapter)
 
-        class IRequest(Interface):
-            pass
+    Notice how the required interfaces are simply provided by a tuple. Now we
+    can get the adapter:
 
-        request = Request(IRequest)
+      >>> adapter = capi.getMultiAdapter((ob, ob2), I3)
+      >>> adapter.__class__ is DoubleAdapter
+      True
+      >>> adapter.first is ob
+      True
+      >>> adapter.second is ob2
+      True
+    """
 
-        class MV(object):
-            implements(I3)
-            def __init__(self, context, other, request):
-               self.context, self.other, self.request = context, other, request
+def testAdapterForInterfaceNone():
+    """Providing an adapter for None says that your adapter can adapt anything
+    to `I2`.
 
-        self.assertEquals(
-            queryMultiView((ob, ob2), request, I3, 'foo', 42), 42)
+      >>> capi.getGlobalSiteManager().registerAdapter((None,), I2, '', Comp)
 
-        getService(Adapters).register((I1, I2, IRequest), I3, 'foo', MV)
+      >>> adapter = I2(ob)
+      >>> adapter.__class__ is Comp
+      True
+      >>> adapter.context is ob
+      True
 
-        view = queryMultiView((ob, ob2), request, I3, 'foo')
-        self.assertEquals(view.__class__, MV)
-        self.assertEquals(view.context, ob)
-        self.assertEquals(view.other, ob2)
-        self.assertEquals(view.request, request)
+    It can really adapt any arbitrary object:
 
-    def test_viewProvidingFunctions(self):        
-        # Confirm that a call to getViewProving/queryViewProviding simply 
-        # passes its arguments through to getView/queryView - here we hack
-        # getView and queryView to inspect the args passed through.
-        import zope.component
+      >>> something = object()
+      >>> adapter = I2(something)
+      >>> adapter.__class__ is Comp
+      True
+      >>> adapter.context is something
+      True
+    """
+    
+def testGetAdapters():
+    """It is sometimes desireable to get a list of all adapters that are
+    registered for a particular output interface, given a set of
+    objects.
 
-        # hack zope.component.getView
-        def getView(object, name, request, context, providing):
-            self.args = [object, name, request, context, providing]
-        savedGetView = zope.component.getView
-        zope.component.getView = getView
+    Let's register some adapters first: 
+    
+      >>> capi.getGlobalSiteManager().registerAdapter([I1], I2, '', Comp)
+      >>> capi.getGlobalSiteManager().registerAdapter([None], I2, 'foo', Comp)
 
-        # confirm pass through of args to getView by way of getViewProviding
-        zope.component.getViewProviding(
-            object='object', providing='providing', request='request', 
-            context='context')
-        self.assertEquals(self.args, 
-            ['object', '', 'request', 'providing', 'context'])
+    Now we get all the adapters that are registered for `ob` that provide
+    `I2`:
+    
+      >>> adapters = capi.getAdapters((ob,), I2)
+      >>> adapters.sort()
+      >>> [(name, adapter.__class__.__name__) for name, adapter in adapters]
+      [(u'', 'Comp'), (u'foo', 'Comp')]
+    """
 
-        # hack zope.component.queryView
-        def queryView(object, name, request, default, providing, context):
-            self.args = [object, name, request, default, providing, context]
-        savedQueryView = zope.component.queryView
-        zope.component.queryView = queryView
+def testUtility():
+    """Utilities are components that simply provide an interface. They are
+    instantiated at the time or before they are registered. Here we test the
+    simple query interface.
 
-        # confirm pass through of args to queryView by way of queryViewProviding
-        zope.component.queryViewProviding(
-            object='object', providing='providing', request='request', 
-            default='default', context='context')
-        self.assertEquals(self.args, 
-            ['object', '', 'request', 'default', 'providing', 'context'])
+    Before we register any utility, there is no utility available, of
+    course. The pure instatiation of an object does not make it a utility. If
+    you do not specify a default, you get a `ComponentLookupError`...
 
-        # restore zope.component
-        zope.component.getView = savedGetView
-        zope.component.queryView = savedQueryView
+      >>> capi.getUtility(I1) #doctest: +NORMALIZE_WHITESPACE
+      Traceback (most recent call last):
+      ...
+      ComponentLookupError: \
+      (<InterfaceClass zope.component.tests.test_api.I1>, '')
 
-    def testResource(self):
-        from zope.component import getResource, queryResource, getService
-        from zope.component.exceptions import ComponentLookupError
+    ...otherwise, you get the default
 
-        r1 = Request(I1)
-        r2 = Request(I2)
+      >>> capi.queryUtility(I1, default='<default>')
+      '<default>'
+      >>> capi.queryUtility(I2, default='<default>')
+      '<default>'
 
-        self.assertRaises(ComponentLookupError, getResource, 'foo', r1)
-        self.assertRaises(ComponentLookupError, getResource, 'foo', r2)
-        self.assertEquals(queryResource('foo', r2, Test), Test)
+    Now we declare `ob` to be the utility providing `I1`
 
-        getService(Adapters).register((I2,), Interface, 'foo', Comp)
-        c = getResource('foo', r2)
-        self.assertEquals(c.__class__, Comp)
-        self.assertEquals(c.context, r2)
+      >>> capi.getGlobalSiteManager().registerUtility(I1, ob)
 
-        self.assertRaises(ComponentLookupError, getResource, 'foo2', r1, ob)
-        self.assertRaises(ComponentLookupError, getResource, 'foo2', r2)
-        self.assertEquals(queryResource('foo2', r2, Test, ob), Test)
+    so that the component is now available:
+    
+      >>> capi.getUtility(I1) is ob
+      True
+    """
 
-        self.assertEquals(queryResource('foo2', r1, None), None)
+def testNamedUtility():
+    """Like adapters, utilities can be named.
 
-    def testResource_w_provided(self):
-        from zope.component import getResource, queryResource, getService
-        from zope.component.exceptions import ComponentLookupError
+    Just because you register an utility having no name
+    
+      >>> capi.getGlobalSiteManager().registerUtility(I1, ob)
 
-        r1 = Request(I1)
-        r2 = Request(I2)
+    does not mean that they are available when you specify a name:
+    
+      >>> capi.getUtility(I1, name='foo') #doctest: +NORMALIZE_WHITESPACE
+      Traceback (most recent call last):
+      ...
+      ComponentLookupError:
+      (<InterfaceClass zope.component.tests.test_api.I1>, 'foo')
 
-        self.assertRaises(ComponentLookupError,
-                          getResource, 'foo', r1, providing=I3)
-        self.assertRaises(ComponentLookupError,
-                          getResource, 'foo', r2, providing=I3)
-        self.assertEquals(queryResource('foo', r2, Test, providing=I3),
-                          Test)
 
-        getService(Adapters).register((I2,), Interface, 'foo', Comp)
+    ...otherwise, you get the default
 
-        self.assertRaises(ComponentLookupError,
-                          getResource, 'foo', r1, providing=I3)
-        self.assertRaises(ComponentLookupError,
-                          getResource, 'foo', r2, providing=I3)
-        self.assertEquals(queryResource('foo', r2, Test, providing=I3),
-                          Test)
+      >>> capi.queryUtility(I1, name='foo', default='<default>')
+      '<default>'
 
-        getService(Adapters).register((I2,), I3, 'foo', Comp)
+    Registering the utility under the correct name 
 
-        c = getResource('foo', r2, providing=I3)
-        self.assertEquals(c.__class__, Comp)
-        self.assertEquals(c.context, r2)
+      >>> capi.getGlobalSiteManager().registerUtility(I1, ob, name='foo')
 
-    def testViewWithContextArgument(self):
-        # Basically the same as testView, but exercising the context
-        # argument. As this only tests global views, the context
-        # argument is pretty much a no-operation.
-        from zope.component import getView, queryView, getService
-        from zope.component.exceptions import ComponentLookupError
+    really helps:
 
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo', Request(I1), context=ob)
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo', Request(I2), context=ob)
-        self.assertEquals(queryView(ob, 'foo', Request(I2), Test, context=ob),
-                          Test)
+      >>> capi.getUtility(I1, 'foo') is ob
+      True
+    """
 
-        getService(Adapters, ob).register((I1, I2), Interface, 'foo', Comp)
+def test_getAllUtilitiesRegisteredFor():
+    """Again, like for adapters, it is often useful to get a list of all
+    utilities that have been registered for a particular interface. Utilities
+    providing a derived interface are also listed.
 
-        c = getView(ob, 'foo', Request(I2), context=ob)
-        self.assertEquals(c.__class__, Comp)
-        self.assertEquals(c.context, ob)
+    Thus, let's create a derivative interface of `I1`:
+    
+      >>> class I11(I1):
+      ...     pass
 
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo2', Request(I1), context=ob)
-        self.assertRaises(ComponentLookupError,
-                          getView, ob, 'foo2', Request(I2), context=ob)
-        self.assertEquals(queryView(ob, 'foo2', Request(I2), Test,
-                                    context=ob),
-                          Test)
+      >>> class Ob11(Ob):
+      ...     implements(I11)
+    
+      >>> ob11 = Ob11()
+      >>> ob_bob = Ob()
 
-        self.assertEquals(queryView(ob, 'foo2', Request(I1), None,
-                                    context=ob),
-                          None)
+    Now we register the new utilities:
 
-    def testDefaultViewName(self):
-        from zope.component import getService
-        getService(Adapters).register((I1, I2), IDefaultViewName,
-                                      '', 'sample_name')
-        self.assertRaises(ComponentLookupError,
-                          getDefaultViewName,
-                          ob, Request(I1))
-        self.assertEquals(getDefaultViewName(ob, Request(I2)),
-                          'sample_name')
-        self.assertRaises(ComponentLookupError,
-                          getDefaultViewName,
-                          ob, Request(I1))
+      >>> gsm = capi.getGlobalSiteManager()
+      >>> gsm.registerUtility(I1, ob)
+      >>> gsm.registerUtility(I11, ob11)
+      >>> gsm.registerUtility(I1, ob_bob, name='bob')
+      >>> gsm.registerUtility(I2, Comp(2))
 
+    We can now get all the utilities that provide interface `I1`:
 
-class TestNoSetup(unittest.TestCase):
+      >>> uts = list(capi.getAllUtilitiesRegisteredFor(I1))
+      >>> uts = [util.__class__.__name__ for util in uts]
+      >>> uts.sort()
+      >>> uts
+      ['Ob', 'Ob', 'Ob11']
 
-    def testNotBrokenWhenNoService(self):
-        # Both of those things emit DeprecationWarnings.
-        self.assertRaises(TypeError, I2, ob)
-        self.assertEquals(I2(ob, 42), 42)
-        pass
+    Note that `getAllUtilitiesRegisteredFor()` does not return the names of
+    the utilities.
+    """
 
+def testNotBrokenWhenNoSiteManager():
+    """Make sure that the adapter lookup is not broken, when no site manager
+    is available.
+
+    Both of those things emit `DeprecationWarnings`.
+
+      >>> I2(ob) #doctest: +NORMALIZE_WHITESPACE
+      Traceback (most recent call last):
+      ...
+      TypeError: ('Could not adapt',
+                  <instance Ob>,
+                  <InterfaceClass zope.component.tests.test_api.I2>)
+
+
+      >>> I2(ob, 42)
+      42
+    """
+
 def test_suite():
     return unittest.TestSuite((
-        unittest.makeSuite(Test),
-        unittest.makeSuite(TestNoSetup),
+        doctest.DocTestSuite(setUp=setUp, tearDown=tearDown),
+        doctest.DocFileSuite('../README.txt',
+                             setUp=setUp, tearDown=tearDown),
         ))
 
 if __name__ == "__main__":

Modified: Zope3/branches/srichter-blow-services/src/zope/component/tests/test_factory.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/test_factory.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/tests/test_factory.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -17,13 +17,12 @@
 """
 import unittest
 from zope.interface import Interface, implements
-from zope.interface.interfaces import IDeclaration
 
-from zope.component import createObject, getFactoryInterfaces, getFactoriesFor
-from zope.component import getService, servicenames
+from zope import component as capi
 from zope.component.interfaces import IFactory
 from zope.component.factory import Factory
-from zope.component.tests.placelesssetup import PlacelessSetup
+from zope.component.tests.placelesssetup import setUp, tearDown
+from zope.testing import doctest
 
 class IFunction(Interface):
     pass
@@ -38,74 +37,91 @@
         self.args = args
         self.kw = kw
 
+factory = Factory(Klass, 'Klass', 'Klassier')
+factory2 = Factory(lambda x: x, 'Func', 'Function')
+factory3 = Factory(lambda x: x, 'Func', 'Function', (IFunction,))
 
-class TestFactory(unittest.TestCase):
+def testFactoryCall():
+    """Here we test whether the factory correctly creates the objects and
+    including the correct handling of constructor elements.
 
-    def setUp(self):
-        self._factory = Factory(Klass, 'Klass', 'Klassier')
-        self._factory2 = Factory(lambda x: x, 'Func', 'Function')
-        self._factory3 = Factory(lambda x: x, 'Func', 'Function', (IFunction,))
+    First we create a factory that creates instanace of the `Klass` class:
 
-    def testCall(self):
-        kl = self._factory(3, foo=4)
-        self.assert_(isinstance(kl, Klass))
-        self.assertEqual(kl.args, (3, ))
-        self.assertEqual(kl.kw, {'foo': 4})
-        self.assertEqual(self._factory2(3), 3)
-        self.assertEqual(self._factory3(3), 3)
+      >>> factory = Factory(Klass, 'Klass', 'Klassier')
 
-    def testTitleDescription(self):
-        self.assertEqual(self._factory.title, 'Klass')
-        self.assertEqual(self._factory.description, 'Klassier')
-        self.assertEqual(self._factory2.title, 'Func')
-        self.assertEqual(self._factory2.description, 'Function')
-        self.assertEqual(self._factory3.title, 'Func')
-        self.assertEqual(self._factory3.description, 'Function')
+    Now we use the factory to create the instance
+    
+      >>> kl = factory(1, 2, foo=3, bar=4)
 
-    def testGetInterfaces(self):
-        implemented = self._factory.getInterfaces()
-        self.assert_(implemented.isOrExtends(IKlass))
-        self.assertEqual(list(implemented), [IKlass])
-        self.assertEqual(implemented.__name__,
-                         'zope.component.tests.test_factory.Klass')
+    and make sure that the correct class was used to create the object:
+    
+      >>> kl.__class__
+      <>
 
-        implemented2 = self._factory2.getInterfaces()
-        self.assertEqual(list(implemented2), [])
-        self.assertEqual(implemented2.__name__, '<lambda>')
+    Since we passed in one 
+      
+      >>> kl.args
+      (3, )
+      >>> kl.kw
+      {'foo': 4}
+      
+      >>> factory2(3)
+      3
+      >>> factory3(3)
+      3
+    """
 
-        implemented3 = self._factory3.getInterfaces()
-        self.assertEqual(list(implemented3), [IFunction])
-        self.assertEqual(implemented3.__name__, '<lambda>')
+def testTitleDescription(self):
+    self.assertEqual(self._factory.title, 'Klass')
+    self.assertEqual(self._factory.description, 'Klassier')
+    self.assertEqual(self._factory2.title, 'Func')
+    self.assertEqual(self._factory2.description, 'Function')
+    self.assertEqual(self._factory3.title, 'Func')
+    self.assertEqual(self._factory3.description, 'Function')
 
+def testGetInterfaces(self):
+    implemented = self._factory.getInterfaces()
+    self.assert_(implemented.isOrExtends(IKlass))
+    self.assertEqual(list(implemented), [IKlass])
+    self.assertEqual(implemented.__name__,
+                     'zope.component.tests.test_factory.Klass')
 
+    implemented2 = self._factory2.getInterfaces()
+    self.assertEqual(list(implemented2), [])
+    self.assertEqual(implemented2.__name__, '<lambda>')
+
+    implemented3 = self._factory3.getInterfaces()
+    self.assertEqual(list(implemented3), [IFunction])
+    self.assertEqual(implemented3.__name__, '<lambda>')
+
+
 class TestFactoryZAPIFunctions(PlacelessSetup, unittest.TestCase):
 
     def setUp(self):
         super(TestFactoryZAPIFunctions, self).setUp()
         self.factory = Factory(Klass, 'Klass', 'Klassier')
-        utilityService = getService(servicenames.Utilities)
-        utilityService.provideUtility(IFactory, self.factory, 'klass')
+        gsm = capi.getGlobalSiteManager() 
+        gsm.registerUtility(IFactory, self.factory, 'klass')
 
     def testCreateObject(self):
-        kl = createObject(None, 'klass', 3, foo=4)
+        kl = capi.createObject(None, 'klass', 3, foo=4)
         self.assert_(isinstance(kl, Klass))
         self.assertEqual(kl.args, (3, ))
         self.assertEqual(kl.kw, {'foo': 4})
 
     def testGetFactoryInterfaces(self):
-        implemented = getFactoryInterfaces('klass')
+        implemented = capi.getFactoryInterfaces('klass')
         self.assert_(implemented.isOrExtends(IKlass))
         self.assertEqual([iface for iface in implemented], [IKlass])
 
     def testGetFactoriesFor(self):
-        self.assertEqual(list(getFactoriesFor(IKlass)),
+        self.assertEqual(list(capi.getFactoriesFor(IKlass)),
                          [('klass', self.factory)])
 
 
 def test_suite():
     return unittest.TestSuite((
-        unittest.makeSuite(TestFactory),
-        unittest.makeSuite(TestFactoryZAPIFunctions)
+        doctest.DocTestSuite(),
         ))
 
 if __name__=='__main__':

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/tests/test_service.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/test_service.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/tests/test_service.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,136 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test ServiceService component
-
-$Id$
-"""
-
-import unittest
-import pickle
-from zope.interface import Interface, implements
-
-from zope.exceptions import DuplicationError
-from zope.testing.cleanup import CleanUp
-
-from zope.component import getServiceDefinitions, getService, getGlobalServices
-from zope.component.service import UndefinedService, InvalidService
-from zope.component.service import GlobalServiceManager, GlobalService
-from zope.component.exceptions import ComponentLookupError
-from zope.component.interfaces import IServiceService
-
-class IOne(Interface):
-    pass
-
-class ITwo(Interface):
-    pass
-
-class ServiceOne(GlobalService):
-    implements(IOne)
-
-class ServiceTwo(GlobalService):
-    implements(ITwo)
-
-class Test(CleanUp, unittest.TestCase):
-
-    def testNormal(self):
-        ss = getGlobalServices()
-        ss.defineService('one', IOne)
-        c = ServiceOne()
-        ss.provideService('one', c)
-        self.assertEqual(id(getService('one')), id(c))
-
-    def testFailedLookup(self):
-        self.assertRaises(ComponentLookupError, getService, 'two')
-
-    def testDup(self):
-        getGlobalServices().defineService('one', IOne)
-        self.assertRaises(DuplicationError,
-                          getGlobalServices().defineService,
-                          'one', ITwo)
-
-        c = ServiceOne()
-        getGlobalServices().provideService('one', c)
-
-        c2 = ServiceOne()
-        self.assertRaises(DuplicationError,
-                          getGlobalServices().provideService,
-                          'one', c2)
-
-        self.assertEqual(id(getService('one')), id(c))
-
-
-    def testUndefined(self):
-        c = ServiceOne()
-        self.assertRaises(UndefinedService,
-                          getGlobalServices().provideService,
-                          'one', c)
-
-    def testInvalid(self):
-        getGlobalServices().defineService('one', IOne)
-        getGlobalServices().defineService('two', ITwo)
-        c = ServiceOne()
-        self.assertRaises(InvalidService,
-                          getGlobalServices().provideService,
-                          'two', c)
-
-    def testGetService(self):
-        # Testing looking up a service from a service manager container that
-        # doesn't have a service manager.
-        getGlobalServices().defineService('one', IOne)
-        c = ServiceOne()
-        getGlobalServices().provideService('one', c)
-        self.assertEqual(id(getService('one')), id(c))
-
-    def testGetServiceDefinitions(self):
-        # test that the service definitions are the ones we added
-        sm = getGlobalServices()
-        sm.defineService('one', IOne)
-        c = ServiceOne()
-        sm.provideService('one', c)
-
-        sm.defineService('two', ITwo)
-        d = ServiceTwo()
-        sm.provideService('two', d)
-        defs = getServiceDefinitions()
-        defs.sort()
-        self.assertEqual(defs,
-            [('Services', IServiceService), ('one', IOne), ('two', ITwo)])
-
-    def testPickling(self):
-        self.assertEqual(testServiceManager.__reduce__(), 'testServiceManager')
-        sm = pickle.loads(pickle.dumps(testServiceManager))
-        self.assert_(sm is testServiceManager)
-
-        s2 = ServiceTwo()
-        sm.defineService('2', ITwo)
-        sm.provideService('2', s2)
-
-        self.assert_(s2.__parent__ is sm)
-        self.assertEqual(s2.__name__, '2')
-
-        s = pickle.loads(pickle.dumps(s2))
-        self.assert_(s is s2)
-        testServiceManager._clear()
-
-
-testServiceManager = GlobalServiceManager('testServiceManager', __name__)
-
-
-def test_suite():
-    loader = unittest.TestLoader()
-    return loader.loadTestsFromTestCase(Test)
-
-
-if __name__ == '__main__':
-    unittest.TextTestRunner().run(test_suite())

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/tests/test_utilityservice.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/tests/test_utilityservice.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/tests/test_utilityservice.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,159 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Utility service tests
-
-$Id$
-"""
-from unittest import TestCase, main, makeSuite
-from zope.component import \
-     getUtility, getUtilitiesFor, getService, queryUtility, \
-     getServices, getUtilitiesFor, getGlobalServices
-from zope.component.exceptions import ComponentLookupError
-from zope.component.servicenames import Utilities
-from zope.interface import Interface, implements
-
-from zope.testing.cleanup import CleanUp # Base class w registry cleanup
-
-class IDummyUtility(Interface):
-    pass
-
-class IDummerUtility(IDummyUtility):
-    pass
-
-class DummyUtility(object):
-    __name__ = 'DummyUtility'
-    implements(IDummyUtility)
-
-class DummyUtility2(object):
-    implements(IDummyUtility)
-    __name__ = 'DummyUtility2'
-
-    def __len__(self):
-        return 0
-
-class DummerUtility(object):
-    __name__ = 'DummerUtility'
-    implements(IDummerUtility)
-
-
-dummyUtility = DummyUtility()
-dummerUtility = DummerUtility()
-dummyUtility2 = DummyUtility2()
-
-class Test(TestCase, CleanUp):
-
-    def setUp(self):
-        CleanUp.setUp(self)
-        sm = getGlobalServices()
-        defineService = sm.defineService
-        provideService = sm.provideService
-        from zope.component.interfaces import IUtilityService
-        defineService('Utilities',IUtilityService)
-        from zope.component.utility import GlobalUtilityService
-        provideService('Utilities', GlobalUtilityService())
-
-    def testGetUtility(self):
-        us = getService(Utilities)
-        self.assertRaises(
-            ComponentLookupError, getUtility, IDummyUtility)
-        us.provideUtility(IDummyUtility, dummyUtility)
-        self.assertEqual(getUtility(IDummyUtility), dummyUtility)
-
-    def testQueryUtility(self):
-        us = getService(Utilities)
-        self.assertEqual(queryUtility(IDummyUtility), None)
-        self.assertEqual(queryUtility(IDummyUtility, default=self), self)
-        us.provideUtility(IDummyUtility, dummyUtility)
-        self.assertEqual(queryUtility(IDummyUtility), dummyUtility)
-
-    def testgetUtilitiesFor(self):
-        us = getService(Utilities)
-        us.provideUtility(IDummyUtility, dummyUtility)
-        self.assertEqual(list(getUtilitiesFor(IDummyUtility)),
-                         [('',dummyUtility)])
-        self.assertEqual(list(us.getUtilitiesFor(IDummyUtility)),
-                         [('',dummyUtility)])
-
-    def testregistrations(self):
-        us = getService(Utilities)
-        us.provideUtility(IDummyUtility, dummyUtility)
-        self.assertEqual(
-            map(str, us.registrations()),
-            ["UtilityRegistration('IDummyUtility', '', 'DummyUtility', '')"])
-
-    def testOverrides(self):
-        us = getService(Utilities)
-
-        # fail if nothing registered:
-        self.assertRaises(
-            ComponentLookupError, getUtility, IDummyUtility)
-
-        # set and retiev dummy
-        us.provideUtility(IDummyUtility, dummyUtility)
-        self.assertEqual(getUtility(IDummyUtility), dummyUtility)
-
-        # dummer overrides
-        us.provideUtility(IDummerUtility, dummerUtility)
-        self.assertEqual(getUtility(IDummerUtility), dummerUtility)
-
-        # But not if we ask for dummy
-        self.assertEqual(getUtility(IDummyUtility), dummyUtility)
-
-        # same for named:
-        self.assertRaises(
-            ComponentLookupError, getUtility, IDummyUtility, 'bob')
-        us.provideUtility(IDummyUtility, dummyUtility, 'bob')
-        self.assertEqual(getUtility(IDummyUtility), dummyUtility, 'bob')
-        us.provideUtility(IDummerUtility, dummerUtility, 'bob')
-        self.assertEqual(getUtility(IDummerUtility), dummerUtility, 'bob')
-        self.assertEqual(getUtility(IDummyUtility), dummyUtility, 'bob')
-
-        # getUtilitiesFor doesn the right thing:
-        uts = list(us.getUtilitiesFor(IDummyUtility))
-        uts.sort()
-        self.assertEqual(uts, [('', dummyUtility), ('bob', dummyUtility)])
-        uts = list(us.getUtilitiesFor(IDummerUtility))
-        uts.sort()
-        self.assertEqual(uts, [('', dummerUtility), ('bob', dummerUtility)])
-
-        return us
-
-    def test_getAllUtilitiesRegisteredFor(self):
-        us = self.testOverrides()
-
-        # getAllUtilitiesRegisteredFor includes overridden
-
-        uts = list(us.getAllUtilitiesRegisteredFor(IDummerUtility))
-        self.assertEqual(uts, [dummerUtility, dummerUtility])
-
-        uts = list(us.getAllUtilitiesRegisteredFor(IDummyUtility))
-        uts.remove(dummyUtility)
-        uts.remove(dummyUtility)
-        uts.remove(dummerUtility)
-        uts.remove(dummerUtility)
-        self.assertEqual(uts, [])
-
-
-    def test_getAllUtilitiesRegisteredFor_empty(self):
-        us = getService(Utilities)
-        class IFoo(Interface):
-            pass
-        self.assertEqual(list(us.getAllUtilitiesRegisteredFor(IFoo)), [])
-
-
-def test_suite():
-    return makeSuite(Test)
-
-if __name__=='__main__':
-    main(defaultTest='test_suite')

Deleted: Zope3/branches/srichter-blow-services/src/zope/component/utility.py
===================================================================
--- Zope3/branches/srichter-blow-services/src/zope/component/utility.py	2004-12-16 17:31:39 UTC (rev 28631)
+++ Zope3/branches/srichter-blow-services/src/zope/component/utility.py	2004-12-16 17:42:59 UTC (rev 28632)
@@ -1,102 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""utility service
-
-$Id$
-"""
-from zope.component.exceptions import Invalid, ComponentLookupError
-from zope.component.interfaces import IUtilityService, IRegistry
-from zope.component.service import GlobalService
-from zope.interface.adapter import AdapterRegistry
-import zope.interface
-
-class IGlobalUtilityService(IUtilityService, IRegistry):
-
-    def provideUtility(providedInterface, component, name='', info=''):
-        """Provide a utility
-
-        A utility is a component that provides an interface.
-        """
-
-class UtilityService(AdapterRegistry):
-    """Provide IUtilityService
-
-    Mixin that superimposes utility management on adapter registery
-    implementation
-    """
-
-    def getUtility(self, interface, name=''):
-        """See IUtilityService interface"""
-        c = self.queryUtility(interface, name)
-        if c is not None:
-            return c
-        raise ComponentLookupError(interface, name)
-
-    def queryUtility(self, interface, name='', default=None):
-        """See IUtilityService interface"""
-
-        byname = self._null.get(interface)
-        if byname:
-            return byname.get(name, default)
-        else:
-            return default
-
-    def getUtilitiesFor(self, interface):
-        byname = self._null.get(interface)
-        if byname:
-            for item in byname.iteritems():
-                yield item
-
-    def getAllUtilitiesRegisteredFor(self, interface):
-        return iter(self._null.get(('s', interface)) or ())
-
-class GlobalUtilityService(UtilityService, GlobalService):
-
-    zope.interface.implementsOnly(IGlobalUtilityService)
-
-    def __init__(self):
-        UtilityService.__init__(self)
-        self._registrations = {}
-
-    def provideUtility(self, providedInterface, component, name='', info=''):
-
-        if not providedInterface.providedBy(component):
-            raise Invalid("The registered component doesn't implement "
-                          "the promised interface.")
-
-        self.register((), providedInterface, name, component)
-
-        # Also subscribe to support getAllUtilitiesRegisteredFor:
-        self.subscribe((), providedInterface, component)
-
-        self._registrations[(providedInterface, name)] = UtilityRegistration(
-            providedInterface, name, component, info)
-
-    def registrations(self):
-        return self._registrations.itervalues()
-
-
-class UtilityRegistration(object):
-
-    def __init__(self, provided, name, component, doc):
-        (self.provided, self.name, self.component, self.doc
-         ) = provided, name, component, doc
-
-    def __repr__(self):
-        return '%s(%r, %r, %r, %r)' % (
-            self.__class__.__name__,
-            self.provided.__name__, self.name,
-            getattr(self.component, '__name__', self.component), self.doc,
-            )
-



More information about the Zope3-Checkins mailing list