[Checkins] SVN: zope.app.component/tags/3.4.2/ Tag the 3.4.2 release of zope.app.component.

Marius Gedminas marius at pov.lt
Wed Jul 15 14:56:05 EDT 2009


Log message for revision 101933:
  Tag the 3.4.2 release of zope.app.component.
  
  

Changed:
  A   zope.app.component/tags/3.4.2/
  D   zope.app.component/tags/3.4.2/CHANGES.txt
  A   zope.app.component/tags/3.4.2/CHANGES.txt
  D   zope.app.component/tags/3.4.2/buildout.cfg
  A   zope.app.component/tags/3.4.2/buildout.cfg
  D   zope.app.component/tags/3.4.2/setup.py
  A   zope.app.component/tags/3.4.2/setup.py
  D   zope.app.component/tags/3.4.2/src/zope/app/component/back35.py
  A   zope.app.component/tags/3.4.2/src/zope/app/component/back35.py
  D   zope.app.component/tags/3.4.2/src/zope/app/component/site.py
  A   zope.app.component/tags/3.4.2/src/zope/app/component/site.py
  D   zope.app.component/tags/3.4.2/src/zope/app/component/tests/test_registration.py
  A   zope.app.component/tags/3.4.2/src/zope/app/component/tests/test_registration.py

-=-
Deleted: zope.app.component/tags/3.4.2/CHANGES.txt
===================================================================
--- zope.app.component/tags/3.4.x/CHANGES.txt	2009-07-15 17:24:15 UTC (rev 101927)
+++ zope.app.component/tags/3.4.2/CHANGES.txt	2009-07-15 18:56:04 UTC (rev 101933)
@@ -1,14 +0,0 @@
-=======
-CHANGES
-=======
-
-3.4.1 (2007-10-31)
-------------------
-
-- Resolve ``ZopeSecurityPolicy`` deprecation warning.
-
-
-3.4.0 (2007-10-11)
-------------------
-
-- Initial release independent of the main Zope tree.

Copied: zope.app.component/tags/3.4.2/CHANGES.txt (from rev 101932, zope.app.component/tags/3.4.x/CHANGES.txt)
===================================================================
--- zope.app.component/tags/3.4.2/CHANGES.txt	                        (rev 0)
+++ zope.app.component/tags/3.4.2/CHANGES.txt	2009-07-15 18:56:04 UTC (rev 101933)
@@ -0,0 +1,24 @@
+=======
+CHANGES
+=======
+
+3.4.2 (2009-07-15)
+------------------
+
+- Fix empty __bases__ on LocalSiteManager objects loaded from old databases,
+  which causes queryNextUtility to never see global utilites and therefore
+  broke minor things like the whole authentication framework.
+- Fix KeyError: 'base' on startup in zope/app/component/back35.py after
+  an inept attempt to fix the above error.
+
+
+3.4.1 (2007-10-31)
+------------------
+
+- Resolve ``ZopeSecurityPolicy`` deprecation warning.
+
+
+3.4.0 (2007-10-11)
+------------------
+
+- Initial release independent of the main Zope tree.

Deleted: zope.app.component/tags/3.4.2/buildout.cfg
===================================================================
--- zope.app.component/tags/3.4.x/buildout.cfg	2009-07-15 17:24:15 UTC (rev 101927)
+++ zope.app.component/tags/3.4.2/buildout.cfg	2009-07-15 18:56:04 UTC (rev 101933)
@@ -1,8 +0,0 @@
-[buildout]
-develop = .
-parts = test
-
-[test]
-recipe = zc.recipe.testrunner
-eggs = zope.app.component [test, back35]
-

Copied: zope.app.component/tags/3.4.2/buildout.cfg (from rev 101929, zope.app.component/tags/3.4.x/buildout.cfg)
===================================================================
--- zope.app.component/tags/3.4.2/buildout.cfg	                        (rev 0)
+++ zope.app.component/tags/3.4.2/buildout.cfg	2009-07-15 18:56:04 UTC (rev 101933)
@@ -0,0 +1,16 @@
+[buildout]
+develop = .
+parts = test
+extends = http://download.zope.org/zope3.4/3.4.0/versions.cfg
+versions = versions
+
+[versions]
+zope.app.component =
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = zope.app.component [test, back35]
+       zope.app.layers     # the utter braindeadness of either setuptools or
+       zope.app.securitypolicy # buildout requires me to state these
+       zope.testbrowser    # dependencies again, here, I don't know why
+defaults = ['-m', 'zope.app.component']

Deleted: zope.app.component/tags/3.4.2/setup.py
===================================================================
--- zope.app.component/tags/3.4.x/setup.py	2009-07-15 17:24:15 UTC (rev 101927)
+++ zope.app.component/tags/3.4.2/setup.py	2009-07-15 18:56:04 UTC (rev 101933)
@@ -1,96 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 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.
-#
-##############################################################################
-"""Setup for zope.app.catalog package
-
-$Id: setup.py 80209 2007-09-27 09:38:31Z berndroessl $
-"""
-import os
-from setuptools import setup, find_packages
-
-def read(*rnames):
-    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-
-setup(name='zope.app.component',
-      version = '3.4.1',
-      author='Zope Corporation and Contributors',
-      author_email='zope3-dev at zope.org',
-      description='Local Zope Component Support',
-      long_description=(
-          read('README.txt')
-          + '\n\n' +
-          'Detailed Documentation\n'
-          '**********************\n'
-          + '\n\n' +
-          read('src', 'zope', 'app', 'component', 'README.txt')
-          + '\n\n' +
-          read('src', 'zope', 'app', 'component', 'site.txt')
-          + '\n\n' +
-          read('CHANGES.txt')
-          ),
-      keywords = "zope component architecture local",
-      classifiers = [
-          'Development Status :: 5 - Production/Stable',
-          'Environment :: Web Environment',
-          'Intended Audience :: Developers',
-          'License :: OSI Approved :: Zope Public License',
-          'Programming Language :: Python',
-          'Natural Language :: English',
-          'Operating System :: OS Independent',
-          'Topic :: Internet :: WWW/HTTP',
-          'Framework :: Zope3'],
-      url='http://pypi.python.org/pypi/zope.app.component',
-      license='ZPL 2.1',
-      packages=find_packages('src'),
-      package_dir = {'': 'src'},
-      namespace_packages=['zope', 'zope.app'],
-      extras_require=dict(
-          test=['zope.app.testing',
-                'zope.app.securitypolicy',
-                'zope.app.zcmlfiles',
-                'zope.modulealias',
-                'zope.app.schema',
-                'zope.testbrowser',
-                ],
-          back35=['zope.app.layers']),
-      install_requires=[
-          'setuptools',
-          'zope.annotation',
-          'zope.app.container',
-          'zope.app.interface',
-          'zope.app.pagetemplate',
-          'zope.app.security',
-          'zope.cachedescriptors',
-          'zope.component [hook]',
-          'zope.configuration',
-          'zope.deferredimport',
-          'zope.deprecation',
-          'zope.event',
-          'zope.exceptions',
-          'zope.filerepresentation',
-          'zope.formlib',
-          'zope.i18nmessageid',
-          'zope.interface',
-          'zope.lifecycleevent',
-          'zope.location>3.4.0b1',
-          'zope.publisher',
-          'zope.schema',
-          'zope.security',
-          'zope.thread',
-          'zope.traversing',
-          'ZODB3',
-          ],
-      include_package_data = True,
-      zip_safe = False,
-      )
-

Copied: zope.app.component/tags/3.4.2/setup.py (from rev 101932, zope.app.component/tags/3.4.x/setup.py)
===================================================================
--- zope.app.component/tags/3.4.2/setup.py	                        (rev 0)
+++ zope.app.component/tags/3.4.2/setup.py	2009-07-15 18:56:04 UTC (rev 101933)
@@ -0,0 +1,96 @@
+##############################################################################
+#
+# Copyright (c) 2006 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.
+#
+##############################################################################
+"""Setup for zope.app.catalog package
+
+$Id: setup.py 80209 2007-09-27 09:38:31Z berndroessl $
+"""
+import os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+setup(name='zope.app.component',
+      version = '3.4.2',
+      author='Zope Corporation and Contributors',
+      author_email='zope3-dev at zope.org',
+      description='Local Zope Component Support',
+      long_description=(
+          read('README.txt')
+          + '\n\n' +
+          'Detailed Documentation\n'
+          '**********************\n'
+          + '\n\n' +
+          read('src', 'zope', 'app', 'component', 'README.txt')
+          + '\n\n' +
+          read('src', 'zope', 'app', 'component', 'site.txt')
+          + '\n\n' +
+          read('CHANGES.txt')
+          ),
+      keywords = "zope component architecture local",
+      classifiers = [
+          'Development Status :: 5 - Production/Stable',
+          'Environment :: Web Environment',
+          'Intended Audience :: Developers',
+          'License :: OSI Approved :: Zope Public License',
+          'Programming Language :: Python',
+          'Natural Language :: English',
+          'Operating System :: OS Independent',
+          'Topic :: Internet :: WWW/HTTP',
+          'Framework :: Zope3'],
+      url='http://pypi.python.org/pypi/zope.app.component',
+      license='ZPL 2.1',
+      packages=find_packages('src'),
+      package_dir = {'': 'src'},
+      namespace_packages=['zope', 'zope.app'],
+      extras_require=dict(
+          test=['zope.app.testing',
+                'zope.app.securitypolicy',
+                'zope.app.zcmlfiles',
+                'zope.modulealias',
+                'zope.app.schema',
+                'zope.testbrowser',
+                ],
+          back35=['zope.app.layers']),
+      install_requires=[
+          'setuptools',
+          'zope.annotation',
+          'zope.app.container',
+          'zope.app.interface',
+          'zope.app.pagetemplate',
+          'zope.app.security',
+          'zope.cachedescriptors',
+          'zope.component [hook]',
+          'zope.configuration',
+          'zope.deferredimport',
+          'zope.deprecation',
+          'zope.event',
+          'zope.exceptions',
+          'zope.filerepresentation',
+          'zope.formlib',
+          'zope.i18nmessageid',
+          'zope.interface',
+          'zope.lifecycleevent',
+          'zope.location>3.4.0b1',
+          'zope.publisher',
+          'zope.schema',
+          'zope.security',
+          'zope.thread',
+          'zope.traversing',
+          'ZODB3',
+          ],
+      include_package_data = True,
+      zip_safe = False,
+      )
+

Deleted: zope.app.component/tags/3.4.2/src/zope/app/component/back35.py
===================================================================
--- zope.app.component/tags/3.4.x/src/zope/app/component/back35.py	2009-07-15 17:24:15 UTC (rev 101927)
+++ zope.app.component/tags/3.4.2/src/zope/app/component/back35.py	2009-07-15 18:56:04 UTC (rev 101933)
@@ -1,922 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 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.
-#
-##############################################################################
-"""Features that will go away in Zope 3.5.
-
-$Id$
-"""
-__docformat__ = 'restructuredtext'
-
-import UserDict
-import warnings
-
-import persistent
-import persistent.list
-import persistent.mapping
-
-from persistent import Persistent
-
-from zope import component
-import zope.cachedescriptors.property
-import zope.event
-import zope.schema
-import zope.component.interfaces
-import zope.deprecation
-import zope.schema.vocabulary
-from zope import interface, schema
-from zope.traversing.interfaces import TraversalError
-from zope.interface import implements
-from zope.security.checker import InterfaceChecker, CheckerPublic
-from zope.security.proxy import Proxy, removeSecurityProxy
-from zope.lifecycleevent import ObjectCreatedEvent
-from zope.component.interfaces import ComponentLookupError
-from zope.configuration.fields import GlobalObject
-from zope.configuration.exceptions import ConfigurationError
-from zope.publisher.interfaces.back35 import ILayer
-
-import zope.app.component.interfaces.registration
-import zope.app.container.interfaces
-import zope.app.container.constraints
-from zope.app import zapi
-from zope.app.component.i18n import ZopeMessageFactory as _
-from zope.app.component.interfaces import registration as interfaces
-from zope.app.container.btree import BTreeContainer
-from zope.app.container.contained import Contained
-
-InactiveStatus = _('Inactive')
-ActiveStatus = _('Active')
-
-class IRegistration(interface.Interface):
-    """Registration object
-
-    A registration object represents a specific registration
-    decision, such as registering an adapter or defining a permission.
-
-    In addition to the attributes or methods defined here,
-    registration objects will include additional attributes
-    identifying how they should be used. For example, a service
-    registration will provide a service type. An adapter
-    registration will specify a used-for interface and a provided
-    interface.
-    """
-
-    status = schema.Choice(
-        title=_("Registration status"),
-        vocabulary= zope.schema.vocabulary.SimpleVocabulary(
-            (zope.schema.vocabulary.SimpleTerm(InactiveStatus,
-                                               title=InactiveStatus),
-             zope.schema.vocabulary.SimpleTerm(ActiveStatus,
-                                               title=ActiveStatus))),
-        default=ActiveStatus
-        )
-
-
-class IComponentRegistration(IRegistration):
-    """Registration object that uses a component.
-
-    An interface can optionally be specified that describes the interface the
-    component provides for the registry.
-
-    The interface will be used to produce a proxy for the component, if
-    the permission is also specified.
-    """
-    component = zope.app.component.interfaces.registration.Component(
-        title=_("Registration Component"),
-        description=_("The component the registration is for."),
-        required=True)
-
-    interface = schema.Field(
-        title=_("Component Interface"),
-        description=_("The interface the component provides through this "
-                      "registration."),
-        required=False,
-        default=None)
-
-    permission = schema.Choice(
-        title=_("The permission needed to use the component"),
-        vocabulary="Permissions",
-        required=False
-        )
-
-
-class IRegistry(zope.component.interfaces.IRegistry):
-    """A component that can be configured using a registration manager."""
-
-    def register(registration):
-        """Register a component with the registry using a registration.
-
-        Once the registration is added to the registry, it will be active. If
-        the registration is already registered with the registry, this method
-        will quietly return.
-        """
-
-    def unregister(registration):
-        """Unregister a component from the registry.
-
-        Unregistering a registration automatically makes the component
-        inactive. If the registration is not registered, this method will
-        quietly return.
-        """
-
-    def registered(registration):
-        """Determine whether a registration is registered with the registry.
-
-        The method will return a Boolean value.
-        """
-
-
-class ILocatedRegistry(IRegistry):
-    """A registry that is located in a tree of registries.
-
-
-    """
-    next = interface.Attribute(
-        "Set the next local registry in the tree. This attribute "
-        "represents the parent of this registry node. If the "
-        "value is `None`, then this registry represents the "
-        "root of the tree")
-
-    subs = interface.Attribute(
-        "A collection of registries that describe the next level "
-        "of the registry tree. They are the children of this "
-        "registry node. This attribute should never be "
-        "manipulated manually. Use `addSub()` and `removeSub()` "
-        "instead.")
-
-    base = interface.Attribute(
-        "Outside of the local registry tree lies the global "
-        "registry, which is known as the base to every local "
-        "registry in the tree.")
-
-    def addSub(sub):
-        """Add a new sub-registry to the node.
-
-        Important: This method should *not* be used manually. It is
-        automatically called by `setNext()`. To add a new registry to the
-        tree, use `sub.setNext(self, self.base)` instead!
-        """
-
-    def removeSub(sub):
-        """Remove a sub-registry to the node.
-
-        Important: This method should *not* be used manually. It is
-        automatically called by `setNext()`. To remove a registry from the
-        tree, use `sub.setNext(None)` instead!
-        """
-
-    def setNext(next, base=None):
-        """Set the next/parent registry in the tree.
-
-        This method should ensure that all relevant registies are updated
-        correctly as well.
-        """
-
-
-class IRegistrationManager(
-    zope.app.container.interfaces.IContainerNamesContainer,
-    ):
-    """Manage Registrations"""
-    zope.app.container.constraints.contains(IRegistration)
-
-    def addRegistration(registration):
-        """Add a registration to the manager.
-
-        The function will automatically choose a name as which the
-        registration will be known. The name of the registration inside this
-        manager is returned.
-        """
-
-
-class IRegistrationManagerContained(zope.app.container.interfaces.IContained):
-    """Objects that can be contained by the registration manager should
-    implement this interface."""
-    zope.app.container.constraints.containers(IRegistrationManager)
-
-
-class IRegisterableContainer(zope.app.container.interfaces.IContainer):
-    """Containers with registration managers
-
-    These are site-management folders of one sort or another.
-
-    The container allows clients to access the registration manager
-    without knowing it's name.
-
-    The registration manager container *also* supports local-module
-    lookup.
-    """
-
-    registrationManager = schema.Field(
-        title=_("Registration Manager"),
-        description=_("The registration manager keeps track of all component "
-                    "registrations."))
-
-
-class IRegisterable(zope.app.container.interfaces.IContained):
-    """Mark a component as registerable.
-
-    All registerable components need to implement this interface.
-    """
-    #zope.app.container.constraints.containers(IRegisterableContainer)
-
-
-class IRegisterableContainerContaining(
-    zope.app.container.interfaces.IContainer,
-    ):
-    """A container that can only contain `IRegisterable`s and
-    `IRegisterableContainer`s.
-
-    This interface was designed to be always used together with the
-    `IRegisterableContainer`.
-    """
-    zope.app.container.constraints.contains(
-        IRegisterable, IRegisterableContainer)
-
-
-class IRegistered(interface.Interface):
-    """An object that can track down its registrations.
-
-    The object need not implement this functionality itself, but must at
-    least support doing so via an adapter.
-    """
-
-    def registrations():
-        """Return a sequence of registration objects for this object."""
-
-class ILocalAdapterRegistry(IRegistry, ILocatedRegistry):
-    pass
-
-class ILocalUtility(IRegisterable):
-    """Local utility marker.
-
-    A marker interface that indicates that a component can be used as
-    a local utility.
-
-    Utilities should usually also declare they implement
-    IAttributeAnnotatable, so that the standard adapter to
-    IRegistered can be used; otherwise, they must provide
-    another way to be adaptable to IRegistered.
-    """
-
-class IAdapterRegistration(IComponentRegistration):
-    """Local Adapter Registration for Local Adapter Registry
-
-    The adapter registration is used to provide local adapters via the
-    adapter registry. It is an extended component registration, whereby the
-    component is the adapter factory in this case.
-    """
-    required = schema.Choice(
-        title = _("For interface"),
-        description = _("The interface of the objects being adapted"),
-        vocabulary="Interfaces",
-        readonly = True,
-        required=False,
-        default=None)
-
-    with = schema.Tuple(
-        title = _("With interfaces"),
-        description = _("Additionally required interfaces"),
-        readonly=True,
-        value_type = zope.schema.Choice(vocabulary='Interfaces'),
-        required=False,
-        default=())
-
-    provided = schema.Choice(
-        title = _("Provided interface"),
-        description = _("The interface provided"),
-        vocabulary="Interfaces",
-        readonly = True,
-        required = True)
-
-    name = schema.TextLine(
-        title=_(u"Name"),
-        readonly=False,
-        required=True,
-        default=u''
-        )
-
-    permission = schema.Choice(
-        title=_("The permission required for use"),
-        vocabulary="Permission Ids",
-        readonly=False,
-        required=False,
-        )
-
-    # TODO: for now until we figure out a way to specify the factory directly
-    factoryName = schema.TextLine(
-        title=_(u"Factory Name"),
-        readonly=False,
-        required=False,
-        )
-
-class IUtilityRegistration(IAdapterRegistration):
-    """Utility registration object.
-
-    Adapter registries are also used to to manage utilities, since utilities
-    are adapters that are instantiated and have no required interfaces. Thus,
-    utility registrations must fulfill all requirements of an adapter
-    registration as well.
-    """
-
-    name = zope.schema.TextLine(
-        title=_("Register As"),
-        description=_("The name under which the utility will be known."),
-        readonly=False,
-        required=True,
-        default=u''
-        )
-
-    provided = zope.schema.Choice(
-        title=_("Provided interface"),
-        description=_("The interface provided by the utility"),
-        vocabulary="Utility Component Interfaces",
-        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 ActiveStatus
-
-        return InactiveStatus
-
-    def __set__(self, inst, value):
-        registration = inst
-        registry = registration.getRegistry()
-        if registry is None:
-            raise ValueError('No registry found.')
-
-        if value == ActiveStatus:
-            if not registry.registered(registration):
-                registry.register(registration)
-                zope.event.notify(
-                    zope.component.interfaces.Registered(registration)
-                    )
-
-        elif value == InactiveStatus:
-            if registry.registered(registration):
-                registry.unregister(registration)
-                zope.event.notify(
-                  zope.component.interfaces.Unregistered(registration)
-                  )
-        else:
-            raise ValueError(value)
-
-
-class SimpleRegistration(persistent.Persistent, Contained):
-    """Registration objects that just contain registration data"""
-    implements(IRegistration, 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(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(IRegistered)
-    __used_for__ = IRegisterable
-
-    def __init__(self, registerable):
-        self.registerable = registerable
-
-    def registrations(self):
-        context = self.registerable
-        return [
-            r
-            for r in component.getSiteManager(context).registeredUtilities()
-            if r.component == context
-            ]
-
-
-class RegistrationManager(BTreeContainer):
-    """Registration manager
-
-    Manages registrations within a package.
-    """
-    implements(IRegistrationManager)
-
-    @zope.deprecation.deprecate("Will go away in Zope 3.5")
-    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`"""
-
-    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(ObjectCreatedEvent(self.registrationManager))
-
-
-class RegistrationManagerNamespace:
-    """Used to traverse to a Registration Manager from a
-       Registerable Container."""
-    __used_for__ = IRegisterableContainer
-
-    def __init__(self, ob, request=None):
-        self.context = ob.registrationManager
-
-    @zope.deprecation.deprecate(
-        "++registration++ namespace is deprecated and will go away in Zope 3.5"
-        )
-    def traverse(self, name, ignore):
-        if name == '':
-            return self.context
-        raise TraversalError(self.context, name)
-
-
-
-class AdapterRegistration(ComponentRegistration):
-    """Adapter component registration for persistent components
-
-    This registration configures persistent components in packages to
-    be adapters.
-    """
-    zope.interface.implements(IAdapterRegistration)
-
-    def __init__(self, required, provided, factoryName,
-                 name='', permission=None):
-        if not isinstance(required, (tuple, list)):
-            self.required = required
-            self.with = ()
-        else:
-            self.required = required[0]
-            self.with = tuple(required[1:])
-        self.provided = provided
-        self.name = name
-        self.factoryName = factoryName
-        self.permission = permission
-
-    def component(self):
-        factory = resolve(self.factoryName, self)
-        return factory
-    component = property(component)
-
-    def getRegistry(self):
-        return zapi.getSiteManager(self)
-
-class AdapterRegistration2(ComponentRegistration):
-    """A simple implementation of the adapter registration interface."""
-    interface.implements(IAdapterRegistration)
-
-    def __init__(self, required, provided, factory,
-                 name='', permission=None, registry=None):
-        if not isinstance(required, (tuple, list)):
-            self.required = required
-            self.with = ()
-        else:
-            self.required = required[0]
-            self.with = tuple(required[1:])
-        self.provided = provided
-        self.name = name
-        self.component = factory
-        self.permission = permission
-        self.registry = registry
-
-    def getRegistry(self):
-        return self.registry
-
-    def __repr__(self):
-        return ('<%s: ' %self.__class__.__name__ +
-                'required=%r, ' %self.required +
-                'with=' + `self.with` + ', ' +
-                'provided=%r, ' %self.provided +
-                'name=%r, ' %self.name +
-                'component=%r, ' %self.component +
-                'permission=%r' %self.permission +
-                '>')
-
-class UtilityRegistration(ComponentRegistration):
-    """Utility component registration for persistent components
-
-    This registration configures persistent components in packages to
-    be utilities.
-    """
-    interface.implements(IUtilityRegistration)
-
-    def __init__(self, name, provided, component, permission=None):
-        super(UtilityRegistration, self).__init__(component, permission)
-        self.name = name
-        self.provided = provided
-
-    def getRegistry(self):
-        return zapi.getSiteManager(self)
-
-
-class LayerField(GlobalObject):
-    r"""This field represents a layer.
-
-    Besides being able to look up the layer by importing it, we also try
-    to look up the name in the site manager.
-
-    >>> from zope.interface import directlyProvides
-    >>> from zope.interface.interface import InterfaceClass
-
-    >>> layer1 = InterfaceClass('layer1', (),
-    ...                         __doc__='Layer: layer1',
-    ...                         __module__='zope.app.layers')
-    >>> directlyProvides(layer1, ILayer)
-
-    >>> layers = None
-    >>> class Resolver(object):
-    ...     def resolve(self, path):
-    ...         if '..' in path:
-    ...             raise ValueError('Empty module name')
-    ...         if (path.startswith('zope.app.layers') and
-    ...             hasattr(layers, 'layer1') or
-    ...             path == 'zope.app.component.fields.layer1' or
-    ...             path == '.fields.layer1'):
-    ...             return layer1
-    ...         raise ConfigurationError('layer1')
-
-    >>> field = LayerField()
-    >>> field = field.bind(Resolver())
-
-    Test 1: Import the layer
-    ------------------------
-
-    >>> field.fromUnicode('zope.app.component.fields.layer1') is layer1
-    True
-
-    Test 2: We have a shortcut name. Import the layer from `zope.app.layers`.
-    -------------------------------------------------------------------------
-
-    >>> from types import ModuleType as module
-    >>> import sys
-    >>> layers = module('layers')
-    >>> import zope.app.layers
-    >>> old = sys.modules['zope.app.layers']
-    >>> sys.modules['zope.app.layers'] = layers
-    >>> setattr(layers, 'layer1', layer1)
-
-    >>> field.fromUnicode('layer1') is layer1
-    True
-
-    >>> sys.modules['zope.app.layers'] = old
-
-    Test 3: Get the layer from the site manager
-    -------------------------------------------
-
-    >>> from zope.app.testing import ztapi
-    >>> ztapi.provideUtility(ILayer, layer1, 'layer1')
-
-    >>> field.fromUnicode('layer1') is layer1
-    True
-
-    Test 4: Import the layer by using a short name
-    ----------------------------------------------
-
-    >>> field.fromUnicode('.fields.layer1') is layer1
-    True
-    """
-
-    def fromUnicode(self, u):
-        name = str(u.strip())
-
-        try:
-            value = zope.component.queryUtility(ILayer, name)
-        except ComponentLookupError:
-            # The component architecture is not up and running.
-            pass
-        else:
-            if value is not None:
-                return value
-
-        try:
-            value = self.context.resolve('zope.app.layers.'+name)
-        except (ConfigurationError, ValueError), v:
-            try:
-                value = self.context.resolve(name)
-            except ConfigurationError, v:
-                raise zope.schema.ValidationError(v)
-
-        self.validate(value)
-        return value
-
-
-class LocalSiteGeneration3SupportMixin:
-
-    @zope.cachedescriptors.property.readproperty
-    def _utility_registrations(self):
-        return _OldUtilityRegistrations(
-            self, 'utilities', '_utility_registrations')
-
-    @zope.cachedescriptors.property.readproperty
-    def _adapter_registrations(self):
-        return _OldAdapterRegistrations(
-            self, 'adapters', '_adapter_registrations')
-
-    @zope.cachedescriptors.property.readproperty
-    def _subscription_registrations(self):
-        return _OldSubscriberRegistrations(self, '_subscription_registrations')
-
-    @zope.cachedescriptors.property.readproperty
-    def _handler_registrations(self):
-        return _OldSubscriberRegistrations(self, '_handler_registrations')
-
-    def _evolve_to_generation_4(self):
-        self._utility_registrations.update(())
-        self._adapter_registrations.update(())
-        self._subscription_registrations.extend(())
-        self._handler_registrations.extend(())
-        for sub in self.subs:
-            sub._evolve_to_generation_4()
-
-
-class _OldUtilityRegistrations(UserDict.DictMixin):
-
-    def __init__(self, site, rname, name):
-        self.site = site
-        self.rname = rname
-        self.__name__ = name
-
-    def _getOldRegistrations(self):
-        return getattr(self.site, self.rname)._registrations
-
-    def __getitem__(self, key):
-        (provided, name) = key
-        for r in self._getOldRegistrations():
-            if r.name == name and r.provided == provided:
-                return r.component, u''
-        raise KeyError, key
-
-    def keys(self):
-        return [
-            (r.provided, r.name)
-            for r in self._getOldRegistrations()
-            ]
-
-    def update(self, other):
-        newregistrations = persistent.mapping.PersistentMapping()
-        for r in self._getOldRegistrations():
-            newregistrations[(r.provided, r.name)] = r.component, u''
-
-        # finish the conversion of the utilities:
-        del getattr(self.site, self.rname)._registrations
-
-        for key, value in dict(other).iteritems():
-            newregistrations[key] = value
-
-        setattr(self.site, self.__name__, newregistrations)
-
-    def __setitem__(self, k, v):
-        self.update([(k, v)])
-
-    def __delitem__(self, k):
-        self.update(())
-        del getattr(self.site, self.__name__)[k]
-
-class _OldAdapterRegistrations(_OldUtilityRegistrations):
-
-    def _getOldRegistrations(self):
-        if self.site.adapters._registrations:
-            warnings.warn(
-                "Old non-utility registrations are not supported and will not "
-                "be converted",
-                DeprecationWarning)
-        return ()
-
-
-class _OldSubscriberRegistrations(object):
-
-    def __init__(self, site, name):
-        self.site = site
-        self.__name__ = name
-
-    def __iter__(self):
-        return iter(())
-
-    def __setslice__(self, i, j, other):
-        assert i == 0
-        self.extend(other)
-
-    def extend(self, other):
-        assert not other
-        setattr(self.site, self.__name__, persistent.list.PersistentList())
-
-    def append(self, value):
-        setattr(self.site, self.__name__,
-                persistent.list.PersistentList([value]),
-                )
-
-class _LocalAdapterRegistryGeneration3SupportMixin(object):
-
-    def __setstate__(self, state):
-        if '_registrations' in state:
-            # convert data to generation 3 data structure:
-            next = state.get('next')
-            if next is None:
-                next = state['base']
-            bases = (next, )
-            self.__init__(bases)
-            registrations = []
-            for r in state['_registrations']:
-                if isinstance(r, UtilityRegistration):
-                    self.register((), r.provided, r.name, r.component)
-
-                    if not [
-                        1 for rseen in registrations
-                        if rseen.provided == r.provided
-                           and rseen.component == r.component
-                        ]:
-                        self.subscribe((), r.provided, r.component)
-
-                    registrations.append(r)
-                else:
-                    warnings.warn(
-                        "Old %s registrations are not supported and will not "
-                        "be converted" % r.__class__.__name__,
-                        DeprecationWarning)
-
-            self._registrations = tuple(registrations)
-        else:
-            super(_LocalAdapterRegistryGeneration3SupportMixin, self
-                  ).__setstate__(state)
-

Copied: zope.app.component/tags/3.4.2/src/zope/app/component/back35.py (from rev 101931, zope.app.component/tags/3.4.x/src/zope/app/component/back35.py)
===================================================================
--- zope.app.component/tags/3.4.2/src/zope/app/component/back35.py	                        (rev 0)
+++ zope.app.component/tags/3.4.2/src/zope/app/component/back35.py	2009-07-15 18:56:04 UTC (rev 101933)
@@ -0,0 +1,922 @@
+##############################################################################
+#
+# Copyright (c) 2006 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.
+#
+##############################################################################
+"""Features that will go away in Zope 3.5.
+
+$Id$
+"""
+__docformat__ = 'restructuredtext'
+
+import UserDict
+import warnings
+
+import persistent
+import persistent.list
+import persistent.mapping
+
+from persistent import Persistent
+
+from zope import component
+import zope.cachedescriptors.property
+import zope.event
+import zope.schema
+import zope.component.interfaces
+import zope.deprecation
+import zope.schema.vocabulary
+from zope import interface, schema
+from zope.traversing.interfaces import TraversalError
+from zope.interface import implements
+from zope.security.checker import InterfaceChecker, CheckerPublic
+from zope.security.proxy import Proxy, removeSecurityProxy
+from zope.lifecycleevent import ObjectCreatedEvent
+from zope.component.interfaces import ComponentLookupError
+from zope.configuration.fields import GlobalObject
+from zope.configuration.exceptions import ConfigurationError
+from zope.publisher.interfaces.back35 import ILayer
+
+import zope.app.component.interfaces.registration
+import zope.app.container.interfaces
+import zope.app.container.constraints
+from zope.app import zapi
+from zope.app.component.i18n import ZopeMessageFactory as _
+from zope.app.component.interfaces import registration as interfaces
+from zope.app.container.btree import BTreeContainer
+from zope.app.container.contained import Contained
+
+InactiveStatus = _('Inactive')
+ActiveStatus = _('Active')
+
+class IRegistration(interface.Interface):
+    """Registration object
+
+    A registration object represents a specific registration
+    decision, such as registering an adapter or defining a permission.
+
+    In addition to the attributes or methods defined here,
+    registration objects will include additional attributes
+    identifying how they should be used. For example, a service
+    registration will provide a service type. An adapter
+    registration will specify a used-for interface and a provided
+    interface.
+    """
+
+    status = schema.Choice(
+        title=_("Registration status"),
+        vocabulary= zope.schema.vocabulary.SimpleVocabulary(
+            (zope.schema.vocabulary.SimpleTerm(InactiveStatus,
+                                               title=InactiveStatus),
+             zope.schema.vocabulary.SimpleTerm(ActiveStatus,
+                                               title=ActiveStatus))),
+        default=ActiveStatus
+        )
+
+
+class IComponentRegistration(IRegistration):
+    """Registration object that uses a component.
+
+    An interface can optionally be specified that describes the interface the
+    component provides for the registry.
+
+    The interface will be used to produce a proxy for the component, if
+    the permission is also specified.
+    """
+    component = zope.app.component.interfaces.registration.Component(
+        title=_("Registration Component"),
+        description=_("The component the registration is for."),
+        required=True)
+
+    interface = schema.Field(
+        title=_("Component Interface"),
+        description=_("The interface the component provides through this "
+                      "registration."),
+        required=False,
+        default=None)
+
+    permission = schema.Choice(
+        title=_("The permission needed to use the component"),
+        vocabulary="Permissions",
+        required=False
+        )
+
+
+class IRegistry(zope.component.interfaces.IRegistry):
+    """A component that can be configured using a registration manager."""
+
+    def register(registration):
+        """Register a component with the registry using a registration.
+
+        Once the registration is added to the registry, it will be active. If
+        the registration is already registered with the registry, this method
+        will quietly return.
+        """
+
+    def unregister(registration):
+        """Unregister a component from the registry.
+
+        Unregistering a registration automatically makes the component
+        inactive. If the registration is not registered, this method will
+        quietly return.
+        """
+
+    def registered(registration):
+        """Determine whether a registration is registered with the registry.
+
+        The method will return a Boolean value.
+        """
+
+
+class ILocatedRegistry(IRegistry):
+    """A registry that is located in a tree of registries.
+
+
+    """
+    next = interface.Attribute(
+        "Set the next local registry in the tree. This attribute "
+        "represents the parent of this registry node. If the "
+        "value is `None`, then this registry represents the "
+        "root of the tree")
+
+    subs = interface.Attribute(
+        "A collection of registries that describe the next level "
+        "of the registry tree. They are the children of this "
+        "registry node. This attribute should never be "
+        "manipulated manually. Use `addSub()` and `removeSub()` "
+        "instead.")
+
+    base = interface.Attribute(
+        "Outside of the local registry tree lies the global "
+        "registry, which is known as the base to every local "
+        "registry in the tree.")
+
+    def addSub(sub):
+        """Add a new sub-registry to the node.
+
+        Important: This method should *not* be used manually. It is
+        automatically called by `setNext()`. To add a new registry to the
+        tree, use `sub.setNext(self, self.base)` instead!
+        """
+
+    def removeSub(sub):
+        """Remove a sub-registry to the node.
+
+        Important: This method should *not* be used manually. It is
+        automatically called by `setNext()`. To remove a registry from the
+        tree, use `sub.setNext(None)` instead!
+        """
+
+    def setNext(next, base=None):
+        """Set the next/parent registry in the tree.
+
+        This method should ensure that all relevant registies are updated
+        correctly as well.
+        """
+
+
+class IRegistrationManager(
+    zope.app.container.interfaces.IContainerNamesContainer,
+    ):
+    """Manage Registrations"""
+    zope.app.container.constraints.contains(IRegistration)
+
+    def addRegistration(registration):
+        """Add a registration to the manager.
+
+        The function will automatically choose a name as which the
+        registration will be known. The name of the registration inside this
+        manager is returned.
+        """
+
+
+class IRegistrationManagerContained(zope.app.container.interfaces.IContained):
+    """Objects that can be contained by the registration manager should
+    implement this interface."""
+    zope.app.container.constraints.containers(IRegistrationManager)
+
+
+class IRegisterableContainer(zope.app.container.interfaces.IContainer):
+    """Containers with registration managers
+
+    These are site-management folders of one sort or another.
+
+    The container allows clients to access the registration manager
+    without knowing it's name.
+
+    The registration manager container *also* supports local-module
+    lookup.
+    """
+
+    registrationManager = schema.Field(
+        title=_("Registration Manager"),
+        description=_("The registration manager keeps track of all component "
+                    "registrations."))
+
+
+class IRegisterable(zope.app.container.interfaces.IContained):
+    """Mark a component as registerable.
+
+    All registerable components need to implement this interface.
+    """
+    #zope.app.container.constraints.containers(IRegisterableContainer)
+
+
+class IRegisterableContainerContaining(
+    zope.app.container.interfaces.IContainer,
+    ):
+    """A container that can only contain `IRegisterable`s and
+    `IRegisterableContainer`s.
+
+    This interface was designed to be always used together with the
+    `IRegisterableContainer`.
+    """
+    zope.app.container.constraints.contains(
+        IRegisterable, IRegisterableContainer)
+
+
+class IRegistered(interface.Interface):
+    """An object that can track down its registrations.
+
+    The object need not implement this functionality itself, but must at
+    least support doing so via an adapter.
+    """
+
+    def registrations():
+        """Return a sequence of registration objects for this object."""
+
+class ILocalAdapterRegistry(IRegistry, ILocatedRegistry):
+    pass
+
+class ILocalUtility(IRegisterable):
+    """Local utility marker.
+
+    A marker interface that indicates that a component can be used as
+    a local utility.
+
+    Utilities should usually also declare they implement
+    IAttributeAnnotatable, so that the standard adapter to
+    IRegistered can be used; otherwise, they must provide
+    another way to be adaptable to IRegistered.
+    """
+
+class IAdapterRegistration(IComponentRegistration):
+    """Local Adapter Registration for Local Adapter Registry
+
+    The adapter registration is used to provide local adapters via the
+    adapter registry. It is an extended component registration, whereby the
+    component is the adapter factory in this case.
+    """
+    required = schema.Choice(
+        title = _("For interface"),
+        description = _("The interface of the objects being adapted"),
+        vocabulary="Interfaces",
+        readonly = True,
+        required=False,
+        default=None)
+
+    with = schema.Tuple(
+        title = _("With interfaces"),
+        description = _("Additionally required interfaces"),
+        readonly=True,
+        value_type = zope.schema.Choice(vocabulary='Interfaces'),
+        required=False,
+        default=())
+
+    provided = schema.Choice(
+        title = _("Provided interface"),
+        description = _("The interface provided"),
+        vocabulary="Interfaces",
+        readonly = True,
+        required = True)
+
+    name = schema.TextLine(
+        title=_(u"Name"),
+        readonly=False,
+        required=True,
+        default=u''
+        )
+
+    permission = schema.Choice(
+        title=_("The permission required for use"),
+        vocabulary="Permission Ids",
+        readonly=False,
+        required=False,
+        )
+
+    # TODO: for now until we figure out a way to specify the factory directly
+    factoryName = schema.TextLine(
+        title=_(u"Factory Name"),
+        readonly=False,
+        required=False,
+        )
+
+class IUtilityRegistration(IAdapterRegistration):
+    """Utility registration object.
+
+    Adapter registries are also used to to manage utilities, since utilities
+    are adapters that are instantiated and have no required interfaces. Thus,
+    utility registrations must fulfill all requirements of an adapter
+    registration as well.
+    """
+
+    name = zope.schema.TextLine(
+        title=_("Register As"),
+        description=_("The name under which the utility will be known."),
+        readonly=False,
+        required=True,
+        default=u''
+        )
+
+    provided = zope.schema.Choice(
+        title=_("Provided interface"),
+        description=_("The interface provided by the utility"),
+        vocabulary="Utility Component Interfaces",
+        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 ActiveStatus
+
+        return InactiveStatus
+
+    def __set__(self, inst, value):
+        registration = inst
+        registry = registration.getRegistry()
+        if registry is None:
+            raise ValueError('No registry found.')
+
+        if value == ActiveStatus:
+            if not registry.registered(registration):
+                registry.register(registration)
+                zope.event.notify(
+                    zope.component.interfaces.Registered(registration)
+                    )
+
+        elif value == InactiveStatus:
+            if registry.registered(registration):
+                registry.unregister(registration)
+                zope.event.notify(
+                  zope.component.interfaces.Unregistered(registration)
+                  )
+        else:
+            raise ValueError(value)
+
+
+class SimpleRegistration(persistent.Persistent, Contained):
+    """Registration objects that just contain registration data"""
+    implements(IRegistration, 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(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(IRegistered)
+    __used_for__ = IRegisterable
+
+    def __init__(self, registerable):
+        self.registerable = registerable
+
+    def registrations(self):
+        context = self.registerable
+        return [
+            r
+            for r in component.getSiteManager(context).registeredUtilities()
+            if r.component == context
+            ]
+
+
+class RegistrationManager(BTreeContainer):
+    """Registration manager
+
+    Manages registrations within a package.
+    """
+    implements(IRegistrationManager)
+
+    @zope.deprecation.deprecate("Will go away in Zope 3.5")
+    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`"""
+
+    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(ObjectCreatedEvent(self.registrationManager))
+
+
+class RegistrationManagerNamespace:
+    """Used to traverse to a Registration Manager from a
+       Registerable Container."""
+    __used_for__ = IRegisterableContainer
+
+    def __init__(self, ob, request=None):
+        self.context = ob.registrationManager
+
+    @zope.deprecation.deprecate(
+        "++registration++ namespace is deprecated and will go away in Zope 3.5"
+        )
+    def traverse(self, name, ignore):
+        if name == '':
+            return self.context
+        raise TraversalError(self.context, name)
+
+
+
+class AdapterRegistration(ComponentRegistration):
+    """Adapter component registration for persistent components
+
+    This registration configures persistent components in packages to
+    be adapters.
+    """
+    zope.interface.implements(IAdapterRegistration)
+
+    def __init__(self, required, provided, factoryName,
+                 name='', permission=None):
+        if not isinstance(required, (tuple, list)):
+            self.required = required
+            self.with = ()
+        else:
+            self.required = required[0]
+            self.with = tuple(required[1:])
+        self.provided = provided
+        self.name = name
+        self.factoryName = factoryName
+        self.permission = permission
+
+    def component(self):
+        factory = resolve(self.factoryName, self)
+        return factory
+    component = property(component)
+
+    def getRegistry(self):
+        return zapi.getSiteManager(self)
+
+class AdapterRegistration2(ComponentRegistration):
+    """A simple implementation of the adapter registration interface."""
+    interface.implements(IAdapterRegistration)
+
+    def __init__(self, required, provided, factory,
+                 name='', permission=None, registry=None):
+        if not isinstance(required, (tuple, list)):
+            self.required = required
+            self.with = ()
+        else:
+            self.required = required[0]
+            self.with = tuple(required[1:])
+        self.provided = provided
+        self.name = name
+        self.component = factory
+        self.permission = permission
+        self.registry = registry
+
+    def getRegistry(self):
+        return self.registry
+
+    def __repr__(self):
+        return ('<%s: ' %self.__class__.__name__ +
+                'required=%r, ' %self.required +
+                'with=' + `self.with` + ', ' +
+                'provided=%r, ' %self.provided +
+                'name=%r, ' %self.name +
+                'component=%r, ' %self.component +
+                'permission=%r' %self.permission +
+                '>')
+
+class UtilityRegistration(ComponentRegistration):
+    """Utility component registration for persistent components
+
+    This registration configures persistent components in packages to
+    be utilities.
+    """
+    interface.implements(IUtilityRegistration)
+
+    def __init__(self, name, provided, component, permission=None):
+        super(UtilityRegistration, self).__init__(component, permission)
+        self.name = name
+        self.provided = provided
+
+    def getRegistry(self):
+        return zapi.getSiteManager(self)
+
+
+class LayerField(GlobalObject):
+    r"""This field represents a layer.
+
+    Besides being able to look up the layer by importing it, we also try
+    to look up the name in the site manager.
+
+    >>> from zope.interface import directlyProvides
+    >>> from zope.interface.interface import InterfaceClass
+
+    >>> layer1 = InterfaceClass('layer1', (),
+    ...                         __doc__='Layer: layer1',
+    ...                         __module__='zope.app.layers')
+    >>> directlyProvides(layer1, ILayer)
+
+    >>> layers = None
+    >>> class Resolver(object):
+    ...     def resolve(self, path):
+    ...         if '..' in path:
+    ...             raise ValueError('Empty module name')
+    ...         if (path.startswith('zope.app.layers') and
+    ...             hasattr(layers, 'layer1') or
+    ...             path == 'zope.app.component.fields.layer1' or
+    ...             path == '.fields.layer1'):
+    ...             return layer1
+    ...         raise ConfigurationError('layer1')
+
+    >>> field = LayerField()
+    >>> field = field.bind(Resolver())
+
+    Test 1: Import the layer
+    ------------------------
+
+    >>> field.fromUnicode('zope.app.component.fields.layer1') is layer1
+    True
+
+    Test 2: We have a shortcut name. Import the layer from `zope.app.layers`.
+    -------------------------------------------------------------------------
+
+    >>> from types import ModuleType as module
+    >>> import sys
+    >>> layers = module('layers')
+    >>> import zope.app.layers
+    >>> old = sys.modules['zope.app.layers']
+    >>> sys.modules['zope.app.layers'] = layers
+    >>> setattr(layers, 'layer1', layer1)
+
+    >>> field.fromUnicode('layer1') is layer1
+    True
+
+    >>> sys.modules['zope.app.layers'] = old
+
+    Test 3: Get the layer from the site manager
+    -------------------------------------------
+
+    >>> from zope.app.testing import ztapi
+    >>> ztapi.provideUtility(ILayer, layer1, 'layer1')
+
+    >>> field.fromUnicode('layer1') is layer1
+    True
+
+    Test 4: Import the layer by using a short name
+    ----------------------------------------------
+
+    >>> field.fromUnicode('.fields.layer1') is layer1
+    True
+    """
+
+    def fromUnicode(self, u):
+        name = str(u.strip())
+
+        try:
+            value = zope.component.queryUtility(ILayer, name)
+        except ComponentLookupError:
+            # The component architecture is not up and running.
+            pass
+        else:
+            if value is not None:
+                return value
+
+        try:
+            value = self.context.resolve('zope.app.layers.'+name)
+        except (ConfigurationError, ValueError), v:
+            try:
+                value = self.context.resolve(name)
+            except ConfigurationError, v:
+                raise zope.schema.ValidationError(v)
+
+        self.validate(value)
+        return value
+
+
+class LocalSiteGeneration3SupportMixin:
+
+    @zope.cachedescriptors.property.readproperty
+    def _utility_registrations(self):
+        return _OldUtilityRegistrations(
+            self, 'utilities', '_utility_registrations')
+
+    @zope.cachedescriptors.property.readproperty
+    def _adapter_registrations(self):
+        return _OldAdapterRegistrations(
+            self, 'adapters', '_adapter_registrations')
+
+    @zope.cachedescriptors.property.readproperty
+    def _subscription_registrations(self):
+        return _OldSubscriberRegistrations(self, '_subscription_registrations')
+
+    @zope.cachedescriptors.property.readproperty
+    def _handler_registrations(self):
+        return _OldSubscriberRegistrations(self, '_handler_registrations')
+
+    def _evolve_to_generation_4(self):
+        self._utility_registrations.update(())
+        self._adapter_registrations.update(())
+        self._subscription_registrations.extend(())
+        self._handler_registrations.extend(())
+        for sub in self.subs:
+            sub._evolve_to_generation_4()
+
+
+class _OldUtilityRegistrations(UserDict.DictMixin):
+
+    def __init__(self, site, rname, name):
+        self.site = site
+        self.rname = rname
+        self.__name__ = name
+
+    def _getOldRegistrations(self):
+        return getattr(self.site, self.rname)._registrations
+
+    def __getitem__(self, key):
+        (provided, name) = key
+        for r in self._getOldRegistrations():
+            if r.name == name and r.provided == provided:
+                return r.component, u''
+        raise KeyError, key
+
+    def keys(self):
+        return [
+            (r.provided, r.name)
+            for r in self._getOldRegistrations()
+            ]
+
+    def update(self, other):
+        newregistrations = persistent.mapping.PersistentMapping()
+        for r in self._getOldRegistrations():
+            newregistrations[(r.provided, r.name)] = r.component, u''
+
+        # finish the conversion of the utilities:
+        del getattr(self.site, self.rname)._registrations
+
+        for key, value in dict(other).iteritems():
+            newregistrations[key] = value
+
+        setattr(self.site, self.__name__, newregistrations)
+
+    def __setitem__(self, k, v):
+        self.update([(k, v)])
+
+    def __delitem__(self, k):
+        self.update(())
+        del getattr(self.site, self.__name__)[k]
+
+class _OldAdapterRegistrations(_OldUtilityRegistrations):
+
+    def _getOldRegistrations(self):
+        if self.site.adapters._registrations:
+            warnings.warn(
+                "Old non-utility registrations are not supported and will not "
+                "be converted",
+                DeprecationWarning)
+        return ()
+
+
+class _OldSubscriberRegistrations(object):
+
+    def __init__(self, site, name):
+        self.site = site
+        self.__name__ = name
+
+    def __iter__(self):
+        return iter(())
+
+    def __setslice__(self, i, j, other):
+        assert i == 0
+        self.extend(other)
+
+    def extend(self, other):
+        assert not other
+        setattr(self.site, self.__name__, persistent.list.PersistentList())
+
+    def append(self, value):
+        setattr(self.site, self.__name__,
+                persistent.list.PersistentList([value]),
+                )
+
+class _LocalAdapterRegistryGeneration3SupportMixin(object):
+
+    def __setstate__(self, state):
+        if '_registrations' in state and '__bases__' not in state:
+            # convert data to generation 3 data structure:
+            next = state.get('next')
+            if next is None:
+                next = state['base']
+            bases = (next, )
+            self.__init__(bases)
+            registrations = []
+            for r in state['_registrations']:
+                if isinstance(r, UtilityRegistration):
+                    self.register((), r.provided, r.name, r.component)
+
+                    if not [
+                        1 for rseen in registrations
+                        if rseen.provided == r.provided
+                           and rseen.component == r.component
+                        ]:
+                        self.subscribe((), r.provided, r.component)
+
+                    registrations.append(r)
+                else:
+                    warnings.warn(
+                        "Old %s registrations are not supported and will not "
+                        "be converted" % r.__class__.__name__,
+                        DeprecationWarning)
+
+            self._registrations = tuple(registrations)
+        else:
+            super(_LocalAdapterRegistryGeneration3SupportMixin, self
+                  ).__setstate__(state)
+

Deleted: zope.app.component/tags/3.4.2/src/zope/app/component/site.py
===================================================================
--- zope.app.component/tags/3.4.x/src/zope/app/component/site.py	2009-07-15 17:24:15 UTC (rev 101927)
+++ zope.app.component/tags/3.4.2/src/zope/app/component/site.py	2009-07-15 18:56:04 UTC (rev 101933)
@@ -1,417 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Site and Local Site Manager implementation
-
-A local site manager has a number of roles:
-
-  - A local site manager, that provides a local adapter and utility registry.
-
-  - A place to do TTW development and/or to manage database-based code.
-
-  - A registry for persistent modules.  The Zope 3 import hook uses the
-    SiteManager to search for modules.
-
-$Id$
-"""
-
-import zope.event
-import zope.interface
-import zope.component
-import zope.component.persistentregistry
-import zope.component.interfaces
-import zope.traversing.api
-import zope.deprecation
-import zope.deferredimport
-import zope.location
-
-from zope.component.interfaces import ComponentLookupError
-from zope.traversing.interfaces import IContainmentRoot
-from zope.lifecycleevent import ObjectCreatedEvent
-from zope.filerepresentation.interfaces import IDirectoryFactory
-
-import zope.app.component.back35
-from zope.app.component import interfaces
-from zope.app.component import registration
-from zope.app.component.hooks import setSite
-from zope.app.container.btree import BTreeContainer
-from zope.app.container.contained import Contained
-
-##############################################################################
-# from zope.app.module import resolve
-
-# Break the dependency on zope.app.module.  In the long run,
-# we need to handle this better.  Perhaps througha utility.
-
-## def findModule(name, context=None):
-##     """Find the module matching the provided name."""
-##     module = ZopeModuleRegistry.findModule(name)
-##     return module or sys.modules.get(name)
-
-import sys
-
-def resolve(name, context=None):
-    """Resolve a dotted name to a Python object."""
-    pos = name.rfind('.')
-    mod = sys.modules.get(name[:pos])
-##    mod = findModule(name[:pos], context)
-    return getattr(mod, name[pos+1:], None)
-
-# from zope.app.module import resolve
-##############################################################################
-
-class SiteManagementFolder(zope.app.component.back35.RegisterableContainer,
-                           BTreeContainer):
-    zope.interface.implements(interfaces.ISiteManagementFolder)
-
-
-class SMFolderFactory(object):
-    zope.interface.implements(IDirectoryFactory)
-
-    def __init__(self, context):
-        self.context = context
-
-    def __call__(self, name):
-        return SiteManagementFolder()
-
-
-class SiteManagerContainer(Contained):
-    """Implement access to the site manager (++etc++site).
-
-    This is a mix-in that implements the IPossibleSite
-    interface; for example, it is used by the Folder implementation.
-    """
-    zope.interface.implements(interfaces.IPossibleSite)
-
-    _sm = None
-
-    def getSiteManager(self):
-        if self._sm is not None:
-            return self._sm
-        else:
-            raise ComponentLookupError('no site manager defined')
-
-    def setSiteManager(self, sm):
-        if interfaces.ISite.providedBy(self):
-            raise TypeError("Already a site")
-
-        if zope.component.interfaces.IComponentLookup.providedBy(sm):
-            self._sm = sm
-            sm.__name__ = '++etc++site'
-            sm.__parent__ = self
-        else:
-            raise ValueError('setSiteManager requires an IComponentLookup')
-
-        zope.interface.directlyProvides(
-            self, interfaces.ISite,
-            zope.interface.directlyProvidedBy(self))
-
-        zope.event.notify(interfaces.NewLocalSite(sm))
-
-def _findNextSiteManager(site):
-    while True:
-        if IContainmentRoot.providedBy(site):
-            # we're the root site, return None
-            return None
-
-        try:
-            site = zope.traversing.api.getParent(site)
-        except TypeError:
-            # there was not enough context; probably run from a test
-            return None
-
-        if interfaces.ISite.providedBy(site):
-            return site.getSiteManager()
-
-
-class _LocalAdapterRegistry(
-    zope.app.component.back35._LocalAdapterRegistryGeneration3SupportMixin,
-    zope.component.persistentregistry.PersistentAdapterRegistry,
-    zope.location.Location,
-    ):
-    pass
-
-class LocalSiteManager(
-    BTreeContainer,
-    zope.app.component.back35.LocalSiteGeneration3SupportMixin,
-    zope.component.persistentregistry.PersistentComponents,
-    ):
-    """Local Site Manager implementation"""
-    zope.interface.implements(interfaces.ILocalSiteManager)
-
-    subs = ()
-
-    @property
-    @zope.deprecation.deprecate("Goes away in Zope 3.5.  Use __bases__[0]")
-    def next(self):
-        if self.__bases__:
-            return self.__bases__[0]
-
-    def _setBases(self, bases):
-
-        # Update base subs
-        for base in self.__bases__:
-            if ((base not in bases)
-                and interfaces.ILocalSiteManager.providedBy(base)
-                ):
-                base.removeSub(self)
-
-        for base in bases:
-            if ((base not in self.__bases__)
-                and interfaces.ILocalSiteManager.providedBy(base)
-                ):
-                base.addSub(self)
-
-        super(LocalSiteManager, self)._setBases(bases)
-
-    def __init__(self, site):
-        # Locate the site manager
-        self.__parent__ = site
-        self.__name__ = '++etc++site'
-
-        BTreeContainer.__init__(self)
-        zope.component.persistentregistry.PersistentComponents.__init__(self)
-        
-        next = _findNextSiteManager(site)
-        if next is None:
-            next = zope.component.getGlobalSiteManager()
-        self.__bases__ = (next, )
-
-        # Setup default site management folder
-        folder = SiteManagementFolder()
-        zope.event.notify(ObjectCreatedEvent(folder))
-        self['default'] = folder
-
-    def _init_registries(self):
-        self.adapters = _LocalAdapterRegistry()
-        self.utilities = _LocalAdapterRegistry()
-        self.adapters.__parent__ = self.utilities.__parent__ = self
-        self.adapters.__name__ = u'adapters'
-        self.utilities.__name__ = u'utilities'
-
-    def addSub(self, sub):
-        """See interfaces.registration.ILocatedRegistry"""
-        self.subs += (sub, )
-
-    def removeSub(self, sub):
-        """See interfaces.registration.ILocatedRegistry"""
-        self.subs = tuple(
-            [s for s in self.subs if s is not sub] )
-
-    @zope.deprecation.deprecate("Will go away in Zope 3.5")
-    def setNext(self, next, base=None):
-        self.__bases__ = tuple([b for b in (next, base) if b is not None])
-
-    def __getRegistry(self, registration):
-        """Determine the correct registry for the registration."""
-        if interfaces.IUtilityRegistration.providedBy(registration):
-            return self.utilities
-        elif interfaces.IAdapterRegistration.providedBy(registration):
-            return self.adapters
-        raise ValueError("Unable to detect registration type or registration "
-                         "type is not supported. The registration object must "
-                         "provide `IAdapterRegistration` or "
-                         "`IUtilityRegistration`.")
-
-    @zope.deprecation.deprecate(
-        "Local registration is now much simpler.  The old baroque APIs "
-        "will go away in Zope 3.5.  See the new component-registration APIs "
-        "defined in zope.component, especially IComponentRegistry.",
-        )
-    def register(self, registration):
-        if interfaces.IUtilityRegistration.providedBy(registration):
-            self.registerUtility(
-                registration.component,
-                registration.provided,
-                registration.name,
-                )
-        elif interfaces.IAdapterRegistration.providedBy(registration):
-            self.registerAdapter(
-                registration.component,
-                (registration.required, ) + registration.with,
-                registration.provided,
-                registration.name,
-                )
-        try:
-            f = registration.activated
-        except AttributeError:
-            pass
-        else:
-            f()
-
-    @zope.deprecation.deprecate(
-        "Local registration is now much simpler.  The old baroque APIs "
-        "will go away in Zope 3.5.  See the new component-registration APIs "
-        "defined in zope.component, especially IComponentRegistry.",
-        )
-    def unregister(self, registration):
-        if interfaces.IUtilityRegistration.providedBy(registration):
-            self.unregisterUtility(
-                registration.component,
-                registration.provided,
-                registration.name,
-                )
-        elif interfaces.IAdapterRegistration.providedBy(registration):
-            self.unregisterAdapter(
-                registration.component,
-                (registration.required, ) + registration.with,
-                registration.provided,
-                registration.name,
-                )
-        try:
-            f = registration.deactivated
-        except AttributeError:
-            pass
-        else:
-            f()
-
-    @zope.deprecation.deprecate(
-        "Local registration is now much simpler.  The old baroque APIs "
-        "will go away in Zope 3.5.  See the new component-registration APIs "
-        "defined in zope.component, especially IComponentRegistry.",
-        )
-    def registered(self, registration):
-        if zope.component.interfaces.IUtilityRegistration.providedBy(
-            registration):
-            return bool([
-                r for r in self.registeredUtilities()
-                if (
-                   r.component == registration.component
-                   and
-                   r.provided == registration.provided
-                   and
-                   r.name == registration.name
-                )
-                ])
-        elif zope.component.interfaces.IAdapterRegistration.providedBy(
-            registration):
-            return bool([
-                r for r in self.registeredAdapters()
-                if (
-                   r.factory == registration.component
-                   and
-                   r.provided == registration.provided
-                   and
-                   r.name == registration.name
-                   and
-                   r.required == ((registration.required, )
-                                  + registration.with)
-                )
-                ])
-        elif (
-         zope.component.interfaces.ISubscriptionAdapterRegistration.providedBy(
-            registration)):
-            return bool([
-                r for r in self.registeredSubscriptionAdapters()
-                if (
-                   r.factory == registration.component
-                   and
-                   r.provided == registration.provided
-                   and
-                   r.name == registration.name
-                   and
-                   r.required == ((registration.required, )
-                                  + registration.with)
-                )
-                ])
-        elif zope.component.interfaces.IHandlerRegistration.providedBy(
-            registration):
-            return bool([
-                r for r in self.registeredHandlers()
-                if (
-                   r.factory == registration.component
-                   and
-                   r.provided == registration.provided
-                   and
-                   r.name == registration.name
-                   and
-                   r.required == ((registration.required, )
-                                  + registration.with)
-                )
-                ])
-        return False
-
-    @zope.deprecation.deprecate(
-        "Local registration is now much simpler.  The old baroque APIs "
-        "will go away in Zope 3.5.  See the new component-registration APIs "
-        "defined in zope.component, especially IComponentRegistry.",
-        )
-    def registrations(self):
-        """See zope.component.interfaces.IRegistry"""
-        for r in self.registeredUtilities():
-            yield r
-        for r in self.registeredAdapters():
-            yield r
-        for r in self.registeredHandlers():
-            yield r
-        for r in self.registeredSubscriptionAdapters():
-            yield r
-
-zope.deferredimport.deprecated(
-    "Local registration is now much simpler.  The old baroque APIs "
-    "will go away in Zope 3.5.  See the new component-registration APIs "
-    "defined in zope.component, especially IComponentRegistry.",
-    LocalAdapterRegistry = 'zope.app.component.site:_LocalAdapterRegistry',
-    LocalUtilityRegistry = 'zope.app.component.site:_LocalAdapterRegistry',
-    UtilityRegistration = 'zope.app.component.back35:UtilityRegistration',
-    AdaptersRegistration = 'zope.app.component.back35:AdaptersRegistration',
-    )
-
-def threadSiteSubscriber(ob, event):
-    """A subscriber to BeforeTraverseEvent
-
-    Sets the 'site' thread global if the object traversed is a site.
-    """
-    setSite(ob)
-
-
-def clearThreadSiteSubscriber(event):
-    """A subscriber to EndRequestEvent
-
-    Cleans up the site thread global after the request is processed.
-    """
-    clearSite()
-
-# Clear the site thread global
-clearSite = setSite
-try:
-    from zope.testing.cleanup import addCleanUp
-except ImportError:
-    pass
-else:
-    addCleanUp(clearSite)
-
-
- at zope.component.adapter(zope.interface.Interface)
- at zope.interface.implementer(zope.component.interfaces.IComponentLookup)
-def SiteManagerAdapter(ob):
-    """An adapter from ILocation to IComponentLookup.
-
-    The ILocation is interpreted flexibly, we just check for
-    ``__parent__``.
-    """
-    current = ob
-    while True:
-        if interfaces.ISite.providedBy(current):
-            return current.getSiteManager()
-        current = getattr(current, '__parent__', None)
-        if current is None:
-            # It is not a location or has no parent, so we return the global
-            # site manager
-            return zope.component.getGlobalSiteManager()
-
-def changeSiteConfigurationAfterMove(site, event):
-    """After a site is moved, its site manager links have to be updated."""
-    if event.newParent is not None:
-        next = _findNextSiteManager(site)
-        site.getSiteManager().__bases__ = (next, )

Copied: zope.app.component/tags/3.4.2/src/zope/app/component/site.py (from rev 101931, zope.app.component/tags/3.4.x/src/zope/app/component/site.py)
===================================================================
--- zope.app.component/tags/3.4.2/src/zope/app/component/site.py	                        (rev 0)
+++ zope.app.component/tags/3.4.2/src/zope/app/component/site.py	2009-07-15 18:56:04 UTC (rev 101933)
@@ -0,0 +1,423 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Site and Local Site Manager implementation
+
+A local site manager has a number of roles:
+
+  - A local site manager, that provides a local adapter and utility registry.
+
+  - A place to do TTW development and/or to manage database-based code.
+
+  - A registry for persistent modules.  The Zope 3 import hook uses the
+    SiteManager to search for modules.
+
+$Id$
+"""
+
+import zope.event
+import zope.interface
+import zope.component
+import zope.component.persistentregistry
+import zope.component.interfaces
+import zope.traversing.api
+import zope.deprecation
+import zope.deferredimport
+import zope.location
+
+from zope.component.interfaces import ComponentLookupError
+from zope.traversing.interfaces import IContainmentRoot
+from zope.lifecycleevent import ObjectCreatedEvent
+from zope.filerepresentation.interfaces import IDirectoryFactory
+
+import zope.app.component.back35
+from zope.app.component import interfaces
+from zope.app.component import registration
+from zope.app.component.hooks import setSite
+from zope.app.container.btree import BTreeContainer
+from zope.app.container.contained import Contained
+
+##############################################################################
+# from zope.app.module import resolve
+
+# Break the dependency on zope.app.module.  In the long run,
+# we need to handle this better.  Perhaps througha utility.
+
+## def findModule(name, context=None):
+##     """Find the module matching the provided name."""
+##     module = ZopeModuleRegistry.findModule(name)
+##     return module or sys.modules.get(name)
+
+import sys
+
+def resolve(name, context=None):
+    """Resolve a dotted name to a Python object."""
+    pos = name.rfind('.')
+    mod = sys.modules.get(name[:pos])
+##    mod = findModule(name[:pos], context)
+    return getattr(mod, name[pos+1:], None)
+
+# from zope.app.module import resolve
+##############################################################################
+
+class SiteManagementFolder(zope.app.component.back35.RegisterableContainer,
+                           BTreeContainer):
+    zope.interface.implements(interfaces.ISiteManagementFolder)
+
+
+class SMFolderFactory(object):
+    zope.interface.implements(IDirectoryFactory)
+
+    def __init__(self, context):
+        self.context = context
+
+    def __call__(self, name):
+        return SiteManagementFolder()
+
+
+class SiteManagerContainer(Contained):
+    """Implement access to the site manager (++etc++site).
+
+    This is a mix-in that implements the IPossibleSite
+    interface; for example, it is used by the Folder implementation.
+    """
+    zope.interface.implements(interfaces.IPossibleSite)
+
+    _sm = None
+
+    def getSiteManager(self):
+        if self._sm is not None:
+            return self._sm
+        else:
+            raise ComponentLookupError('no site manager defined')
+
+    def setSiteManager(self, sm):
+        if interfaces.ISite.providedBy(self):
+            raise TypeError("Already a site")
+
+        if zope.component.interfaces.IComponentLookup.providedBy(sm):
+            self._sm = sm
+            sm.__name__ = '++etc++site'
+            sm.__parent__ = self
+        else:
+            raise ValueError('setSiteManager requires an IComponentLookup')
+
+        zope.interface.directlyProvides(
+            self, interfaces.ISite,
+            zope.interface.directlyProvidedBy(self))
+
+        zope.event.notify(interfaces.NewLocalSite(sm))
+
+def _findNextSiteManager(site):
+    while True:
+        if IContainmentRoot.providedBy(site):
+            # we're the root site, return None
+            return None
+
+        try:
+            site = zope.traversing.api.getParent(site)
+        except TypeError:
+            # there was not enough context; probably run from a test
+            return None
+
+        if interfaces.ISite.providedBy(site):
+            return site.getSiteManager()
+
+
+class _LocalAdapterRegistry(
+    zope.app.component.back35._LocalAdapterRegistryGeneration3SupportMixin,
+    zope.component.persistentregistry.PersistentAdapterRegistry,
+    zope.location.Location,
+    ):
+    pass
+
+class LocalSiteManager(
+    BTreeContainer,
+    zope.app.component.back35.LocalSiteGeneration3SupportMixin,
+    zope.component.persistentregistry.PersistentComponents,
+    ):
+    """Local Site Manager implementation"""
+    zope.interface.implements(interfaces.ILocalSiteManager)
+
+    subs = ()
+
+    @property
+    @zope.deprecation.deprecate("Goes away in Zope 3.5.  Use __bases__[0]")
+    def next(self):
+        if self.__bases__:
+            return self.__bases__[0]
+
+    def _setBases(self, bases):
+
+        # Update base subs
+        for base in self.__bases__:
+            if ((base not in bases)
+                and interfaces.ILocalSiteManager.providedBy(base)
+                ):
+                base.removeSub(self)
+
+        for base in bases:
+            if ((base not in self.__bases__)
+                and interfaces.ILocalSiteManager.providedBy(base)
+                ):
+                base.addSub(self)
+
+        super(LocalSiteManager, self)._setBases(bases)
+
+    def __init__(self, site):
+        # Locate the site manager
+        self.__parent__ = site
+        self.__name__ = '++etc++site'
+
+        BTreeContainer.__init__(self)
+        zope.component.persistentregistry.PersistentComponents.__init__(self)
+        
+        next = _findNextSiteManager(site)
+        if next is None:
+            next = zope.component.getGlobalSiteManager()
+        self.__bases__ = (next, )
+
+        # Setup default site management folder
+        folder = SiteManagementFolder()
+        zope.event.notify(ObjectCreatedEvent(folder))
+        self['default'] = folder
+
+    def __setstate__(self, state):
+        if not state.get('__bases__'):
+            next = zope.component.getGlobalSiteManager()
+            state['__bases__'] = (next, )
+        super(LocalSiteManager, self).__setstate__(state)
+
+    def _init_registries(self):
+        self.adapters = _LocalAdapterRegistry()
+        self.utilities = _LocalAdapterRegistry()
+        self.adapters.__parent__ = self.utilities.__parent__ = self
+        self.adapters.__name__ = u'adapters'
+        self.utilities.__name__ = u'utilities'
+
+    def addSub(self, sub):
+        """See interfaces.registration.ILocatedRegistry"""
+        self.subs += (sub, )
+
+    def removeSub(self, sub):
+        """See interfaces.registration.ILocatedRegistry"""
+        self.subs = tuple(
+            [s for s in self.subs if s is not sub] )
+
+    @zope.deprecation.deprecate("Will go away in Zope 3.5")
+    def setNext(self, next, base=None):
+        self.__bases__ = tuple([b for b in (next, base) if b is not None])
+
+    def __getRegistry(self, registration):
+        """Determine the correct registry for the registration."""
+        if interfaces.IUtilityRegistration.providedBy(registration):
+            return self.utilities
+        elif interfaces.IAdapterRegistration.providedBy(registration):
+            return self.adapters
+        raise ValueError("Unable to detect registration type or registration "
+                         "type is not supported. The registration object must "
+                         "provide `IAdapterRegistration` or "
+                         "`IUtilityRegistration`.")
+
+    @zope.deprecation.deprecate(
+        "Local registration is now much simpler.  The old baroque APIs "
+        "will go away in Zope 3.5.  See the new component-registration APIs "
+        "defined in zope.component, especially IComponentRegistry.",
+        )
+    def register(self, registration):
+        if interfaces.IUtilityRegistration.providedBy(registration):
+            self.registerUtility(
+                registration.component,
+                registration.provided,
+                registration.name,
+                )
+        elif interfaces.IAdapterRegistration.providedBy(registration):
+            self.registerAdapter(
+                registration.component,
+                (registration.required, ) + registration.with,
+                registration.provided,
+                registration.name,
+                )
+        try:
+            f = registration.activated
+        except AttributeError:
+            pass
+        else:
+            f()
+
+    @zope.deprecation.deprecate(
+        "Local registration is now much simpler.  The old baroque APIs "
+        "will go away in Zope 3.5.  See the new component-registration APIs "
+        "defined in zope.component, especially IComponentRegistry.",
+        )
+    def unregister(self, registration):
+        if interfaces.IUtilityRegistration.providedBy(registration):
+            self.unregisterUtility(
+                registration.component,
+                registration.provided,
+                registration.name,
+                )
+        elif interfaces.IAdapterRegistration.providedBy(registration):
+            self.unregisterAdapter(
+                registration.component,
+                (registration.required, ) + registration.with,
+                registration.provided,
+                registration.name,
+                )
+        try:
+            f = registration.deactivated
+        except AttributeError:
+            pass
+        else:
+            f()
+
+    @zope.deprecation.deprecate(
+        "Local registration is now much simpler.  The old baroque APIs "
+        "will go away in Zope 3.5.  See the new component-registration APIs "
+        "defined in zope.component, especially IComponentRegistry.",
+        )
+    def registered(self, registration):
+        if zope.component.interfaces.IUtilityRegistration.providedBy(
+            registration):
+            return bool([
+                r for r in self.registeredUtilities()
+                if (
+                   r.component == registration.component
+                   and
+                   r.provided == registration.provided
+                   and
+                   r.name == registration.name
+                )
+                ])
+        elif zope.component.interfaces.IAdapterRegistration.providedBy(
+            registration):
+            return bool([
+                r for r in self.registeredAdapters()
+                if (
+                   r.factory == registration.component
+                   and
+                   r.provided == registration.provided
+                   and
+                   r.name == registration.name
+                   and
+                   r.required == ((registration.required, )
+                                  + registration.with)
+                )
+                ])
+        elif (
+         zope.component.interfaces.ISubscriptionAdapterRegistration.providedBy(
+            registration)):
+            return bool([
+                r for r in self.registeredSubscriptionAdapters()
+                if (
+                   r.factory == registration.component
+                   and
+                   r.provided == registration.provided
+                   and
+                   r.name == registration.name
+                   and
+                   r.required == ((registration.required, )
+                                  + registration.with)
+                )
+                ])
+        elif zope.component.interfaces.IHandlerRegistration.providedBy(
+            registration):
+            return bool([
+                r for r in self.registeredHandlers()
+                if (
+                   r.factory == registration.component
+                   and
+                   r.provided == registration.provided
+                   and
+                   r.name == registration.name
+                   and
+                   r.required == ((registration.required, )
+                                  + registration.with)
+                )
+                ])
+        return False
+
+    @zope.deprecation.deprecate(
+        "Local registration is now much simpler.  The old baroque APIs "
+        "will go away in Zope 3.5.  See the new component-registration APIs "
+        "defined in zope.component, especially IComponentRegistry.",
+        )
+    def registrations(self):
+        """See zope.component.interfaces.IRegistry"""
+        for r in self.registeredUtilities():
+            yield r
+        for r in self.registeredAdapters():
+            yield r
+        for r in self.registeredHandlers():
+            yield r
+        for r in self.registeredSubscriptionAdapters():
+            yield r
+
+zope.deferredimport.deprecated(
+    "Local registration is now much simpler.  The old baroque APIs "
+    "will go away in Zope 3.5.  See the new component-registration APIs "
+    "defined in zope.component, especially IComponentRegistry.",
+    LocalAdapterRegistry = 'zope.app.component.site:_LocalAdapterRegistry',
+    LocalUtilityRegistry = 'zope.app.component.site:_LocalAdapterRegistry',
+    UtilityRegistration = 'zope.app.component.back35:UtilityRegistration',
+    AdaptersRegistration = 'zope.app.component.back35:AdaptersRegistration',
+    )
+
+def threadSiteSubscriber(ob, event):
+    """A subscriber to BeforeTraverseEvent
+
+    Sets the 'site' thread global if the object traversed is a site.
+    """
+    setSite(ob)
+
+
+def clearThreadSiteSubscriber(event):
+    """A subscriber to EndRequestEvent
+
+    Cleans up the site thread global after the request is processed.
+    """
+    clearSite()
+
+# Clear the site thread global
+clearSite = setSite
+try:
+    from zope.testing.cleanup import addCleanUp
+except ImportError:
+    pass
+else:
+    addCleanUp(clearSite)
+
+
+ at zope.component.adapter(zope.interface.Interface)
+ at zope.interface.implementer(zope.component.interfaces.IComponentLookup)
+def SiteManagerAdapter(ob):
+    """An adapter from ILocation to IComponentLookup.
+
+    The ILocation is interpreted flexibly, we just check for
+    ``__parent__``.
+    """
+    current = ob
+    while True:
+        if interfaces.ISite.providedBy(current):
+            return current.getSiteManager()
+        current = getattr(current, '__parent__', None)
+        if current is None:
+            # It is not a location or has no parent, so we return the global
+            # site manager
+            return zope.component.getGlobalSiteManager()
+
+def changeSiteConfigurationAfterMove(site, event):
+    """After a site is moved, its site manager links have to be updated."""
+    if event.newParent is not None:
+        next = _findNextSiteManager(site)
+        site.getSiteManager().__bases__ = (next, )

Deleted: zope.app.component/tags/3.4.2/src/zope/app/component/tests/test_registration.py
===================================================================
--- zope.app.component/tags/3.4.x/src/zope/app/component/tests/test_registration.py	2009-07-15 17:24:15 UTC (rev 101927)
+++ zope.app.component/tags/3.4.2/src/zope/app/component/tests/test_registration.py	2009-07-15 18:56:04 UTC (rev 101933)
@@ -1,508 +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 os
-import unittest
-import warnings
-
-from ZODB.DB import DB
-import ZODB.FileStorage
-from ZODB.DemoStorage import DemoStorage
-import transaction
-import persistent
-
-import zope.component.globalregistry
-import zope.component.testing as placelesssetup
-from zope.testing import doctest
-from zope.app.testing import setup
-import zope.app.container.contained
-from zope import interface
-
-import zope.app.component.site
-
-
-# test class for testing data conversion
-class IFoo(interface.Interface):
-    pass
-class Foo(persistent.Persistent, zope.app.container.contained.Contained):
-    interface.implements(IFoo)
-    name = ''
-    def __init__(self, name=''):
-        self.name = name
-
-    def __repr__(self):
-        return 'Foo(%r)' % self.name
-
-def setUpOld(test):
-    placelesssetup.setUp(test)
-    setup.setUpAnnotations()
-    setup.setUpDependable()
-    setup.setUpTraversal()
-    test.globs['showwarning'] = warnings.showwarning
-    warnings.showwarning = lambda *a, **k: None
-
-def tearDown(test):
-    warnings.showwarning = test.globs['showwarning']
-    placelesssetup.tearDown(test)
-
-def setUp(test):
-    placelesssetup.setUp(test)
-    test.globs['showwarning'] = warnings.showwarning
-    warnings.showwarning = lambda *a, **k: None
-
-def oldfs():
-    return FileStorage(
-        os.path.join(os.path.dirname(__file__), 'gen3.fs'),
-        read_only=True,
-        )
-
-# Work around a bug in ZODB
-# XXX fix ZODB
-class FileStorage(ZODB.FileStorage.FileStorage):
-    
-    def new_oid(self):
-        self._lock_acquire()
-        try:
-            last = self._oid
-            d = ord(last[-1])
-            if d < 255:  # fast path for the usual case
-                last = last[:-1] + chr(d+1)
-            else:        # there's a carry out of the last byte
-                last_as_long, = _structunpack(">Q", last)
-                last = _structpack(">Q", last_as_long + 1)
-            self._oid = last
-            return last
-        finally:
-             self._lock_release()
- 
-
-def test_old_databases_backward_compat():
-    """
-
-Let's open an old database and get the 3 site managers in it:
-
-    >>> fs = oldfs()
-    >>> demo = DemoStorage(base=fs)
-    >>> db = DB(demo)
-    >>> tm = transaction.TransactionManager()
-    >>> root = db.open(transaction_manager=tm).root()
-    >>> _ = tm.begin()
-    
-    >>> sm1 = root['Application'].getSiteManager()
-    >>> [sm2] = sm1.subs
-    >>> [sm3] = sm2.subs
-
-We can look up utilities as we expect:
-
-    >>> sm1.getUtility(IFoo, '1') is sm1['default']['1']
-    True
-
-    >>> sm3.getUtility(IFoo, '3') is sm3['default']['3']
-    True
-
-    >>> sm2.getUtility(IFoo, '2') is sm2['default']['2']
-    True
-
-    >>> sm1.getUtility(IFoo, '2') is sm1['default']['2']
-    True
-
-    >>> sm1.getUtility(IFoo, '3') is sm1['default']['3']
-    True
-
-    >>> sm2.getUtility(IFoo, '3') is sm2['default']['3']
-    True
-
-    >>> sm2.getUtility(IFoo, '4') is sm2['default']['4']
-    True
-
-    >>> sm3.getUtility(IFoo, '4') is sm3['default']['4']
-    True
-
-    >>> sm3.getUtility(IFoo, '5') is sm3['default']['5']
-    True
-
-and we get registration info:
-
-    >>> sorted([r.name for r in sm2.registeredUtilities()])
-    [u'2', u'3', u'4']
-
-We don't have any adapter or subscriber information, because it wasn't
-previously supported to register those:
-
-    >>> len(list(sm2.registeredAdapters()))
-    0
-    >>> len(list(sm2.registeredSubscriptionAdapters()))
-    0
-    >>> len(list(sm2.registeredHandlers()))
-    0
-
-We haven't modified anything yet.  We can see this in a number of
-ways.  If we look at the internal data structured used, we can see
-that they are weird:
-
-    >>> sm2._utility_registrations.__class__.__name__
-    '_OldUtilityRegistrations'
-
-    >>> sm2._adapter_registrations.__class__.__name__
-    '_OldAdapterRegistrations'
-
-    >>> sm2._subscription_registrations.__class__.__name__
-    '_OldSubscriberRegistrations'
-
-    >>> sm2._handler_registrations.__class__.__name__
-    '_OldSubscriberRegistrations'
-
-and the registries have a _registrations attribute, which is a sign
-that they haven't been converted yet:
-
-    >>> hasattr(sm2.utilities, '_registrations')
-    True
-
-    >>> hasattr(sm2.adapters, '_registrations')
-    True
-
-We'll commit the transaction and make sure the database hasn't
-grown. (This relies on a buglet in DemoStorage length computation.)
-
-    >>> tm.commit()
-    >>> len(demo) == len(fs)
-    True
-
-Of course, we can register new utilities:
-
-    >>> _ = tm.begin()
-    >>> sm1.registerUtility(Foo('one'), IFoo, '1')
-    >>> sm2.registerUtility(Foo('two'), IFoo, '2')
-    >>> tm.commit()
-
-We should then be able to look up the newly registered utilities.
-Let's try to do so in a separate connection:
-
-    >>> tm2 = transaction.TransactionManager()
-    >>> root2 = db.open(transaction_manager=tm2).root()
-    >>> _ = tm2.begin()
-    
-    >>> sm1 = root2['Application'].getSiteManager()
-    >>> [sm2] = sm1.subs
-    >>> [sm3] = sm2.subs
-
-    >>> sm1.getUtility(IFoo, '1').name
-    'one'
-
-    >>> sm2.getUtility(IFoo, '2').name
-    'two'
-
-    >>> sm1.getUtility(IFoo, '2') is sm1['default']['2']
-    True
-
-    >>> sm1.getUtility(IFoo, '3') is sm1['default']['3']
-    True
-
-    >>> sm2.getUtility(IFoo, '3') is sm2['default']['3']
-    True
-
-    >>> sm2.getUtility(IFoo, '4') is sm2['default']['4']
-    True
-
-    >>> sm3.getUtility(IFoo, '4') is sm3['default']['4']
-    True
-
-    >>> sm3.getUtility(IFoo, '5') is sm3['default']['5']
-    True
-
-    >>> sorted([r.name for r in sm2.registeredUtilities()])
-    [u'2', u'3', u'4']
-
-
-Because we registered utilities, the corresponding data structures
-have been updated:
-
-    >>> sm2._utility_registrations.__class__.__name__
-    'PersistentMapping'
-
-    >>> hasattr(sm2.utilities, '_registrations')
-    False
-
-But other data structures haven't been effected:
-
-    >>> sm2._adapter_registrations.__class__.__name__
-    '_OldAdapterRegistrations'
-
-    >>> hasattr(sm2.adapters, '_registrations')
-    True
-
-Nor, of course, have the data structures for sites that we haven't
-changed:
-
-    >>> sm3._utility_registrations.__class__.__name__
-    '_OldUtilityRegistrations'
-
-    >>> hasattr(sm3.utilities, '_registrations')
-    True
-
-The _evolve_to_generation_4 method actually converts the remaining
-data structures. It also evolves all of it's subsites:
-
-    >>> sm1._evolve_to_generation_4()
-    >>> tm2.commit()
-
-and we see that all of the data structures have been converted:
-
-    >>> sm1._utility_registrations.__class__.__name__
-    'PersistentMapping'
-    >>> sm1._adapter_registrations.__class__.__name__
-    'PersistentMapping'
-    >>> sm1._subscription_registrations.__class__.__name__
-    'PersistentList'
-    >>> sm1._handler_registrations.__class__.__name__
-    'PersistentList'
-    >>> hasattr(sm1.utilities, '_registrations')
-    False
-    >>> hasattr(sm1.adapters, '_registrations')
-    False
-
-    >>> sm2._utility_registrations.__class__.__name__
-    'PersistentMapping'
-    >>> sm2._adapter_registrations.__class__.__name__
-    'PersistentMapping'
-    >>> sm2._subscription_registrations.__class__.__name__
-    'PersistentList'
-    >>> sm2._handler_registrations.__class__.__name__
-    'PersistentList'
-    >>> hasattr(sm2.utilities, '_registrations')
-    False
-    >>> hasattr(sm2.adapters, '_registrations')
-    False
-
-    >>> sm3._utility_registrations.__class__.__name__
-    'PersistentMapping'
-    >>> sm3._adapter_registrations.__class__.__name__
-    'PersistentMapping'
-    >>> sm3._subscription_registrations.__class__.__name__
-    'PersistentList'
-    >>> sm3._handler_registrations.__class__.__name__
-    'PersistentList'
-    >>> hasattr(sm3.utilities, '_registrations')
-    False
-    >>> hasattr(sm3.adapters, '_registrations')
-    False
-
-and that lookups still work as expected:
-
-
-    >>> sm1.getUtility(IFoo, '1').name
-    'one'
-
-    >>> sm2.getUtility(IFoo, '2').name
-    'two'
-
-    >>> sm1.getUtility(IFoo, '2') is sm1['default']['2']
-    True
-
-    >>> sm1.getUtility(IFoo, '3') is sm1['default']['3']
-    True
-
-    >>> sm2.getUtility(IFoo, '3') is sm2['default']['3']
-    True
-
-    >>> sm2.getUtility(IFoo, '4') is sm2['default']['4']
-    True
-
-    >>> sm3.getUtility(IFoo, '4') is sm3['default']['4']
-    True
-
-    >>> sm3.getUtility(IFoo, '5') is sm3['default']['5']
-    True
-
-getAllUtilitiesRegisteredFor should work too: :)
-
-    >>> all = list(sm3.getAllUtilitiesRegisteredFor(IFoo))
-    >>> all.remove(sm1['default']['1'])
-    >>> all.remove(sm1['default']['2'])
-    >>> all.remove(sm1['default']['3'])
-    >>> all.remove(sm2['default']['2'])
-    >>> all.remove(sm2['default']['3'])
-    >>> all.remove(sm2['default']['4'])
-    >>> all.remove(sm3['default']['3'])
-    >>> all.remove(sm3['default']['4'])
-    >>> all.remove(sm3['default']['5'])
-    >>> len(all)
-    2
-
-Cleanup:
-
-    >>> db.close()
-
-"""
-
-
-class GlobalRegistry:
-    pass
-
-base = zope.component.globalregistry.GlobalAdapterRegistry(
-    GlobalRegistry, 'adapters')
-GlobalRegistry.adapters = base
-def clear_base():
-    base.__init__(GlobalRegistry, 'adapters')
-    
-    
-def test_deghostification_of_persistent_adapter_registries():
-    """
-
-Note that this test duplicates one from zope.component.tests.
-We should be able to get rid of this one when we get rid of
-__setstate__ implementation we have in back35.
-    
-We want to make sure that we see updates corrextly.
-
-    >>> import ZODB.tests.util
-    >>> db = ZODB.tests.util.DB()
-    >>> tm1 = transaction.TransactionManager()
-    >>> c1 = db.open(transaction_manager=tm1)
-    >>> r1 = zope.app.component.site._LocalAdapterRegistry((base,))
-    >>> r2 = zope.app.component.site._LocalAdapterRegistry((r1,))
-    >>> c1.root()[1] = r1
-    >>> c1.root()[2] = r2
-    >>> tm1.commit()
-    >>> r1._p_deactivate()
-    >>> r2._p_deactivate()
-
-    >>> tm2 = transaction.TransactionManager()
-    >>> c2 = db.open(transaction_manager=tm2)
-    >>> r1 = c2.root()[1]
-    >>> r2 = c2.root()[2]
-
-    >>> r1.lookup((), IFoo, '')
-
-    >>> base.register((), IFoo, '', Foo(''))
-    >>> r1.lookup((), IFoo, '')
-    Foo('')
-
-    >>> r2.lookup((), IFoo, '1')
-
-    >>> r1.register((), IFoo, '1', Foo('1'))
-
-    >>> r2.lookup((), IFoo, '1')
-    Foo('1')
-
-    >>> r1.lookup((), IFoo, '2')
-    >>> r2.lookup((), IFoo, '2')
-
-    >>> base.register((), IFoo, '2', Foo('2'))
-    
-    >>> r1.lookup((), IFoo, '2')
-    Foo('2')
-
-    >>> r2.lookup((), IFoo, '2')
-    Foo('2')
-
-Cleanup:
-
-    >>> db.close()
-    >>> clear_base()
-
-    """
-
-barcode = """
-from zope.interface import Interface
-class IBar(Interface): pass
-class IBaz(Interface): pass
-"""
-
-class Bar(persistent.Persistent): pass
-class Baz(persistent.Persistent): pass
-
-def test_persistent_interfaces():
-    """
-Registrations for persistent interfaces are accessible from separate
-connections.
-
-Setup the DB and our first connection::
-
-    >>> import ZODB.tests.util
-    >>> db = ZODB.tests.util.DB()
-    >>> conn1 = db.open()
-    >>> root1 = conn1.root()
-
-Setup the persistent module registry and the local component
-registry::
-
-    >>> from zodbcode.module import ManagedRegistry
-    >>> registry = root1['registry'] = ManagedRegistry()
-    >>> from zope.component.persistentregistry import PersistentComponents
-    >>> manager = root1['manager'] = PersistentComponents()
-
-Create a persistent module::
-
-    >>> registry.newModule('barmodule', barcode)
-    >>> barmodule = registry.findModule('barmodule')
-
-Create a persistent instance::
-
-    >>> bar = root1['bar'] = Bar()
-    >>> from zope.interface import directlyProvides
-    >>> directlyProvides(bar, barmodule.IBar)
-    >>> from transaction import commit
-    >>> commit()
-
-Register an adapter::
-
-    >>> manager.queryAdapter(bar, barmodule.IBaz)
-    >>> manager.registerAdapter(Baz, [barmodule.IBar], barmodule.IBaz)
-    >>> manager.getAdapter(bar, barmodule.IBaz) # doctest: +ELLIPSIS
-    <zope.app.component.tests.test_registration.Baz object at ...>
-
-Before commit, the adapter is not available from another connection::
-
-    >>> conn2 = db.open()
-    >>> root2 = conn2.root()
-    >>> registry2 = root2['registry']
-    >>> barmodule2 = registry2.findModule('barmodule')
-    >>> bar2 = root2['bar']
-    >>> manager2 = root2['manager']
-    >>> manager2.queryAdapter(bar2, barmodule2.IBaz)
-
-After commit, it is::
-
-    >>> commit()
-    >>> conn2.sync()
-    >>> manager2.getAdapter(bar2, barmodule2.IBaz)
-    ... # doctest: +ELLIPSIS
-    <zope.app.component.tests.test_registration.Baz object at ...>
-
-Cleanup::
-
-    >>> conn1.close()
-    >>> conn2.close()
-    >>> db.close()
-"""
-
-
-def test_suite():
-    suite = unittest.TestSuite((
-        doctest.DocFileSuite('deprecated35_statusproperty.txt',
-                             'deprecated35_registration.txt',
-                             setUp=setUpOld, tearDown=tearDown),
-        doctest.DocTestSuite(setUp=setUp, tearDown=tearDown)
-        ))
-    return suite
-
-
-if __name__ == "__main__":
-    unittest.main(defaultTest='test_suite')

Copied: zope.app.component/tags/3.4.2/src/zope/app/component/tests/test_registration.py (from rev 101931, zope.app.component/tags/3.4.x/src/zope/app/component/tests/test_registration.py)
===================================================================
--- zope.app.component/tags/3.4.2/src/zope/app/component/tests/test_registration.py	                        (rev 0)
+++ zope.app.component/tags/3.4.2/src/zope/app/component/tests/test_registration.py	2009-07-15 18:56:04 UTC (rev 101933)
@@ -0,0 +1,555 @@
+##############################################################################
+#
+# 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 os
+import unittest
+import warnings
+
+from ZODB.DB import DB
+import ZODB.FileStorage
+from ZODB.DemoStorage import DemoStorage
+import transaction
+import persistent
+
+import zope.component.globalregistry
+import zope.component.testing as placelesssetup
+from zope.testing import doctest
+from zope.app.testing import setup
+import zope.app.container.contained
+from zope import interface
+
+import zope.app.component.site
+
+
+# test class for testing data conversion
+class IFoo(interface.Interface):
+    pass
+class Foo(persistent.Persistent, zope.app.container.contained.Contained):
+    interface.implements(IFoo)
+    name = ''
+    def __init__(self, name=''):
+        self.name = name
+
+    def __repr__(self):
+        return 'Foo(%r)' % self.name
+
+def setUpOld(test):
+    placelesssetup.setUp(test)
+    setup.setUpAnnotations()
+    setup.setUpDependable()
+    setup.setUpTraversal()
+    test.globs['showwarning'] = warnings.showwarning
+    warnings.showwarning = lambda *a, **k: None
+
+def tearDown(test):
+    warnings.showwarning = test.globs['showwarning']
+    placelesssetup.tearDown(test)
+
+def setUp(test):
+    placelesssetup.setUp(test)
+    zope.component.provideUtility(Foo(), provides=IFoo, name='globalfoo')
+    test.globs['showwarning'] = warnings.showwarning
+    warnings.showwarning = lambda *a, **k: None
+
+def oldfs():
+    return FileStorage(
+        os.path.join(os.path.dirname(__file__), 'gen3.fs'),
+        read_only=True,
+        )
+
+# Work around a bug in ZODB
+# XXX fix ZODB
+class FileStorage(ZODB.FileStorage.FileStorage):
+    
+    def new_oid(self):
+        self._lock_acquire()
+        try:
+            last = self._oid
+            d = ord(last[-1])
+            if d < 255:  # fast path for the usual case
+                last = last[:-1] + chr(d+1)
+            else:        # there's a carry out of the last byte
+                last_as_long, = _structunpack(">Q", last)
+                last = _structpack(">Q", last_as_long + 1)
+            self._oid = last
+            return last
+        finally:
+             self._lock_release()
+ 
+
+def test_old_databases_backward_compat():
+    """
+
+Let's open an old database and get the 3 site managers in it:
+
+    >>> fs = oldfs()
+    >>> demo = DemoStorage(base=fs)
+    >>> db = DB(demo)
+    >>> tm = transaction.TransactionManager()
+    >>> root = db.open(transaction_manager=tm).root()
+    >>> _ = tm.begin()
+    
+    >>> sm1 = root['Application'].getSiteManager()
+    >>> [sm2] = sm1.subs
+    >>> [sm3] = sm2.subs
+
+We can look up utilities as we expect:
+
+    >>> sm1.getUtility(IFoo, '1') is sm1['default']['1']
+    True
+
+    >>> sm3.getUtility(IFoo, '3') is sm3['default']['3']
+    True
+
+    >>> sm2.getUtility(IFoo, '2') is sm2['default']['2']
+    True
+
+    >>> sm1.getUtility(IFoo, '2') is sm1['default']['2']
+    True
+
+    >>> sm1.getUtility(IFoo, '3') is sm1['default']['3']
+    True
+
+    >>> sm2.getUtility(IFoo, '3') is sm2['default']['3']
+    True
+
+    >>> sm2.getUtility(IFoo, '4') is sm2['default']['4']
+    True
+
+    >>> sm3.getUtility(IFoo, '4') is sm3['default']['4']
+    True
+
+    >>> sm3.getUtility(IFoo, '5') is sm3['default']['5']
+    True
+
+The bases are loaded correctly and therefore we can look up global utilities
+
+    >>> sm1.queryUtility(IFoo, 'globalfoo') is not None
+    True
+    >>> zope.app.component.queryNextUtility(sm1, IFoo, 'globalfoo') is not None
+    True
+
+and we get registration info:
+
+    >>> sorted([r.name for r in sm2.registeredUtilities()])
+    [u'2', u'3', u'4']
+
+We don't have any adapter or subscriber information, because it wasn't
+previously supported to register those:
+
+    >>> len(list(sm2.registeredAdapters()))
+    0
+    >>> len(list(sm2.registeredSubscriptionAdapters()))
+    0
+    >>> len(list(sm2.registeredHandlers()))
+    0
+
+We haven't modified anything yet.  We can see this in a number of
+ways.  If we look at the internal data structured used, we can see
+that they are weird:
+
+    >>> sm2._utility_registrations.__class__.__name__
+    '_OldUtilityRegistrations'
+
+    >>> sm2._adapter_registrations.__class__.__name__
+    '_OldAdapterRegistrations'
+
+    >>> sm2._subscription_registrations.__class__.__name__
+    '_OldSubscriberRegistrations'
+
+    >>> sm2._handler_registrations.__class__.__name__
+    '_OldSubscriberRegistrations'
+
+and the registries have a _registrations attribute, which is a sign
+that they haven't been converted yet:
+
+    >>> hasattr(sm2.utilities, '_registrations')
+    True
+
+    >>> hasattr(sm2.adapters, '_registrations')
+    True
+
+We'll commit the transaction and make sure the database hasn't
+grown. (This relies on a buglet in DemoStorage length computation.)
+
+    >>> tm.commit()
+    >>> len(demo) == len(fs)
+    True
+
+Of course, we can register new utilities:
+
+    >>> _ = tm.begin()
+    >>> sm1.registerUtility(Foo('one'), IFoo, '1')
+    >>> sm2.registerUtility(Foo('two'), IFoo, '2')
+    >>> tm.commit()
+
+We should then be able to look up the newly registered utilities.
+Let's try to do so in a separate connection:
+
+    >>> tm2 = transaction.TransactionManager()
+    >>> root2 = db.open(transaction_manager=tm2).root()
+    >>> _ = tm2.begin()
+    
+    >>> sm1 = root2['Application'].getSiteManager()
+    >>> [sm2] = sm1.subs
+    >>> [sm3] = sm2.subs
+
+    >>> sm1.getUtility(IFoo, '1').name
+    'one'
+
+    >>> sm2.getUtility(IFoo, '2').name
+    'two'
+
+    >>> sm1.getUtility(IFoo, '2') is sm1['default']['2']
+    True
+
+    >>> sm1.getUtility(IFoo, '3') is sm1['default']['3']
+    True
+
+    >>> sm2.getUtility(IFoo, '3') is sm2['default']['3']
+    True
+
+    >>> sm2.getUtility(IFoo, '4') is sm2['default']['4']
+    True
+
+    >>> sm3.getUtility(IFoo, '4') is sm3['default']['4']
+    True
+
+    >>> sm3.getUtility(IFoo, '5') is sm3['default']['5']
+    True
+
+    >>> sorted([r.name for r in sm2.registeredUtilities()])
+    [u'2', u'3', u'4']
+
+
+Because we registered utilities, the corresponding data structures
+have been updated:
+
+    >>> sm2._utility_registrations.__class__.__name__
+    'PersistentMapping'
+
+    >>> hasattr(sm2.utilities, '_registrations')
+    False
+
+But other data structures haven't been effected:
+
+    >>> sm2._adapter_registrations.__class__.__name__
+    '_OldAdapterRegistrations'
+
+    >>> hasattr(sm2.adapters, '_registrations')
+    True
+
+Nor, of course, have the data structures for sites that we haven't
+changed:
+
+    >>> sm3._utility_registrations.__class__.__name__
+    '_OldUtilityRegistrations'
+
+    >>> hasattr(sm3.utilities, '_registrations')
+    True
+
+The _evolve_to_generation_4 method actually converts the remaining
+data structures. It also evolves all of it's subsites:
+
+    >>> sm1._evolve_to_generation_4()
+    >>> tm2.commit()
+
+and we see that all of the data structures have been converted:
+
+    >>> sm1._utility_registrations.__class__.__name__
+    'PersistentMapping'
+    >>> sm1._adapter_registrations.__class__.__name__
+    'PersistentMapping'
+    >>> sm1._subscription_registrations.__class__.__name__
+    'PersistentList'
+    >>> sm1._handler_registrations.__class__.__name__
+    'PersistentList'
+    >>> hasattr(sm1.utilities, '_registrations')
+    False
+    >>> hasattr(sm1.adapters, '_registrations')
+    False
+
+    >>> sm2._utility_registrations.__class__.__name__
+    'PersistentMapping'
+    >>> sm2._adapter_registrations.__class__.__name__
+    'PersistentMapping'
+    >>> sm2._subscription_registrations.__class__.__name__
+    'PersistentList'
+    >>> sm2._handler_registrations.__class__.__name__
+    'PersistentList'
+    >>> hasattr(sm2.utilities, '_registrations')
+    False
+    >>> hasattr(sm2.adapters, '_registrations')
+    False
+
+    >>> sm3._utility_registrations.__class__.__name__
+    'PersistentMapping'
+    >>> sm3._adapter_registrations.__class__.__name__
+    'PersistentMapping'
+    >>> sm3._subscription_registrations.__class__.__name__
+    'PersistentList'
+    >>> sm3._handler_registrations.__class__.__name__
+    'PersistentList'
+    >>> hasattr(sm3.utilities, '_registrations')
+    False
+    >>> hasattr(sm3.adapters, '_registrations')
+    False
+
+and that lookups still work as expected:
+
+
+    >>> sm1.getUtility(IFoo, '1').name
+    'one'
+
+    >>> sm2.getUtility(IFoo, '2').name
+    'two'
+
+    >>> sm1.getUtility(IFoo, '2') is sm1['default']['2']
+    True
+
+    >>> sm1.getUtility(IFoo, '3') is sm1['default']['3']
+    True
+
+    >>> sm2.getUtility(IFoo, '3') is sm2['default']['3']
+    True
+
+    >>> sm2.getUtility(IFoo, '4') is sm2['default']['4']
+    True
+
+    >>> sm3.getUtility(IFoo, '4') is sm3['default']['4']
+    True
+
+    >>> sm3.getUtility(IFoo, '5') is sm3['default']['5']
+    True
+
+getAllUtilitiesRegisteredFor should work too: :)
+
+    >>> all = list(sm3.getAllUtilitiesRegisteredFor(IFoo))
+    >>> all.remove(sm1['default']['1'])
+    >>> all.remove(sm1['default']['2'])
+    >>> all.remove(sm1['default']['3'])
+    >>> all.remove(sm2['default']['2'])
+    >>> all.remove(sm2['default']['3'])
+    >>> all.remove(sm2['default']['4'])
+    >>> all.remove(sm3['default']['3'])
+    >>> all.remove(sm3['default']['4'])
+    >>> all.remove(sm3['default']['5'])
+    >>> len(all)
+    3
+
+Cleanup:
+
+    >>> db.close()
+
+"""
+
+
+def test_old_databases_backward_compat_shoot_self_in_foot():
+    """
+
+    >>> fs = oldfs()
+    >>> demo = DemoStorage(base=fs)
+    >>> db = DB(demo)
+    >>> tm = transaction.TransactionManager()
+    >>> root = db.open(transaction_manager=tm).root()
+    >>> _ = tm.begin()
+
+When I did this in production, in a vain attempt to fix the queryNextUtility
+problem:
+
+    >>> sm1 = root['Application'].getSiteManager()
+    >>> sm1.__bases__ = (zope.component.getGlobalSiteManager(), )
+    >>> tm.commit()
+
+I started getting KeyError: 'base' in _LocalAdapterRegistryGeneration3SupportMixin
+__setstate__ which didn't expect the registry to be pickled without someone
+carefully removing the _registrations attribute it left in place.
+
+    >>> tm2 = transaction.TransactionManager()
+    >>> root2 = db.open(transaction_manager=tm2).root()
+    >>> _ = tm2.begin()
+    >>> sm1 = root2['Application'].getSiteManager()
+    >>> len(sm1.__bases__)
+    1
+    >>> sm1.queryUtility(IFoo, 'globalfoo') is not None
+    True
+    >>> zope.app.component.queryNextUtility(sm1, IFoo, 'globalfoo') is not None
+    True
+
+Cleanup:
+
+    >>> db.close()
+
+"""
+
+
+class GlobalRegistry:
+    pass
+
+base = zope.component.globalregistry.GlobalAdapterRegistry(
+    GlobalRegistry, 'adapters')
+GlobalRegistry.adapters = base
+def clear_base():
+    base.__init__(GlobalRegistry, 'adapters')
+    
+    
+def test_deghostification_of_persistent_adapter_registries():
+    """
+
+Note that this test duplicates one from zope.component.tests.
+We should be able to get rid of this one when we get rid of
+__setstate__ implementation we have in back35.
+    
+We want to make sure that we see updates corrextly.
+
+    >>> import ZODB.tests.util
+    >>> db = ZODB.tests.util.DB()
+    >>> tm1 = transaction.TransactionManager()
+    >>> c1 = db.open(transaction_manager=tm1)
+    >>> r1 = zope.app.component.site._LocalAdapterRegistry((base,))
+    >>> r2 = zope.app.component.site._LocalAdapterRegistry((r1,))
+    >>> c1.root()[1] = r1
+    >>> c1.root()[2] = r2
+    >>> tm1.commit()
+    >>> r1._p_deactivate()
+    >>> r2._p_deactivate()
+
+    >>> tm2 = transaction.TransactionManager()
+    >>> c2 = db.open(transaction_manager=tm2)
+    >>> r1 = c2.root()[1]
+    >>> r2 = c2.root()[2]
+
+    >>> r1.lookup((), IFoo, '')
+
+    >>> base.register((), IFoo, '', Foo(''))
+    >>> r1.lookup((), IFoo, '')
+    Foo('')
+
+    >>> r2.lookup((), IFoo, '1')
+
+    >>> r1.register((), IFoo, '1', Foo('1'))
+
+    >>> r2.lookup((), IFoo, '1')
+    Foo('1')
+
+    >>> r1.lookup((), IFoo, '2')
+    >>> r2.lookup((), IFoo, '2')
+
+    >>> base.register((), IFoo, '2', Foo('2'))
+    
+    >>> r1.lookup((), IFoo, '2')
+    Foo('2')
+
+    >>> r2.lookup((), IFoo, '2')
+    Foo('2')
+
+Cleanup:
+
+    >>> db.close()
+    >>> clear_base()
+
+    """
+
+barcode = """
+from zope.interface import Interface
+class IBar(Interface): pass
+class IBaz(Interface): pass
+"""
+
+class Bar(persistent.Persistent): pass
+class Baz(persistent.Persistent): pass
+
+def test_persistent_interfaces():
+    """
+Registrations for persistent interfaces are accessible from separate
+connections.
+
+Setup the DB and our first connection::
+
+    >>> import ZODB.tests.util
+    >>> db = ZODB.tests.util.DB()
+    >>> conn1 = db.open()
+    >>> root1 = conn1.root()
+
+Setup the persistent module registry and the local component
+registry::
+
+    >>> from zodbcode.module import ManagedRegistry
+    >>> registry = root1['registry'] = ManagedRegistry()
+    >>> from zope.component.persistentregistry import PersistentComponents
+    >>> manager = root1['manager'] = PersistentComponents()
+
+Create a persistent module::
+
+    >>> registry.newModule('barmodule', barcode)
+    >>> barmodule = registry.findModule('barmodule')
+
+Create a persistent instance::
+
+    >>> bar = root1['bar'] = Bar()
+    >>> from zope.interface import directlyProvides
+    >>> directlyProvides(bar, barmodule.IBar)
+    >>> from transaction import commit
+    >>> commit()
+
+Register an adapter::
+
+    >>> manager.queryAdapter(bar, barmodule.IBaz)
+    >>> manager.registerAdapter(Baz, [barmodule.IBar], barmodule.IBaz)
+    >>> manager.getAdapter(bar, barmodule.IBaz) # doctest: +ELLIPSIS
+    <zope.app.component.tests.test_registration.Baz object at ...>
+
+Before commit, the adapter is not available from another connection::
+
+    >>> conn2 = db.open()
+    >>> root2 = conn2.root()
+    >>> registry2 = root2['registry']
+    >>> barmodule2 = registry2.findModule('barmodule')
+    >>> bar2 = root2['bar']
+    >>> manager2 = root2['manager']
+    >>> manager2.queryAdapter(bar2, barmodule2.IBaz)
+
+After commit, it is::
+
+    >>> commit()
+    >>> conn2.sync()
+    >>> manager2.getAdapter(bar2, barmodule2.IBaz)
+    ... # doctest: +ELLIPSIS
+    <zope.app.component.tests.test_registration.Baz object at ...>
+
+Cleanup::
+
+    >>> conn1.close()
+    >>> conn2.close()
+    >>> db.close()
+"""
+
+
+def test_suite():
+    suite = unittest.TestSuite((
+        doctest.DocFileSuite('deprecated35_statusproperty.txt',
+                             'deprecated35_registration.txt',
+                             setUp=setUpOld, tearDown=tearDown),
+        doctest.DocTestSuite(setUp=setUp, tearDown=tearDown)
+        ))
+    return suite
+
+
+if __name__ == "__main__":
+    unittest.main(defaultTest='test_suite')



More information about the Checkins mailing list