[Zope3-checkins] SVN: Zope3/branches/jim-adapter/src/zope/app/
Deprecated much of the existing registration framework. I still
Jim Fulton
jim at zope.com
Thu Mar 16 07:29:20 EST 2006
Log message for revision 66056:
Deprecated much of the existing registration framework. I still
haven't implemented the replacement, so we still get lots of warnings.
I also starting "getting rid" of things in bbb, which, sadly, was
done, in some cases, by moving them to back35.
Changed:
U Zope3/branches/jim-adapter/src/zope/app/apidoc/bookmodule/book.zcml
U Zope3/branches/jim-adapter/src/zope/app/component/adapter.py
D Zope3/branches/jim-adapter/src/zope/app/component/adapterregistry.txt
U Zope3/branches/jim-adapter/src/zope/app/component/back35.py
U Zope3/branches/jim-adapter/src/zope/app/component/bbb/__init__.py
D Zope3/branches/jim-adapter/src/zope/app/component/bbb/registration.py
D Zope3/branches/jim-adapter/src/zope/app/component/bbb/site.py
U Zope3/branches/jim-adapter/src/zope/app/component/configure.zcml
U Zope3/branches/jim-adapter/src/zope/app/component/registration.py
D Zope3/branches/jim-adapter/src/zope/app/component/registration.txt
U Zope3/branches/jim-adapter/src/zope/app/component/site.py
D Zope3/branches/jim-adapter/src/zope/app/component/statusproperty.txt
A Zope3/branches/jim-adapter/src/zope/app/component/tests/deprecated35_registration.txt
A Zope3/branches/jim-adapter/src/zope/app/component/tests/deprecated35_statusproperty.txt
D Zope3/branches/jim-adapter/src/zope/app/component/tests/test_adapter.py
U Zope3/branches/jim-adapter/src/zope/app/component/tests/test_registration.py
U Zope3/branches/jim-adapter/src/zope/app/testing/setup.py
-=-
Modified: Zope3/branches/jim-adapter/src/zope/app/apidoc/bookmodule/book.zcml
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/apidoc/bookmodule/book.zcml 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/apidoc/bookmodule/book.zcml 2006-03-16 12:29:18 UTC (rev 66056)
@@ -83,18 +83,6 @@
doc_path="README.txt"
/>
<bookchapter
- id="registration"
- title="Registration Framework"
- parent="ca/local"
- doc_path="registration.txt"
- />
- <bookchapter
- id="adapterregistry"
- title="Local Adapter Registry"
- parent="ca/local"
- doc_path="adapterregistry.txt"
- />
- <bookchapter
id="site"
title="Local Sites & Site Managers"
parent="ca/local"
Modified: Zope3/branches/jim-adapter/src/zope/app/component/adapter.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/adapter.py 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/adapter.py 2006-03-16 12:29:18 UTC (rev 66056)
@@ -11,11 +11,15 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Local/Persistent Adapter Registry
+"""DEPRECATED"""
-$Id$
-"""
-__docformat__ = 'restructuredtext'
+import warnings
+
+warnings.warn(
+ "This module is deprecated and will go away in Zope 3.5",
+ DeprecationWarning, 2)
+
+
import persistent
import zope.interface
Deleted: Zope3/branches/jim-adapter/src/zope/app/component/adapterregistry.txt
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/adapterregistry.txt 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/adapterregistry.txt 2006-03-16 12:29:18 UTC (rev 66056)
@@ -1,213 +0,0 @@
-==========================
-The Local Adapter Registry
-==========================
-
-The local adapter registry, like its global parent at
-`zope.interface.adapter`, is responsible for managing registered
-adapters. However, local adapter registries must always be instantiated by
-providing their base (or global registry), which will always be a global
-adapter registry isntance:
-
- >>> import zope.interface
- >>> gar = zope.interface.adapter.AdapterRegistry()
-
- >>> from zope.app.component import adapter
- >>> lar = adapter.LocalAdapterRegistry(gar)
- >>> lar.base is gar
- True
-
-The local adapter registry uses the registration framework (introduced in
-`registration.txt`) to manage the adapter registrations. To demonstrate we
-need to create an adapter first. Let's say we have a file
-
- >>> class IFile(zope.interface.Interface):
- ... content = zope.interface.Attribute('File Content')
-
-and we want to know the size of the file, which can be gotten by having a
-component providing the `ISized` interface:
-
- >>> class ISized(zope.interface.Interface):
- ... def getSize():
- ... """Return the size of the component."""
-
- >>> FileSize = '<FileSize>'
-
-As you can see, the adapter itself has no meaning in the adapter registry,
-which is merely responsible for looking up the component, but asserts no
-interpretation. Thus the adapter component can be any Python object.
-
-Instead of registering the adapter with the registry directly, we use an
-adapter registration to register the adapter with the local adapter registry:
-
- >>> reg = adapter.AdapterRegistration(
- ... required = (IFile,),
- ... provided = ISized,
- ... factory = FileSize,
- ... registry = lar)
- >>> reg.status
- u'Inactive'
-
-The adapter registration is an extended `ComponentRegistration`. Here the
-factory is the component. We can register the registration with the adapter
-registry using
-
- >>> lar.register(reg)
-
-Note that the registration's status is automatically set to active, when you
-register a registration:
-
- >>> reg.status
- u'Active'
-
-What really happens behind the scene is that the registry keeps track of a
-list of registrations and the registration's status property calls the
-registry's `registered()` method to determine whether the registration is
-activated.
-
- >>> lar.registered(reg)
- True
-
-You can also ask the registry for all of its registrations:
-
- >>> lar.registrations() #doctest: +NORMALIZE_WHITESPACE
- (<AdapterRegistration:
- required=<InterfaceClass __builtin__.IFile>,
- with=(),
- provided=<InterfaceClass __builtin__.ISized>,
- name='',
- component='<FileSize>',
- permission=None>,)
-
-Later you can unregister the adapter registration:
-
- >>> lar.unregister(reg)
- >>> lar.registered(reg)
- False
- >>> lar.registrations()
- ()
- >>> reg.status
- u'Inactive'
-
-Of course, the same can be achieved by setting the registration's status:
-
- >>> from zope.app.component import interfaces
- >>> reg.status = interfaces.registration.ActiveStatus
- >>> lar.registered(reg)
- True
-
- >>> reg.status = interfaces.registration.InactiveStatus
- >>> lar.registered(reg)
- False
-
-But the true flexibility of the local adapter registry is that it can be
-located in an adapter registry tree. Each node of the tree is a location and
-can override existing and register new adapters. The parent of a node can be
-accessed using
-
- >>> lar.next is None
- True
-
-In our case there is no nect registry, since the `lar` instance is the root
-node. The base registry, which is always a global one, can be accessed using
-
- >>> lar.base is gar
- True
-
-The node also knows about its children via
-
- >>> lar.subs
- ()
-
-Thus this is a double-linked tree. If I now create a second local adapter
-registry in which `lar` is the parent
-
- >>> lar2 = adapter.LocalAdapterRegistry(gar, lar)
-
-then we have
-
- >>> lar2.next is lar
- True
- >>> lar.subs == (lar2,)
- True
- >>> lar2.base is lar.base is gar
- True
-
-Let's now register our adapter with `lar` again:
-
- >>> reg.status = interfaces.registration.ActiveStatus
-
-On the second level, however, the size should be a word count instead of a
-character count:
-
- >>> FileWordCount = '<FileWordCount>'
-
-
- >>> reg2 = adapter.AdapterRegistration(
- ... required = (IFile,),
- ... provided = ISized,
- ... factory = FileWordCount,
- ... registry = lar2)
- >>> reg2.status = interfaces.registration.ActiveStatus
-
-If we now lookup the adapter in `lar`, we get the original `ISized` adapter:
-
- >>> lar.lookup((IFile,), ISized)
- '<FileSize>'
-
-but from the second registry we get
-
- >>> lar2.lookup((IFile,), ISized)
- '<FileWordCount>'
-
-If we now unregister the word counting size adapter
-
- >>> reg2.status = interfaces.registration.InactiveStatus
-
-then `lar2` will get the adapter from its parent:
-
- >>> lar2.lookup((IFile,), ISized)
- '<FileSize>'
-
-We can also change the location of a local adapter registry using
-
- >>> lar2.setNext(None)
- >>> lar2.next
- >>> lar.subs
- ()
-
-In this case we made `lar2` a root node itself. Clearly, now the `FileSize`
-adapter should not be available anymore:
-
- >>> lar2.lookup((IFile,), ISized)
-
-Now we make `lar` a sub registry of `lar2`:
-
- >>> lar.setNext(lar2)
- >>> lar.next is lar2
- True
- >>> lar2.subs == (lar,)
- True
-
-Note that you should never set the next attribute directly, but always use the
-`setNext()` method, since it ensures the integrety of all the links in the
-tree and updates the adapter lookup caches.
-
-The global adapter registry is taken into account during the lookup too, of
-course. Let's say we want to have an adapter that determines the type of the
-file and register it globally:
-
- >>> class IFileType(zope.interface.Interface):
- ... def getType():
- ... """Return the type of the file."""
-
- >>> FileType = '<FileType>'
-
- >>> gar.register((IFile,), IFileType, '', FileType)
-
-Then this adapter will be available in any local adapter registry:
-
- >>> lar.lookup((IFile,), IFileType, '')
- '<FileType>'
- >>> lar2.lookup((IFile,), IFileType, '')
- '<FileType>'
-
Modified: Zope3/branches/jim-adapter/src/zope/app/component/back35.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/back35.py 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/back35.py 2006-03-16 12:29:18 UTC (rev 66056)
@@ -16,6 +16,10 @@
$Id$
"""
+from persistent import Persistent
+
+import zope.event
+
from zope import interface, schema
import zope.component.interfaces
import zope.app.component.interfaces.registration
@@ -23,7 +27,19 @@
from zope.app.i18n import ZopeMessageFactory as _
import zope.app.container.interfaces
import zope.app.container.constraints
+from zope.interface import implements
+from zope.security.checker import InterfaceChecker, CheckerPublic
+from zope.security.proxy import Proxy, removeSecurityProxy
+from zope.app import zapi
+from zope.app.component.interfaces import registration as interfaces
+from zope.app.container.btree import BTreeContainer
+from zope.app.container.contained import Contained
+from zope.app.event import objectevent
+from zope.app.traversing.interfaces import TraversalError
+from zope.app.i18n import ZopeMessageFactory as _
+import zope.app.component.registration
+
InactiveStatus = _('Inactive')
ActiveStatus = _('Active')
@@ -313,3 +329,272 @@
readonly=True,
required=True,
)
+
+
+
+class RegistrationStatusProperty(object):
+ """A descriptor used to implement `IRegistration`'s `status` property."""
+ def __get__(self, inst, klass):
+ registration = inst
+ if registration is None:
+ return self
+
+ registry = registration.getRegistry()
+ if registry and registry.registered(registration):
+ return interfaces.ActiveStatus
+
+ return interfaces.InactiveStatus
+
+ def __set__(self, inst, value):
+ registration = inst
+ registry = registration.getRegistry()
+ if registry is None:
+ raise ValueError('No registry found.')
+
+ if value == interfaces.ActiveStatus:
+ if not registry.registered(registration):
+ registry.register(registration)
+ zope.event.notify(
+ zope.app.component.registration.RegistrationActivatedEvent(
+ registration)
+ )
+
+ elif value == interfaces.InactiveStatus:
+ if registry.registered(registration):
+ registry.unregister(registration)
+ zope.event.notify(
+ zope.app.component.registration.RegistrationDeactivatedEvent(
+ registration)
+ )
+ else:
+ raise ValueError(value)
+
+
+class SimpleRegistration(Persistent, Contained):
+ """Registration objects that just contain registration data"""
+ implements(interfaces.IRegistration,
+ interfaces.IRegistrationManagerContained)
+
+ # See interfaces.IRegistration
+ status = RegistrationStatusProperty()
+
+ def getRegistry(self):
+ """See interfaces.IRegistration"""
+ raise NotImplementedError(
+ 'This method must be implemented by each specific regstration.')
+
+
+
+
+# Note that I could get rid of the base class below, but why bother.
+# The thing that uses it is going away too. I really have no way of
+# knowing that there aren't still registrations that use the older
+# data structures. The better approach will be to just stop using
+# registrations.
+
+NULL_COMPONENT = object()
+
+class BBBComponentRegistration(object):
+
+ _BBB_componentPath = None
+
+ def __init__(self, component, permission=None):
+ # BBB: 12/05/2004
+ if isinstance(component, (str, unicode)):
+ self.componentPath = component
+ else:
+ # We always want to set the plain component. Untrusted code will
+ # get back a proxied component anyways.
+ self.component = removeSecurityProxy(component)
+ if permission == 'zope.Public':
+ permission = CheckerPublic
+ self.permission = permission
+
+ def getComponent(self):
+ return self.__BBB_getComponent()
+ getComponent = zope.deprecation.deprecated(getComponent,
+ 'Use component directly. '
+ 'The reference will be gone in Zope 3.3.')
+
+ def __BBB_getComponent(self):
+ if self._component is NULL_COMPONENT:
+ return self.__BBB_old_getComponent(self._BBB_componentPath)
+
+ # This condition should somehow make it in the final code, since it
+ # honors the permission.
+ if self.permission:
+ checker = InterfaceChecker(self.getInterface(), self.permission)
+ return Proxy(self._component, checker)
+
+ return self._component
+
+ def __BBB_old_getComponent(self, path):
+ service_manager = zapi.getSiteManager(self)
+
+ # Get the root and unproxy it
+ if path.startswith("/"):
+ # Absolute path
+ root = removeAllProxies(zapi.getRoot(service_manager))
+ component = zapi.traverse(root, path)
+ else:
+ # Relative path.
+ ancestor = self.__parent__.__parent__
+ component = zapi.traverse(ancestor, path)
+
+ if self.permission:
+ if type(component) is Proxy:
+ # There should be at most one security Proxy around an object.
+ # So, if we're going to add a new security proxy, we need to
+ # remove any existing one.
+ component = removeSecurityProxy(component)
+
+ interface = self.getInterface()
+
+ checker = InterfaceChecker(interface, self.permission)
+
+ component = Proxy(component, checker)
+
+ return component
+
+ def __BBB_setComponent(self, component):
+ self._BBB_componentPath = None
+ self._component = component
+
+ component = property(__BBB_getComponent, __BBB_setComponent)
+
+ def __BBB_getComponentPath(self):
+ if self._BBB_componentPath is not None:
+ return self._BBB_componentPath
+ return '/' + '/'.join(zapi.getPath(self.component))
+
+ def __BBB_setComponentPath(self, path):
+ self._component = NULL_COMPONENT
+ self._BBB_componentPath = path
+
+ componentPath = property(__BBB_getComponentPath, __BBB_setComponentPath)
+ componentPath = zope.deprecation.deprecated(
+ componentPath,
+ 'Use component directly. '
+ 'The reference will be gone in Zope 3.3.')
+
+ def __setstate__(self, dict):
+ super(BBBComponentRegistration, self).__setstate__(dict)
+ # For some reason the component path is not set correctly by the
+ # default __setstate__ mechanism.
+ if 'componentPath' in dict:
+ self._component = NULL_COMPONENT
+ self._BBB_componentPath = dict['componentPath']
+
+ if isinstance(self._BBB_componentPath, (str, unicode)):
+ self._component = NULL_COMPONENT
+
+
+class ComponentRegistration(BBBComponentRegistration,
+ SimpleRegistration):
+ """Component registration.
+
+ Subclasses should define a getInterface() method returning the interface
+ of the component.
+ """
+ implements(interfaces.IComponentRegistration)
+
+ def __init__(self, component, permission=None):
+ super(ComponentRegistration, self).__init__(component, permission)
+ if permission == 'zope.Public':
+ permission = CheckerPublic
+ self.permission = permission
+
+ def _getComponent(self):
+ if self.permission and self.interface:
+ checker = InterfaceChecker(self.interface, self.permission)
+ return Proxy(self._component, checker)
+ return self._component
+
+ def _setComponent(self, component):
+ # We always want to set the plain component. Untrusted code will
+ # get back a proxied component anyways.
+ self._component = removeSecurityProxy(component)
+
+ # See zope.app.component.interfaces.registration.IComponentRegistration
+ component = property(_getComponent, _setComponent)
+
+ # See zope.app.component.interfaces.registration.IComponentRegistration
+ interface = None
+
+
+class Registered:
+ """An adapter from IRegisterable to IRegistered.
+
+ This class is the only place that knows how 'Registered'
+ data is represented.
+ """
+ implements(interfaces.IRegistered)
+ __used_for__ = interfaces.IRegisterable
+
+ def __init__(self, registerable):
+ self.registerable = registerable
+
+ def registrations(self):
+ rm = zapi.getParent(self.registerable).registrationManager
+ return [reg for reg in rm.values()
+ if (interfaces.IComponentRegistration.providedBy(reg) and
+ reg.component is self.registerable)]
+
+
+class RegistrationManager(BTreeContainer):
+ """Registration manager
+
+ Manages registrations within a package.
+ """
+ implements(interfaces.IRegistrationManager)
+
+ def addRegistration(self, reg):
+ "See IWriteContainer"
+ key = self._chooseName('', reg)
+ self[key] = reg
+ return key
+
+ def _chooseName(self, name, reg):
+ """Choose a name for the registration."""
+ if not name:
+ name = reg.__class__.__name__
+
+ i = 1
+ chosenName = name
+ while chosenName in self:
+ i += 1
+ chosenName = name + str(i)
+
+ return chosenName
+
+class RegisterableContainer(object):
+ """Mix-in to implement `IRegisterableContainer`"""
+ implements(interfaces.IRegisterableContainer,
+ interfaces.IRegisterableContainerContaining)
+
+ def __init__(self):
+ super(RegisterableContainer, self).__init__()
+ self.__createRegistrationManager()
+
+ def __createRegistrationManager(self):
+ "Create a registration manager and store it as `registrationManager`"
+ # See interfaces.IRegisterableContainer
+ self.registrationManager = RegistrationManager()
+ self.registrationManager.__parent__ = self
+ self.registrationManager.__name__ = '++registrations++'
+ zope.event.notify(
+ objectevent.ObjectCreatedEvent(self.registrationManager))
+
+
+class RegistrationManagerNamespace:
+ """Used to traverse to a Registration Manager from a
+ Registerable Container."""
+ __used_for__ = interfaces.IRegisterableContainer
+
+ def __init__(self, ob, request=None):
+ self.context = ob.registrationManager
+
+ def traverse(self, name, ignore):
+ if name == '':
+ return self.context
+ raise TraversalError(self.context, name)
Modified: Zope3/branches/jim-adapter/src/zope/app/component/bbb/__init__.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/bbb/__init__.py 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/bbb/__init__.py 2006-03-16 12:29:18 UTC (rev 66056)
@@ -3,6 +3,5 @@
import sys
import localservice
import interfaces
-import registration
sys.modules['zope.app.component.localservice'] = localservice
Deleted: Zope3/branches/jim-adapter/src/zope/app/component/bbb/registration.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/bbb/registration.py 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/bbb/registration.py 2006-03-16 12:29:18 UTC (rev 66056)
@@ -1,281 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2005 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.
-#
-##############################################################################
-"""Registration BBB components
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-from persistent import Persistent
-import zope.deprecation
-from zope.cachedescriptors.property import Lazy
-from zope.interface import implements
-from zope.proxy import removeAllProxies
-from zope.security.checker import InterfaceChecker, CheckerPublic
-from zope.security.proxy import Proxy, removeSecurityProxy
-
-from zope.app import zapi
-from zope.app.container.contained import Contained
-
-import interfaces
-
-
-class RegistrationStack(Contained, Persistent):
- """Registration registry implemention
-
- A registration stack provides support for a collection of
- registrations such that, at any time, at most one is active. The
- "stack" aspect of the api is designed to support "uninstallation",
- as will be described below.
- """
- implements(interfaces.IRegistrationStack)
-
- def __init__(self, container):
- self.__parent__ = container
- self.sitemanager = zapi.getSiteManager(container)
-
- def register(self, registration):
- self.sitemanager.register(registration)
- self._activate(registration)
-
- def unregister(self, registration):
- self.sitemanager.register(registration)
- self._deactivate(registration)
-
- def registered(self, registration):
- self.sitemanager.registered(registration)
-
- def _activate(self, registration):
- zope.event.notify(RegistrationActivatedEvent(registration))
- registration.activated()
-
- def _deactivate(self, registration):
- zope.event.notify(RegistrationDeactivatedEvent(registration))
- registration.deactivated()
-
- def activate(self, registration):
- self.sitemanager.register(registration)
- self._activate(registration)
-
-
- def deactivate(self, registration):
- self.sitemanager.register(registration)
- self._deactivate(registration)
-
- def active(self):
- return True
-
- def __nonzero__(self):
- return True
-
- def info(self):
- # This registration stack stub does not really know about the
- # registration it manages. Thus the registration component is None
- # here. It might be that someone has a problem with this code, but I
- # am sceptical that someone used this method manually.
- return [{'active': True,
- 'registration': None}]
-
-
-NULL_COMPONENT = object()
-
-class BBBComponentRegistration(object):
-
- _BBB_componentPath = None
-
- def __init__(self, component, permission=None):
- # BBB: 12/05/2004
- if isinstance(component, (str, unicode)):
- self.componentPath = component
- else:
- # We always want to set the plain component. Untrusted code will
- # get back a proxied component anyways.
- self.component = removeSecurityProxy(component)
- if permission == 'zope.Public':
- permission = CheckerPublic
- self.permission = permission
-
- def getComponent(self):
- return self.__BBB_getComponent()
- getComponent = zope.deprecation.deprecated(getComponent,
- 'Use component directly. '
- 'The reference will be gone in Zope 3.3.')
-
- def __BBB_getComponent(self):
- if self._component is NULL_COMPONENT:
- return self.__BBB_old_getComponent(self._BBB_componentPath)
-
- # This condition should somehow make it in the final code, since it
- # honors the permission.
- if self.permission:
- checker = InterfaceChecker(self.getInterface(), self.permission)
- return Proxy(self._component, checker)
-
- return self._component
-
- def __BBB_old_getComponent(self, path):
- service_manager = zapi.getSiteManager(self)
-
- # Get the root and unproxy it
- if path.startswith("/"):
- # Absolute path
- root = removeAllProxies(zapi.getRoot(service_manager))
- component = zapi.traverse(root, path)
- else:
- # Relative path.
- ancestor = self.__parent__.__parent__
- component = zapi.traverse(ancestor, path)
-
- if self.permission:
- if type(component) is Proxy:
- # There should be at most one security Proxy around an object.
- # So, if we're going to add a new security proxy, we need to
- # remove any existing one.
- component = removeSecurityProxy(component)
-
- interface = self.getInterface()
-
- checker = InterfaceChecker(interface, self.permission)
-
- component = Proxy(component, checker)
-
- return component
-
- def __BBB_setComponent(self, component):
- self._BBB_componentPath = None
- self._component = component
-
- component = property(__BBB_getComponent, __BBB_setComponent)
-
- def __BBB_getComponentPath(self):
- if self._BBB_componentPath is not None:
- return self._BBB_componentPath
- return '/' + '/'.join(zapi.getPath(self.component))
-
- def __BBB_setComponentPath(self, path):
- self._component = NULL_COMPONENT
- self._BBB_componentPath = path
-
- componentPath = property(__BBB_getComponentPath, __BBB_setComponentPath)
- componentPath = zope.deprecation.deprecated(
- componentPath,
- 'Use component directly. '
- 'The reference will be gone in Zope 3.3.')
-
- def __setstate__(self, dict):
- super(BBBComponentRegistration, self).__setstate__(dict)
- # For some reason the component path is not set correctly by the
- # default __setstate__ mechanism.
- if 'componentPath' in dict:
- self._component = NULL_COMPONENT
- self._BBB_componentPath = dict['componentPath']
-
- if isinstance(self._BBB_componentPath, (str, unicode)):
- self._component = NULL_COMPONENT
-
-
-class BBBRegistry(object):
-
- def queryRegistrationsFor(self, cfg, default=None):
- return RegistrationStack(self, cfg.name)
- queryRegistrationsFor = zope.deprecation.deprecated(
- queryRegistrationsFor,
- 'This method is not needed anymore, since registration stacks are '
- 'gone. There is now always only one registration per configuration '
- 'in the registry. '
- 'The reference will be gone in Zope 3.3.')
-
- def createRegistrationsFor(self, cfg):
- # Ignore
- pass
- createRegistrationsFor = zope.deprecation.deprecated(
- createRegistrationsFor,
- 'This method used to create a registration stack. These stacks are '
- 'gone, so that this method is not required anymore. You can now '
- 'directly activate and deactivate registrations with a registry. '
- 'The reference will be gone in Zope 3.3.')
-
-
-class BBBRegistrationManager(object):
-
- def _SampleContainer__data(self):
- from BTrees.OOBTree import OOBTree
- if '_data' in self.__dict__:
- return OOBTree(self._data)
- _SampleContainer__data = Lazy(_SampleContainer__data)
-
-
-class BBBRegisterableContainer(object):
-
- def registrationManager(self):
- from zope.app.component.registration import RegistrationManager
- for obj in self.values():
- if isinstance(obj, RegistrationManager):
- return obj
- registrationManager = Lazy(registrationManager)
-
- def getRegistrationManager(self):
- return self.registrationManager
- getRegistrationManager = zope.deprecation.deprecated(
- getRegistrationManager,
- 'This method has been deprecated in favor of the '
- '`registrationManager` attribute. '
- 'The reference will be gone in Zope 3.3.')
-
- def findModule(self, name):
- from zope.app.module import findModule
- return findModule(name)
- findModule = zope.deprecation.deprecated(
- findModule,
- 'This method has been deprecated and its functionality is now '
- 'available via the `zope.app.module.findModule` function. '
- 'The reference will be gone in Zope 3.3.')
-
- def resolve(self, name):
- from zope.app.module import resolve
- return resolve(name)
- findModule = zope.deprecation.deprecated(
- findModule,
- 'This method has been deprecated and its functionality is now '
- 'available via the `zope.app.module.resolve` function. '
- 'The reference will be gone in Zope 3.3.')
-
-
-class BBBRegistered(object):
-
- def addUsage(self, location):
- # Ignore in the hope that noone uses this
- pass
- addUsage = zope.deprecation.deprecated(
- addUsage,
- 'The concept of usages has been deprecated. `Registered` is now a '
- 'read-only adapter. '
- 'The reference will be gone in Zope 3.3.')
-
- def removeUsage(self, location):
- # Ignore in the hope that noone uses this
- pass
- removeUsage = zope.deprecation.deprecated(
- removeUsage,
- 'The concept of usages has been deprecated. `Registered` is now a '
- 'read-only adapter. '
- 'The reference will be gone in Zope 3.3.')
-
- def usages(self):
- return [zapi.getPath(reg.component)
- for reg in self.registrations]
- usages = zope.deprecation.deprecated(
- usages,
- 'The concept of usages has been deprecated. You can get the '
- 'registrations for a component now via the `registrations` attribute. '
- 'The reference will be gone in Zope 3.3.')
Deleted: Zope3/branches/jim-adapter/src/zope/app/component/bbb/site.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/bbb/site.py 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/bbb/site.py 2006-03-16 12:29:18 UTC (rev 66056)
@@ -1,176 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2005 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.
-#
-##############################################################################
-"""Site-related BBB components
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-import zope.deprecation
-from zope.component.service import IService
-from zope.cachedescriptors import property
-
-from zope.app import zapi
-import registration
-
-
-class BBBSiteManagerContainer(object):
-
- def _sm(self):
- if '_ServiceManagerContainer__sm' in self.__dict__:
- return self._ServiceManagerContainer__sm
- elif '_SiteManagerContainer__sm' in self.__dict__:
- return self._SiteManagerContainer__sm
- else:
- return None
- _sm = property.Lazy(_sm)
-
-
-class BBBSiteManager(object):
-
- def utilities(self):
- gsm = zapi.getGlobalSiteManager()
- from zope.app.component.site import LocalUtilityRegistry
- return LocalUtilityRegistry(gsm.utilities)
- utilities = property.Lazy(utilities)
-
- def adapters(self):
- gsm = zapi.getGlobalSiteManager()
- from zope.app.component import adapter
- return adapter.LocalAdapterRegistry(gsm.adapters)
- adapters = property.Lazy(adapters)
-
- def queryRegistrationsFor(self, cfg, default=None):
- return self.queryRegistrations(cfg.name, default)
- queryRegistrationsFor = zope.deprecation.deprecated(
- queryRegistrationsFor,
- 'The site manager does not handle registrations directly anymore. '
- 'The utility and adapter registry are available via the `utilities` '
- 'and `adapters` attributes, respectively. '
- 'The method will be gone in Zope 3.3.')
-
- def queryRegistrations(self, name, default=None):
- """See INameRegistry"""
- return registration.RegistrationStack(self, name)
- queryRegistrations = zope.deprecation.deprecated(
- queryRegistrations,
- 'The site manager does not handle registrations directly anymore. '
- 'The utility and adapter registry are available via the `utilities` '
- 'and `adapters` attributes, respectively. '
- 'The method will be gone in Zope 3.3.')
-
- def addSubsite(self, sub):
- return self.addSub(sub)
- addSubsite = zope.deprecation.deprecated(
- addSubsite,
- 'Use `addSub()` instead. '
- 'The reference will be gone in Zope 3.3.')
-
- def createRegistrationsFor(self, cfg):
- # Ignore
- pass
- createRegistrationsFor = zope.deprecation.deprecated(
- createRegistrationsFor,
- 'The site manager does not handle registrations directly anymore. '
- 'The utility and adapter registry are available via the `utilities` '
- 'and `adapters` attributes, respectively. '
- 'The reference will be gone in Zope 3.3.')
-
- def createRegistrations(self, name):
- # Ignore
- pass
- createRegistrations = zope.deprecation.deprecated(
- createRegistrations,
- 'The site manager does not handle registrations directly anymore. '
- 'The utility and adapter registry are available via the `utilities` '
- 'and `adapters` attributes, respectively. '
- 'The reference will be gone in Zope 3.3.')
-
- def listRegistrationNames(self):
- # Only used for services
- services = ['Utilities', 'Adapters']
- return [reg.name
- for reg in self.utilities.registrations()
- if reg.provided is IService] + services
- listRegistrationNames = zope.deprecation.deprecated(
- listRegistrationNames,
- 'The site manager does not handle registrations directly anymore. '
- 'The utility and adapter registry are available via the `utilities` '
- 'and `adapters` attributes, respectively. '
- 'The method will be gone in Zope 3.3.')
-
- def queryActiveComponent(self, name, default=None):
- return self.queryLocalService(name, default)
- queryActiveComponent = zope.deprecation.deprecated(
- queryActiveComponent,
- 'The site manager does not handle registrations directly anymore. '
- 'The utility and adapter registry are available via the `utilities` '
- 'and `adapters` attributes, respectively. '
- 'The method will be gone in Zope 3.3.')
-
- def getServiceDefinitions(self):
- gsm = zapi.getGlobalSiteManager()
- return gsm.getServiceDefinitions()
- getServiceDefinitions = zope.deprecation.deprecated(
- getServiceDefinitions,
- 'The concept of services has been removed. Use utilities instead. '
- 'The method will be gone in Zope 3.3.')
-
- def getService(self, name):
- return zapi.getUtility(IService, name, self)
- getService = zope.deprecation.deprecated(
- getService,
- 'The concept of services has been removed. Use utilities instead. '
- 'The method will be gone in Zope 3.3.')
-
- def queryLocalService(self, name, default=None):
- if name in _builtinServices:
- return self
- service = zapi.queryUtility(IService, name, self)
- if service is None:
- return default
- if zapi.getSiteManager(service) is not self:
- return default
- return service
- queryLocalService = zope.deprecation.deprecated(
- queryLocalService,
- 'The concept of services has been removed. Use utilities instead. '
- 'The method will be gone in Zope 3.3.')
-
- def getInterfaceFor(self, service_type):
- iface = [iface
- for name, iface in self.getServiceDefinitions()
- if name == service_type]
- return iface[0]
- getInterfaceFor = zope.deprecation.deprecated(
- getInterfaceFor,
- 'The concept of services has been removed. Use utilities instead. '
- 'The method will be gone in Zope 3.3.')
-
- def queryComponent(self, type=None, filter=None, all=0):
- # Ignore, hoping that noone uses this horrible method
- return []
- getInterfaceFor = zope.deprecation.deprecated(
- getInterfaceFor,
- 'This method was pretty useless even before services were gone! '
- 'The method will be gone in Zope 3.3.')
-
-_builtinServices = ('Utilities', 'Adapters')
-
-
-class BBBUtilityRegistration(object):
-
- def provided(self):
- if 'interface' in self.__dict__:
- return self.interface
- provided = property.Lazy(provided)
Modified: Zope3/branches/jim-adapter/src/zope/app/component/configure.zcml
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/configure.zcml 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/configure.zcml 2006-03-16 12:29:18 UTC (rev 66056)
@@ -46,31 +46,7 @@
trusted="true"
/>
- <subscriber
- for=".interfaces.registration.IComponentRegistration
- zope.app.container.interfaces.IObjectRemovedEvent"
- handler=".registration.ComponentRegistrationRemoveSubscriber"
- />
- <subscriber
- for=".interfaces.registration.IComponentRegistration
- zope.app.container.interfaces.IObjectAddedEvent"
- handler=".registration.ComponentRegistrationAddSubscriber"
- />
-
- <subscriber
- for=".interfaces.registration.IComponentRegistration
- .interfaces.registration.IRegistrationEvent"
- handler=".registration.componentRegistrationEventNotify"
- />
-
- <subscriber
- for=".interfaces.registration.IRegisterable
- zope.app.container.interfaces.IObjectMovedEvent"
- handler=".registration.RegisterableMoveSubscriber"
- />
-
-
<!-- Site and Site Manager Framework -->
<module module=".interfaces">
Modified: Zope3/branches/jim-adapter/src/zope/app/component/registration.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/registration.py 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/registration.py 2006-03-16 12:29:18 UTC (rev 66056)
@@ -15,257 +15,44 @@
$Id$
"""
-from persistent import Persistent
-import zope.event
-from zope.component import subscribers
+from zope.app.event import objectevent
from zope.interface import implements
-from zope.security.checker import InterfaceChecker, CheckerPublic
-from zope.security.proxy import Proxy, removeSecurityProxy
+import zope.app.component.interfaces.registration
+import zope.deferredimport
-from zope.app import zapi
-from zope.app.component.interfaces import registration as interfaces
-from zope.app.container.btree import BTreeContainer
-from zope.app.container.contained import Contained
-from zope.app.dependable.interfaces import IDependable, DependencyError
-from zope.app.event import objectevent
-from zope.app.location import inside
-from zope.app.traversing.interfaces import TraversalError
-from zope.app.i18n import ZopeMessageFactory as _
+zope.deferredimport.deprecatedFrom(
+ """The old registration APIs, are deprecated and will go away in Zope 3.5
-# BBB: First introduced in 3.1; should go away in 3.3
-import bbb
+ See the newer component-registration APIs in
+ zope.component.interfaces.IComponentRegistry.
+ """,
+ "zope.app.component.back35",
+ 'RegistrationStatusProperty',
+ 'SimpleRegistration',
+ 'ComponentRegistration',
+ 'Registered',
+ 'RegistrationManager',
+ 'RegisterableContainer',
+ 'RegistrationManagerNamespace',
+ )
-
class RegistrationEvent(objectevent.ObjectEvent):
"""An event that is created when a registration-related activity occurred.
"""
- implements(interfaces.IRegistrationEvent)
+ implements(zope.app.component.interfaces.registration.IRegistrationEvent)
class RegistrationActivatedEvent(RegistrationEvent):
"""An event that is created when a registration is activated."""
- implements(interfaces.IRegistrationActivatedEvent)
+ implements(
+ zope.app.component.interfaces.registration.IRegistrationActivatedEvent,
+ )
class RegistrationDeactivatedEvent(RegistrationEvent):
"""An event that is created when a registration is deactivated."""
- implements(interfaces.IRegistrationDeactivatedEvent)
+ implements(
+ zope.app.component.interfaces.registration.IRegistrationDeactivatedEvent,
+ )
-class RegistrationStatusProperty(object):
- """A descriptor used to implement `IRegistration`'s `status` property."""
- def __get__(self, inst, klass):
- registration = inst
- if registration is None:
- return self
- registry = registration.getRegistry()
- if registry and registry.registered(registration):
- return interfaces.ActiveStatus
-
- return interfaces.InactiveStatus
-
- def __set__(self, inst, value):
- registration = inst
- registry = registration.getRegistry()
- if registry is None:
- raise ValueError('No registry found.')
-
- if value == interfaces.ActiveStatus:
- if not registry.registered(registration):
- registry.register(registration)
- zope.event.notify(RegistrationActivatedEvent(registration))
-
- elif value == interfaces.InactiveStatus:
- if registry.registered(registration):
- registry.unregister(registration)
- zope.event.notify(RegistrationDeactivatedEvent(registration))
- else:
- raise ValueError(value)
-
-
-class SimpleRegistration(Persistent, Contained):
- """Registration objects that just contain registration data"""
- implements(interfaces.IRegistration,
- interfaces.IRegistrationManagerContained)
-
- # See interfaces.IRegistration
- status = RegistrationStatusProperty()
-
- def getRegistry(self):
- """See interfaces.IRegistration"""
- raise NotImplementedError(
- 'This method must be implemented by each specific regstration.')
-
-
-class ComponentRegistration(bbb.registration.BBBComponentRegistration,
- SimpleRegistration):
- """Component registration.
-
- Subclasses should define a getInterface() method returning the interface
- of the component.
- """
- implements(interfaces.IComponentRegistration)
-
- def __init__(self, component, permission=None):
- # BBB: Will go away in 3.3.
- super(ComponentRegistration, self).__init__(component, permission)
- # self.component = component
- if permission == 'zope.Public':
- permission = CheckerPublic
- self.permission = permission
-
- def _getComponent(self):
- if self.permission and self.interface:
- checker = InterfaceChecker(self.interface, self.permission)
- return Proxy(self._component, checker)
- return self._component
-
- def _setComponent(self, component):
- # We always want to set the plain component. Untrusted code will
- # get back a proxied component anyways.
- self._component = removeSecurityProxy(component)
-
- # See zope.app.component.interfaces.registration.IComponentRegistration
- component = property(_getComponent, _setComponent)
-
- # See zope.app.component.interfaces.registration.IComponentRegistration
- interface = None
-
-
-def SimpleRegistrationRemoveSubscriber(registration, event):
- """Receive notification of remove event."""
- sm = zapi.getSiteManager(registration)
- removed = event.object
- if (sm == removed) or inside(sm, removed):
- # we don't really care if the registration is active, since the site
- # is going away.
- return
-
- objectstatus = registration.status
-
- if objectstatus == interfaces.ActiveStatus:
- try:
- objectpath = zapi.getPath(registration)
- except: # TODO decide if this is really the best fall-back plan
- objectpath = str(registration)
- msg = _("Can't delete active registration (${path})",
- mapping={u'path': objectpath})
- raise DependencyError(msg)
-
-
-def ComponentRegistrationRemoveSubscriber(componentRegistration, event):
- """Receive notification of remove event."""
- component = componentRegistration.component
- try:
- dependents = IDependable(component)
- except TypeError:
- return
- objectpath = zapi.getPath(componentRegistration)
- dependents.removeDependent(objectpath)
-
-
-def ComponentRegistrationAddSubscriber(componentRegistration, event):
- """Receive notification of add event."""
- component = componentRegistration.component
- try:
- dependents = IDependable(component)
- except TypeError:
- return
- objectpath = zapi.getPath(componentRegistration)
- dependents.addDependent(objectpath)
-
-
-def componentRegistrationEventNotify(componentReg, event):
- """Subscriber to dispatch registration events for components."""
- adapters = subscribers((componentReg.component, event), None)
- for adapter in adapters:
- pass # getting them does the work
-
-
-def RegisterableMoveSubscriber(registerable, event):
- """A registerable cannot be moved as long as it has registrations in the
- registration manager."""
- if event.oldParent is not None and event.newParent is not None:
- if event.oldParent is not event.newParent:
- raise DependencyError(
- _("Can't move a registered component from its container."))
-
-
-class Registered(bbb.registration.BBBRegistered, object):
- """An adapter from IRegisterable to IRegistered.
-
- This class is the only place that knows how 'Registered'
- data is represented.
- """
- implements(interfaces.IRegistered)
- __used_for__ = interfaces.IRegisterable
-
- def __init__(self, registerable):
- self.registerable = registerable
-
- def registrations(self):
- rm = zapi.getParent(self.registerable).registrationManager
- return [reg for reg in rm.values()
- if (interfaces.IComponentRegistration.providedBy(reg) and
- reg.component is self.registerable)]
-
-
-class RegistrationManager(bbb.registration.BBBRegistrationManager,
- BTreeContainer):
- """Registration manager
-
- Manages registrations within a package.
- """
- implements(interfaces.IRegistrationManager)
-
- def addRegistration(self, reg):
- "See IWriteContainer"
- key = self._chooseName('', reg)
- self[key] = reg
- return key
-
- def _chooseName(self, name, reg):
- """Choose a name for the registration."""
- if not name:
- name = reg.__class__.__name__
-
- i = 1
- chosenName = name
- while chosenName in self:
- i += 1
- chosenName = name + str(i)
-
- return chosenName
-
-
-class RegisterableContainer(bbb.registration.BBBRegisterableContainer):
- """Mix-in to implement `IRegisterableContainer`"""
- implements(interfaces.IRegisterableContainer,
- interfaces.IRegisterableContainerContaining)
-
- def __init__(self):
- super(RegisterableContainer, self).__init__()
- self.__createRegistrationManager()
-
- def __createRegistrationManager(self):
- "Create a registration manager and store it as `registrationManager`"
- # See interfaces.IRegisterableContainer
- self.registrationManager = RegistrationManager()
- self.registrationManager.__parent__ = self
- self.registrationManager.__name__ = '++registrations++'
- zope.event.notify(
- objectevent.ObjectCreatedEvent(self.registrationManager))
-
-
-class RegistrationManagerNamespace(object):
- """Used to traverse to a Registration Manager from a
- Registerable Container."""
- __used_for__ = interfaces.IRegisterableContainer
-
- def __init__(self, ob, request=None):
- self.context = ob.registrationManager
-
- def traverse(self, name, ignore):
- if name == '':
- return self.context
- raise TraversalError(self.context, name)
Deleted: Zope3/branches/jim-adapter/src/zope/app/component/registration.txt
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/registration.txt 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/registration.txt 2006-03-16 12:29:18 UTC (rev 66056)
@@ -1,461 +0,0 @@
-==========================
-The Registration Framework
-==========================
-
-The registration framework's task is to manage registrations and ensure that
-the correct registrations are inserted into the correct registries. Each
-registration knows to which registry it belongs. If a registration is set
-active, then the registration is added to the regstry; when inactive, it is
-removed from the registry. Please see `statusproperty.txt` for a demonstration
-on how the setting of the registration's status affects the registry.
-
-The true power of the registration framework, however, comes from the ability
-to provide registrations for registerable components. In the context of Zope
-3's component architecture, registerable components are adapters and
-utilities. Since the registration framework can be used for any kind of
-component registration, I am going to refer to registerable components
-(including adapters and interface) as components.
-
-The first task is to create a simple component registry. It will implement all
-required `IRegistry` methods and a `getComponents()` method, which will return
-a list of all registered (active) components.
-
- >>> import zope.interface
- >>> from zope.app.component import interfaces
- >>> class ComponentRegistry(object):
- ... zope.interface.implements(interfaces.registration.IRegistry)
- ...
- ... def __init__(self):
- ... self._registrations = []
- ...
- ... def registrations(self):
- ... """See zope.component.interfaces.IRegistry"""
- ... return self._registrations
- ...
- ... def register(self, registration):
- ... """See interfaces.registration.IRegistry"""
- ... self._registrations.append(registration)
- ...
- ... def unregister(self, registration):
- ... """See interfaces.registration.IRegistry"""
- ... del self._registrations[self._registrations.index(registration)]
- ...
- ... def registered(self, registration):
- ... """See interfaces.registration.IRegistry"""
- ... return registration in self._registrations
- ...
- ... def getComponents(self):
- ... return [reg.component for reg in self.registrations()]
-
- >>> registry = ComponentRegistry()
-
-Effectively, a registry manages a set of active registrations. A simple
-UML diagram would be::
-
- ---------------------------
- --------------- * 1 | IRegistration |
- | IRegistry |-------| - - - - - - - - - - - - |
- --------------- | status = ActiveStatus |
- ---------------------------
-
-Next we need to create a registration object that can register components with
-our new registry. The framework already provides a base-class for
-component-based registrations, so that we only need to implement the
-`getRegistry()` method:
-
- >>> from zope.app.component.registration import ComponentRegistration
- >>> class Registration(ComponentRegistration):
- ...
- ... def getRegistry(self):
- ... global registry
- ... return registry
- ...
- ... def __repr__(self):
- ... return "<Registration for '%s'>" %self.component
-
-In the implementation above, all `Registration` instances are simply going to
-use the global `registry` object. Now that we have a registry and a suitable
-registration class, let's test what we have so far. To do that we have to
-create a component that we would like to register:
-
- >>> from zope.app.container.contained import Contained
- >>> class Component(Contained):
- ... zope.interface.implements(interfaces.registration.IRegisterable)
- ... def __init__(self, title=u''):
- ... self.title = title
- ... def __repr__(self):
- ... return "<Component: '%s'>" %self.title
-
-Note that `Contained` is used as a base class, since `IRegisterable` requires
-it to be. We will later see why this is the case.
-
-Before we are registering any component, the registry is empty:
-
- >>> registry.getComponents()
- []
-
-Now we create a component and a registration:
-
- >>> foo = Component('Foo')
- >>> regFoo = Registration(foo)
- >>> regFoo.component
- <Component: 'Foo'>
- >>> regFoo.status
- u'Inactive'
-
-Finally, we activate the registration:
-
-
- >>> regFoo.status = interfaces.registration.ActiveStatus
- >>> regFoo.status
- u'Active'
- >>> registry.getComponents()
- [<Component: 'Foo'>]
-
-Of course, we can add a second registered component:
-
- >>> bar = Component('Bar')
- >>> regBar = Registration(bar)
- >>> regBar.component
- <Component: 'Bar'>
- >>> regBar.status
- u'Inactive'
- >>> regBar.status = interfaces.registration.ActiveStatus
- >>> regBar.status
- u'Active'
- >>> registry.getComponents()
- [<Component: 'Foo'>, <Component: 'Bar'>]
-
-Of course, when deactivating a registration, it will be gone from the registry
-as well:
-
- >>> regFoo.status = interfaces.registration.InactiveStatus
- >>> regFoo.status
- u'Inactive'
- >>> registry.getComponents()
- [<Component: 'Bar'>]
-
-This is everything that there is about registrations and their interaction
-with a registry. However, the point of registrations and registerable
-components is that they should be persistent (otherwise we could use
-ZCML). Thus we need a way of managing local components and their
-registrations.
-
-
-Management of Local Components and Registrations
-------------------------------------------------
-
-The starting point here is the `IRegisterableContainer`, which can contain
-`IRegiserable` and other `IRegisterableContainer` components.
-
- >>> from zope.app.container.btree import BTreeContainer
- >>> from zope.app.component.registration import RegisterableContainer
-
- >>> class RegisterableManager(RegisterableContainer, BTreeContainer):
- ... pass
- >>> registerables = RegisterableManager()
-
-The `RegisterableContainer` class is merely a mixin and leaves it up to the
-developer to implement the `IContainer` interface. In our case, we simply used
-the default btree container implementation to provide the container
-interface. However, the `RegisterableContainer` class does implement the
-`IRegisterableContainer` interface, which means it ensures the existance of
-the `registrationManager` attribute, which always contains an
-`IRegistrationManager` instance:
-
- >>> registerables.registrationManager is not None
- True
- >>> interfaces.registration.IRegistrationManager.providedBy(
- ... registerables.registrationManager)
- True
-
-The registration manager is a simple container that can only contain
-components providing `IRegistration` and implements a method called
-`addRegistration(registration)` that lets you add a registration to the
-manager without specifying a name. The name will be automatically chosen for
-you and is returned. So let's add our two existing components and their
-registrations:
-
- >>> regManager = registerables.registrationManager
-
- >>> registerables['foo'] = foo
- >>> regManager.addRegistration(regFoo)
- 'Registration'
-
- >>> registerables['bar'] = bar
- >>> regManager.addRegistration(regBar)
- 'Registration2'
-
- >>> items = list(registerables.items())
- >>> items.sort()
- >>> items
- [(u'bar', <Component: 'Bar'>), (u'foo', <Component: 'Foo'>)]
- >>> regs = list(regManager.items())
- >>> regs.sort()
- >>> regs #doctest: +NORMALIZE_WHITESPACE
- [(u'Registration', <Registration for '<Component: 'Foo'>'>),
- (u'Registration2', <Registration for '<Component: 'Bar'>'>)]
-
-Of course, adding a registration to the registration manager does not mean the
-registration is added to the registry, since it still may not be active:
-
- >>> registry.getComponents()
- [<Component: 'Bar'>]
-
-Also, there are no restrictions on how many registrations you can create for a
-single component. For example, we can register the `foo` one more time:
-
- >>> regFoo2 = Registration(foo)
- >>> regManager.addRegistration(regFoo2)
- 'Registration3'
- >>> regs = list(regManager.items())
- >>> regs.sort()
- >>> regs #doctest: +NORMALIZE_WHITESPACE
- [(u'Registration', <Registration for '<Component: 'Foo'>'>),
- (u'Registration2', <Registration for '<Component: 'Bar'>'>),
- (u'Registration3', <Registration for '<Component: 'Foo'>'>)]
-
-This also means that our registry can provide a component multiple times:
-
- >>> regFoo.status = interfaces.registration.ActiveStatus
- >>> regFoo2.status = interfaces.registration.ActiveStatus
- >>> registry.getComponents()
- [<Component: 'Bar'>, <Component: 'Foo'>, <Component: 'Foo'>]
-
-Here is a UML diagram of the registerable container and registration manager
-and their relationships to the other registration-related components we
-discussed.
-
-::
-
- ----------------------------
- | IRegisterableContainer |
- | - - - - - - - - - - - - -|
- | 1 | 1 --------------------------
- | registrationManager ----+------| IRegistrationManager |
- | | --------------------------
- ---------------------------+ | *
- | * | * | 1 |
- | | | | 1
- | 1 +----+ -------------------
- ------------------- | IRegistration |
- | IRegisterable | -------------------
- ------------------- | *
- |
- --------------- 1 |
- | IRegistry |------+ if status == Active
- ---------------
-
-
-The ++registrations++ traversal namespace
------------------------------------------
-
-To make the registration manager easier accessible via a traversal path, a
-special traversal namespace has been implemented. But first we have to
-register the traversal namespace:
-
- >>> from zope.app.traversing.interfaces import ITraversable
- >>> from zope.app.component.registration import RegistrationManagerNamespace
- >>> from zope.app.testing import ztapi
- >>> ztapi.provideAdapter(
- ... interfaces.registration.IRegisterableContainer,
- ... ITraversable,
- ... RegistrationManagerNamespace,
- ... 'registrations')
-
-Now we can use the namespace during traversal:
-
- >>> from zope.app.traversing.api import traverse
- >>> traverse(registerables, '++registrations++') is regManager
- True
-
-
-The Component Registration
---------------------------
-
-Until now we have only discussed the most primitive usage of the
-`ComponentRegistration`. Usually, a registry is not just interested in a
-component, but a set of methods which are specified by a particular
-interface. Thus the component registration supports the `interface`
-attribute. By default it is `None`:
-
- >>> regFoo.interface is None
- True
-
-We can now write another `IComponentRegistration` implementation that knows
-about the interface; in fact, it will pick the most specific one of the
-component:
-
- >>> from zope.interface import providedBy
- >>> class SomethingRegistration(Registration):
- ...
- ... def interface(self):
- ... return list(providedBy(self._component))[0]
- ... interface = property(interface)
-
-Next we create an interface and its implementation:
-
- >>> class ISomething(zope.interface.Interface):
- ... pass
-
- >>> class Something(Component):
- ... zope.interface.implements(ISomething)
-
-Creating a "something registration", we can see that the interface attribute
-is now available:
-
- >>> something = Something('Something')
- >>> reg = SomethingRegistration(something)
- >>> reg.interface
- <InterfaceClass __builtin__.ISomething>
-
-But hold on, we are not done yet! The component registration also supports a
-`permission` attribute. When set and an interface is available, the component
-will always be proxied using an interface checker for the specified
-permission. By default the permission is `None`:
-
- >>> reg.permission is None
- True
-
-Now we set a permission for the registration and the component should be
-proxies when returned:
-
- >>> from zope.security.checker import CheckerPublic
- >>> reg.permission = CheckerPublic
- >>> reg.component is something
- False
- >>> type(reg.component)
- <type 'zope.security._proxy._Proxy'>
-
-You can also, specify a permission in the constructor:
-
- >>> regNone = SomethingRegistration(None, 'zope.Public')
- >>> regNone.permission is CheckerPublic
- True
-
-If the interface is not available, the permission is ignored and the bare
-component is returned:
-
- >>> regSomething2 = Registration(something, 'zope.Public')
- >>> regSomething2.permission is CheckerPublic
- True
- >>> regSomething2.component is something
- True
-
-
-The `Registered` Adapter
-------------------------
-
-Registerable components are able to get a list of all their
-registrations. However, the adapter only works for components and
-registrations that are stored in the registerable container and registration
-manager, respectively.
-
- >>> from zope.app.component.registration import Registered
- >>> registered = Registered(foo)
- >>> registered.registrations() #doctest: +NORMALIZE_WHITESPACE
- [<Registration for '<Component: 'Foo'>'>,
- <Registration for '<Component: 'Foo'>'>]
-
-If the registerable component is not stored in a registrable container, a
-type error is raised, since no parent can be found:
-
- >>> registered = Registered(something)
- >>> registered.registrations() #doctest: +NORMALIZE_WHITESPACE
- Traceback (most recent call last):
- ...
- TypeError: ('Not enough context information to get parent',
- <Component: 'Something'>)
-
-
-Registrations and Dependencies
-------------------------------
-
-Registerable objects and registrations have a very close dependence. For
-example, it makes no sense to delete a registerable component and leave its
-registrations around. Instead, registrations always are required to be removed
-before the component. Thus, it is also not allowed to simply copy a
-registerable component to another registerable container:
-
- >>> orig = RegisterableManager()
- >>> new = RegisterableManager()
- >>> comp = Component('comp')
-
- >>> from zope.app.container.contained import ObjectMovedEvent
- >>> event = ObjectMovedEvent(comp, orig, 'comp', new, 'comp')
-
- >>> from zope.app.component.registration import RegisterableMoveSubscriber
- >>> RegisterableMoveSubscriber(comp, event)
- Traceback (most recent call last):
- ...
- DependencyError: Can't move a registered component from its container.
-
-Hoever, renaming the component is no problem:
-
- >>> event = ObjectMovedEvent(comp, orig, 'comp', orig, 'comp-new')
- >>> RegisterableMoveSubscriber(comp, event)
-
-Whenever a registration is created it is added as a dependence to the
-registerable component, which is removed once the registration is removed. Two
-subscribers handle the management of the dependemcies.
-
-Since the default `IDependable` adapter uses annotations to store the
-dependents, our component has to provide `IAttrbuteAnnotatable`:
-
- >>> from zope.app.annotation.interfaces import IAttributeAnnotatable
- >>> from zope.interface import directlyProvides
- >>> directlyProvides(comp, IAttributeAnnotatable)
-
-Make sure that we do not initially have any dependencies:
-
- >>> from zope.app.dependable.interfaces import IDependable
- >>> dependents = IDependable(comp)
- >>> dependents.getPaths()
- ()
-
-Since the path of the registration is used to store the dependency, we need to
-make sure that we have a containment root; so make the registration itself the
-root:
-
- >>> reg = Registration(comp)
- >>> from zope.app.traversing.interfaces import IContainmentRoot
- >>> directlyProvides(reg, IContainmentRoot)
-
-The component registration add subscriber adds a dependent.
-
- >>> from zope.app.container.contained import ObjectAddedEvent
- >>> from zope.app.component.registration import RegistrationManager
- >>> event = ObjectAddedEvent(reg, RegistrationManager(), 'reg1')
-
- >>> from zope.app.component.registration import \
- ... ComponentRegistrationAddSubscriber
- >>> ComponentRegistrationAddSubscriber(reg, event)
-
- >>> dependents = IDependable(comp)
- >>> dependents.getPaths()
- (u'/',)
-
-We simply got a slash here, since the registration is a root object. Now we
-remove the dependency again by calling the component registration remove
-subscriber:
-
- >>> from zope.app.container.contained import ObjectRemovedEvent
- >>> event = ObjectRemovedEvent(reg, RegistrationManager(), 'reg1')
-
- >>> from zope.app.component.registration import \
- ... ComponentRegistrationRemoveSubscriber
- >>> ComponentRegistrationRemoveSubscriber(reg, event)
-
- >>> dependents = IDependable(comp)
- >>> dependents.getPaths()
- ()
-
-Note that not all components of a registration must be adaptable to
-`IDependable`. This might be the case for components that are
-autogenerated. If this is the case, the subscribers should simply ignore those
-components:
-
- >>> reg.component = object()
- >>> ComponentRegistrationAddSubscriber(reg, event)
- >>> ComponentRegistrationRemoveSubscriber(reg, event)
-
\ No newline at end of file
Modified: Zope3/branches/jim-adapter/src/zope/app/component/site.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/site.py 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/site.py 2006-03-16 12:29:18 UTC (rev 66056)
@@ -65,9 +65,6 @@
# from zope.app.module import resolve
##############################################################################
-# Goes away in 3.3.
-import bbb.site
-
class SiteManagementFolder(registration.RegisterableContainer,
BTreeContainer):
zope.interface.implements(interfaces.ISiteManagementFolder)
@@ -83,7 +80,7 @@
return SiteManagementFolder()
-class SiteManagerContainer(bbb.site.BBBSiteManagerContainer, Contained):
+class SiteManagerContainer(Contained):
"""Implement access to the site manager (++etc++site).
This is a mix-in that implements the IPossibleSite
@@ -91,8 +88,7 @@
"""
zope.interface.implements(interfaces.IPossibleSite)
- # BBB: Deactive in 3.3 again. Now provided by BBBSiteManagerContainer
- #_sm = None
+ _sm = None
def getSiteManager(self):
if self._sm is not None:
@@ -180,7 +176,6 @@
class LocalSiteManager(BTreeContainer,
- bbb.site.BBBSiteManager,
zope.component.registry.Components):
"""Local Site Manager implementation"""
zope.interface.implements(
@@ -306,8 +301,7 @@
return zapi.getSiteManager(self)
-class UtilityRegistration(bbb.site.BBBUtilityRegistration,
- registration.ComponentRegistration):
+class UtilityRegistration(registration.ComponentRegistration):
"""Utility component registration for persistent components
This registration configures persistent components in packages to
Deleted: Zope3/branches/jim-adapter/src/zope/app/component/statusproperty.txt
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/statusproperty.txt 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/statusproperty.txt 2006-03-16 12:29:18 UTC (rev 66056)
@@ -1,124 +0,0 @@
-============================
-Registration Status Property
-============================
-
-The registratio status property is a descriptor used to implement the
-`IRegistration`' interface's `status` property.
-
-The property accepts two possible values: `ActiveStatus` and
-`InactiveStatus`. When the registration is active, then the registration is
-also activated in the registry.
-
- >>> from zope.app.component.interfaces.registration import ActiveStatus
- >>> from zope.app.component.interfaces.registration import InactiveStatus
-
-When setting the `status` property to `ActiveStatus`, then the registration
-should be added to the nearest matching registry. Here, the registration's
-`getRegistry()` method is used to determine the registry. On the same token,
-if the value is set to `InactiveStatus` the registration should be removed
-from the registry.
-
-To demonstrate this functionality, we first have to create a stub registry
-
- >>> class Registry(object):
- ... registrations = []
- ... def register(self, registration):
- ... self.registrations.append(registration)
- ...
- ... def unregister(self, registration):
- ... del self.registrations[self.registrations.index(registration)]
- ...
- ... def registered(self, registration):
- ... return registration in self.registrations
-
- >>> registry = Registry()
-
-and a simple registration object
-
- >>> from zope.app.component.registration import RegistrationStatusProperty
- >>> class Registration(object):
- ... status = RegistrationStatusProperty()
- ...
- ... def __init__(self, registry):
- ... self.registry = registry
- ...
- ... def getRegistry(self):
- ... return self.registry
-
-Note that here only the `getRegistry()` is part of the registration API.
-
-Now that we have a registry and a registration class, let's create a
-registration:
-
- >>> reg = Registration(registry)
-
-At the beginning the registration is inactive:
-
- >>> reg.status
- u'Inactive'
- >>> reg.status is InactiveStatus
- True
- >>> reg in registry.registrations
- False
-
-Once we activate the registration, it appears in the registry:
-
- >>> reg.status = ActiveStatus
- >>> reg.status
- u'Active'
- >>> reg.status is ActiveStatus
- True
- >>> reg in registry.registrations
- True
-
-Now, once we deactivate the registration, it is not available in the registry
-anymore:
-
- >>> reg.status = InactiveStatus
- >>> reg.status
- u'Inactive'
- >>> reg.status is InactiveStatus
- True
- >>> reg in registry.registrations
- False
-
-
-Registration Events
--------------------
-
-When a registration is activated or deactivated, an
-`RegistrationActivatedEvent` or `RegistrationDeactivatedEvent` is created,
-respectively. Listening to these events can be useful for cases where you want
-to change the component based on registration status.
-
-To catch the events, we have to register a subscriber with the event
-framework:
-
- >>> events = []
- >>> def subscriber(event):
- ... global events
- ... events.append(event)
-
- >>> import zope.event
- >>> zope.event.subscribers.append(subscriber)
-
-Now we switch our registration to active:
-
- >>> reg.status = ActiveStatus
- >>> event = events.pop()
- >>> event.__class__
- <class 'zope.app.component.registration.RegistrationActivatedEvent'>
- >>> event.object is reg
- True
-
-and deactivate it again:
-
- >>> reg.status = InactiveStatus
- >>> events.pop().__class__
- <class 'zope.app.component.registration.RegistrationDeactivatedEvent'>
- >>> event.object is reg
- True
-
-Now make sure that we remove the subscriber again:
-
- >>> del zope.event.subscribers[zope.event.subscribers.index(subscriber)]
Copied: Zope3/branches/jim-adapter/src/zope/app/component/tests/deprecated35_registration.txt (from rev 66026, Zope3/branches/jim-adapter/src/zope/app/component/registration.txt)
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/registration.txt 2006-03-15 12:19:19 UTC (rev 66026)
+++ Zope3/branches/jim-adapter/src/zope/app/component/tests/deprecated35_registration.txt 2006-03-16 12:29:18 UTC (rev 66056)
@@ -0,0 +1,370 @@
+==========================
+The Registration Framework
+==========================
+
+The registration framework's task is to manage registrations and ensure that
+the correct registrations are inserted into the correct registries. Each
+registration knows to which registry it belongs. If a registration is set
+active, then the registration is added to the regstry; when inactive, it is
+removed from the registry. Please see `statusproperty.txt` for a demonstration
+on how the setting of the registration's status affects the registry.
+
+The true power of the registration framework, however, comes from the ability
+to provide registrations for registerable components. In the context of Zope
+3's component architecture, registerable components are adapters and
+utilities. Since the registration framework can be used for any kind of
+component registration, I am going to refer to registerable components
+(including adapters and interface) as components.
+
+The first task is to create a simple component registry. It will implement all
+required `IRegistry` methods and a `getComponents()` method, which will return
+a list of all registered (active) components.
+
+ >>> import zope.interface
+ >>> from zope.app.component import interfaces
+ >>> class ComponentRegistry(object):
+ ... zope.interface.implements(interfaces.registration.IRegistry)
+ ...
+ ... def __init__(self):
+ ... self._registrations = []
+ ...
+ ... def registrations(self):
+ ... """See zope.component.interfaces.IRegistry"""
+ ... return self._registrations
+ ...
+ ... def register(self, registration):
+ ... """See interfaces.registration.IRegistry"""
+ ... self._registrations.append(registration)
+ ...
+ ... def unregister(self, registration):
+ ... """See interfaces.registration.IRegistry"""
+ ... del self._registrations[self._registrations.index(registration)]
+ ...
+ ... def registered(self, registration):
+ ... """See interfaces.registration.IRegistry"""
+ ... return registration in self._registrations
+ ...
+ ... def getComponents(self):
+ ... return [reg.component for reg in self.registrations()]
+
+ >>> registry = ComponentRegistry()
+
+Effectively, a registry manages a set of active registrations. A simple
+UML diagram would be::
+
+ ---------------------------
+ --------------- * 1 | IRegistration |
+ | IRegistry |-------| - - - - - - - - - - - - |
+ --------------- | status = ActiveStatus |
+ ---------------------------
+
+Next we need to create a registration object that can register components with
+our new registry. The framework already provides a base-class for
+component-based registrations, so that we only need to implement the
+`getRegistry()` method:
+
+ >>> from zope.app.component.registration import ComponentRegistration
+ >>> class Registration(ComponentRegistration):
+ ...
+ ... def getRegistry(self):
+ ... global registry
+ ... return registry
+ ...
+ ... def __repr__(self):
+ ... return "<Registration for '%s'>" %self.component
+
+In the implementation above, all `Registration` instances are simply going to
+use the global `registry` object. Now that we have a registry and a suitable
+registration class, let's test what we have so far. To do that we have to
+create a component that we would like to register:
+
+ >>> from zope.app.container.contained import Contained
+ >>> class Component(Contained):
+ ... zope.interface.implements(interfaces.registration.IRegisterable)
+ ... def __init__(self, title=u''):
+ ... self.title = title
+ ... def __repr__(self):
+ ... return "<Component: '%s'>" %self.title
+
+Note that `Contained` is used as a base class, since `IRegisterable` requires
+it to be. We will later see why this is the case.
+
+Before we are registering any component, the registry is empty:
+
+ >>> registry.getComponents()
+ []
+
+Now we create a component and a registration:
+
+ >>> foo = Component('Foo')
+ >>> regFoo = Registration(foo)
+ >>> regFoo.component
+ <Component: 'Foo'>
+ >>> regFoo.status
+ u'Inactive'
+
+Finally, we activate the registration:
+
+
+ >>> regFoo.status = interfaces.registration.ActiveStatus
+ >>> regFoo.status
+ u'Active'
+ >>> registry.getComponents()
+ [<Component: 'Foo'>]
+
+Of course, we can add a second registered component:
+
+ >>> bar = Component('Bar')
+ >>> regBar = Registration(bar)
+ >>> regBar.component
+ <Component: 'Bar'>
+ >>> regBar.status
+ u'Inactive'
+ >>> regBar.status = interfaces.registration.ActiveStatus
+ >>> regBar.status
+ u'Active'
+ >>> registry.getComponents()
+ [<Component: 'Foo'>, <Component: 'Bar'>]
+
+Of course, when deactivating a registration, it will be gone from the registry
+as well:
+
+ >>> regFoo.status = interfaces.registration.InactiveStatus
+ >>> regFoo.status
+ u'Inactive'
+ >>> registry.getComponents()
+ [<Component: 'Bar'>]
+
+This is everything that there is about registrations and their interaction
+with a registry. However, the point of registrations and registerable
+components is that they should be persistent (otherwise we could use
+ZCML). Thus we need a way of managing local components and their
+registrations.
+
+
+Management of Local Components and Registrations
+------------------------------------------------
+
+The starting point here is the `IRegisterableContainer`, which can contain
+`IRegiserable` and other `IRegisterableContainer` components.
+
+ >>> from zope.app.container.btree import BTreeContainer
+ >>> from zope.app.component.registration import RegisterableContainer
+
+ >>> class RegisterableManager(RegisterableContainer, BTreeContainer):
+ ... pass
+ >>> registerables = RegisterableManager()
+
+The `RegisterableContainer` class is merely a mixin and leaves it up to the
+developer to implement the `IContainer` interface. In our case, we simply used
+the default btree container implementation to provide the container
+interface. However, the `RegisterableContainer` class does implement the
+`IRegisterableContainer` interface, which means it ensures the existance of
+the `registrationManager` attribute, which always contains an
+`IRegistrationManager` instance:
+
+ >>> registerables.registrationManager is not None
+ True
+ >>> interfaces.registration.IRegistrationManager.providedBy(
+ ... registerables.registrationManager)
+ True
+
+The registration manager is a simple container that can only contain
+components providing `IRegistration` and implements a method called
+`addRegistration(registration)` that lets you add a registration to the
+manager without specifying a name. The name will be automatically chosen for
+you and is returned. So let's add our two existing components and their
+registrations:
+
+ >>> regManager = registerables.registrationManager
+
+ >>> registerables['foo'] = foo
+ >>> regManager.addRegistration(regFoo)
+ 'Registration'
+
+ >>> registerables['bar'] = bar
+ >>> regManager.addRegistration(regBar)
+ 'Registration2'
+
+ >>> items = list(registerables.items())
+ >>> items.sort()
+ >>> items
+ [(u'bar', <Component: 'Bar'>), (u'foo', <Component: 'Foo'>)]
+ >>> regs = list(regManager.items())
+ >>> regs.sort()
+ >>> regs #doctest: +NORMALIZE_WHITESPACE
+ [(u'Registration', <Registration for '<Component: 'Foo'>'>),
+ (u'Registration2', <Registration for '<Component: 'Bar'>'>)]
+
+Of course, adding a registration to the registration manager does not mean the
+registration is added to the registry, since it still may not be active:
+
+ >>> registry.getComponents()
+ [<Component: 'Bar'>]
+
+Also, there are no restrictions on how many registrations you can create for a
+single component. For example, we can register the `foo` one more time:
+
+ >>> regFoo2 = Registration(foo)
+ >>> regManager.addRegistration(regFoo2)
+ 'Registration3'
+ >>> regs = list(regManager.items())
+ >>> regs.sort()
+ >>> regs #doctest: +NORMALIZE_WHITESPACE
+ [(u'Registration', <Registration for '<Component: 'Foo'>'>),
+ (u'Registration2', <Registration for '<Component: 'Bar'>'>),
+ (u'Registration3', <Registration for '<Component: 'Foo'>'>)]
+
+This also means that our registry can provide a component multiple times:
+
+ >>> regFoo.status = interfaces.registration.ActiveStatus
+ >>> regFoo2.status = interfaces.registration.ActiveStatus
+ >>> registry.getComponents()
+ [<Component: 'Bar'>, <Component: 'Foo'>, <Component: 'Foo'>]
+
+Here is a UML diagram of the registerable container and registration manager
+and their relationships to the other registration-related components we
+discussed.
+
+::
+
+ ----------------------------
+ | IRegisterableContainer |
+ | - - - - - - - - - - - - -|
+ | 1 | 1 --------------------------
+ | registrationManager ----+------| IRegistrationManager |
+ | | --------------------------
+ ---------------------------+ | *
+ | * | * | 1 |
+ | | | | 1
+ | 1 +----+ -------------------
+ ------------------- | IRegistration |
+ | IRegisterable | -------------------
+ ------------------- | *
+ |
+ --------------- 1 |
+ | IRegistry |------+ if status == Active
+ ---------------
+
+
+The ++registrations++ traversal namespace
+-----------------------------------------
+
+To make the registration manager easier accessible via a traversal path, a
+special traversal namespace has been implemented. But first we have to
+register the traversal namespace:
+
+ >>> from zope.app.traversing.interfaces import ITraversable
+ >>> from zope.app.component.registration import RegistrationManagerNamespace
+ >>> from zope.app.testing import ztapi
+ >>> ztapi.provideAdapter(
+ ... interfaces.registration.IRegisterableContainer,
+ ... ITraversable,
+ ... RegistrationManagerNamespace,
+ ... 'registrations')
+
+Now we can use the namespace during traversal:
+
+ >>> from zope.app.traversing.api import traverse
+ >>> traverse(registerables, '++registrations++') is regManager
+ True
+
+
+The Component Registration
+--------------------------
+
+Until now we have only discussed the most primitive usage of the
+`ComponentRegistration`. Usually, a registry is not just interested in a
+component, but a set of methods which are specified by a particular
+interface. Thus the component registration supports the `interface`
+attribute. By default it is `None`:
+
+ >>> regFoo.interface is None
+ True
+
+We can now write another `IComponentRegistration` implementation that knows
+about the interface; in fact, it will pick the most specific one of the
+component:
+
+ >>> from zope.interface import providedBy
+ >>> class SomethingRegistration(Registration):
+ ...
+ ... def interface(self):
+ ... return list(providedBy(self._component))[0]
+ ... interface = property(interface)
+
+Next we create an interface and its implementation:
+
+ >>> class ISomething(zope.interface.Interface):
+ ... pass
+
+ >>> class Something(Component):
+ ... zope.interface.implements(ISomething)
+
+Creating a "something registration", we can see that the interface attribute
+is now available:
+
+ >>> something = Something('Something')
+ >>> reg = SomethingRegistration(something)
+ >>> reg.interface
+ <InterfaceClass __builtin__.ISomething>
+
+But hold on, we are not done yet! The component registration also supports a
+`permission` attribute. When set and an interface is available, the component
+will always be proxied using an interface checker for the specified
+permission. By default the permission is `None`:
+
+ >>> reg.permission is None
+ True
+
+Now we set a permission for the registration and the component should be
+proxies when returned:
+
+ >>> from zope.security.checker import CheckerPublic
+ >>> reg.permission = CheckerPublic
+ >>> reg.component is something
+ False
+ >>> type(reg.component)
+ <type 'zope.security._proxy._Proxy'>
+
+You can also, specify a permission in the constructor:
+
+ >>> regNone = SomethingRegistration(None, 'zope.Public')
+ >>> regNone.permission is CheckerPublic
+ True
+
+If the interface is not available, the permission is ignored and the bare
+component is returned:
+
+ >>> regSomething2 = Registration(something, 'zope.Public')
+ >>> regSomething2.permission is CheckerPublic
+ True
+ >>> regSomething2.component is something
+ True
+
+
+The `Registered` Adapter
+------------------------
+
+Registerable components are able to get a list of all their
+registrations. However, the adapter only works for components and
+registrations that are stored in the registerable container and registration
+manager, respectively.
+
+ >>> from zope.app.component.registration import Registered
+ >>> registered = Registered(foo)
+ >>> registered.registrations() #doctest: +NORMALIZE_WHITESPACE
+ [<Registration for '<Component: 'Foo'>'>,
+ <Registration for '<Component: 'Foo'>'>]
+
+If the registerable component is not stored in a registrable container, a
+type error is raised, since no parent can be found:
+
+ >>> registered = Registered(something)
+ >>> registered.registrations() #doctest: +NORMALIZE_WHITESPACE
+ Traceback (most recent call last):
+ ...
+ TypeError: ('Not enough context information to get parent',
+ <Component: 'Something'>)
+
+
Copied: Zope3/branches/jim-adapter/src/zope/app/component/tests/deprecated35_statusproperty.txt (from rev 66026, Zope3/branches/jim-adapter/src/zope/app/component/statusproperty.txt)
Deleted: Zope3/branches/jim-adapter/src/zope/app/component/tests/test_adapter.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/tests/test_adapter.py 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/tests/test_adapter.py 2006-03-16 12:29:18 UTC (rev 66056)
@@ -1,691 +0,0 @@
-##############################################################################
-#
-# 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.
-#
-##############################################################################
-"""Registration Tests
-
-$Id$
-"""
-__docformat__ = "reStructuredText"
-import unittest
-import transaction
-from ZODB.tests.util import DB
-
-import zope.component.testing as placelesssetup
-import zope.interface
-from zope.interface.adapter import AdapterRegistry
-from zope.testing import doctest
-
-from zope.app.component import interfaces
-from zope.app.component.adapter import LocalAdapterRegistry, AdapterRegistration
-from zope.app.testing import setup
-
-class IF0(zope.interface.Interface):
- pass
-
-class IF1(IF0):
- pass
-
-class IF2(IF1):
- pass
-
-class IB0(zope.interface.Interface):
- pass
-
-class IB1(IB0):
- pass
-
-class IR0(zope.interface.Interface):
- pass
-
-class IR1(IR0):
- pass
-
-class R1(object):
- zope.interface.implements(IR1)
-
-class F0(object):
- zope.interface.implements(IF0)
-
-class F2(object):
- zope.interface.implements(IF2)
-
-# Create a picklable global registry. The pickleability of other
-# global adapter registries is beyond the scope of these tests:
-class GlobalAdapterRegistry(AdapterRegistry):
- def __reduce__(self):
- return 'globalAdapterRegistry'
-
-globalAdapterRegistry = GlobalAdapterRegistry()
-
-def test_local_adapter():
- """Local Adapter Tests
-
- Local surrogates and adapter registries share declarations with
- those "above" them.
-
- Suppose we have a global AdapterRegistry:
-
- >>> G = AdapterRegistry()
-
- we also have a local adapter registry, with G as it's base:
-
- >>> L1 = LocalAdapterRegistry(G)
-
- and so on:
-
- >>> L2 = LocalAdapterRegistry(G, L1)
-
- Now, if we declare an adapter globally:
-
- >>> G.register([IF1], IB1, '', 'A11G')
-
- we can query it locally:
-
- >>> L1.lookup([IF2], IB1)
- 'A11G'
-
- >>> L2.lookup([IF2], IB1)
- 'A11G'
-
- We can add local definitions:
-
- >>> ra011 = AdapterRegistration(required=IF0, provided=IB1, factory='A011',
- ... registry=L1)
- >>> ra011.status = interfaces.registration.ActiveStatus
-
- and use it:
-
- >>> L1.lookup([IF0], IB1)
- 'A011'
-
- >>> L2.lookup([IF0], IB1)
- 'A011'
-
- but not outside L1:
-
- >>> G.lookup([IF0], IB1)
-
- Note that it overrides the non-local adapter:
-
- >>> L1.lookup([IF2], IB1)
- 'A011'
-
- >>> L2.lookup([IF2], IB1)
- 'A011'
-
- because it was more specific.
-
- Let's override the adapter in L2:
-
- >>> ra112 = AdapterRegistration(required=IF1, provided=IB1, factory='A112',
- ... registry=L2)
- >>> ra112.status = interfaces.registration.ActiveStatus
-
- Now, in L2, we get the new adapter, because it's as specific and more
- local than the one from G:
-
- >>> L2.lookup([IF2], IB1)
- 'A112'
-
- Note that we can ask for less specific interfaces and still get the adapter:
-
- >>> L2.lookup([IF2], IB0)
- 'A112'
-
- >>> L1.lookup([IF2], IB0)
- 'A011'
-
- We get the more specific adapter even if there is a less-specific
- adapter to B0:
-
- >>> G.register([IF1], IB1, '', 'A10G')
-
- >>> L2.lookup([IF2], IB0)
- 'A112'
-
- But if we have an equally specific and equally local adapter to B0, it
- will win:
-
- >>> ra102 = AdapterRegistration(required=IF1, provided=IB0, factory='A102',
- ... registry=L2)
- >>> ra102.status = interfaces.registration.ActiveStatus
-
- >>> L2.lookup([IF2], IB0)
- 'A102'
-
- We can deactivate registrations, which has the effect of deleting adapters:
-
-
- >>> ra112.status = interfaces.registration.InactiveStatus
-
- >>> L2.lookup([IF2], IB0)
- 'A102'
-
- >>> L2.lookup([IF2], IB1)
- 'A011'
-
- >>> ra102.status = interfaces.registration.InactiveStatus
-
- >>> L2.lookup([IF2], IB0)
- 'A011'
-
- We can ask for all of the registrations :
-
- >>> L1.registrations() #doctest: +NORMALIZE_WHITESPACE
- (<AdapterRegistration:
- required=<InterfaceClass zope.app.component.tests.test_adapter.IF0>,
- with=(),
- provided=<InterfaceClass zope.app.component.tests.test_adapter.IB1>,
- name='',
- component='A011',
- permission=None>,)
-
- This shows only the local registrations in L1.
- """
-
-def test_named_adapters():
- """
- Suppose we have a global AdapterRegistry:
-
- >>> G = AdapterRegistry()
-
- we also have a local adapter registry, with G as it's base:
-
- >>> L1 = LocalAdapterRegistry(G)
-
- and so on:
-
- >>> L2 = LocalAdapterRegistry(G, L1)
-
- Now, if we declare an adapter globally:
-
- >>> G.register([IF1], IB1, 'bob', 'A11G')
-
- we can query it locally:
-
- >>> L1.lookup([IF2], IB1)
- >>> L1.lookup([IF2], IB1, 'bob')
- 'A11G'
-
- >>> L2.lookup([IF2], IB1)
- >>> L2.lookup([IF2], IB1, 'bob')
- 'A11G'
-
- We can add local definitions:
-
- >>> ra011 = AdapterRegistration(required = IF0, provided=IB1,
- ... factory='A011', name='bob',
- ... registry=L1)
- >>> ra011.status = interfaces.registration.ActiveStatus
-
- and use it:
-
- >>> L1.lookup([IF0], IB1)
- >>> L1.lookup([IF0], IB1, 'bob')
- 'A011'
-
- >>> L2.lookup([IF0], IB1)
- >>> L2.lookup([IF0], IB1, 'bob')
- 'A011'
-
- but not outside L1:
-
- >>> G.lookup([IF0], IB1, 'bob')
-
- Note that it overrides the non-local adapter:
-
- >>> L1.lookup([IF2], IB1)
- >>> L1.lookup([IF2], IB1, 'bob')
- 'A011'
-
- >>> L2.lookup([IF2], IB1)
- >>> L2.lookup([IF2], IB1, 'bob')
- 'A011'
-
- because it was more specific.
-
- Let's override the adapter in L2:
-
- >>> ra112 = AdapterRegistration(required=IF1, provided=IB1,
- ... factory='A112', name='bob',
- ... registry=L2)
- >>> ra112.status = interfaces.registration.ActiveStatus
-
- Now, in L2, we get the new adapter, because it's as specific and more
- local than the one from G:
-
- >>> L2.lookup([IF2], IB1)
- >>> L2.lookup([IF2], IB1, 'bob')
- 'A112'
-
- Note that we can ask for less specific interfaces and still get
- the adapter:
-
- >>> L2.lookup([IF2], IB0)
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A112'
-
- >>> L1.lookup([IF2], IB0)
- >>> L1.lookup([IF2], IB0, 'bob')
- 'A011'
-
- We get the more specific adapter even if there is a less-specific
- adapter to B0:
-
- >>> G.register([IF1], IB1, 'bob', 'A10G')
-
- >>> L2.lookup([IF2], IB0)
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A112'
-
- But if we have an equally specific and equally local adapter to B0, it
- will win:
-
- >>> ra102 = AdapterRegistration(required = IF1, provided=IB0,
- ... factory='A102', name='bob',
- ... registry=L2)
- >>> ra102.status = interfaces.registration.ActiveStatus
-
- >>> L2.lookup([IF2], IB0)
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A102'
-
- We can deactivate registrations, which has the effect of deleting adapters:
-
-
- >>> ra112.status = interfaces.registration.InactiveStatus
-
- >>> L2.lookup([IF2], IB0)
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A102'
-
- >>> L2.lookup([IF2], IB1)
- >>> L2.lookup([IF2], IB1, 'bob')
- 'A011'
-
- >>> ra102.status = interfaces.registration.InactiveStatus
-
- >>> L2.lookup([IF2], IB0)
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A011'
- """
-
-def test_multi_adapters():
- """
- Suppose we have a global AdapterRegistry:
-
- >>> G = AdapterRegistry()
-
- we also have a local adapter registry, with G as it's base:
-
- >>> L1 = LocalAdapterRegistry(G)
-
- and so on:
-
- >>> L2 = LocalAdapterRegistry(G, L1)
-
- Now, if we declare an adapter globally:
-
- >>> G.register([IF1, IR0], IB1, 'bob', 'A11G')
-
- we can query it locally:
-
- >>> L1.lookup([IF2, IR1], IB1, 'bob')
- 'A11G'
-
- >>> L2.lookup([IF2, IR1], IB1, 'bob')
- 'A11G'
-
- We can add local definitions:
-
- >>> ra011 = AdapterRegistration(required=(IF0, IR0), provided=IB1,
- ... factory='A011', name='bob',
- ... registry=L1)
- >>> ra011.status = interfaces.registration.ActiveStatus
-
- and use it:
-
- >>> L1.lookup([IF0, IR1], IB1, 'bob')
- 'A011'
-
- >>> L2.lookup([IF0, IR1], IB1, 'bob')
- 'A011'
-
- but not outside L1:
-
- >>> G.lookup((IF0, IR1), IB1, 'bob')
-
- Note that overridea the non-local adapter:
-
- >>> L1.lookup([IF2, IR1], IB1, 'bob')
- 'A011'
-
- >>> L2.lookup((IF2, IR1), IB1, 'bob')
- 'A011'
-
- because it was more specific.
-
- Let's override the adapter in L2:
-
- >>> ra112 = AdapterRegistration(required=(IF1, IR0), provided=IB1,
- ... factory='A112', name='bob',
- ... registry=L2)
- >>> ra112.status = interfaces.registration.ActiveStatus
-
- Now, in L2, we get the new adapter, because it's as specific and more
- local than the one from G:
-
- >>> L2.lookup((IF2, IR1), IB1, 'bob')
- 'A112'
-
- Note that we can ask for less specific interfaces and still get
- the adapter:
-
- >>> L2.lookup((IF2, IR1), IB0, 'bob')
- 'A112'
-
- >>> L1.lookup((IF2, IR1), IB0, 'bob')
- 'A011'
-
- We get the more specific adapter even if there is a less-specific
- adapter to B0:
-
- >>> G.register([IF1, IR0], IB1, 'bob', 'A10G')
-
- >>> L2.lookup((IF2, IR1), IB0, 'bob')
- 'A112'
-
- But if we have an equally specific and equally local adapter to B0, it
- will win:
-
- >>> ra102 = AdapterRegistration(required=(IF1, IR0), provided=IB0,
- ... factory='A102', name='bob',
- ... registry=L2)
- >>> ra102.status = interfaces.registration.ActiveStatus
-
- >>> L2.lookup((IF2, IR1), IB0, 'bob')
- 'A102'
-
- We can deactivate registrations, which has the effect of deleting adapters:
-
- >>> ra112.status = interfaces.registration.InactiveStatus
-
- >>> L2.lookup((IF2, IR1), IB0, 'bob')
- 'A102'
-
- >>> L2.lookup((IF2, IR1), IB1, 'bob')
- 'A011'
-
- >>> ra102.status = interfaces.registration.InactiveStatus
-
- >>> L2.lookup([IF2], IB0)
- >>> L2.lookup((IF2, IR1), IB0, 'bob')
- 'A011'
- """
-
-def test_persistence():
- """
- >>> db = DB()
- >>> conn1 = db.open()
-
- >>> G = globalAdapterRegistry
- >>> L1 = LocalAdapterRegistry(G)
- >>> L2 = LocalAdapterRegistry(G, L1)
-
- >>> conn1.root()['L1'] = L1
- >>> conn1.root()['L2'] = L2
-
- >>> G.register([IF1], IB1, 'bob', 'A11G')
- >>> L1.lookup([IF2], IB1)
- >>> L1.lookup([IF2], IB1, 'bob')
- 'A11G'
-
- >>> L2.lookup([IF2], IB1)
- >>> L2.lookup([IF2], IB1, 'bob')
- 'A11G'
-
- We can add local definitions:
-
- >>> ra011 = AdapterRegistration(required=IF0, provided=IB1,
- ... factory='A011', name='bob',
- ... registry=L1)
- >>> ra011.status = interfaces.registration.ActiveStatus
-
- and use it:
-
- >>> L1.lookup([IF0], IB1)
- >>> L1.lookup([IF0], IB1, 'bob')
- 'A011'
-
- >>> L2.lookup([IF0], IB1)
- >>> L2.lookup([IF0], IB1, 'bob')
- 'A011'
-
- but not outside L1:
-
- >>> G.lookup([IF0], IB1)
-
- Note that it overrides the non-local adapter:
-
- >>> L1.lookup([IF2], IB1)
- >>> L1.lookup([IF2], IB1, 'bob')
- 'A011'
-
- >>> L2.lookup([IF2], IB1)
- >>> L2.lookup([IF2], IB1, 'bob')
- 'A011'
-
- because it was more specific.
-
- Let's override the adapter in L2:
-
- >>> ra112 = AdapterRegistration(required=IF1, provided=IB1,
- ... factory='A112', name='bob',
- ... registry=L2)
- >>> ra112.status = interfaces.registration.ActiveStatus
-
- Now, in L2, we get the new adapter, because it's as specific and more
- local than the one from G:
-
- >>> L2.lookup([IF2], IB1)
- >>> L2.lookup([IF2], IB1, 'bob')
- 'A112'
-
- Note that we can ask for less specific interfaces and still get
- the adapter:
-
- >>> L2.lookup([IF2], IB0)
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A112'
-
- >>> L1.lookup([IF2], IB0)
- >>> L1.lookup([IF2], IB0, 'bob')
- 'A011'
-
- We get the more specific adapter even if there is a less-specific
- adapter to B0:
-
- >>> G.register([IF0], IB0, 'bob', 'A00G')
-
- >>> L2.lookup([IF2], IB0)
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A112'
-
- But if we have an equally specific and equally local adapter to B0, it
- will win:
-
- >>> ra102 = AdapterRegistration(required=IF1, provided=IB0,
- ... factory='A102', name='bob',
- ... registry=L2)
- >>> ra102.status = interfaces.registration.ActiveStatus
-
- >>> L2.lookup([IF2], IB0)
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A102'
-
- >>> L1.lookup([IF2], IB0, 'bob')
- 'A011'
- >>> L1.lookup([IF2], IB1, 'bob')
- 'A011'
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A102'
- >>> L2.lookup([IF2], IB1, 'bob')
- 'A112'
-
- >>> transaction.commit()
-
- Now, let's open another transaction:
-
- >>> conn2 = db.open()
-
- >>> L1 = conn2.root()['L1']
- >>> L2 = conn2.root()['L2']
- >>> ra112 = L2._registrations[0]
- >>> ra102 = L2._registrations[1]
-
- We should get the same outputs:
-
- >>> L1.lookup([IF2], IB0, 'bob')
- 'A011'
- >>> L1.lookup([IF2], IB1, 'bob')
- 'A011'
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A102'
- >>> L2.lookup([IF2], IB1, 'bob')
- 'A112'
-
- We can deactivate registrations, which has the effect of deleting
- adapters:
-
- >>> ra112.status = interfaces.registration.InactiveStatus
- >>> ra102.status = interfaces.registration.InactiveStatus
-
- >>> L1.lookup([IF2], IB0, 'bob')
- 'A011'
- >>> L1.lookup([IF2], IB1, 'bob')
- 'A011'
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A011'
- >>> L2.lookup([IF2], IB1, 'bob')
- 'A011'
-
- >>> transaction.commit()
-
- If we look back at the first connection, we should get the same data:
-
- >>> conn1.sync()
- >>> L1 = conn1.root()['L1']
- >>> L2 = conn1.root()['L2']
-
- We should see the result of the deactivations:
-
- >>> L1.lookup([IF2], IB0, 'bob')
- 'A011'
- >>> L1.lookup([IF2], IB1, 'bob')
- 'A011'
- >>> L2.lookup([IF2], IB0, 'bob')
- 'A011'
- >>> L2.lookup([IF2], IB1, 'bob')
- 'A011'
-
- Cleanup:
- >>> G.__init__()
- >>> db.close()
- """
-
-
-def test_local_default():
- """
- >>> G = AdapterRegistry()
- >>> L1 = LocalAdapterRegistry(G)
-
- >>> r = AdapterRegistration(required=None, provided=IB1,
- ... factory='Adapter', registry=L1)
- >>> r.status = interfaces.registration.ActiveStatus
- >>> L1.lookup([IF2], IB1)
- 'Adapter'
- """
-
-
-def test_changing_next():
- """
- >>> G = AdapterRegistry()
- >>> L1 = LocalAdapterRegistry(G)
- >>> L2 = LocalAdapterRegistry(G, L1)
- >>> f2 = F2()
-
- >>> L2.lookup([IF2], IB1)
-
- >>> G.register([IF1], IB1, '', 'A11G')
- >>> L2.lookup([IF2], IB1)
- 'A11G'
-
-
- >>> ra111 = AdapterRegistration(required=IF1, provided=IB1,
- ... factory='A111', registry=L1)
- >>> ra111.status = interfaces.registration.ActiveStatus
- >>> L2.lookup([IF2], IB1)
- 'A111'
-
- >>> L1.next
- >>> L2.next == L1
- True
- >>> L1.subs == (L2,)
- True
- >>> L3 = LocalAdapterRegistry(G, L1)
- >>> L2.setNext(L3)
- >>> L2.next == L3
- True
- >>> L3.next == L1
- True
- >>> L1.subs == (L3,)
- True
- >>> L3.subs == (L2,)
- True
-
- >>> ra113 = AdapterRegistration(required=IF1, provided=IB1,
- ... factory='A113', registry=L3)
- >>> ra113.status = interfaces.registration.ActiveStatus
-
- >>> L2.lookup([IF2], IB1)
- 'A113'
- >>> L2.setNext(L1)
- >>> L2.next == L1
- True
- >>> L3.next == L1
- True
- >>> L1.subs == (L3, L2)
- True
- >>> L3.subs == ()
- True
- >>> L2.lookup([IF2], IB1)
- 'A111'
-
- """
-
-def setUp(test):
- placelesssetup.setUp(test)
- setup.setUpAnnotations()
- setup.setUpDependable()
- setup.setUpTraversal()
-
-def test_suite():
- return unittest.TestSuite((
- doctest.DocTestSuite(),
- doctest.DocFileSuite('../adapterregistry.txt',
- setUp=setUp, tearDown=placelesssetup.tearDown),
- ))
-
-if __name__ == "__main__":
- unittest.main(defaultTest='test_suite')
-
Modified: Zope3/branches/jim-adapter/src/zope/app/component/tests/test_registration.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/component/tests/test_registration.py 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/component/tests/test_registration.py 2006-03-16 12:29:18 UTC (rev 66056)
@@ -30,8 +30,8 @@
def test_suite():
return unittest.TestSuite((
- doctest.DocFileSuite('../statusproperty.txt'),
- doctest.DocFileSuite('../registration.txt',
+ doctest.DocFileSuite('deprecated35_statusproperty.txt'),
+ doctest.DocFileSuite('deprecated35_registration.txt',
setUp=setUp, tearDown=placelesssetup.tearDown),
))
Modified: Zope3/branches/jim-adapter/src/zope/app/testing/setup.py
===================================================================
--- Zope3/branches/jim-adapter/src/zope/app/testing/setup.py 2006-03-16 06:17:50 UTC (rev 66055)
+++ Zope3/branches/jim-adapter/src/zope/app/testing/setup.py 2006-03-16 12:29:18 UTC (rev 66056)
@@ -47,16 +47,6 @@
Dependable)
#------------------------------------------------------------------------
-# Registrations
-
-from zope.app.component.interfaces.registration import IComponentRegistration
-from zope.app.component.interfaces.registration import IRegistrationEvent
-from zope.app.component.registration import componentRegistrationEventNotify
-def setUpRegistered():
- ztapi.subscribe((IComponentRegistration, IRegistrationEvent), None,
- componentRegistrationEventNotify)
-
-#------------------------------------------------------------------------
# Traversal
from zope.app.traversing.browser.interfaces import IAbsoluteURL
from zope.app.container.traversal import ContainerTraversable
@@ -112,7 +102,6 @@
zope.app.component.hooks.setHooks()
setUpAnnotations()
setUpDependable()
- setUpRegistered()
setUpTraversal()
setUpSiteManagerLookup()
More information about the Zope3-Checkins
mailing list