[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