[Checkins] SVN: zope.component/trunk/ Merge tseaver-test_cleanup branch.

Tres Seaver cvs-admin at zope.org
Fri Jun 29 14:47:59 UTC 2012


Log message for revision 127192:
  Merge tseaver-test_cleanup branch.

Changed:
  _U  zope.component/trunk/
  U   zope.component/trunk/.bzrignore
  U   zope.component/trunk/CHANGES.txt
  A   zope.component/trunk/docs/
  U   zope.component/trunk/docs/Makefile
  U   zope.component/trunk/docs/api/adapter.rst
  U   zope.component/trunk/docs/api/factory.rst
  U   zope.component/trunk/docs/api/interface.rst
  U   zope.component/trunk/docs/api/interfaces.rst
  U   zope.component/trunk/docs/api/persistent.rst
  U   zope.component/trunk/docs/api/security.rst
  U   zope.component/trunk/docs/api/sitemanager.rst
  U   zope.component/trunk/docs/api/utility.rst
  U   zope.component/trunk/docs/api.rst
  U   zope.component/trunk/docs/conf.py
  U   zope.component/trunk/docs/configure.rst
  U   zope.component/trunk/docs/event.rst
  U   zope.component/trunk/docs/factory.rst
  U   zope.component/trunk/docs/hooks.rst
  U   zope.component/trunk/docs/index.rst
  U   zope.component/trunk/docs/make.bat
  U   zope.component/trunk/docs/narr.rst
  U   zope.component/trunk/docs/persistentregistry.rst
  U   zope.component/trunk/docs/socketexample.rst
  U   zope.component/trunk/docs/testlayer.rst
  U   zope.component/trunk/docs/zcml.rst
  A   zope.component/trunk/setup.cfg
  U   zope.component/trunk/setup.py
  D   zope.component/trunk/src/zope/component/README.txt
  U   zope.component/trunk/src/zope/component/_api.py
  A   zope.component/trunk/src/zope/component/_compat.py
  U   zope.component/trunk/src/zope/component/_declaration.py
  D   zope.component/trunk/src/zope/component/configure.txt
  U   zope.component/trunk/src/zope/component/event.py
  D   zope.component/trunk/src/zope/component/event.txt
  U   zope.component/trunk/src/zope/component/eventtesting.py
  U   zope.component/trunk/src/zope/component/factory.py
  D   zope.component/trunk/src/zope/component/factory.txt
  U   zope.component/trunk/src/zope/component/globalregistry.py
  U   zope.component/trunk/src/zope/component/hooks.py
  D   zope.component/trunk/src/zope/component/hooks.txt
  D   zope.component/trunk/src/zope/component/index.txt
  U   zope.component/trunk/src/zope/component/interface.py
  U   zope.component/trunk/src/zope/component/interfaces.py
  D   zope.component/trunk/src/zope/component/nexttesting.py
  U   zope.component/trunk/src/zope/component/persistentregistry.py
  D   zope.component/trunk/src/zope/component/persistentregistry.txt
  D   zope.component/trunk/src/zope/component/registry.txt
  U   zope.component/trunk/src/zope/component/security.py
  D   zope.component/trunk/src/zope/component/socketexample.txt
  U   zope.component/trunk/src/zope/component/standalonetests.py
  U   zope.component/trunk/src/zope/component/testfiles/adapter.py
  U   zope.component/trunk/src/zope/component/testfiles/components.py
  U   zope.component/trunk/src/zope/component/testfiles/views.py
  U   zope.component/trunk/src/zope/component/testing.py
  U   zope.component/trunk/src/zope/component/testlayer.py
  D   zope.component/trunk/src/zope/component/testlayer.txt
  A   zope.component/trunk/src/zope/component/tests/
  U   zope.component/trunk/src/zope/component/tests/__init__.py
  U   zope.component/trunk/src/zope/component/tests/examples.py
  U   zope.component/trunk/src/zope/component/tests/test___init__.py
  U   zope.component/trunk/src/zope/component/tests/test__api.py
  U   zope.component/trunk/src/zope/component/tests/test__declaration.py
  U   zope.component/trunk/src/zope/component/tests/test_event.py
  U   zope.component/trunk/src/zope/component/tests/test_factory.py
  U   zope.component/trunk/src/zope/component/tests/test_globalregistry.py
  U   zope.component/trunk/src/zope/component/tests/test_hookable.py
  U   zope.component/trunk/src/zope/component/tests/test_hooks.py
  U   zope.component/trunk/src/zope/component/tests/test_interface.py
  U   zope.component/trunk/src/zope/component/tests/test_persistentregistry.py
  U   zope.component/trunk/src/zope/component/tests/test_registry.py
  U   zope.component/trunk/src/zope/component/tests/test_security.py
  U   zope.component/trunk/src/zope/component/tests/test_standalone.py
  U   zope.component/trunk/src/zope/component/tests/test_zcml.py
  D   zope.component/trunk/src/zope/component/tests.py
  U   zope.component/trunk/src/zope/component/zcml.py
  D   zope.component/trunk/src/zope/component/zcml.txt
  D   zope.component/trunk/src/zope/component/zcml_conditional.txt
  A   zope.component/trunk/tox.ini

-=-

Property changes on: zope.component/trunk
___________________________________________________________________
Added: svn:mergeinfo
   + /zope.component/tseaver-test_cleanup:126964-126965,126977-126979,126985-126993,127019-127036,127043-127050,127060-127065,127081-127090,127107-127128,127133-127140,127144

Added: svk:merge
   + 62d5b8a3-27da-0310-9561-8e5933582275:/zope.component/tseaver-test_cleanup:127144


Modified: zope.component/trunk/.bzrignore
===================================================================
--- zope.component/trunk/.bzrignore	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/.bzrignore	2012-06-29 14:47:56 UTC (rev 127192)
@@ -5,3 +5,9 @@
 ./docs
 ./parts
 *.egg-info
+.coverage
+docs/_build
+.tox
+nosetests.xml
+coverage.xml
+__pycache__

Modified: zope.component/trunk/CHANGES.txt
===================================================================
--- zope.component/trunk/CHANGES.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/CHANGES.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,12 +1,34 @@
 CHANGES
 *******
 
-3.12.2 (unreleased)
-===================
+4.0.0 (unreleased)
+==================
 
-- Nothing changed yet.
+- Added PyPy and Python 3.2 support:
 
+  - Security support omitted until ``zope.security`` ported.
 
+  - Persistent registry support omitted until ``ZODB`` ported (or
+    ``persistent`` factored out).
+
+- 100% unit test coverage.
+
+- Removed the long-deprecated ``layer`` argument to the
+  ``zope.component.zcml.view`` and ``zope.component.zcml.resource``
+  ZCML directives.
+
+- Added support for continuous integration using ``tox`` and ``jenkins``.
+
+- Got tests to run using ``setup.py test``.
+
+- Added ``Sphinx`` documentation.
+
+- Added ``setup.py docs`` alias (installs ``Sphinx`` and dependencies).
+
+- Added ``setup.py dev`` alias (runs ``setup.py develop`` plus installs
+  ``nose`` and ``coverage``).
+
+
 3.12.1 (2012-04-02)
 ===================
 

Copied: zope.component/trunk/setup.cfg (from rev 127144, zope.component/tseaver-test_cleanup/setup.cfg)
===================================================================
--- zope.component/trunk/setup.cfg	                        (rev 0)
+++ zope.component/trunk/setup.cfg	2012-06-29 14:47:56 UTC (rev 127192)
@@ -0,0 +1,10 @@
+[nosetests]
+nocapture=1
+cover-package=zope.component
+cover-erase=1
+with-doctest=0
+where=src
+
+[aliases]
+dev = develop easy_install zope.component[testing]
+docs = easy_install zope.component[docs]

Modified: zope.component/trunk/setup.py
===================================================================
--- zope.component/trunk/setup.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/setup.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -23,14 +23,48 @@
 from setuptools import setup, find_packages
 
 
-tests_require = [
-    'ZODB3',
-    'zope.hookable',
+TESTS_REQUIRE = [
     'zope.testing',
-    'zope.testrunner',
+    'zope.component[hook]',
+    'zope.component[persistentregistry]',
+    'zope.component[security]',
+    'zope.component[zcml]',
     ]
 
+def _modname(path, base, name=''):
+    if path == base:
+        return name
+    dirname, basename = os.path.split(path)
+    return _modname(dirname, base, basename + '.' + name)
 
+def alltests():
+    import logging
+    import pkg_resources
+    import unittest
+
+    class NullHandler(logging.Handler):
+        level = 50
+        
+        def emit(self, record):
+            pass
+
+    logging.getLogger().addHandler(NullHandler())
+
+    suite = unittest.TestSuite()
+    base = pkg_resources.working_set.find(
+        pkg_resources.Requirement.parse('zope.component')).location
+    for dirpath, dirnames, filenames in os.walk(base):
+        if os.path.basename(dirpath) == 'tests':
+            for filename in filenames:
+                if ( filename.endswith('.py') and
+                     filename.startswith('test') ):
+                    mod = __import__(
+                        _modname(dirpath, base, os.path.splitext(filename)[0]),
+                        {}, {}, ['*'])
+                    suite.addTest(mod.test_suite())
+    return suite
+
+
 def read(*rnames):
     return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
 
@@ -45,25 +79,7 @@
     long_description=(
         read('README.txt')
         + '\n' +
-        'Detailed Documentation\n'
-        '**********************\n'
-        + '\n' +
-        read('src', 'zope', 'component', 'README.txt')
-        + '\n' +
-        read('src', 'zope', 'component', 'event.txt')
-        + '\n' +
-        read('src', 'zope', 'component', 'factory.txt')
-        + '\n' +
-        read('src', 'zope', 'component', 'registry.txt')
-        + '\n' +
-        read('src', 'zope', 'component', 'persistentregistry.txt')
-        + '\n' +
-        read('src', 'zope', 'component', 'socketexample.txt')
-        + '\n' +
         read('CHANGES.txt')
-        + '\n' +
-        'Download\n'
-        '********\n'
         ),
     packages = find_packages('src'),
     package_dir = {'': 'src'},
@@ -75,29 +91,35 @@
         "Operating System :: OS Independent",
         "Programming Language :: Python",
         "Programming Language :: Python :: 2",
-        "Programming Language :: Python :: 2.5",
         "Programming Language :: Python :: 2.6",
         "Programming Language :: Python :: 2.7",
+        "Programming Language :: Python :: 3",
+        "Programming Language :: Python :: 3.2",
+        "Programming Language :: Python :: Implementation :: CPython",
+        "Programming Language :: Python :: Implementation :: PyPy",
         "Topic :: Software Development :: Libraries :: Python Modules",
     ],
     namespace_packages=['zope',],
-    tests_require = tests_require,
+    tests_require = TESTS_REQUIRE,
+    test_suite='__main__.alltests',
     install_requires=['setuptools',
                       'zope.interface>=3.8.0',
                       'zope.event',
                       ],
     include_package_data = True,
     zip_safe = False,
-    extras_require = dict(
-        hook = ['zope.hookable'],
-        persistentregistry = ['ZODB3'],
-        security = ['zope.location',
+    extras_require = {
+        'hook': ['zope.hookable'],
+        'persistentregistry': ['ZODB3'],
+        'security': ['zope.location',
                     'zope.proxy',
                     'zope.security',
                     ],
-        zcml = ['zope.configuration',
+        'zcml': ['zope.configuration',
                 'zope.i18nmessageid',
                 ],
-        test = tests_require,
-        ),
+        'test': TESTS_REQUIRE,
+        'testing': TESTS_REQUIRE + ['nose', 'coverage'],
+        'docs': ['Sphinx', 'repoze.sphinx.autointerface'],
+        },
     )

Deleted: zope.component/trunk/src/zope/component/README.txt
===================================================================
--- zope.component/trunk/src/zope/component/README.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/README.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,402 +0,0 @@
-Zope Component Architecture
-===========================
-
-This package, together with `zope.interface`, provides facilities for
-defining, registering and looking up components.  There are two basic
-kinds of components: adapters and utilities.
-
-Utilities
----------
-
-Utilities are just components that provide an interface and that are
-looked up by an interface and a name.  Let's look at a trivial utility
-definition:
-
-    >>> from zope import interface
-
-    >>> class IGreeter(interface.Interface):
-    ...     def greet():
-    ...         "say hello"
-
-    >>> class Greeter:
-    ...     interface.implements(IGreeter)
-    ...
-    ...     def __init__(self, other="world"):
-    ...         self.other = other
-    ...
-    ...     def greet(self):
-    ...         print "Hello", self.other
-
-We can register an instance this class using `provideUtility` [1]_:
-
-    >>> from zope import component
-    >>> greet = Greeter('bob')
-    >>> component.provideUtility(greet, IGreeter, 'robert')
-
-In this example we registered the utility as providing the `IGreeter`
-interface with a name of 'bob'. We can look the interface up with
-either `queryUtility` or `getUtility`:
-
-    >>> component.queryUtility(IGreeter, 'robert').greet()
-    Hello bob
-
-    >>> component.getUtility(IGreeter, 'robert').greet()
-    Hello bob
-
-`queryUtility` and `getUtility` differ in how failed lookups are handled:
-
-    >>> component.queryUtility(IGreeter, 'ted')
-    >>> component.queryUtility(IGreeter, 'ted', 42)
-    42
-    >>> component.getUtility(IGreeter, 'ted')
-    ... # doctest: +ELLIPSIS
-    Traceback (most recent call last):
-    ...
-    ComponentLookupError: (<InterfaceClass ...IGreeter>, 'ted')
-
-If a component provides only one interface, as in the example above,
-then we can omit the provided interface from the call to `provideUtility`:
-
-    >>> ted = Greeter('ted')
-    >>> component.provideUtility(ted, name='ted')
-    >>> component.queryUtility(IGreeter, 'ted').greet()
-    Hello ted
-
-The name defaults to an empty string:
-
-    >>> world = Greeter()
-    >>> component.provideUtility(world)
-    >>> component.queryUtility(IGreeter).greet()
-    Hello world
-
-Adapters
---------
-
-Adapters are components that are computed from other components to
-adapt them to some interface.  Because they are computed from other
-objects, they are provided as factories, usually classes.  Here, we'll
-create a greeter for persons, so we can provide personalized greetings
-for different people:
-
-    >>> class IPerson(interface.Interface):
-    ...     name = interface.Attribute("Name")
-
-    >>> class PersonGreeter:
-    ...
-    ...     component.adapts(IPerson)
-    ...     interface.implements(IGreeter)
-    ...
-    ...     def __init__(self, person):
-    ...         self.person = person
-    ...
-    ...     def greet(self):
-    ...         print "Hello", self.person.name
-
-The class defines a constructor that takes an argument for every
-object adapted.
-
-We used `component.adapts` to declare what we adapt.  We can find
-out if an object declares that it adapts anything using adaptedBy:
-
-    >>> list(component.adaptedBy(PersonGreeter)) == [IPerson]
-    True
-
-If an object makes no declaration, then None is returned:
-
-    >>> component.adaptedBy(Greeter()) is None
-    True
-
-
-If we declare the interfaces adapted and if we provide only one
-interface, as in the example above, then we can provide the adapter
-very simply [1]_:
-
-    >>> component.provideAdapter(PersonGreeter)
-
-For adapters that adapt a single interface to a single interface
-without a name, we can get the adapter by simply calling the
-interface:
-
-    >>> class Person:
-    ...     interface.implements(IPerson)
-    ...
-    ...     def __init__(self, name):
-    ...         self.name = name
-
-    >>> IGreeter(Person("Sally")).greet()
-    Hello Sally
-
-We can also provide arguments to be very specific about what
-how to register the adapter.
-
-    >>> class BobPersonGreeter(PersonGreeter):
-    ...     name = 'Bob'
-    ...     def greet(self):
-    ...         print "Hello", self.person.name, "my name is", self.name
-
-    >>> component.provideAdapter(
-    ...                        BobPersonGreeter, [IPerson], IGreeter, 'bob')
-
-The arguments can also be provided as keyword arguments:
-
-    >>> class TedPersonGreeter(BobPersonGreeter):
-    ...     name = "Ted"
-
-    >>> component.provideAdapter(
-    ...     factory=TedPersonGreeter, adapts=[IPerson],
-    ...     provides=IGreeter, name='ted')
-
-For named adapters, use `queryAdapter`, or `getAdapter`:
-
-    >>> component.queryAdapter(Person("Sally"), IGreeter, 'bob').greet()
-    Hello Sally my name is Bob
-
-    >>> component.getAdapter(Person("Sally"), IGreeter, 'ted').greet()
-    Hello Sally my name is Ted
-
-If an adapter can't be found, `queryAdapter` returns a default value
-and `getAdapter` raises an error:
-
-    >>> component.queryAdapter(Person("Sally"), IGreeter, 'frank')
-    >>> component.queryAdapter(Person("Sally"), IGreeter, 'frank', 42)
-    42
-    >>> component.getAdapter(Person("Sally"), IGreeter, 'frank')
-    ... # doctest: +ELLIPSIS
-    Traceback (most recent call last):
-    ...
-    ComponentLookupError: (...Person...>, <...IGreeter>, 'frank')
-
-Adapters can adapt multiple objects:
-
-    >>> class TwoPersonGreeter:
-    ...
-    ...     component.adapts(IPerson, IPerson)
-    ...     interface.implements(IGreeter)
-    ...
-    ...     def __init__(self, person, greeter):
-    ...         self.person = person
-    ...         self.greeter = greeter
-    ...
-    ...     def greet(self):
-    ...         print "Hello", self.person.name
-    ...         print "my name is", self.greeter.name
-
-    >>> component.provideAdapter(TwoPersonGreeter)
-
-Note that the declaration-order of the Interfaces beeing adapted to is
-important for adapter look up. It must be the the same as the order of
-parameters given to the adapter and used to query the adapter. This is
-especially the case when different Interfaces are adapt to (opposed to
-this example).
-
-To look up a multi-adapter, use either `queryMultiAdapter` or
-`getMultiAdapter`:
-
-    >>> component.queryMultiAdapter((Person("Sally"), Person("Bob")),
-    ...                                  IGreeter).greet()
-    Hello Sally
-    my name is Bob
-
-Adapters need not be classes.  Any callable will do.  We use the
-adapter decorator (in the Python 2.4 decorator sense) to declare that
-a callable object adapts some interfaces (or classes):
-
-    >>> class IJob(interface.Interface):
-    ...     "A job"
-
-    >>> class Job:
-    ...     interface.implements(IJob)
-
-    >>> def personJob(person):
-    ...     return getattr(person, 'job', None)
-    >>> personJob = interface.implementer(IJob)(personJob)
-    >>> personJob = component.adapter(IPerson)(personJob)
-
-In Python 2.4, the example can be written:
-
-    >>> @interface.implementer(IJob)
-    ... @component.adapter(IPerson)
-    ... def personJob(person):
-    ...     return getattr(person, 'job', None)
-
-which looks a bit nicer.
-
-In this example, the personJob function simply returns the person's
-`job` attribute if present, or None if it's not present.  An adapter
-factory can return None to indicate that adaptation wasn't possible.
-Let's register this adapter and try it out:
-
-    >>> component.provideAdapter(personJob)
-    >>> sally = Person("Sally")
-    >>> IJob(sally) # doctest: +ELLIPSIS
-    Traceback (most recent call last):
-    ...
-    TypeError: ('Could not adapt', ...
-
-The adaptation failed because sally didn't have a job.  Let's give her
-one:
-
-    >>> job = Job()
-    >>> sally.job = job
-    >>> IJob(sally) is job
-    True
-
-Subscription Adapters
----------------------
-
-Unlike regular adapters, subscription adapters are used when we want
-all of the adapters that adapt an object to a particular adapter.
-
-Consider a validation problem.  We have objects and we want to assess
-whether they meet some sort of standards.  We define a validation
-interface:
-
-    >>> class IValidate(interface.Interface):
-    ...     def validate(ob):
-    ...         """Determine whether the object is valid
-    ...
-    ...         Return a string describing a validation problem.
-    ...         An empty string is returned to indicate that the
-    ...         object is valid.
-    ...         """
-
-Perhaps we have documents:
-
-    >>> class IDocument(interface.Interface):
-    ...     summary = interface.Attribute("Document summary")
-    ...     body = interface.Attribute("Document text")
-
-    >>> class Document:
-    ...     interface.implements(IDocument)
-    ...     def __init__(self, summary, body):
-    ...         self.summary, self.body = summary, body
-
-Now, we may want to specify various validation rules for
-documents. For example, we might require that the summary be a single
-line:
-
-    >>> class SingleLineSummary:
-    ...     component.adapts(IDocument)
-    ...     interface.implements(IValidate)
-    ...
-    ...     def __init__(self, doc):
-    ...         self.doc = doc
-    ...
-    ...     def validate(self):
-    ...         if '\n' in self.doc.summary:
-    ...             return 'Summary should only have one line'
-    ...         else:
-    ...             return ''
-
-Or we might require the body to be at least 1000 characters in length:
-
-    >>> class AdequateLength:
-    ...     component.adapts(IDocument)
-    ...     interface.implements(IValidate)
-    ...
-    ...     def __init__(self, doc):
-    ...         self.doc = doc
-    ...
-    ...     def validate(self):
-    ...         if len(self.doc.body) < 1000:
-    ...             return 'too short'
-    ...         else:
-    ...             return ''
-
-We can register these as subscription adapters [1]_:
-
-    >>> component.provideSubscriptionAdapter(SingleLineSummary)
-    >>> component.provideSubscriptionAdapter(AdequateLength)
-
-We can then use the subscribers to validate objects:
-
-    >>> doc = Document("A\nDocument", "blah")
-    >>> [adapter.validate()
-    ...  for adapter in component.subscribers([doc], IValidate)
-    ...  if adapter.validate()]
-    ['Summary should only have one line', 'too short']
-
-    >>> doc = Document("A\nDocument", "blah" * 1000)
-    >>> [adapter.validate()
-    ...  for adapter in component.subscribers([doc], IValidate)
-    ...  if adapter.validate()]
-    ['Summary should only have one line']
-
-    >>> doc = Document("A Document", "blah")
-    >>> [adapter.validate()
-    ...  for adapter in component.subscribers([doc], IValidate)
-    ...  if adapter.validate()]
-    ['too short']
-
-Handlers
---------
-
-Handlers are subscription adapter factories that don't produce
-anything.  They do all of their work when called.  Handlers
-are typically used to handle events.
-
-Event subscribers are different from other subscription adapters in
-that the caller of event subscribers doesn't expect to interact with
-them in any direct way.  For example, an event publisher doesn't
-expect to get any return value.  Because subscribers don't need to
-provide an API to their callers, it is more natural to define them
-with functions, rather than classes.  For example, in a
-document-management system, we might want to record creation times for
-documents:
-
-    >>> import datetime
-
-    >>> def documentCreated(event):
-    ...     event.doc.created = datetime.datetime.utcnow()
-
-In this example, we have a function that takes an event and performs
-some processing.  It doesn't actually return anything.  This is a
-special case of a subscription adapter that adapts an event to
-nothing.  All of the work is done when the adapter "factory" is
-called.  We call subscribers that don't actually create anything
-"handlers".  There are special APIs for registering and calling
-them.
-
-To register the subscriber above, we define a document-created event:
-
-    >>> class IDocumentCreated(interface.Interface):
-    ...     doc = interface.Attribute("The document that was created")
-
-    >>> class DocumentCreated:
-    ...     interface.implements(IDocumentCreated)
-    ...
-    ...     def __init__(self, doc):
-    ...         self.doc = doc
-
-We'll also change our handler definition to:
-
-    >>> def documentCreated(event):
-    ...     event.doc.created = datetime.datetime.utcnow()
-
-    >>> documentCreated = component.adapter(IDocumentCreated)(documentCreated)
-
-Note that in Python 2.4, this can be written:
-
-    >>> @component.adapter(IDocumentCreated)
-    ... def documentCreated(event):
-    ...     event.doc.created = datetime.datetime.utcnow()
-
-This marks the handler as an adapter of `IDocumentCreated` events.
-
-Now we'll register the handler  [1]_:
-
-    >>> component.provideHandler(documentCreated)
-
-Now, if we can create an event and use the `handle` function to call
-handlers registered for the event:
-
-    >>> component.handle(DocumentCreated(doc))
-    >>> doc.created.__class__.__name__
-    'datetime'
-
-
-
-.. [1] CAUTION: This API should only be used from test or
-       application-setup code. This API shouldn't be used by regular
-       library modules, as component registration is a configuration
-       activity.

Modified: zope.component/trunk/src/zope/component/_api.py
===================================================================
--- zope.component/trunk/src/zope/component/_api.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/_api.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -25,6 +25,7 @@
 from zope.component.interfaces import IFactory
 from zope.component.interfaces import ComponentLookupError
 from zope.component.interfaces import IComponentLookup
+from zope.component._compat import _BLANK
 from zope.component._declaration import adaptedBy
 from zope.component._declaration import adapter
 from zope.component._declaration import adapts
@@ -33,7 +34,7 @@
 # to our Python version if not.
 try:
     from zope.hookable import hookable
-except ImportError:
+except ImportError: #pragma NO COVER
     from zope.component.hookable import hookable
 
 # getSiteManager() returns a component registry.  Although the term
@@ -42,6 +43,8 @@
 base = None
 @hookable
 def getSiteManager(context=None):
+    """ See IComponentArchitecture.
+    """
     global base
     if context is None:
         if base is None:
@@ -52,7 +55,7 @@
         # to avoid the recursion implied by using a local `getAdapter()` call.
         try:
             return IComponentLookup(context)
-        except TypeError, error:
+        except TypeError as error:
             raise ComponentLookupError(*error.args)
 
 # Adapter API
@@ -90,26 +93,26 @@
 
     return getSiteManager(context).queryAdapter(object, interface, '', default)
 
-def getAdapter(object, interface=Interface, name=u'', context=None):
+def getAdapter(object, interface=Interface, name=_BLANK, context=None):
     adapter = queryAdapter(object, interface, name, None, context)
     if adapter is None:
         raise ComponentLookupError(object, interface, name)
     return adapter
 
-def queryAdapter(object, interface=Interface, name=u'', default=None,
+def queryAdapter(object, interface=Interface, name=_BLANK, default=None,
                  context=None):
     if context is None:
         return adapter_hook(interface, object, name, default)
     return getSiteManager(context).queryAdapter(object, interface, name,
                                                 default)
 
-def getMultiAdapter(objects, interface=Interface, name=u'', context=None):
+def getMultiAdapter(objects, interface=Interface, name=_BLANK, context=None):
     adapter = queryMultiAdapter(objects, interface, name, context=context)
     if adapter is None:
         raise ComponentLookupError(objects, interface, name)
     return adapter
 
-def queryMultiAdapter(objects, interface=Interface, name=u'', default=None,
+def queryMultiAdapter(objects, interface=Interface, name=_BLANK, default=None,
                       context=None):
     try:
         sitemanager = getSiteManager(context)
@@ -136,10 +139,7 @@
     return sitemanager.subscribers(objects, interface)
 
 def handle(*objects):
-    sitemanager = getSiteManager(None)
-    # iterating over subscribers assures they get executed
-    for ignored in sitemanager.subscribers(objects, None):
-        pass
+    getSiteManager(None).subscribers(objects, None)
 
 #############################################################################
 # Register the component architectures adapter hook, with the adapter hook
@@ -150,7 +150,7 @@
 def adapter_hook(interface, object, name='', default=None):
     try:
         sitemanager = getSiteManager()
-    except ComponentLookupError:
+    except ComponentLookupError: #pragma NO COVER w/o context, cannot test
         # Oh blast, no site manager. This should *never* happen!
         return None
     return sitemanager.queryAdapter(object, interface, name, default)
@@ -216,13 +216,23 @@
 # Factories
 
 def createObject(__factory_name, *args, **kwargs):
+    """Invoke the named factory and return the result.
+
+    ``__factory_name`` is a positional-only argument.
+    """
     context = kwargs.pop('context', None)
     return getUtility(IFactory, __factory_name, context)(*args, **kwargs)
 
 def getFactoryInterfaces(name, context=None):
+    """Return the interface provided by the named factory's objects
+
+    Result might be a single interface. XXX
+    """
     return getUtility(IFactory, name, context).getInterfaces()
 
 def getFactoriesFor(interface, context=None):
+    """Return info on all factories implementing the given interface.
+    """
     utils = getSiteManager(context)
     for (name, factory) in utils.getUtilitiesFor(IFactory):
         interfaces = factory.getInterfaces()

Copied: zope.component/trunk/src/zope/component/_compat.py (from rev 127144, zope.component/tseaver-test_cleanup/src/zope/component/_compat.py)
===================================================================
--- zope.component/trunk/src/zope/component/_compat.py	                        (rev 0)
+++ zope.component/trunk/src/zope/component/_compat.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -0,0 +1,42 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002 Zope Foundation 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.
+#
+##############################################################################
+
+import sys
+import types
+
+if sys.version_info[0] < 3: #pragma NO COVER
+
+    import cPickle as _pickle
+
+    def _u(s):
+        return unicode(s, 'unicode_escape')
+
+    CLASS_TYPES = (type, types.ClassType)
+
+    PYTHON3 = False
+    PYTHON2 = True
+
+else: #pragma NO COVER
+
+    import pickle as _pickle
+
+    def _u(s):
+        return s
+
+    CLASS_TYPES = (type,)
+
+    PYTHON3 = True
+    PYTHON2 = False
+
+_BLANK = _u('')

Modified: zope.component/trunk/src/zope/component/_declaration.py
===================================================================
--- zope.component/trunk/src/zope/component/_declaration.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/_declaration.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -13,16 +13,17 @@
 ##############################################################################
 """Adapter declarations
 """
-import types
 import sys
 
-class adapter:
+from zope.component._compat import CLASS_TYPES
 
+class adapter(object):
+
     def __init__(self, *interfaces):
         self.interfaces = interfaces
 
     def __call__(self, ob):
-        if isinstance(ob, _class_types):
+        if isinstance(ob, CLASS_TYPES):
             ob.__component_adapts__ = _adapts_descr(self.interfaces)
         else:
             ob.__component_adapts__ = self.interfaces
@@ -33,11 +34,8 @@
     frame = sys._getframe(1)
     locals = frame.f_locals
 
-    # Try to make sure we were called from a class def. In 2.2.0 we can't
-    # check for __module__ since it doesn't seem to be added to the locals
-    # until later on.
-    if (locals is frame.f_globals) or (
-        ('__module__' not in locals) and sys.version_info[:3] > (2, 2, 0)):
+    # Ensure we were called from a class def.
+    if locals is frame.f_globals or '__module__' not in locals:
         raise TypeError("adapts can be used only from a class definition.")
 
     if '__component_adapts__' in locals:
@@ -48,8 +46,6 @@
 def adaptedBy(ob):
     return getattr(ob, '__component_adapts__', None)
 
-_class_types = type, types.ClassType
-
 class _adapts_descr(object):
     def __init__(self, interfaces):
         self.interfaces = interfaces

Deleted: zope.component/trunk/src/zope/component/configure.txt
===================================================================
--- zope.component/trunk/src/zope/component/configure.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/configure.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,13 +0,0 @@
-Package configuration
-=====================
-
-The ``zope.component`` package provides a ZCML file that configures some basic
-components:
-
-  >>> from zope.configuration.xmlconfig import XMLConfig
-  >>> import zope.component
-
-  >>> XMLConfig('configure.zcml', zope.component)()
-
-  >>> len(list(zope.component.getGlobalSiteManager().registeredHandlers()))
-  5

Modified: zope.component/trunk/src/zope/component/event.py
===================================================================
--- zope.component/trunk/src/zope/component/event.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/event.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -11,22 +11,26 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-"""Implement Component Architecture-specific event dispatching, based
-on subscription adapters / handlers.
+"""Component Architecture-specific event dispatching
+
+Based on subscription adapters / handlers.
 """
-__docformat__ = 'restructuredtext'
 
-import zope.component.interfaces
-import zope.event
+from zope.event import subscribers as event_subscribers
 
+from zope.component.interfaces import IObjectEvent
+from zope.component._api import subscribers as component_subscribers
+from zope.component._declaration import adapter
 
+
 def dispatch(*event):
-    zope.component.subscribers(event, None)
+    component_subscribers(event, None)
 
-zope.event.subscribers.append(dispatch)
+event_subscribers.append(dispatch)
 
 
- at zope.component.adapter(zope.component.interfaces.IObjectEvent)
+ at adapter(IObjectEvent)
 def objectEventNotify(event):
-    """Event subscriber to dispatch ObjectEvents to interested adapters."""
-    zope.component.subscribers((event.object, event), None)
+    """Dispatch ObjectEvents to interested adapters.
+    """
+    component_subscribers((event.object, event), None)

Deleted: zope.component/trunk/src/zope/component/event.txt
===================================================================
--- zope.component/trunk/src/zope/component/event.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/event.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,142 +0,0 @@
-Events
-======
-
-The Component Architecture provides a way to dispatch events to event
-handlers.  Event handlers are registered as *subscribers*
-a.k.a. *handlers*.
-
-Before we can start we need to import ``zope.component.event`` to make
-the dispatching effective:
-
-  >>> import zope.component.event
-
-Consider two event classes:
-
-  >>> class Event1(object):
-  ...     pass
-
-  >>> class Event2(Event1):
-  ...     pass
-
-Now consider two handlers for these event classes:
-
-  >>> called = []
-
-  >>> import zope.component
-  >>> @zope.component.adapter(Event1)
-  ... def handler1(event):
-  ...     called.append(1)
-
-  >>> @zope.component.adapter(Event2)
-  ... def handler2(event):
-  ...     called.append(2)
-
-We can register them with the Component Architecture:
-
-  >>> zope.component.provideHandler(handler1)
-  >>> zope.component.provideHandler(handler2)
-
-Now let's go through the events.  We'll see that the handlers have been
-called accordingly:
-
-  >>> from zope.event import notify
-  >>> notify(Event1())
-  >>> called
-  [1]
-
-  >>> del called[:]
-  >>> notify(Event2())
-  >>> called.sort()
-  >>> called
-  [1, 2]
-
-
-
-Object events
--------------
-
-
-The ``objectEventNotify`` function is a subscriber to dispatch
-ObjectEvents to interested adapters.
-
-First create an object class:
-
-  >>> class IUseless(zope.interface.Interface):
-  ...     """Useless object"""
-
-  >>> class UselessObject(object):
-  ...     """Useless object"""
-  ...     zope.interface.implements(IUseless)
-
-Then create an event class:
-
-  >>> class IObjectThrownEvent(zope.component.interfaces.IObjectEvent):
-  ...     """An object has been thrown away"""
-
-  >>> class ObjectThrownEvent(zope.component.interfaces.ObjectEvent):
-  ...     """An object has been thrown away"""
-  ...     zope.interface.implements(IObjectThrownEvent)
-
-Create an object and an event:
-
-  >>> hammer = UselessObject()
-  >>> event = ObjectThrownEvent(hammer)
-
-Then notify the event to the subscribers.
-Since the subscribers list is empty, nothing happens.
-
-  >>> zope.component.event.objectEventNotify(event)
-
-Now create an handler for the event:
-
-  >>> events = []
-  >>> def record(*args):
-  ...     events.append(args)
-
-  >>> zope.component.provideHandler(record, [IUseless, IObjectThrownEvent])
-
-The event is notified to the subscriber:
-
-  >>> zope.component.event.objectEventNotify(event)
-  >>> events == [(hammer, event)]
-  True
-
-Following test demonstrates how a subscriber can raise an exception
-to prevent an action.
-
-  >>> zope.component.provideHandler(zope.component.event.objectEventNotify)
-
-Let's create a container:
-
-  >>> class ToolBox(dict):
-  ...     def __delitem__(self, key):
-  ...         notify(ObjectThrownEvent(self[key]))
-  ...         return super(ToolBox,self).__delitem__(key)
-
-  >>> container = ToolBox()
-
-And put the object into the container:
-
-  >>> container['Red Hammer'] = hammer
-
-Create an handler function that will raise an error when called:
-
-  >>> class Veto(Exception):
-  ...     pass
-
-  >>> def callback(item, event):
-  ...     assert(item == event.object)
-  ...     raise Veto
-
-Register the handler:
-
-  >>> zope.component.provideHandler(callback, [IUseless, IObjectThrownEvent])
-
-Then if we try to remove the object, an ObjectThrownEvent is fired:
-
-  >>> del container['Red Hammer']
-  ... # doctest: +NORMALIZE_WHITESPACE
-  Traceback (most recent call last):
-  ...
-      raise Veto
-  Veto

Modified: zope.component/trunk/src/zope/component/eventtesting.py
===================================================================
--- zope.component/trunk/src/zope/component/eventtesting.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/eventtesting.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -20,10 +20,14 @@
 from zope.component.registry import (
     dispatchSubscriptionAdapterRegistrationEvent)
 from zope.component.registry import dispatchHandlerRegistrationEvent
-from zope.testing import cleanup
+try:
+    from zope.testing.cleanup import addCleanUp
+except ImportError: #pragma NO COVER
+    def addCleanUp(x):
+        pass
 
 events = []
-def getEvents(event_type=None, filter=None):
+def getEvents(event_type=None, filter=None): #pragma NO COVER going aaway
     r = []
     for event in events:
         if event_type is not None and not event_type.providedBy(event):
@@ -34,11 +38,11 @@
 
     return r
 
-def clearEvents():
+def clearEvents(): #pragma NO COVER going aaway
     del events[:]
-cleanup.addCleanUp(clearEvents)
+addCleanUp(clearEvents)
 
-class PlacelessSetup:
+class PlacelessSetup: #pragma NO COVER going aaway
 
     def setUp(self):
         provideHandler(objectEventNotify)
@@ -48,5 +52,5 @@
         provideHandler(dispatchHandlerRegistrationEvent)
         provideHandler(events.append, (None,))
 
-def setUp(test=None):
+def setUp(test=None): #pragma NO COVER going aaway
     PlacelessSetup().setUp()

Modified: zope.component/trunk/src/zope/component/factory.py
===================================================================
--- zope.component/trunk/src/zope/component/factory.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/factory.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -13,17 +13,19 @@
 ##############################################################################
 """Factory object
 """
-from zope.interface import implements, implementedBy
+from zope.interface import implementer
+from zope.interface import implementedBy
 from zope.interface.declarations import Implements
 from zope.component.interfaces import IFactory
 
+
+ at implementer(IFactory)
 class Factory(object):
     """Generic factory implementation.
 
     The purpose of this implementation is to provide a quick way of creating
     factories for classes, functions and other objects.
     """
-    implements(IFactory)
 
     def __init__(self, callable, title='', description='', interfaces=None):
         self._callable = callable
@@ -41,5 +43,5 @@
             return spec
         return implementedBy(self._callable)
 
-    def __repr__(self):
+    def __repr__(self): #pragma NO COVER
         return '<%s for %s>' % (self.__class__.__name__, repr(self._callable))

Deleted: zope.component/trunk/src/zope/component/factory.txt
===================================================================
--- zope.component/trunk/src/zope/component/factory.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/factory.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,131 +0,0 @@
-Factories
-=========
-
-
-The Factory Class
------------------
-
-  >>> from zope.interface import Interface
-  >>> class IFunction(Interface):
-  ...     pass
-
-  >>> class IKlass(Interface):
-  ...     pass
-
-  >>> from zope.interface import implements
-  >>> class Klass(object):
-  ...     implements(IKlass)
-  ... 
-  ...     def __init__(self, *args, **kw):
-  ...         self.args = args
-  ...         self.kw = kw
-
-  >>> from zope.component.factory import Factory
-  >>> factory = Factory(Klass, 'Klass', 'Klassier')
-  >>> factory2 = Factory(lambda x: x, 'Func', 'Function')
-  >>> factory3 = Factory(lambda x: x, 'Func', 'Function', (IFunction,))
-
-Calling a Factory
-~~~~~~~~~~~~~~~~~
-
-Here we test whether the factory correctly creates the objects and
-including the correct handling of constructor elements.
-
-First we create a factory that creates instanace of the `Klass` class:
-
-  >>> factory = Factory(Klass, 'Klass', 'Klassier')
-
-Now we use the factory to create the instance
-
-  >>> kl = factory(1, 2, foo=3, bar=4)
-
-and make sure that the correct class was used to create the object:
-
-  >>> kl.__class__
-  <class 'Klass'>
-
-Since we passed in a couple positional and keyword arguments
-  
-  >>> kl.args
-  (1, 2)
-  >>> kl.kw
-  {'foo': 3, 'bar': 4}
-  
-  >>> factory2(3)
-  3
-  >>> factory3(3)
-  3
-
-
-Title and Description
-~~~~~~~~~~~~~~~~~~~~~
-
-  >>> factory.title
-  'Klass'
-  >>> factory.description
-  'Klassier'
-  >>> factory2.title
-  'Func'
-  >>> factory2.description
-  'Function'
-  >>> factory3.title
-  'Func'
-  >>> factory3.description
-  'Function'
-
-
-Provided Interfaces
-~~~~~~~~~~~~~~~~~~~
-
-  >>> implemented = factory.getInterfaces()
-  >>> implemented.isOrExtends(IKlass)
-  True
-  >>> list(implemented)
-  [<InterfaceClass __builtin__.IKlass>]
-  
-  >>> implemented2 = factory2.getInterfaces()
-  >>> list(implemented2)
-  []
-  
-  >>> implemented3 = factory3.getInterfaces()
-  >>> list(implemented3)
-  [<InterfaceClass __builtin__.IFunction>]
-
-
-The Component Architecture Factory API
---------------------------------------
-
-  >>> import zope.component
-  >>> factory = Factory(Klass, 'Klass', 'Klassier')
-  >>> gsm = zope.component.getGlobalSiteManager() 
-
-  >>> from zope.component.interfaces import IFactory
-  >>> gsm.registerUtility(factory, IFactory, 'klass')
-
-Creating an Object
-~~~~~~~~~~~~~~~~~~
-
-  >>> kl = zope.component.createObject('klass', 1, 2, foo=3, bar=4)
-  >>> isinstance(kl, Klass)
-  True
-  >>> kl.args
-  (1, 2)
-  >>> kl.kw
-  {'foo': 3, 'bar': 4}
-
-Accessing Provided Interfaces
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-  >>> implemented = zope.component.getFactoryInterfaces('klass')
-  >>> implemented.isOrExtends(IKlass)
-  True
-  >>> [iface for iface in implemented]
-  [<InterfaceClass __builtin__.IKlass>]
-
-List of All Factories
-~~~~~~~~~~~~~~~~~~~~~
-
-  >>> [(name, fac.__class__) for name, fac in
-  ...  zope.component.getFactoriesFor(IKlass)]
-  [(u'klass', <class 'zope.component.factory.Factory'>)]
-

Modified: zope.component/trunk/src/zope/component/globalregistry.py
===================================================================
--- zope.component/trunk/src/zope/component/globalregistry.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/globalregistry.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -13,10 +13,12 @@
 ##############################################################################
 """Global components support
 """
-from zope.interface import implements
+from zope.interface import implementer
 from zope.interface.adapter import AdapterRegistry
 from zope.interface.registry import Components
+
 from zope.component.interfaces import IComponentLookup
+from zope.component._compat import _BLANK
 
 def GAR(components, registryName):
     return getattr(components, registryName)
@@ -35,8 +37,8 @@
     def __reduce__(self):
         return GAR, (self.__parent__, self.__name__)
 
+ at implementer(IComponentLookup)
 class BaseGlobalComponents(Components):
-    implements(IComponentLookup)
 
     def _init_registries(self):
         self.adapters = GlobalAdapterRegistry(self, 'adapters')
@@ -50,7 +52,7 @@
 
 try:
     from zope.testing.cleanup import addCleanUp
-except ImportError:
+except ImportError: #pragma NO COVER
     pass
 else:
     addCleanUp(lambda: base.__init__('base'))
@@ -64,10 +66,10 @@
 # We eventually want to deprecate these in favor of using the global
 # component registry directly.
 
-def provideUtility(component, provides=None, name=u''):
+def provideUtility(component, provides=None, name=_BLANK):
     base.registerUtility(component, provides, name, event=False)
 
-def provideAdapter(factory, adapts=None, provides=None, name=''):
+def provideAdapter(factory, adapts=None, provides=None, name=_BLANK):
     base.registerAdapter(factory, adapts, provides, name, event=False)
 
 def provideSubscriptionAdapter(factory, adapts=None, provides=None):
@@ -75,12 +77,3 @@
 
 def provideHandler(factory, adapts=None):
     base.registerHandler(factory, adapts, event=False)
-
-import zope.component._api # see http://www.zope.org/Collectors/Zope3-dev/674
-# Ideally, we will switch to an explicit adapter hook registration.  For now,
-# if you provide an adapter, we want to make sure that the adapter hook is
-# registered, and that registration depends on code in _api, which itself
-# depends on code in this module.  So, for now, we do another of these nasty
-# circular import workarounds.  See also standalonetests.py, as run by
-# tests.py in StandaloneTests, for a test that fails without this hack, and
-# succeeds with it.

Modified: zope.component/trunk/src/zope/component/hooks.py
===================================================================
--- zope.component/trunk/src/zope/component/hooks.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/hooks.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -17,17 +17,24 @@
 
 import contextlib
 import threading
-import zope.component
 
 try:
-    import zope.security.proxy
-except ImportError:
-    SECURITY_SUPPORT = False
-else:
-    SECURITY_SUPPORT = True
+    from zope.security.proxy import removeSecurityProxy
+except ImportError: #pragma NO COVER
+    def removeSecurityProxy(x):
+        return x
 
+from zope.component.globalregistry import getGlobalSiteManager
+from zope.component.interfaces import ComponentLookupError
+from zope.component.interfaces import IComponentLookup
 
+
 class read_property(object):
+    """Descriptor for property-like computed attributes.
+
+    Unlike the standard 'property', this descriptor allows assigning a
+    value to the instance, shadowing the property getter function.
+    """
     def __init__(self, func):
         self.func = func
 
@@ -39,20 +46,19 @@
 
 class SiteInfo(threading.local):
     site = None
-    sm = zope.component.getGlobalSiteManager()
+    sm = getGlobalSiteManager()
 
+    @read_property
     def adapter_hook(self):
         adapter_hook = self.sm.adapters.adapter_hook
         self.adapter_hook = adapter_hook
         return adapter_hook
 
-    adapter_hook = read_property(adapter_hook)
-
 siteinfo = SiteInfo()
 
 def setSite(site=None):
     if site is None:
-        sm = zope.component.getGlobalSiteManager()
+        sm = getGlobalSiteManager()
     else:
 
         # We remove the security proxy because there's no way for
@@ -62,8 +68,7 @@
         # once site managers do less.  There's probably no good reason why
         # they can't be proxied.  Well, except maybe for performance.
 
-        if SECURITY_SUPPORT:
-            site = zope.security.proxy.removeSecurityProxy(site)
+        site = removeSecurityProxy(site)
         # The getSiteManager method is defined by IPossibleSite.
         sm = site.getSiteManager()
 
@@ -103,34 +108,35 @@
     # We should really look look at this again though, especially
     # once site managers do less.  There's probably no good reason why
     # they can't be proxied.  Well, except maybe for performance.
-    sm = zope.component.interfaces.IComponentLookup(
-        context, zope.component.getGlobalSiteManager())
-    if SECURITY_SUPPORT:
-        sm = zope.security.proxy.removeSecurityProxy(sm)
+    sm = IComponentLookup(
+        context, getGlobalSiteManager())
+    sm = removeSecurityProxy(sm)
     return sm
 
 
 def adapter_hook(interface, object, name='', default=None):
     try:
         return siteinfo.adapter_hook(interface, object, name, default)
-    except zope.component.interfaces.ComponentLookupError:
+    except ComponentLookupError:
         return default
 
 
 def setHooks():
-    zope.component.adapter_hook.sethook(adapter_hook)
-    zope.component.getSiteManager.sethook(getSiteManager)
+    from zope.component import _api
+    _api.adapter_hook.sethook(adapter_hook)
+    _api.getSiteManager.sethook(getSiteManager)
 
 def resetHooks():
     # Reset hookable functions to original implementation.
-    zope.component.adapter_hook.reset()
-    zope.component.getSiteManager.reset()
+    from zope.component import _api
+    _api.adapter_hook.reset()
+    _api.getSiteManager.reset()
 
 # Clear the site thread global
 clearSite = setSite
 try:
     from zope.testing.cleanup import addCleanUp
-except ImportError:
+except ImportError: #pragma NO COVER
     pass
 else:
     addCleanUp(resetHooks)

Deleted: zope.component/trunk/src/zope/component/hooks.txt
===================================================================
--- zope.component/trunk/src/zope/component/hooks.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/hooks.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,97 +0,0 @@
-==============================
-The current component registry
-==============================
-
-There can be any number of component registries in an application. One of them
-is the global component registry, and there is also the concept of a currently
-used component registry. Component registries other than the global one are
-associated with objects called sites. The ``zope.component.hooks`` module
-provides an API to set and access the current site as well as manipulate the
-adapter hook associated with it.
-
-As long as we haven't set a site, none is being considered current:
-
->>> from zope.component.hooks import getSite
->>> print getSite()
-None
-
-We can also ask for the current component registry (aka site manager
-historically); it will return the global one if no current site is set:
-
->>> from zope.component.hooks import getSiteManager
->>> getSiteManager()
-<BaseGlobalComponents base>
-
-Let's set a site now. A site has to be an object that provides the
-``getSiteManager`` method, which is specified by
-``zope.component.interfaces.IPossibleSite``:
-
->>> from zope.interface.registry import Components
->>> class Site(object):
-...     def __init__(self):
-...         self.registry = Components('components')
-...     def getSiteManager(self):
-...         return self.registry
-
->>> from zope.component.hooks import setSite
->>> site1 = Site()
->>> setSite(site1)
-
-After this, the newly set site is considered the currently active one:
-
->>> getSite() is site1
-True
->>> getSiteManager() is site1.registry
-True
-
-If we set another site, that one will be considered current:
-
->>> site2 = Site()
->>> site2.registry is not site1.registry
-True
->>> setSite(site2)
-
->>> getSite() is site2
-True
->>> getSiteManager() is site2.registry
-True
-
-Finally we can unset the site and the global component registry is used again:
-
->>> setSite()
->>> print getSite()
-None
->>> getSiteManager()
-<BaseGlobalComponents base>
-
-
-Context manager
-===============
-
-There also is a context manager for setting the site, which is especially
-useful when writing tests:
-
->>> import zope.component.hooks
->>> dummy = with_statement # support for Python-2.5
->>> print getSite()
-None
->>> with zope.component.hooks.site(site2):
-...     getSite() is site2
-True
->>> print getSite()
-None
-
-The site is properly restored even if the body of the with statement
-raises an exception:
-
->>> print getSite()
-None
->>> with zope.component.hooks.site(site2):
-...    getSite() is site2
-...    raise ValueError('An error in the body')
-Traceback (most recent call last):
-    ...
-ValueError: An error in the body
->>> print getSite()
-None
-

Deleted: zope.component/trunk/src/zope/component/index.txt
===================================================================
--- zope.component/trunk/src/zope/component/index.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/index.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,22 +0,0 @@
-Welcome to zope.component's documentation!
-==========================================
-
-Contents:
-
-.. toctree::
-   :maxdepth: 2
-
-   README
-   socketexample
-   event
-   factory
-   registry
-   persistentregistry
-   zcml
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`

Modified: zope.component/trunk/src/zope/component/interface.py
===================================================================
--- zope.component/trunk/src/zope/component/interface.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/interface.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -13,78 +13,22 @@
 ##############################################################################
 """Interface utility functions
 """
-__docformat__ = 'restructuredtext'
-
-from types import ClassType
-
-import zope.component
-from zope.component.interfaces import ComponentLookupError
 from zope.interface import alsoProvides
 from zope.interface.interfaces import IInterface
 
-def provideInterface(id, interface, iface_type=None, info=''):
-    """register Interface with global site manager as utility
+from zope.component.globalregistry import getGlobalSiteManager
+from zope.component.interfaces import ComponentLookupError
+from zope.component._api import queryUtility
+from zope.component._compat import CLASS_TYPES
 
-    >>> gsm = zope.component.getGlobalSiteManager()
-
-    >>> from zope.interface import Interface
-    >>> from zope.interface.interfaces import IInterface
-    >>> from zope.component.tests import ITestType
-
-    >>> class I(Interface):
-    ...     pass
-    >>> IInterface.providedBy(I)
-    True
-    >>> ITestType.providedBy(I)
-    False
-    >>> interfaces = gsm.getUtilitiesFor(ITestType)
-    >>> list(interfaces)
-    []
-
-    # provide first interface type
-    >>> provideInterface('', I, ITestType)
-    >>> ITestType.providedBy(I)
-    True
-    >>> interfaces = list(gsm.getUtilitiesFor(ITestType))
-    >>> [name for (name, iface) in interfaces]
-    [u'zope.component.interface.I']
-    >>> [iface.__name__ for (name, iface) in interfaces]
-    ['I']
-
-    # provide second interface type
-    >>> class IOtherType(IInterface):
-    ...     pass
-    >>> provideInterface('', I, IOtherType)
-
-    >>> ITestType.providedBy(I)
-    True
-    >>> IOtherType.providedBy(I)
-    True
-    >>> interfaces = list(gsm.getUtilitiesFor(ITestType))
-    >>> [name for (name, iface) in interfaces]
-    [u'zope.component.interface.I']
-    >>> interfaces = list(gsm.getUtilitiesFor(IOtherType))
-    >>> [name for (name, iface) in interfaces]
-    [u'zope.component.interface.I']
-
-    >>> class I1(Interface):
-    ...     pass
-    >>> provideInterface('', I1)
-    >>> IInterface.providedBy(I1)
-    True
-    >>> ITestType.providedBy(I1)
-    False
-    >>> interfaces = list(gsm.getUtilitiesFor(ITestType))
-    >>> [name for (name, iface) in interfaces]
-    [u'zope.component.interface.I']
-    >>> [iface.__name__ for (name, iface) in interfaces]
-    ['I']
+def provideInterface(id, interface, iface_type=None, info=''):
+    """ Mark 'interface' as a named utilty providing 'iface_type'.
     """
     if not id:
         id = "%s.%s" % (interface.__module__, interface.__name__)
 
     if not IInterface.providedBy(interface):
-        if not isinstance(interface, (type, ClassType)):
+        if not isinstance(interface, CLASS_TYPES):
             raise TypeError(id, "is not an interface or class")
         return
 
@@ -95,33 +39,12 @@
     else:
         iface_type = IInterface
 
-    gsm = zope.component.getGlobalSiteManager()
+    gsm = getGlobalSiteManager()
     gsm.registerUtility(interface, iface_type, id, info)
 
 
 def getInterface(context, id):
     """Return interface or raise ComponentLookupError
-
-    >>> from zope.interface import Interface
-    >>> from zope.component.tests import ITestType
-
-    >>> class I4(Interface):
-    ...     pass
-    >>> IInterface.providedBy(I4)
-    True
-    >>> ITestType.providedBy(I4)
-    False
-    >>> getInterface(None, 'zope.component.interface.I4')
-    Traceback (most recent call last):
-    ...
-    ComponentLookupError: zope.component.interface.I4
-    >>> provideInterface('', I4, ITestType)
-    >>> ITestType.providedBy(I4)
-    True
-    >>> iface = queryInterface( """\
-                """ 'zope.component.interface.I4')
-    >>> iface.__name__
-    'I4'
     """
     iface = queryInterface(id, None)
     if iface is None:
@@ -130,51 +53,13 @@
 
 
 def queryInterface(id, default=None):
-    """return interface or ``None``
-
-    >>> from zope.interface import Interface
-    >>> from zope.interface.interfaces import IInterface
-    >>> from zope.component.tests import ITestType
-
-    >>> class I3(Interface):
-    ...     pass
-    >>> IInterface.providedBy(I3)
-    True
-    >>> ITestType.providedBy(I3)
-    False
-    >>> queryInterface('zope.component.interface.I3')
-    
-    >>> provideInterface('', I3, ITestType)
-    >>> ITestType.providedBy(I3)
-    True
-    >>> iface = queryInterface('zope.component.interface.I3')
-    >>> iface.__name__
-    'I3'
+    """Return an interface or ``None``
     """
-    return zope.component.queryUtility(IInterface, id, default)
+    return queryUtility(IInterface, id, default)
 
 
 def searchInterface(context, search_string=None, base=None):
     """Interfaces search
-
-    >>> from zope.interface import Interface
-    >>> from zope.interface.interfaces import IInterface
-    >>> from zope.component.tests import ITestType
-
-    >>> class I5(Interface):
-    ...     pass
-    >>> IInterface.providedBy(I5)
-    True
-    >>> ITestType.providedBy(I5)
-    False
-    >>> searchInterface(None, 'zope.component.interface.I5')
-    []
-    >>> provideInterface('', I5, ITestType)
-    >>> ITestType.providedBy(I5)
-    True
-    >>> iface = searchInterface(None, 'zope.component.interface.I5')
-    >>> iface[0].__name__
-    'I5'
     """
     return [iface_util[1] for iface_util in
             searchInterfaceUtilities(context, search_string, base)]
@@ -182,32 +67,13 @@
 
 def searchInterfaceIds(context, search_string=None, base=None):
     """Interfaces search
-
-    >>> from zope.interface import Interface
-    >>> from zope.interface.interfaces import IInterface
-    >>> from zope.component.tests import ITestType
-
-    >>> class I5(Interface):
-    ...     pass
-    >>> IInterface.providedBy(I5)
-    True
-    >>> ITestType.providedBy(I5)
-    False
-    >>> searchInterface(None, 'zope.component.interface.I5')
-    []
-    >>> provideInterface('', I5, ITestType)
-    >>> ITestType.providedBy(I5)
-    True
-    >>> iface = searchInterfaceIds(None, 'zope.component.interface.I5')
-    >>> iface
-    [u'zope.component.interface.I5']
     """
     return [iface_util[0] for iface_util in
             searchInterfaceUtilities(context, search_string, base)]
 
 
 def searchInterfaceUtilities(context, search_string=None, base=None):
-    gsm = zope.component.getGlobalSiteManager()
+    gsm = getGlobalSiteManager()
     iface_utilities = gsm.getUtilitiesFor(IInterface)
 
     if search_string:
@@ -217,7 +83,7 @@
                                find(search_string) >= 0)]
     if base:
         res = [iface_util for iface_util in iface_utilities
-               if iface_util[1].extends(base)]
+               if iface_util[1].isOrExtends(base)]
     else:
         res = [iface_util for iface_util in iface_utilities]
     return res
@@ -245,6 +111,8 @@
 def interfaceToName(context, interface):
     if interface is None:
         return 'None'
+    # XXX this search is pointless:  we are always going to return the
+    #     same value whether or not we find anything.
     items = searchInterface(context, base=interface)
     ids = [('%s.%s' %(iface.__module__, iface.__name__))
            for iface in items

Modified: zope.component/trunk/src/zope/component/interfaces.py
===================================================================
--- zope.component/trunk/src/zope/component/interfaces.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/interfaces.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -38,6 +38,9 @@
 from zope.interface.interfaces import IComponentRegistry
 from zope.interface.interfaces import IComponents
 
+from zope.component._compat import _BLANK
+
+
 class IComponentArchitecture(Interface):
     """The Component Architecture is defined by two key components: Adapters
     and Utiltities. Both are managed by site managers. All other components
@@ -112,7 +115,7 @@
     # Adapter API
 
     def getAdapter(object,
-                   interface=Interface, name=u'',
+                   interface=Interface, name=_BLANK,
                    context=None):
         """Get a named adapter to an interface for an object
 
@@ -167,7 +170,7 @@
         named adapter methods with an empty string for a name.
         """
 
-    def queryAdapter(object, interface=Interface, name=u'',
+    def queryAdapter(object, interface=Interface, name=_BLANK,
                      default=None, context=None):
         """Look for a named adapter to an interface for an object
 
@@ -204,7 +207,7 @@
         """
 
     def queryMultiAdapter(objects,
-                          interface=Interface, name=u'',
+                          interface=Interface, name=_BLANK,
                           default=None,
                           context=None):
         """Look for a multi-adapter to an interface for objects
@@ -316,7 +319,7 @@
     activity.
     """
 
-    def provideUtility(component, provides=None, name=u''):
+    def provideUtility(component, provides=None, name=_BLANK):
         """Register a utility globally
 
         A utility is registered to provide an interface with a
@@ -332,7 +335,7 @@
 
         """
 
-    def provideAdapter(factory, adapts=None, provides=None, name=u''):
+    def provideAdapter(factory, adapts=None, provides=None, name=_BLANK):
         """Register an adapter globally
 
         An adapter is registered to provide an interface with a name

Deleted: zope.component/trunk/src/zope/component/nexttesting.py
===================================================================
--- zope.component/trunk/src/zope/component/nexttesting.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/nexttesting.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,104 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2009 Zope Foundation 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.
-#
-##############################################################################
-"""Helper functions for testing utilities that use get/queryNextUtility.
-"""
-import zope.interface
-from zope.component.interfaces import IComponentLookup, IComponents
-
-
-class SiteManagerStub(object):
-    zope.interface.implements(IComponents)
-
-    __bases__ = ()
-
-    def __init__(self):
-        self._utils = {}
-
-    def setNext(self, next):
-        self.__bases__ = (next, )
-
-    def provideUtility(self, iface, util, name=''):
-        self._utils[(iface, name)] = util
-
-    def queryUtility(self, iface, name='', default=None):
-        return self._utils.get((iface, name), default)
-
-
-def testingNextUtility(utility, nextutility, interface, name='',
-                       sitemanager=None, nextsitemanager=None):
-    """Provide a next utility for testing.
-
-    This function sets up two utilities, so the get/queryNextUtility functions
-    will see the second one as the "next" to the first one. 
-
-    To test it, we need to create a utility interface and implementation:
-
-      >>> from zope.interface import Interface, implements
-      >>> class IAnyUtility(Interface):
-      ...     pass
-      
-      >>> class AnyUtility(object):
-      ...     implements(IAnyUtility)
-      ...     def __init__(self, id):
-      ...         self.id = id
-      
-      >>> any1 = AnyUtility(1)
-      >>> any1next = AnyUtility(2)
-
-    Now, we can make the "any1next" be next to "any1". 
-
-      >>> testingNextUtility(any1, any1next, IAnyUtility)
-      
-      >>> from zope.component import getNextUtility
-      >>> getNextUtility(any1, IAnyUtility) is any1next
-      True
-
-    It will work for named utilities as well.
-
-      >>> testingNextUtility(any1, any1next, IAnyUtility, 'any')
-      >>> getNextUtility(any1, IAnyUtility, 'any') is any1next
-      True
-
-    We can also provide our custom component registries:
-    
-      >>> sm = SiteManagerStub()
-      >>> nextsm = SiteManagerStub()
-      
-      >>> testingNextUtility(any1, any1next, IAnyUtility,
-      ...     sitemanager=sm, nextsitemanager=nextsm)
-    
-      >>> IComponentLookup(any1) is sm
-      True
-      >>> IComponentLookup(any1next) is nextsm
-      True
-      >>> getNextUtility(any1, IAnyUtility) is any1next
-      True
-    
-    """
-    if sitemanager is None:
-        sitemanager = SiteManagerStub()
-    if nextsitemanager is None:
-        nextsitemanager = SiteManagerStub()
-    sitemanager.setNext(nextsitemanager)
-
-    sitemanager.provideUtility(interface, utility, name)
-    utility.__conform__ = (
-        lambda iface:
-        iface.isOrExtends(IComponentLookup) and sitemanager or None
-        )
-    nextsitemanager.provideUtility(interface, nextutility, name)
-    nextutility.__conform__ = (
-        lambda iface:
-        iface.isOrExtends(IComponentLookup) and nextsitemanager or None
-        )

Modified: zope.component/trunk/src/zope/component/persistentregistry.py
===================================================================
--- zope.component/trunk/src/zope/component/persistentregistry.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/persistentregistry.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -13,16 +13,13 @@
 ##############################################################################
 """Persistent component managers
 """
-import persistent.mapping
-import persistent.list
-import zope.interface.adapter
-
+from persistent import Persistent
+from persistent.mapping import PersistentMapping
+from persistent.list import PersistentList
+from zope.interface.adapter import VerifyingAdapterRegistry
 from zope.interface.registry import Components
 
-class PersistentAdapterRegistry(
-    zope.interface.adapter.VerifyingAdapterRegistry,
-    persistent.Persistent,
-    ):
+class PersistentAdapterRegistry(VerifyingAdapterRegistry, Persistent):
 
     def changed(self, originally_changed):
         if originally_changed is self:
@@ -48,7 +45,7 @@
         self.utilities = PersistentAdapterRegistry()
 
     def _init_registrations(self):
-        self._utility_registrations = persistent.mapping.PersistentMapping()
-        self._adapter_registrations = persistent.mapping.PersistentMapping()
-        self._subscription_registrations = persistent.list.PersistentList()
-        self._handler_registrations = persistent.list.PersistentList()
+        self._utility_registrations = PersistentMapping()
+        self._adapter_registrations = PersistentMapping()
+        self._subscription_registrations = PersistentList()
+        self._handler_registrations = PersistentList()

Deleted: zope.component/trunk/src/zope/component/persistentregistry.txt
===================================================================
--- zope.component/trunk/src/zope/component/persistentregistry.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/persistentregistry.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,6 +0,0 @@
-Persistent Component Management
-===============================
-
-Persistent component management allows persistent management of
-components.  From a usage point of view, there shouldn't be any new
-behavior beyond what's described in registry.txt.

Deleted: zope.component/trunk/src/zope/component/registry.txt
===================================================================
--- zope.component/trunk/src/zope/component/registry.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/registry.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,1117 +0,0 @@
-Component-Management objects
-============================
-
-Component-management objects provide a higher-level
-component-management API over the basic adapter-registration API
-provided by the zope.interface package.  In particular, it provides:
-
-- utilities
-
-- support for computing adapters, rather than just looking up adapter
-  factories.
-
-- management of registration comments
-
-The zope.component.registry.Components class provides an
-implementation of zope.component.interfaces.IComponents that provides
-these features.
-
-    >>> from zope.component import registry
-    >>> from zope.component import tests
-    >>> components = registry.Components('comps')
-
-As components are registered, events are generated.  Let's register
-an event subscriber, so we can see the events generated:
-
-    >>> import zope.event
-    >>> def logevent(event):
-    ...     print event
-    >>> zope.event.subscribers.append(logevent)
-    
-Utilities
----------
-
-You can register Utilities using registerUtility:
-
-    >>> components.registerUtility(tests.U1(1))
-    Registered event:
-    UtilityRegistration(<Components comps>, I1, u'', 1, None, u'')
-
-Here we didn't specify an interface or name.  An unnamed utility was
-registered for interface I1, since that is only interface implemented
-by the U1 class:
-
-    >>> components.getUtility(tests.I1)
-    U1(1)
-
-You can also register a utility using a factory instead of a utility instance:
-
-    >>> def factory():
-    ...    return tests.U1(1)
-    >>> components.registerUtility(factory=factory)
-    Unregistered event:
-    UtilityRegistration(<Components comps>, I1, u'', 1, None, u'')
-    Registered event:
-    UtilityRegistration(<Components comps>, I1, u'', 1, <function factory at <SOME ADDRESS>>, u'')
-
-
-If a component implements other than one interface or no interface,
-then an error will be raised:
-
-    >>> components.registerUtility(tests.U12(2))
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The utility doesn't provide a single interface and
-    no provided interface was specified.
-
-    >>> components.registerUtility(tests.A)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The utility doesn't provide a single interface and
-    no provided interface was specified.
- 
-    
-We can provide an interface if desired:
-
-    >>> components.registerUtility(tests.U12(2), tests.I2)
-    Registered event:
-    UtilityRegistration(<Components comps>, I2, u'', 2, None, u'')
-
-and we can specify a name:
-
-    >>> components.registerUtility(tests.U12(3), tests.I2, u'three')
-    Registered event:
-    UtilityRegistration(<Components comps>, I2, u'three', 3, None, u'')
-
-    >>> components.getUtility(tests.I2)
-    U12(2)
-
-    >>> components.getUtility(tests.I2, 'three')
-    U12(3)
-
-If you try to get a utility that doesn't exist, you'll get a component
-lookup error:
-
-    >>> components.getUtility(tests.I3)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    ComponentLookupError: 
-    (<InterfaceClass zope.component.tests.I3>, u'')
-
-Unless you use queryUtility:
-
-    >>> components.queryUtility(tests.I3)
-    >>> components.queryUtility(tests.I3, default=42)
-    42
-
-You can get information about registered utilities with the
-registeredUtilities method:
-
-    >>> for registration in sorted(components.registeredUtilities()):
-    ...     print registration.provided, registration.name
-    ...     print registration.component, registration.info
-    <InterfaceClass zope.component.tests.I1> 
-    U1(1) 
-    <InterfaceClass zope.component.tests.I2> 
-    U12(2) 
-    <InterfaceClass zope.component.tests.I2> three
-    U12(3) 
-
-Duplicate registrations replace existing ones:
-
-    >>> components.registerUtility(tests.U1(4), info=u'use 4 now')
-    Unregistered event:
-    UtilityRegistration(<Components comps>, I1, u'', 1, <function factory at <SOME ADDRESS>>, u'')
-    Registered event:
-    UtilityRegistration(<Components comps>, I1, u'', 4, None, u'use 4 now')
-    >>> components.getUtility(tests.I1)
-    U1(4)
-
-    >>> for registration in sorted(components.registeredUtilities()):
-    ...     print registration.provided, registration.name
-    ...     print registration.component, registration.info
-    <InterfaceClass zope.component.tests.I1> 
-    U1(4) use 4 now
-    <InterfaceClass zope.component.tests.I2> 
-    U12(2) 
-    <InterfaceClass zope.component.tests.I2> three
-    U12(3) 
-
-As shown in the this example, you can provide an "info" argumemnt when
-registering utilities.  This provides extra documentation about the
-registration itself that is shown when listing registrations.
-
-You can also unregister utilities:
-
-    >>> components.unregisterUtility(provided=tests.I1)
-    Unregistered event:
-    UtilityRegistration(<Components comps>, I1, u'', 4, None, u'use 4 now')
-    True
-
-A boolean is returned indicating whether anything changed:
-
-    >>> components.queryUtility(tests.I1)
-    >>> for registration in sorted(components.registeredUtilities()):
-    ...     print registration.provided, registration.name
-    ...     print registration.component, registration.info
-    <InterfaceClass zope.component.tests.I2> 
-    U12(2) 
-    <InterfaceClass zope.component.tests.I2> three
-    U12(3) 
-
-When you unregister, you can specify a component.  If the component
-doesn't match the one registered, then nothing happens:
-
-    >>> u5 = tests.U1(5)
-    >>> components.registerUtility(u5)
-    Registered event:
-    UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
-    >>> components.unregisterUtility(tests.U1(6))
-    False
-    >>> components.queryUtility(tests.I1)
-    U1(5)
-    >>> components.unregisterUtility(u5)
-    Unregistered event:
-    UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
-    True
-    >>> components.queryUtility(tests.I1)
-
-You can get the name and utility for all of the utilities that provide
-an interface using getUtilitiesFor:
-
-    >>> sorted(components.getUtilitiesFor(tests.I2))
-    [(u'', U12(2)), (u'three', U12(3))]
-
-getAllUtilitiesRegisteredFor is similar to getUtilitiesFor except that
-it includes utilities that are overridden.  For example, we'll
-register a utility that for an extending interface of I2:
-
-    >>> util = tests.U('ext')
-    >>> components.registerUtility(util, tests.I2e)
-    Registered event:
-    UtilityRegistration(<Components comps>, I2e, u'', ext, None, u'')
-
-We don't get the new utility for getUtilitiesFor:
-
-    >>> sorted(components.getUtilitiesFor(tests.I2))
-    [(u'', U12(2)), (u'three', U12(3))]
-
-but we do get it from getAllUtilitiesRegisteredFor:
-
-    >>> sorted(map(str, components.getAllUtilitiesRegisteredFor(tests.I2)))
-    ['U(ext)', 'U12(2)', 'U12(3)']
-
-Removing a utility also makes it disappear from getUtilitiesFor:
-
-    >>> components.unregisterUtility(util, tests.I2e)
-    Unregistered event:
-    UtilityRegistration(<Components comps>, I2e, u'', ext, None, u'')
-    True
-    >>> list(components.getAllUtilitiesRegisteredFor(tests.I2e))
-    []
-
-Adapters
---------
-
-You can register adapters with registerAdapter:
-
-    >>> components.registerAdapter(tests.A12_1)
-    Registered event:
-    AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
-
-Here, we didn't specify required interfaces, a provided interface, or
-a name.  The required interfaces were determined from the factory
-s __component_adapts__ attribute and the provided interface was
-determined by introspecting what the factory implements.
-
-    >>> components.getMultiAdapter((tests.U1(6), tests.U12(7)), tests.IA1)
-    A12_1(U1(6), U12(7))
-
-If a factory implements more than one interface, an exception will be
-raised:
-
-    >>> components.registerAdapter(tests.A1_12)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't implement a single
-    interface and no provided interface was specified.
-
-Unless the provided interface is specified:
-
-    >>> components.registerAdapter(tests.A1_12, provided=tests.IA2)
-    Registered event:
-    AdapterRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
-
-If a factory doesn't declare an implemented interface, an exception will be
-raised:
-
-    >>> components.registerAdapter(tests.A12_)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't implement a single
-    interface and no provided interface was specified. 
-
-Unless the provided interface is specified:
-
-    >>> components.registerAdapter(tests.A12_, provided=tests.IA2)
-    Registered event:
-    AdapterRegistration(<Components comps>, [I1, I2], IA2, u'', A12_, u'')
-
-The required interface needs to be specified in the registration if
-the factory doesn't have a __component_adapts__ attribute: 
-
-    >>> components.registerAdapter(tests.A_2)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't have a __component_adapts__
-    attribute and no required specifications were specified 
-
-Unless the required specifications specified:
-
-    >>> components.registerAdapter(tests.A_2, required=[tests.I3])
-    Registered event:
-    AdapterRegistration(<Components comps>, [I3], IA2, u'', A_2, u'')
-
-Classes can be specified in place of specifications, in which case the
-implementedBy specification for the class is used:
-
-    >>> components.registerAdapter(tests.A_3, required=[tests.U],
-    ...                            info="Really class specific")
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Registered event:
-    AdapterRegistration(<Components comps>, [zope.component.tests.U], IA3, u'',
-                        A_3, 'Really class specific')
-
-We can see the adapters that have been registered using the
-registeredAdapters method:
-
-    >>> for registration in sorted(components.registeredAdapters()):
-    ...     print registration.required
-    ...     print registration.provided, registration.name
-    ...     print registration.factory, registration.info
-    ... # doctest: +NORMALIZE_WHITESPACE
-    (<InterfaceClass zope.component.tests.I1>, 
-     <InterfaceClass zope.component.tests.I2>)
-    <InterfaceClass zope.component.tests.IA1> 
-    zope.component.tests.A12_1 
-    (<InterfaceClass zope.component.tests.I1>, 
-     <InterfaceClass zope.component.tests.I2>)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A12_ 
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A1_12 
-    (<InterfaceClass zope.component.tests.I3>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A_2 
-    (<implementedBy zope.component.tests.U>,)
-    <InterfaceClass zope.component.tests.IA3> 
-    zope.component.tests.A_3 Really class specific
-
-As with utilities, we can provide registration information when
-registering adapters.
-
-If you try to fetch an adapter that isn't registered, you'll get a
-component-lookup error:
-
-    >>> components.getMultiAdapter((tests.U(8), ), tests.IA1)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    ComponentLookupError: ((U(8),), 
-                          <InterfaceClass zope.component.tests.IA1>, u'')
-
-unless you use queryAdapter:
-
-    >>> components.queryMultiAdapter((tests.U(8), ), tests.IA1)
-    >>> components.queryMultiAdapter((tests.U(8), ), tests.IA1, default=42)
-    42
-
-When looking up an adapter for a single object, you can use the
-slightly simpler getAdapter and queryAdapter calls:
-
-    >>> components.getAdapter(tests.U1(9), tests.IA2)
-    A1_12(U1(9))
-
-    >>> components.queryAdapter(tests.U1(9), tests.IA2)
-    A1_12(U1(9))
-
-    >>> components.getAdapter(tests.U(8), tests.IA1)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    ComponentLookupError: (U(8), 
-                           <InterfaceClass zope.component.tests.IA1>, u'')
-
-    >>> components.queryAdapter(tests.U(8), tests.IA2)
-    >>> components.queryAdapter(tests.U(8), tests.IA2, default=42)
-    42
-
-You can unregister an adapter.  If a factory is provided and if the
-rewuired and provided interfaces, can be infered, then they need not
-be provided:
-
-    >>> components.unregisterAdapter(tests.A12_1)
-    Unregistered event:
-    AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
-    True
-
-    >>> for registration in sorted(components.registeredAdapters()):
-    ...     print registration.required
-    ...     print registration.provided, registration.name
-    ...     print registration.factory, registration.info
-    ... # doctest: +NORMALIZE_WHITESPACE
-    (<InterfaceClass zope.component.tests.I1>, 
-     <InterfaceClass zope.component.tests.I2>)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A12_ 
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A1_12 
-    (<InterfaceClass zope.component.tests.I3>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A_2 
-    (<implementedBy zope.component.tests.U>,)
-    <InterfaceClass zope.component.tests.IA3> 
-    zope.component.tests.A_3 Really class specific
-
-A boolean is returned indicating whether a change was made.
-
-If a factory implements more than one interface, an exception will be
-raised:
-
-    >>> components.unregisterAdapter(tests.A1_12)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't implement a single
-    interface and no provided interface was specified.
-
-Unless the provided interface is specified:
-
-    >>> components.unregisterAdapter(tests.A1_12, provided=tests.IA2)
-    Unregistered event:
-    AdapterRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
-    True
-
-If a factory doesn't declare an implemented interface, an exception will be
-raised:
-
-    >>> components.unregisterAdapter(tests.A12_)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't implement a single
-    interface and no provided interface was specified. 
-
-Unless the provided interface is specified:
-
-    >>> components.unregisterAdapter(tests.A12_, provided=tests.IA2)
-    Unregistered event:
-    AdapterRegistration(<Components comps>, [I1, I2], IA2, u'', A12_, u'')
-    True
-
-The required interface needs to be specified if the factory doesn't
-have a __component_adapts__ attribute:
-
-    >>> components.unregisterAdapter(tests.A_2)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't have a __component_adapts__
-    attribute and no required specifications were specified 
-
-    >>> components.unregisterAdapter(tests.A_2, required=[tests.I3])
-    Unregistered event:
-    AdapterRegistration(<Components comps>, [I3], IA2, u'', A_2, u'')
-    True
-
-    >>> for registration in sorted(components.registeredAdapters()):
-    ...     print registration.required
-    ...     print registration.provided, registration.name
-    ...     print registration.factory, registration.info
-    ... # doctest: +NORMALIZE_WHITESPACE
-    (<implementedBy zope.component.tests.U>,)
-    <InterfaceClass zope.component.tests.IA3> 
-    zope.component.tests.A_3 Really class specific
-
-If a factory is unregistered that is not registered, False is
-returned:
-
-
-    >>> components.unregisterAdapter(tests.A_2, required=[tests.I3])
-    False
-    >>> components.unregisterAdapter(tests.A12_1, required=[tests.U])
-    False
-
-The factory can be omitted, to unregister *any* factory that matches
-specified required and provided interfaces:
-
-    >>> components.unregisterAdapter(required=[tests.U], provided=tests.IA3)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Unregistered event:
-    AdapterRegistration(<Components comps>, [zope.component.tests.U], 
-                        IA3, u'', A_3, 'Really class specific')
-    True
-
-    >>> for registration in sorted(components.registeredAdapters()):
-    ...     print registration
-
-Adapters can be named:
-
-    >>> components.registerAdapter(tests.A1_12, provided=tests.IA2, 
-    ...                            name=u'test')
-    Registered event:
-    AdapterRegistration(<Components comps>, [I1], IA2, u'test', A1_12, u'')
-
-    >>> components.queryMultiAdapter((tests.U1(9), ), tests.IA2)
-    >>> components.queryMultiAdapter((tests.U1(9), ), tests.IA2, name=u'test')
-    A1_12(U1(9))
-
-    >>> components.queryAdapter(tests.U1(9), tests.IA2)
-    >>> components.queryAdapter(tests.U1(9), tests.IA2, name=u'test')
-    A1_12(U1(9))
-    >>> components.getAdapter(tests.U1(9), tests.IA2, name=u'test')
-    A1_12(U1(9))
-
-It is possible to look up all of the adapters that provide an
-interface:
-
-    >>> components.registerAdapter(tests.A1_23, provided=tests.IA2, 
-    ...                            name=u'test 2')
-    Registered event:
-    AdapterRegistration(<Components comps>, [I1], IA2, u'test 2', A1_23, u'')
-
-    >>> components.registerAdapter(tests.A1_12, provided=tests.IA2)
-    Registered event:
-    AdapterRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
-
-    >>> for name, adapter in sorted(components.getAdapters((tests.U1(9), ), 
-    ...                                                    tests.IA2)):
-    ...     print name, adapter
-     A1_12(U1(9))
-    test A1_12(U1(9))
-    test 2 A1_23(U1(9))
-
-
-getAdapters is most commonly used as the basis of menu systems.
-
-If an adapter factory returns None, it is equivalent to there being no
-factory:
-
-    >>> components.registerAdapter(tests.noop, 
-    ...                            required=[tests.IA1], provided=tests.IA2, 
-    ...                            name=u'test noop')
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Registered event:
-    AdapterRegistration(<Components comps>, [IA1], IA2, u'test noop', 
-                        noop, u'')
-    >>> components.queryAdapter(tests.U1(9), tests.IA2, name=u'test noop')
-
-    >>> components.registerAdapter(tests.A1_12, provided=tests.IA2)
-    Registered event:
-    AdapterRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
-
-    >>> for name, adapter in sorted(components.getAdapters((tests.U1(9), ), 
-    ...                                                    tests.IA2)):
-    ...     print name, adapter
-     A1_12(U1(9))
-    test A1_12(U1(9))
-    test 2 A1_23(U1(9))
-
-
-    >>> components.unregisterAdapter(tests.A1_12, provided=tests.IA2, 
-    ...                              name=u'test')
-    Unregistered event:
-    AdapterRegistration(<Components comps>, [I1], IA2, u'test', A1_12, u'')
-    True
-    >>> components.unregisterAdapter(tests.A1_12, provided=tests.IA2)
-    Unregistered event:
-    AdapterRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
-    True
-    >>> for registration in sorted(components.registeredAdapters()):
-    ...     print registration.required
-    ...     print registration.provided, registration.name
-    ...     print registration.factory, registration.info
-    ... # doctest: +NORMALIZE_WHITESPACE
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> test 2
-    zope.component.tests.A1_23 
-    (<InterfaceClass zope.component.tests.IA1>,)
-    <InterfaceClass zope.component.tests.IA2> test noop
-    <function noop at 0xb79a1064> 
-
-
-Subscribers
------------
-
-Subscribers provide a way to get multiple adapters of a given type.
-In this regard, subscribers are like named adapters, except that there
-isn't any concept of the most specific adapter for a given name.
-
-Subscribers are registered by calling registerSubscriptionAdapter:
-
-    >>> components.registerSubscriptionAdapter(tests.A1_2)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Registered event:
-    SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, u'')
-
-    >>> components.registerSubscriptionAdapter(
-    ...     tests.A1_12, provided=tests.IA2)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Registered event:
-    SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_12, u'')
-
-    >>> components.registerSubscriptionAdapter(
-    ...     tests.A, [tests.I1], tests.IA2,
-    ...     info='a sample comment')
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Registered event:
-    SubscriptionRegistration(<Components comps>, [I1], IA2, u'', 
-                             A, 'a sample comment')
-
-The same rules, with regard to when required and provided interfaces
-have to be specified apply as with adapters:
-
-    >>> components.registerSubscriptionAdapter(tests.A1_12)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't implement a single 
-    interface and no provided interface was specified.
-
-    >>> components.registerSubscriptionAdapter(tests.A)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't implement a single interface and
-     no provided interface was specified.
-
-    >>> components.registerSubscriptionAdapter(tests.A, required=[tests.IA1])
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't implement a single interface
-    and no provided interface was specified.
-
-Note that we provided the info argument as a keyword argument above.
-That's because there is a name argument that's reserved for future
-use. We can give a name, as long as it is an empty string:
-
-    >>> components.registerSubscriptionAdapter(
-    ...     tests.A, [tests.I1], tests.IA2, u'', 'a sample comment')
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Registered event:
-    SubscriptionRegistration(<Components comps>, [I1], IA2, u'', 
-                             A, 'a sample comment')
-
-    >>> components.registerSubscriptionAdapter(
-    ...     tests.A, [tests.I1], tests.IA2, u'oops', 'a sample comment')
-    Traceback (most recent call last):
-    ...
-    TypeError: Named subscribers are not yet supported
-
-Subscribers are looked up using the subscribers method:
-
-    >>> for s in components.subscribers((tests.U1(1), ), tests.IA2):
-    ...    print s
-    A1_2(U1(1))
-    A1_12(U1(1))
-    A(U1(1),)
-    A(U1(1),)
-
-Note that, because we created multiple subscriptions for A, we got multiple
-subscriber instances.
-
-As with normal adapters, if a factory returns None, the result is skipped:
-
-    >>> components.registerSubscriptionAdapter(
-    ...     tests.noop, [tests.I1], tests.IA2)
-    Registered event:
-    SubscriptionRegistration(<Components comps>, [I1], IA2, u'', noop, u'')
-
-    >>> for s in components.subscribers((tests.U1(1), ), tests.IA2):
-    ...    print s
-    A1_2(U1(1))
-    A1_12(U1(1))
-    A(U1(1),)
-    A(U1(1),)
-
-We can get registration information for subscriptions:
-
-    >>> for registration in sorted(
-    ...     components.registeredSubscriptionAdapters()):
-    ...     print registration.required
-    ...     print registration.provided, registration.name
-    ...     print registration.factory, registration.info
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A a sample comment
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A a sample comment
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A1_12 
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A1_2 
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    <function noop at 0xb796ff7c> 
-
-We can also unregister subscriptions in much the same way we can for adapters:
-
-    >>> components.unregisterSubscriptionAdapter(tests.A1_2)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Unregistered event:
-    SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, '')
-    True
-
-    >>> for s in components.subscribers((tests.U1(1), ), tests.IA2):
-    ...    print s
-    A1_12(U1(1))
-    A(U1(1),)
-    A(U1(1),)
-
-    >>> for registration in sorted(
-    ...     components.registeredSubscriptionAdapters()):
-    ...     print registration.required
-    ...     print registration.provided, registration.name
-    ...     print registration.factory, registration.info
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A a sample comment
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A a sample comment
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A1_12 
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    <function noop at 0xb796ff7c> 
-
-    >>> components.unregisterSubscriptionAdapter(
-    ...     tests.A, [tests.I1], tests.IA2)
-    Unregistered event:
-    SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A, '')
-    True
-
-    >>> for s in components.subscribers((tests.U1(1), ), tests.IA2):
-    ...    print s
-    A1_12(U1(1))
-
-    >>> for registration in sorted(
-    ...     components.registeredSubscriptionAdapters()):
-    ...     print registration.required
-    ...     print registration.provided, registration.name
-    ...     print registration.factory, registration.info
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    zope.component.tests.A1_12 
-    (<InterfaceClass zope.component.tests.I1>,)
-    <InterfaceClass zope.component.tests.IA2> 
-    <function noop at 0xb796ff7c> 
-
-Note here that both registrations for A were removed.
-
-If we omit the factory, we must specify the required and provided interfaces:
-
-    >>> components.unregisterSubscriptionAdapter(required=[tests.I1])
-    Traceback (most recent call last):
-    ...
-    TypeError: Must specify one of factory and provided
-
-    >>> components.unregisterSubscriptionAdapter(provided=tests.IA2)
-    Traceback (most recent call last):
-    ...
-    TypeError: Must specify one of factory and required
-
-    >>> components.unregisterSubscriptionAdapter(
-    ...     required=[tests.I1], provided=tests.IA2)
-    Unregistered event:
-    SubscriptionRegistration(<Components comps>, [I1], IA2, u'', None, '')
-    True
-
-    >>> for s in components.subscribers((tests.U1(1), ), tests.IA2):
-    ...    print s
-
-    >>> for registration in sorted(
-    ...     components.registeredSubscriptionAdapters()):
-    ...     print registration.factory
-
-As when registering, an error is raised if the registration
-information can't be determined from the factory and isn't specified:
-
-    >>> components.unregisterSubscriptionAdapter(tests.A1_12)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't implement a single 
-    interface and no provided interface was specified.
-
-    >>> components.unregisterSubscriptionAdapter(tests.A)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't implement a single interface and
-     no provided interface was specified.
-
-    >>> components.unregisterSubscriptionAdapter(tests.A, required=[tests.IA1])
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't implement a single interface
-    and no provided interface was specified.
-
-If you unregister something that's not registered, nothing will be
-changed and False will be returned:
-
-
-    >>> components.unregisterSubscriptionAdapter(
-    ...     required=[tests.I1], provided=tests.IA2)
-    False
-
-Handlers
---------
-
-Handlers are used when you want to perform some function in response
-to an event.  Handlers aren't expected to return anything when called
-and are not registered to provide any interface.
-
-    >>> from zope import component
-    >>> @component.adapter(tests.I1)
-    ... def handle1(x):
-    ...     print 'handle1', x
-
-    >>> components.registerHandler(handle1, info="First handler")
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Registered event:
-    HandlerRegistration(<Components comps>, [I1], u'', 
-                        handle1, 'First handler')
-    >>> components.handle(tests.U1(1))
-    handle1 U1(1)
-
-    >>> @component.adapter(tests.I1, tests.I2)
-    ... def handle12(x, y):
-    ...     print 'handle12', x, y
-
-    >>> components.registerHandler(handle12)
-    Registered event:
-    HandlerRegistration(<Components comps>, [I1, I2], u'', handle12, u'')
-    >>> components.handle(tests.U1(1), tests.U12(2))
-    handle12 U1(1) U12(2)
-
-If a handler doesn't document interfaces it handles, then 
-the required interfaces must be specified:
-
-    >>> def handle(*objects):
-    ...     print 'handle', objects
-
-    >>> components.registerHandler(handle)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't have a __component_adapts__ 
-    attribute and no required specifications were specified
-
-    >>> components.registerHandler(handle, required=[tests.I1], 
-    ...                            info="a comment")
-    Registered event:
-    HandlerRegistration(<Components comps>, [I1], u'', handle, 'a comment')
-
-Handlers can also be registered for classes:
-
-    >>> components.registerHandler(handle, required=[tests.U], 
-    ...                            info="handle a class")
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Registered event:
-    HandlerRegistration(<Components comps>, [zope.component.tests.U], u'', 
-                        handle, 'handle a class')
-
-
-    >>> components.handle(tests.U1(1))
-    handle (U1(1),)
-    handle1 U1(1)
-    handle (U1(1),)
-
-We can list the handler registrations:
-
-    >>> for registration in components.registeredHandlers():
-    ...     print registration.required
-    ...     print registration.handler, registration.info
-    ... # doctest: +NORMALIZE_WHITESPACE
-    (<InterfaceClass zope.component.tests.I1>,)
-    <function handle1 at 0xb78f5bfc> First handler
-    (<InterfaceClass zope.component.tests.I1>,
-     <InterfaceClass zope.component.tests.I2>)
-    <function handle12 at 0xb78f5c34> 
-    (<InterfaceClass zope.component.tests.I1>,)
-    <function handle at 0xb78f5ca4> a comment
-    (<implementedBy zope.component.tests.U>,)
-    <function handle at 0xb78f5ca4> handle a class
-
-and we can unregister handlers:
-
-    >>> components.unregisterHandler(required=[tests.U])
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Unregistered event:
-    HandlerRegistration(<Components comps>, [zope.component.tests.U], u'', 
-                        None, '')
-    True
-
-    >>> for registration in components.registeredHandlers():
-    ...     print registration.required
-    ...     print registration.handler, registration.info
-    ... # doctest: +NORMALIZE_WHITESPACE
-    (<InterfaceClass zope.component.tests.I1>,)
-    <function handle1 at 0xb78f5bfc> First handler
-    (<InterfaceClass zope.component.tests.I1>,
-     <InterfaceClass zope.component.tests.I2>)
-    <function handle12 at 0xb78f5c34> 
-    (<InterfaceClass zope.component.tests.I1>,)
-    <function handle at 0xb78f5ca4> a comment
-
-    >>> components.unregisterHandler(handle12)
-    Unregistered event:
-    HandlerRegistration(<Components comps>, [I1, I2], u'', handle12, '')
-    True
-
-    >>> for registration in components.registeredHandlers():
-    ...     print registration.required
-    ...     print registration.handler, registration.info
-    (<InterfaceClass zope.component.tests.I1>,)
-    <function handle1 at 0xb78f5bfc> First handler
-    (<InterfaceClass zope.component.tests.I1>,)
-    <function handle at 0xb78f5ca4> a comment
-
-    >>> components.unregisterHandler(handle12)
-    False
-
-    >>> components.unregisterHandler()
-    Traceback (most recent call last):
-    ...
-    TypeError: Must specify one of factory and required
-
-    >>> components.registerHandler(handle)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Traceback (most recent call last):
-    ...
-    TypeError: The adapter factory doesn't have a __component_adapts__ 
-    attribute and no required specifications were specified
-
-Extending
----------
-
-Component-management objects can extend other component-management
-objects. 
-
-    >>> c1 = registry.Components('1')
-    >>> c1.__bases__
-    ()
-
-    >>> c2 = registry.Components('2', (c1, ))
-    >>> c2.__bases__ == (c1, )
-    True
-
-    >>> c1.registerUtility(tests.U1(1))
-    Registered event:
-    UtilityRegistration(<Components 1>, I1, u'', 1, None, u'')
-
-    >>> c1.queryUtility(tests.I1)
-    U1(1)
-    >>> c2.queryUtility(tests.I1)
-    U1(1)
-    >>> c1.registerUtility(tests.U1(2))
-    Unregistered event:
-    UtilityRegistration(<Components 1>, I1, u'', 1, None, u'')
-    Registered event:
-    UtilityRegistration(<Components 1>, I1, u'', 2, None, u'')
-
-    >>> c2.queryUtility(tests.I1)
-    U1(2)
-
-We can use multiple inheritence:
-
-    >>> c3 = registry.Components('3', (c1, ))
-    >>> c4 = registry.Components('4', (c2, c3))
-    >>> c4.queryUtility(tests.I1)
-    U1(2)
-
-    >>> c1.registerUtility(tests.U12(1), tests.I2)
-    Registered event:
-    UtilityRegistration(<Components 1>, I2, u'', 1, None, u'')
-
-    >>> c4.queryUtility(tests.I2)
-    U12(1)
-
-    >>> c3.registerUtility(tests.U12(3), tests.I2)
-    Registered event:
-    UtilityRegistration(<Components 3>, I2, u'', 3, None, u'')
-    >>> c4.queryUtility(tests.I2)
-    U12(3)
-
-    >>> c1.registerHandler(handle1, info="First handler")
-    Registered event:
-    HandlerRegistration(<Components 1>, [I1], u'', handle1, 'First handler')
-
-    >>> c2.registerHandler(handle, required=[tests.U])
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Registered event:
-    HandlerRegistration(<Components 2>, [zope.component.tests.U], u'', 
-                        handle, u'')
-    
-    >>> @component.adapter(tests.I1)
-    ... def handle3(x):
-    ...     print 'handle3', x
-    >>> c3.registerHandler(handle3)
-    Registered event:
-    HandlerRegistration(<Components 3>, [I1], u'', handle3, u'')
-    
-    >>> @component.adapter(tests.I1)
-    ... def handle4(x):
-    ...     print 'handle4', x
-    >>> c4.registerHandler(handle4)
-    Registered event:
-    HandlerRegistration(<Components 4>, [I1], u'', handle4, u'')
-
-    >>> c4.handle(tests.U1(1))
-    handle1 U1(1)
-    handle3 U1(1)
-    handle (U1(1),)
-    handle4 U1(1)
-
-Redispatch of registration events
----------------------------------
-
-Some handlers are available that, if registered, redispatch
-registration events to the objects being registered.  They depend on
-being dispatched to by the object-event dispatcher:
-
-    >>> from zope import component
-    >>> import zope.component.event
-    >>> zope.component.getGlobalSiteManager().registerHandler(
-    ...      zope.component.event.objectEventNotify)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Registered event:
-    HandlerRegistration(<BaseGlobalComponents base>, 
-                        [IObjectEvent], u'', objectEventNotify, u'')
-
-To see this, we'll first register a multi-handler to show is when
-handlers are called on 2 objects:
-
-    >>> @zope.component.adapter(None, None)
-    ... def double_handler(o1, o2):
-    ...     print 'Double dispatch:'
-    ...     print ' ', o1
-    ...     print ' ', o2
-    >>> zope.component.getGlobalSiteManager().registerHandler(double_handler)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Double dispatch:
-      HandlerRegistration(<BaseGlobalComponents base>, 
-                          [Interface, Interface], u'', double_handler, u'')
-      Registered event:
-      HandlerRegistration(<BaseGlobalComponents base>, 
-      [Interface, Interface], u'', double_handler, u'')
-    Registered event:
-    HandlerRegistration(<BaseGlobalComponents base>, 
-                        [Interface, Interface], u'', double_handler, u'')
-
-In the example above, the double_handler reported it's own registration. :)
-
-Now we'll register our handlers:
-
-    >>> zope.component.getGlobalSiteManager().registerHandler(
-    ...     registry.dispatchUtilityRegistrationEvent)
-    ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-    Double dispatch:
-    ...
-
-    >>> zope.component.getGlobalSiteManager().registerHandler(
-    ...     registry.dispatchAdapterRegistrationEvent)
-    ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-    Double dispatch:
-    ...
-
-    >>> zope.component.getGlobalSiteManager().registerHandler(
-    ...     registry.dispatchSubscriptionAdapterRegistrationEvent)
-    ... # doctest: +NORMALIZE_WHITESPACE +ELLIPSIS
-    Double dispatch:
-    ...
-
-    >>> zope.component.getGlobalSiteManager().registerHandler(
-    ...     registry.dispatchHandlerRegistrationEvent)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Double dispatch:
-      HandlerRegistration(<BaseGlobalComponents base>, 
-                          [IHandlerRegistration, IRegistrationEvent], u'', 
-                          dispatchHandlerRegistrationEvent, u'')
-      Registered event:
-      HandlerRegistration(<BaseGlobalComponents base>, 
-                          [IHandlerRegistration, IRegistrationEvent], u'', 
-                          dispatchHandlerRegistrationEvent, u'')
-    Double dispatch:
-      <function dispatchHandlerRegistrationEvent at 0xb799f72c>
-      Registered event:
-      HandlerRegistration(<BaseGlobalComponents base>,
-                          [IHandlerRegistration, IRegistrationEvent], u'',
-                          dispatchHandlerRegistrationEvent, u'')
-    Registered event:
-    HandlerRegistration(<BaseGlobalComponents base>,
-                        [IHandlerRegistration, IRegistrationEvent], u'',
-                        dispatchHandlerRegistrationEvent, u'')
-
-In the last example above, we can see that the registration of
-dispatchHandlerRegistrationEvent was handled by
-dispatchHandlerRegistrationEvent and redispatched.  This can be seen
-in the second double-dispatch output, where the first argument is the
-object being registered, which is dispatchHandlerRegistrationEvent.
-
-If we change some other registrations, we can the double dispatch
-taking place:
-
-    >>> components.registerUtility(u5)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Double dispatch:
-      UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
-      Registered event:
-      UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
-    Double dispatch:
-      U1(5)
-      Registered event:
-      UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
-    Registered event:
-    UtilityRegistration(<Components comps>, I1, u'', 5, None, u'')
-
-    >>> components.registerAdapter(tests.A12_1)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Double dispatch:
-      AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
-      Registered event:
-      AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
-    Double dispatch:
-      zope.component.tests.A12_1
-      Registered event:
-      AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
-    Registered event:
-    AdapterRegistration(<Components comps>, [I1, I2], IA1, u'', A12_1, u'')
-
-    >>> components.registerSubscriptionAdapter(tests.A1_2)
-    ... # doctest: +NORMALIZE_WHITESPACE
-    Double dispatch:
-      SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, u'')
-      Registered event:
-      SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, u'')
-    Double dispatch:
-      zope.component.tests.A1_2
-      Registered event:
-      SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, u'')
-    Registered event:
-    SubscriptionRegistration(<Components comps>, [I1], IA2, u'', A1_2, u'')

Modified: zope.component/trunk/src/zope/component/security.py
===================================================================
--- zope.component/trunk/src/zope/component/security.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/security.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -13,13 +13,15 @@
 ##############################################################################
 """zope.security support for the configuration handlers
 """
-__docformat__ = "reStructuredText"
-
 from zope.interface import providedBy
-from zope.proxy import ProxyBase, getProxiedObject
-from zope.security.adapter import LocatingTrustedAdapterFactory, \
-    LocatingUntrustedAdapterFactory, TrustedAdapterFactory
-from zope.security.checker import Checker, CheckerPublic, InterfaceChecker
+from zope.proxy import ProxyBase
+from zope.proxy import getProxiedObject
+from zope.security.adapter import LocatingTrustedAdapterFactory
+from zope.security.adapter import LocatingUntrustedAdapterFactory
+from zope.security.adapter import TrustedAdapterFactory
+from zope.security.checker import Checker
+from zope.security.checker import CheckerPublic
+from zope.security.checker import InterfaceChecker
 from zope.security.proxy import Proxy
 
 
@@ -60,7 +62,8 @@
 
     if checker is None:
         if provides is None or permission is None:
-            raise ValueError, 'Required arguments: checker or both provides and permissions'
+            raise ValueError('Required arguments: '
+                                'checker or both provides and permissions')
         if permission == PublicPermission:
             permission = CheckerPublic
         checker = InterfaceChecker(provides, permission)
@@ -84,82 +87,6 @@
     return factory
 
 def securityAdapterFactory(factory, permission, locate, trusted):
-    """
-    If a permission is provided when wrapping the adapter, it will be
-    wrapped in a LocatingAdapterFactory.
-
-      >>> class Factory:
-      ...     pass
-
-    If both locate and trusted are False and a non-public
-    permission is provided, then the factory is wrapped into a
-    LocatingUntrustedAdapterFactory:
-
-      >>> factory = securityAdapterFactory(Factory, 'zope.AnotherPermission',
-      ...    locate=False, trusted=False)
-
-      >>> isinstance(factory, LocatingUntrustedAdapterFactory)
-      True
-
-    If a PublicPermission is provided, then the factory is not touched.
-
-      >>> factory = securityAdapterFactory(Factory, PublicPermission,
-      ...    locate=False, trusted=False)
-
-      >>> factory is Factory
-      True
-
-    Same for CheckerPublic:
-
-      >>> factory = securityAdapterFactory(Factory, CheckerPublic,
-      ...    locate=False, trusted=False)
-
-      >>> factory is Factory
-      True
-
-    If the permission is None, the factory isn't touched:
-
-      >>> factory = securityAdapterFactory(Factory, None,
-      ...    locate=False, trusted=False)
-
-      >>> factory is Factory
-      True
-
-    If the factory is trusted and a no permission is provided then the
-    adapter is wrapped into a TrustedAdapterFactory:
-
-      >>> factory = securityAdapterFactory(Factory, None,
-      ...    locate=False, trusted=True)
-
-      >>> isinstance(factory, TrustedAdapterFactory)
-      True
-
-    Same for PublicPermission:
-
-      >>> factory = securityAdapterFactory(Factory, PublicPermission,
-      ...    locate=False, trusted=True)
-
-      >>> isinstance(factory, TrustedAdapterFactory)
-      True
-
-    Same for CheckerPublic:
-
-      >>> factory = securityAdapterFactory(Factory, CheckerPublic,
-      ...    locate=False, trusted=True)
-
-      >>> isinstance(factory, TrustedAdapterFactory)
-      True
-
-    If the factory is trusted and a locate is true, then the
-    adapter is wrapped into a LocatingTrustedAdapterFactory:
-
-      >>> factory = securityAdapterFactory(Factory, 'zope.AnotherPermission',
-      ...    locate=True, trusted=True)
-
-      >>> isinstance(factory, LocatingTrustedAdapterFactory)
-      True
-
-    """
     if permission == PublicPermission:
         permission = CheckerPublic
     if locate or (permission is not None and permission is not CheckerPublic):

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

Modified: zope.component/trunk/src/zope/component/standalonetests.py
===================================================================
--- zope.component/trunk/src/zope/component/standalonetests.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/standalonetests.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,54 +1,49 @@
 """
-Standalone Tests
+See: https://bugs.launchpad.net/zope3/+bug/98401
 """
-import unittest
-import doctest
 import sys
 import pickle
 
-if __name__ == "__main__":
-    sys.path = pickle.loads(sys.stdin.read())
+def write(x):
+    sys.stdout.write('%s\n' % x)
 
-from zope import interface
-from zope.component.testing import setUp, tearDown
+if __name__ == "__main__": #pragma NO COVER (runs in subprocess)
+    #sys.path = pickle.loads(sys.stdin.read())
+    write('XXXXXXXXXX')
+    for p in sys.path:
+        write('- %s' % p)
+    write('XXXXXXXXXX')
 
-class I1(interface.Interface):
-    pass
+    import zope
+    from zope.interface import Interface
+    from zope.interface import implementer
 
-class I2(interface.Interface):
-    pass
+    class I1(Interface):
+        pass
 
-class Ob(object):
-    interface.implements(I1)
-    def __repr__(self):
-        return '<instance Ob>'
+    class I2(Interface):
+        pass
 
-ob = Ob()
+    @implementer(I1)
+    class Ob(object):
+        def __repr__(self):
+            return '<instance Ob>'
 
-class Comp(object):
-    interface.implements(I2)
-    def __init__(self, context):
-        self.context = context
+    ob = Ob()
 
-def providing_adapter_sets_adapter_hook():
-    """
-    A side effect of importing installs the adapter hook.  See
-    http://www.zope.org/Collectors/Zope3-dev/674.
+    @implementer(I2)
+    class Comp(object):
+        def __init__(self, context):
+            self.context = context
 
-      >>> import zope.component
-      >>> zope.component.provideAdapter(Comp, (I1,), I2)
-      >>> adapter = I2(ob)
-      >>> adapter.__class__ is Comp
-      True
-      >>> adapter.context is ob
-      True
-    """
+    write('YYYYYYYYY')
+    for p in zope.__path__:
+        write('- %s' % p)
+    write('YYYYYYYYY')
+    import zope.component
 
-
-def test_suite():
-    return unittest.TestSuite((
-        doctest.DocTestSuite(setUp=setUp, tearDown=tearDown),
-        ))
-
-if __name__ == "__main__":
-    unittest.main(defaultTest='test_suite')
+    zope.component.provideAdapter(Comp, (I1,), I2)
+    adapter = I2(ob)
+    write('ZZZZZZZZ')
+    assert adapter.__class__ is Comp
+    assert adapter.context is ob

Modified: zope.component/trunk/src/zope/component/testfiles/adapter.py
===================================================================
--- zope.component/trunk/src/zope/component/testfiles/adapter.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/testfiles/adapter.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -13,22 +13,25 @@
 ##############################################################################
 """Sample adapter class for testing
 """
-import zope.interface
-import zope.component
-import components
 
-class I1(zope.interface.Interface):
+from zope.interface import Interface
+from zope.interface import implementer
+
+from zope.component import adapter
+from zope.component.testfiles import components
+
+class I1(Interface):
     pass
 
-class I2(zope.interface.Interface):
+class I2(Interface):
     pass
 
-class I3(zope.interface.Interface):
+class I3(Interface):
     def f1(): pass
     def f2(): pass
     def f3(): pass
 
-class IS(zope.interface.Interface):
+class IS(Interface):
     pass
 
 
@@ -36,23 +39,27 @@
     def __init__(self, *args):
         self.context = args
 
+ at implementer(I1)
 class A1(Adapter):
-    zope.interface.implements(I1)
+    pass
 
+ at implementer(I2)
 class A2(Adapter):
-    zope.interface.implements(I2)
+    pass
 
+ at adapter(components.IContent, I1, I2)
+ at implementer(I3)
 class A3(Adapter):
-    zope.component.adapts(components.IContent, I1, I2)
-    zope.interface.implements(I3)
+    pass
 
 class A4:
     pass
 
 a4 = A4()
 
+ at implementer(I1, I2)
 class A5:
-    zope.interface.implements(I1, I2)
+    pass
 
 a5 = A5()
 

Modified: zope.component/trunk/src/zope/component/testfiles/components.py
===================================================================
--- zope.component/trunk/src/zope/component/testfiles/components.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/testfiles/components.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -13,8 +13,10 @@
 ##############################################################################
 """Components for testing
 """
-from zope.interface import Interface, Attribute, implements
-from zope.component import adapts
+from zope.interface import Interface
+from zope.interface import Attribute
+from zope.interface import implementer
+from zope.component import adapter
 
 class IAppb(Interface):
     a = Attribute('test attribute')
@@ -31,12 +33,14 @@
 
 class IContent(Interface): pass
 
+ at implementer(IContent)
 class Content(object):
-    implements(IContent)
+    pass
 
+ at adapter(IContent)
+ at implementer(IApp)
 class Comp(object):
-    adapts(IContent)
-    implements(IApp)
+    pass
 
     def __init__(self, *args):
         # Ignore arguments passed to constructor

Modified: zope.component/trunk/src/zope/component/testfiles/views.py
===================================================================
--- zope.component/trunk/src/zope/component/testfiles/views.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/testfiles/views.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -13,8 +13,11 @@
 ##############################################################################
 """Views test.
 """
-from zope.interface import Interface, implements, directlyProvides
 
+from zope.interface import Interface
+from zope.interface import implementer
+from zope.interface import directlyProvides
+
 class Request(object):
 
     def __init__(self, type):
@@ -29,8 +32,8 @@
 
 class IC(Interface): pass
 
+ at implementer(IV)
 class V1(object):
-    implements(IV)
 
     def __init__(self, context, request):
         self.context = context
@@ -46,6 +49,7 @@
     def index(self):
         return 'ZMI here'
 
+ at implementer(IV)
 class R1(object):
 
     def index(self):
@@ -57,7 +61,6 @@
     def __init__(self, request):
         pass
 
-    implements(IV)
 
 class RZMI(R1):
     pass

Modified: zope.component/trunk/src/zope/component/testing.py
===================================================================
--- zope.component/trunk/src/zope/component/testing.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/testing.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -18,7 +18,17 @@
 import zope.component.event
 
 # we really don't need special setup now:
-from zope.testing.cleanup import CleanUp as PlacelessSetup
+try:
+    from zope.testing.cleanup import CleanUp as PlacelessSetup
+except ImportError:
+    class PlacelessSetup(object):
+        def cleanUp(self):
+            from zope.component.globalregistry import base
+            base.__init__('base')
+        def setUp(self):
+            self.cleanUp()
+        def tearDown(self):
+            self.cleanUp()
 
 def setUp(test=None):
     PlacelessSetup().setUp()

Modified: zope.component/trunk/src/zope/component/testlayer.py
===================================================================
--- zope.component/trunk/src/zope/component/testlayer.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/testlayer.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -15,7 +15,12 @@
 import os
 
 from zope.configuration import xmlconfig, config
-from zope.testing.cleanup import cleanUp
+try:
+    from zope.testing.cleanup import cleanUp
+except ImportError:
+    def cleanUp():
+        pass
+
 from zope.component import provideHandler
 from zope.component.hooks import setHooks
 from zope.component.eventtesting import events, clearEvents

Deleted: zope.component/trunk/src/zope/component/testlayer.txt
===================================================================
--- zope.component/trunk/src/zope/component/testlayer.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/testlayer.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,100 +0,0 @@
-Layers
-======
-
-zope.component.testlayer defines two things:
-
-* a LayerBase that makes it easier and saner to use zope.testing's
-  test layers.
-
-* a ZCMLLayer which lets you implement a layer that loads up some
-  ZCML.
-
-LayerBase
----------
-
-We check whether our LayerBase can be used to create layers of our
-own. We do this simply by subclassing:
-
-  >>> from zope.component.testlayer import LayerBase
-  >>> class OurLayer(LayerBase):
-  ...     def setUp(self):
-  ...         super(OurLayer, self).setUp()
-  ...         print "setUp called"
-  ...     def tearDown(self):
-  ...         super(OurLayer, self).tearDown()
-  ...         print "tearDown called"
-  ...     def testSetUp(self):
-  ...         super(OurLayer, self).testSetUp()
-  ...         print "testSetUp called"
-  ...     def testTearDown(self):
-  ...         super(OurLayer, self).testTearDown()
-  ...         print "testTearDown called"
-
-Note that if we wanted to ensure that the methods of the superclass
-were called we have to use super(). In this case we actually wouldn't
-need to, as these methods do nothing at all, but we just ensure that
-they are there in the first place.
-
-Let's instantiate our layer. We need to supply it with the package the
-layer is defined in::
-
-  >>> import zope.component
-  >>> layer = OurLayer(zope.component)
-
-Now we run some tests with this layer:
-
-  >>> import unittest
-  >>> class TestCase(unittest.TestCase):
-  ...    layer = layer
-  ...    
-  ...    def testFoo(self):
-  ...        print "testFoo"
-  >>> suite = unittest.TestSuite()
-  >>> suite.addTest(unittest.makeSuite(TestCase))
-  >>> from zope.testrunner.runner import Runner
-  >>> runner = Runner(args=[], found_suites=[suite])
-  >>> succeeded = runner.run()
-  Running zope.component.OurLayer tests:
-    Set up zope.component.OurLayer setUp called
-  in ... seconds.
-  testSetUp called
-  testFoo
-  testTearDown called
-    Ran 1 tests with 0 failures and 0 errors in ... seconds.
-  Tearing down left over layers:
-    Tear down zope.component.OurLayer tearDown called
-  in ... seconds.
-
-ZCMLLayer
----------
-
-We now want a layer that loads up some ZCML from a file. The default
-is ``ftesting.zcml``, but here we'll load a test ``testlayer.zcml``.
-
-  >>> from zope.component.testlayer import ZCMLFileLayer
-  >>> zcml_file_layer = ZCMLFileLayer(
-  ...     zope.component.testfiles,
-  ...     'testlayer.zcml')
-
-  >>> class TestCase(unittest.TestCase):
-  ...    layer = zcml_file_layer
-  ...    
-  ...    def testFoo(self):
-  ...        # we should now have the adapter registered
-  ...        from zope import component
-  ...        from zope.component.testfiles import components
-  ...        self.assert_(isinstance(
-  ...            components.IApp2(components.content), components.Comp2))
-
-Since the ZCML sets up an adapter, we expect the tests to pass::
-
-  >>> suite = unittest.TestSuite()
-  >>> suite.addTest(unittest.makeSuite(TestCase))
-  >>> runner = Runner(args=[], found_suites=[suite])
-  >>> succeeded = runner.run()
-  Running zope.component.testfiles.ZCMLFileLayer tests:
-    Set up zope.component.testfiles.ZCMLFileLayer in ... seconds.
-    Ran 1 tests with 0 failures and 0 errors in ... seconds.
-  Tearing down left over layers:
-    Tear down zope.component.testfiles.ZCMLFileLayer in ... seconds.
-

Deleted: zope.component/trunk/src/zope/component/tests.py
===================================================================
--- zope.component/trunk/src/zope/component/tests.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/tests.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,1748 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2001, 2002, 2009 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Component Architecture Tests
-"""
-
-import __future__
-
-import doctest
-import persistent
-import re
-import sys
-import unittest
-import transaction
-from cStringIO import StringIO
-
-from zope import interface, component
-from zope.interface.verify import verifyObject
-from zope.interface.interfaces import IInterface
-from zope.testing import renormalizing
-from zope.testrunner.layer import UnitTests
-
-from zope.component.interfaces import ComponentLookupError
-from zope.component.interfaces import IComponentArchitecture
-from zope.component.interfaces import IComponentLookup
-from zope.component.testing import setUp, tearDown, PlacelessSetup
-import zope.component.persistentregistry
-import zope.component.globalregistry
-
-from zope.configuration.xmlconfig import XMLConfig, xmlconfig
-from zope.configuration.exceptions import ConfigurationError
-from zope.security.checker import ProxyFactory
-
-from zope.component.testfiles.adapter import A1, A2, A3
-from zope.component.testfiles.components import IContent, Content
-from zope.component.testfiles.components import IApp
-from zope.component.testfiles.views import Request, IC, IV, V1, R1, IR
-
-# side effect gets component-based event dispatcher installed.
-# we should obviously make this more explicit
-import zope.component.event
-
-class I1(interface.Interface):
-    pass
-class I2(interface.Interface):
-    pass
-class I2e(I2):
-    pass
-class I3(interface.Interface):
-    pass
-
-class ITestType(IInterface):
-    pass
-
-class U:
-
-    def __init__(self, name):
-        self.__name__ = name
-
-    def __repr__(self):
-        return "%s(%s)" % (self.__class__.__name__, self.__name__)
-
-class U1(U):
-    interface.implements(I1)
-
-class U12(U):
-    interface.implements(I1, I2)
-
-class IA1(interface.Interface):
-    pass
-
-class IA2(interface.Interface):
-    pass
-
-class IA3(interface.Interface):
-    pass
-
-class A:
-
-    def __init__(self, *context):
-        self.context = context
-
-    def __repr__(self):
-        return "%s%r" % (self.__class__.__name__, self.context)
-
-class A12_1(A):
-    component.adapts(I1, I2)
-    interface.implements(IA1)
-
-class A12_(A):
-    component.adapts(I1, I2)
-
-class A_2(A):
-    interface.implements(IA2)
-
-class A_3(A):
-    interface.implements(IA3)
-
-class A1_12(U):
-    component.adapts(I1)
-    interface.implements(IA1, IA2)
-
-class A1_2(U):
-    component.adapts(I1)
-    interface.implements(IA2)
-
-class A1_23(U):
-    component.adapts(I1)
-    interface.implements(IA1, IA3)
-
-def noop(*args):
-    pass
-
- at component.adapter(I1)
-def handle1(x):
-    print 'handle1', x
-
-def handle(*objects):
-    print 'handle', objects
-
- at component.adapter(I1)
-def handle3(x):
-    print 'handle3', x
-
- at component.adapter(I1)
-def handle4(x):
-    print 'handle4', x
-
-class Ob(object):
-    interface.implements(I1)
-    def __repr__(self):
-        return '<instance Ob>'
-
-
-ob = Ob()
-
-class Ob2(object):
-    interface.implements(I2)
-    def __repr__(self):
-        return '<instance Ob2>'
-
-class Comp(object):
-    interface.implements(I2)
-    def __init__(self, context):
-        self.context = context
-
-comp = Comp(1)
-
-class Comp2(object):
-    interface.implements(I3)
-    def __init__(self, context):
-        self.context = context
-
-
-class ConformsToIComponentLookup(object):
-    """This object allows the sitemanager to conform/adapt to
-    `IComponentLookup` and thus to itself."""
-
-    def __init__(self, sitemanager):
-        self.sitemanager = sitemanager
-
-    def __conform__(self, interface):
-        """This method is specified by the adapter PEP to do the adaptation."""
-        if interface is IComponentLookup:
-            return self.sitemanager
-
-
-def testInterfaces():
-    """Ensure that the component architecture API is provided by
-    `zope.component`.
-
-    >>> verifyObject(IComponentArchitecture, component)
-    True
-    """
-
-def test_getGlobalSiteManager():
-    """One of the most important functions is to get the global site manager.
-
-      >>> from zope.component.interfaces import IComponentLookup
-      >>> from zope.component.globalregistry import base
-
-    Get the global site manager via the CA API function:
-
-      >>> gsm = component.getGlobalSiteManager()
-
-    Make sure that the global site manager implements the correct interface
-    and is the global site manager instance we expect to get.
-
-      >>> IComponentLookup.providedBy(gsm)
-      True
-      >>> base is gsm
-      True
-
-    Finally, ensure that we always get the same global site manager, otherwise
-    our component registry will always be reset.
-
-      >>> component.getGlobalSiteManager() is gsm
-      True
-    """
-
-def test_getSiteManager():
-    """Make sure that `getSiteManager()` always returns the correct site
-    manager instance.
-
-    We don't know anything about the default service manager, except that it
-    is an `IComponentLookup`.
-
-      >>> from zope.component.interfaces import IComponentLookup
-      >>> IComponentLookup.providedBy(component.getSiteManager())
-      True
-
-    Calling `getSiteManager()` with no args is equivalent to calling it with a
-    context of `None`.
-
-      >>> component.getSiteManager() is component.getSiteManager(None)
-      True
-
-    If the context passed to `getSiteManager()` is not `None`, it is
-    adapted to `IComponentLookup` and this adapter returned.  So, we
-    create a context that can be adapted to `IComponentLookup` using
-    the `__conform__` API.
-
-    Let's create the simplest stub-implementation of a site manager possible:
-
-      >>> sitemanager = object()
-
-    Now create a context that knows how to adapt to our newly created site
-    manager.
-
-      >>> context = ConformsToIComponentLookup(sitemanager)
-
-    Now make sure that the `getSiteManager()` API call returns the correct
-    site manager.
-
-      >>> component.getSiteManager(context) is sitemanager
-      True
-
-    Using a context that is not adaptable to `IComponentLookup` should fail.
-
-      >>> component.getSiteManager(ob) #doctest: +NORMALIZE_WHITESPACE, +ELLIPSIS
-      Traceback (most recent call last):
-      ...
-      ComponentLookupError: ('Could not adapt', <instance Ob>,
-      <InterfaceClass zope...interfaces.IComponentLookup>)
-    """
-
-def testAdapterInContext(self):
-    """The `getAdapterInContext()` and `queryAdapterInContext()` API functions
-    do not only use the site manager to look up the adapter, but first tries
-    to use the `__conform__()` method of the object to find an adapter as
-    specified by PEP 246.
-
-    Let's start by creating a component that support's the PEP 246's
-    `__conform__()` method:
-
-      >>> class Component(object):
-      ...     interface.implements(I1)
-      ...     def __conform__(self, iface, default=None):
-      ...         if iface == I2:
-      ...             return 42
-      ...     def __repr__(self):
-      ...         return '''<Component implementing 'I1'>'''
-
-      >>> ob = Component()
-
-    We also gave the component a custom representation, so it will be easier
-    to use in these tests.
-
-    We now have to create a site manager (other than the default global one)
-    with which we can register adapters for `I1`.
-
-      >>> from zope.component.globalregistry import BaseGlobalComponents
-      >>> sitemanager = BaseGlobalComponents()
-
-    Now we create a new `context` that knows how to get to our custom site
-    manager.
-
-      >>> context = ConformsToIComponentLookup(sitemanager)
-
-    We now register an adapter from `I1` to `I3`:
-
-      >>> sitemanager.registerAdapter(lambda x: 43, (I1,), I3, '')
-
-    If an object implements the interface you want to adapt to,
-    `getAdapterInContext()` should simply return the object.
-
-      >>> component.getAdapterInContext(ob, I1, context)
-      <Component implementing 'I1'>
-      >>> component.queryAdapterInContext(ob, I1, context)
-      <Component implementing 'I1'>
-
-    If an object conforms to the interface you want to adapt to,
-    `getAdapterInContext()` should simply return the conformed object.
-
-      >>> component.getAdapterInContext(ob, I2, context)
-      42
-      >>> component.queryAdapterInContext(ob, I2, context)
-      42
-
-    If an adapter isn't registered for the given object and interface, and you
-    provide no default, raise ComponentLookupError...
-
-      >>> class I4(interface.Interface):
-      ...     pass
-
-      >>> component.getAdapterInContext(ob, I4, context) \\
-      ... #doctest: +NORMALIZE_WHITESPACE
-      Traceback (most recent call last):
-      ...
-      ComponentLookupError: (<Component implementing 'I1'>,
-                             <InterfaceClass zope.component.tests.I4>)
-
-    ...otherwise, you get the default:
-
-      >>> component.queryAdapterInContext(ob, I4, context, 44)
-      44
-
-    If you ask for an adapter for which something's registered you get the
-    registered adapter
-
-      >>> component.getAdapterInContext(ob, I3, context)
-      43
-      >>> component.queryAdapterInContext(ob, I3, context)
-      43
-    """
-
-def testAdapter():
-    """The `getAdapter()` and `queryAdapter()` API functions are similar to
-    `{get|query}AdapterInContext()` functions, except that they do not care
-    about the `__conform__()` but also handle named adapters. (Actually, the
-    name is a required argument.)
-
-    If an adapter isn't registered for the given object and interface, and you
-    provide no default, raise `ComponentLookupError`...
-
-      >>> component.getAdapter(ob, I2, '') #doctest: +NORMALIZE_WHITESPACE
-      Traceback (most recent call last):
-      ...
-      ComponentLookupError: (<instance Ob>,
-                             <InterfaceClass zope.component.tests.I2>,
-                             '')
-
-    ...otherwise, you get the default
-
-      >>> component.queryAdapter(ob, I2, '', '<default>')
-      '<default>'
-
-    Now get the global site manager and register an adapter from `I1` to `I2`
-    without a name:
-
-      >>> component.getGlobalSiteManager().registerAdapter(
-      ...     Comp, (I1,), I2, '')
-
-    You should get a sensible error message if you forget that the 'requires'
-    argument is supposed to be a sequence
-
-      >>> component.getGlobalSiteManager().registerAdapter(
-      ...     Comp, I1, I2, '')
-      Traceback (most recent call last):
-        ...
-      TypeError: the required argument should be a list of interfaces, not a single interface
-
-    You can now simply access the adapter using the `getAdapter()` API
-    function:
-
-      >>> adapter = component.getAdapter(ob, I2, '')
-      >>> adapter.__class__ is Comp
-      True
-      >>> adapter.context is ob
-      True
-    """
-
-def testInterfaceCall():
-    """Here we test the `adapter_hook()` function that we registered with the
-    `zope.interface` adapter hook registry, so that we can call interfaces to
-    do adaptation.
-
-    First, we need to register an adapter:
-
-      >>> component.getGlobalSiteManager().registerAdapter(
-      ...     Comp, [I1], I2, '')
-
-    Then we try to adapt `ob` to provide an `I2` interface by calling the `I2`
-    interface with the obejct as first argument:
-
-      >>> adapter = I2(ob)
-      >>> adapter.__class__ is Comp
-      True
-      >>> adapter.context is ob
-      True
-
-    If no adapter is found, a `TypeError is raised...
-
-      >>> I1(Ob2()) #doctest: +NORMALIZE_WHITESPACE
-      Traceback (most recent call last):
-      ...
-      TypeError: ('Could not adapt', <instance Ob2>,
-                  <InterfaceClass zope.component.tests.I1>)
-
-    ...unless we specify an alternative adapter:
-
-      >>> marker = object()
-      >>> I2(object(), marker) is marker
-      True
-    """
-
-def testNamedAdapter():
-    """Make sure that adapters with names are correctly selected from the
-    registry.
-
-    First we register some named adapter:
-
-      >>> component.getGlobalSiteManager().registerAdapter(
-      ...     lambda x: 0, [I1], I2, 'foo')
-
-    If an adapter isn't registered for the given object and interface,
-    and you provide no default, raise `ComponentLookupError`...
-
-      >>> component.getAdapter(ob, I2, 'bar') \\
-      ... #doctest: +NORMALIZE_WHITESPACE
-      Traceback (most recent call last):
-      ...
-      ComponentLookupError:
-      (<instance Ob>, <InterfaceClass zope.component.tests.I2>, 'bar')
-
-    ...otherwise, you get the default
-
-      >>> component.queryAdapter(ob, I2, 'bar', '<default>')
-      '<default>'
-
-    But now we register an adapter for the object having the correct name
-
-      >>> component.getGlobalSiteManager().registerAdapter(
-      ...     Comp, [I1], I2, 'bar')
-
-    so that the lookup succeeds:
-
-      >>> adapter = component.getAdapter(ob, I2, 'bar')
-      >>> adapter.__class__ is Comp
-      True
-      >>> adapter.context is ob
-      True
-    """
-
-def testMultiAdapter():
-    """Adapting a combination of 2 objects to an interface
-
-    Multi-adapters adapt one or more objects to another interface. To make
-    this demonstration non-trivial, we need to create a second object to be
-    adapted:
-
-      >>> ob2 = Ob2()
-
-    Like for regular adapters, if an adapter isn't registered for the given
-    objects and interface, and you provide no default, raise
-    `ComponentLookupError`...
-
-      >>> component.getMultiAdapter((ob, ob2), I3) \\
-      ... #doctest: +NORMALIZE_WHITESPACE
-      Traceback (most recent call last):
-      ...
-      ComponentLookupError:
-      ((<instance Ob>, <instance Ob2>),
-       <InterfaceClass zope.component.tests.I3>,
-       u'')
-
-    ...otherwise, you get the default
-
-      >>> component.queryMultiAdapter((ob, ob2), I3, default='<default>')
-      '<default>'
-
-    Note that the name is not a required attribute here.
-
-    To test multi-adapters, we also have to create an adapter class that
-    handles to context objects:
-
-      >>> class DoubleAdapter(object):
-      ...     interface.implements(I3)
-      ...     def __init__(self, first, second):
-      ...         self.first = first
-      ...         self.second = second
-
-    Now we can register the multi-adapter using
-
-      >>> component.getGlobalSiteManager().registerAdapter(
-      ...     DoubleAdapter, (I1, I2), I3, '')
-
-    Notice how the required interfaces are simply provided by a tuple. Now we
-    can get the adapter:
-
-      >>> adapter = component.getMultiAdapter((ob, ob2), I3)
-      >>> adapter.__class__ is DoubleAdapter
-      True
-      >>> adapter.first is ob
-      True
-      >>> adapter.second is ob2
-      True
-    """
-
-def testAdapterForInterfaceNone():
-    """Providing an adapter for None says that your adapter can adapt anything
-    to `I2`.
-
-      >>> component.getGlobalSiteManager().registerAdapter(
-      ...     Comp, (None,), I2, '')
-
-      >>> adapter = I2(ob)
-      >>> adapter.__class__ is Comp
-      True
-      >>> adapter.context is ob
-      True
-
-    It can really adapt any arbitrary object:
-
-      >>> something = object()
-      >>> adapter = I2(something)
-      >>> adapter.__class__ is Comp
-      True
-      >>> adapter.context is something
-      True
-    """
-
-def testGetAdapters():
-    """It is sometimes desireable to get a list of all adapters that are
-    registered for a particular output interface, given a set of
-    objects.
-
-    Let's register some adapters first:
-
-      >>> component.getGlobalSiteManager().registerAdapter(
-      ...     Comp, [I1], I2, '')
-      >>> component.getGlobalSiteManager().registerAdapter(
-      ...     Comp, [None], I2, 'foo')
-
-    Now we get all the adapters that are registered for `ob` that provide
-    `I2`:
-
-      >>> adapters = sorted(component.getAdapters((ob,), I2))
-      >>> [(name, adapter.__class__.__name__) for name, adapter in adapters]
-      [(u'', 'Comp'), (u'foo', 'Comp')]
-
-    Note that the output doesn't include None values. If an adapter
-    factory returns None, it is as if it wasn't present.
-
-      >>> component.getGlobalSiteManager().registerAdapter(
-      ...     lambda context: None, [I1], I2, 'nah')
-      >>> adapters = sorted(component.getAdapters((ob,), I2))
-      >>> [(name, adapter.__class__.__name__) for name, adapter in adapters]
-      [(u'', 'Comp'), (u'foo', 'Comp')]
-
-    """
-
-def testUtility():
-    """Utilities are components that simply provide an interface. They are
-    instantiated at the time or before they are registered. Here we test the
-    simple query interface.
-
-    Before we register any utility, there is no utility available, of
-    course. The pure instatiation of an object does not make it a utility. If
-    you do not specify a default, you get a `ComponentLookupError`...
-
-      >>> component.getUtility(I1) #doctest: +NORMALIZE_WHITESPACE
-      Traceback (most recent call last):
-      ...
-      ComponentLookupError: \
-      (<InterfaceClass zope.component.tests.I1>, '')
-
-    ...otherwise, you get the default
-
-      >>> component.queryUtility(I1, default='<default>')
-      '<default>'
-      >>> component.queryUtility(I2, default='<default>')
-      '<default>'
-
-    Now we declare `ob` to be the utility providing `I1`
-
-      >>> component.getGlobalSiteManager().registerUtility(ob, I1)
-
-    so that the component is now available:
-
-      >>> component.getUtility(I1) is ob
-      True
-    """
-
-def testNamedUtility():
-    """Like adapters, utilities can be named.
-
-    Just because you register an utility having no name
-
-      >>> component.getGlobalSiteManager().registerUtility(ob, I1)
-
-    does not mean that they are available when you specify a name:
-
-      >>> component.getUtility(I1, name='foo') \\
-      ... #doctest: +NORMALIZE_WHITESPACE
-      Traceback (most recent call last):
-      ...
-      ComponentLookupError:
-      (<InterfaceClass zope.component.tests.I1>, 'foo')
-
-
-    ...otherwise, you get the default
-
-      >>> component.queryUtility(I1, name='foo', default='<default>')
-      '<default>'
-
-    Registering the utility under the correct name
-
-      >>> component.getGlobalSiteManager().registerUtility(
-      ...     ob, I1, name='foo')
-
-    really helps:
-
-      >>> component.getUtility(I1, 'foo') is ob
-      True
-    """
-
-def test_getAllUtilitiesRegisteredFor():
-    """Again, like for adapters, it is often useful to get a list of all
-    utilities that have been registered for a particular interface. Utilities
-    providing a derived interface are also listed.
-
-    Thus, let's create a derivative interface of `I1`:
-
-      >>> class I11(I1):
-      ...     pass
-
-      >>> class Ob11(Ob):
-      ...     interface.implements(I11)
-
-      >>> ob11 = Ob11()
-      >>> ob_bob = Ob()
-
-    Now we register the new utilities:
-
-      >>> gsm = component.getGlobalSiteManager()
-      >>> gsm.registerUtility(ob, I1)
-      >>> gsm.registerUtility(ob11, I11)
-      >>> gsm.registerUtility(ob_bob, I1, name='bob')
-      >>> gsm.registerUtility(Comp(2), I2)
-
-    We can now get all the utilities that provide interface `I1`:
-
-      >>> uts = list(component.getAllUtilitiesRegisteredFor(I1))
-      >>> uts = sorted([util.__class__.__name__ for util in uts])
-      >>> uts
-      ['Ob', 'Ob', 'Ob11']
-
-    Note that `getAllUtilitiesRegisteredFor()` does not return the names of
-    the utilities.
-    """
-
-def testNotBrokenWhenNoSiteManager():
-    """Make sure that the adapter lookup is not broken, when no site manager
-    is available.
-
-    Both of those things emit `DeprecationWarnings`.
-
-      >>> I2(ob) #doctest: +NORMALIZE_WHITESPACE
-      Traceback (most recent call last):
-      ...
-      TypeError: ('Could not adapt',
-                  <instance Ob>,
-                  <InterfaceClass zope.component.tests.I2>)
-
-
-      >>> I2(ob, 42)
-      42
-    """
-
-
-def testNo__component_adapts__leakage():
-    """
-    We want to make sure that an `adapts()` call in a class definition
-    doesn't affect instances.
-
-      >>> class C:
-      ...     component.adapts()
-
-      >>> C.__component_adapts__
-      ()
-      >>> C().__component_adapts__
-      Traceback (most recent call last):
-      ...
-      AttributeError: __component_adapts__
-    """
-
-def test_ability_to_pickle_globalsitemanager():
-    """
-    We need to make sure that it is possible to pickle the global site manager
-    and its two global adapter registries.
-
-      >>> from zope.component import globalSiteManager
-      >>> import cPickle
-      >>> pickle = cPickle.dumps(globalSiteManager)
-      >>> sm = cPickle.loads(pickle)
-      >>> sm is globalSiteManager
-      True
-
-    Now let's ensure that the registries themselves can be pickled as well:
-
-      >>> pickle = cPickle.dumps(globalSiteManager.adapters)
-      >>> adapters = cPickle.loads(pickle)
-      >>> adapters is globalSiteManager.adapters
-      True
-    """
-
-def test_persistent_component_managers():
-    """
-Here, we'll demonstrate that changes work even when data are stored in
-a database and when accessed from multiple connections.
-
-Start by setting up a database and creating two transaction
-managers and database connections to work with.
-
-    >>> import ZODB.tests.util
-    >>> db = ZODB.tests.util.DB()
-    >>> import transaction
-    >>> t1 = transaction.TransactionManager()
-    >>> c1 = db.open(transaction_manager=t1)
-    >>> r1 = c1.root()
-    >>> t2 = transaction.TransactionManager()
-    >>> c2 = db.open(transaction_manager=t2)
-    >>> r2 = c2.root()
-
-Create a set of components registries in the database, alternating
-connections.
-
-    >>> from zope.component.persistentregistry import PersistentComponents
-
-    >>> _ = t1.begin()
-    >>> r1[1] = PersistentComponents('1')
-    >>> t1.commit()
-
-    >>> _ = t2.begin()
-    >>> r2[2] = PersistentComponents('2', (r2[1], ))
-    >>> t2.commit()
-
-    >>> _ = t1.begin()
-    >>> r1[3] = PersistentComponents('3', (r1[1], ))
-    >>> t1.commit()
-
-    >>> _ = t2.begin()
-    >>> r2[4] = PersistentComponents('4', (r2[2], r2[3]))
-    >>> t2.commit()
-
-    >>> _ = t1.begin()
-    >>> r1[1].__bases__
-    ()
-    >>> r1[2].__bases__ == (r1[1], )
-    True
-
-    >>> r1[1].registerUtility(U1(1))
-    >>> r1[1].queryUtility(I1)
-    U1(1)
-    >>> r1[2].queryUtility(I1)
-    U1(1)
-    >>> t1.commit()
-
-    >>> _ = t2.begin()
-    >>> r2[1].registerUtility(U1(2))
-    >>> r2[2].queryUtility(I1)
-    U1(2)
-
-    >>> r2[4].queryUtility(I1)
-    U1(2)
-    >>> t2.commit()
-
-
-    >>> _ = t1.begin()
-    >>> r1[1].registerUtility(U12(1), I2)
-    >>> r1[4].queryUtility(I2)
-    U12(1)
-    >>> t1.commit()
-
-
-    >>> _ = t2.begin()
-    >>> r2[3].registerUtility(U12(3), I2)
-    >>> r2[4].queryUtility(I2)
-    U12(3)
-    >>> t2.commit()
-
-    >>> _ = t1.begin()
-
-    >>> r1[1].registerHandler(handle1, info="First handler")
-    >>> r1[2].registerHandler(handle, required=[U])
-
-    >>> r1[3].registerHandler(handle3)
-
-    >>> r1[4].registerHandler(handle4)
-
-    >>> r1[4].handle(U1(1))
-    handle1 U1(1)
-    handle3 U1(1)
-    handle (U1(1),)
-    handle4 U1(1)
-
-    >>> t1.commit()
-
-    >>> _ = t2.begin()
-    >>> r2[4].handle(U1(1))
-    handle1 U1(1)
-    handle3 U1(1)
-    handle (U1(1),)
-    handle4 U1(1)
-    >>> t2.abort()
-
-    >>> db.close()
-    """
-
-def persistent_registry_doesnt_scew_up_subsribers():
-    """
-    >>> import ZODB.tests.util
-    >>> db = ZODB.tests.util.DB()
-    >>> import transaction
-    >>> t1 = transaction.TransactionManager()
-    >>> c1 = db.open(transaction_manager=t1)
-    >>> r1 = c1.root()
-    >>> t2 = transaction.TransactionManager()
-    >>> c2 = db.open(transaction_manager=t2)
-    >>> r2 = c2.root()
-
-    >>> from zope.component.persistentregistry import PersistentComponents
-
-    >>> _ = t1.begin()
-    >>> r1[1] = PersistentComponents('1')
-    >>> r1[1].registerHandler(handle1)
-    >>> r1[1].registerSubscriptionAdapter(handle1, provided=I2)
-    >>> _ = r1[1].unregisterHandler(handle1)
-    >>> _ = r1[1].unregisterSubscriptionAdapter(handle1, provided=I2)
-    >>> t1.commit()
-    >>> _ = t1.begin()
-    >>> r1[1].registerHandler(handle1)
-    >>> r1[1].registerSubscriptionAdapter(handle1, provided=I2)
-    >>> t1.commit()
-
-    >>> _ = t2.begin()
-    >>> len(list(r2[1].registeredHandlers()))
-    1
-    >>> len(list(r2[1].registeredSubscriptionAdapters()))
-    1
-    >>> t2.abort()
-
-    """
-
-
-
-class GlobalRegistry:
-    pass
-
-base = zope.component.globalregistry.GlobalAdapterRegistry(
-    GlobalRegistry, 'adapters')
-GlobalRegistry.adapters = base
-def clear_base():
-    base.__init__(GlobalRegistry, 'adapters')
-
-class IFoo(interface.Interface):
-    pass
-class Foo(persistent.Persistent):
-    interface.implements(IFoo)
-    name = ''
-    def __init__(self, name=''):
-        self.name = name
-
-    def __repr__(self):
-        return 'Foo(%r)' % self.name
-
-def test_deghostification_of_persistent_adapter_registries():
-    """
-
-We want to make sure that we see updates corrextly.
-
-    >>> len(base._v_subregistries)
-    0
-
-    >>> import ZODB.tests.util
-    >>> db = ZODB.tests.util.DB()
-    >>> tm1 = transaction.TransactionManager()
-    >>> c1 = db.open(transaction_manager=tm1)
-    >>> r1 = zope.component.persistentregistry.PersistentAdapterRegistry(
-    ...           (base,))
-    >>> r2 = zope.component.persistentregistry.PersistentAdapterRegistry((r1,))
-    >>> c1.root()[1] = r1
-    >>> c1.root()[2] = r2
-    >>> tm1.commit()
-    >>> r1._p_deactivate()
-
-    >>> len(base._v_subregistries)
-    0
-
-    >>> 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()
-
-    """
-
-
-def test_multi_handler_unregistration():
-    """
-    There was a bug where multiple handlers for the same required
-    specification would all be removed when one of them was
-    unregistered:
-
-    >>> class I(zope.interface.Interface):
-    ...     pass
-    >>> def factory1(event):
-    ...     print "| Factory 1 is here"
-    >>> def factory2(event):
-    ...     print "| Factory 2 is here"
-    >>> class Event(object):
-    ...     zope.interface.implements(I)
-    >>> from zope.interface.registry import Components
-    >>> registry = Components()
-    >>> registry.registerHandler(factory1, [I,])
-    >>> registry.registerHandler(factory2, [I,])
-    >>> registry.handle(Event())
-    | Factory 1 is here
-    | Factory 2 is here
-    >>> registry.unregisterHandler(factory1, [I,])
-    True
-    >>> registry.handle(Event())
-    | Factory 2 is here
-    """
-
-def test_next_utilities():
-    """
-    It is common for a utility to delegate its answer to a utility
-    providing the same interface in one of the component registry's
-    bases. Let's first create a global utility::
-
-      >>> import zope.interface
-      >>> class IMyUtility(zope.interface.Interface):
-      ...     pass
-
-      >>> class MyUtility(ConformsToIComponentLookup):
-      ...     zope.interface.implements(IMyUtility)
-      ...     def __init__(self, id, sm):
-      ...         self.id = id
-      ...         self.sitemanager = sm
-      ...     def __repr__(self):
-      ...         return "%s('%s')" % (self.__class__.__name__, self.id)
-
-      >>> from zope.component import getGlobalSiteManager
-      >>> gsm = getGlobalSiteManager()
-
-      >>> gutil = MyUtility('global', gsm)
-      >>> gsm.registerUtility(gutil, IMyUtility, 'myutil')
-
-    Now, let's create two registries and set up the bases hierarchy::
-
-      >>> from zope.interface.registry import Components
-      >>> sm1 = Components('sm1', bases=(gsm, ))
-      >>> sm1_1 = Components('sm1_1', bases=(sm1, ))
-
-    Now we create two utilities and insert them in our folder hierarchy:
-
-      >>> util1 = MyUtility('one', sm1)
-      >>> sm1.registerUtility(util1, IMyUtility, 'myutil')
-      >>> IComponentLookup(util1) is sm1
-      True
-
-      >>> util1_1 = MyUtility('one-one', sm1_1)
-      >>> sm1_1.registerUtility(util1_1, IMyUtility, 'myutil')
-      >>> IComponentLookup(util1_1) is sm1_1
-      True
-
-    Now, if we ask `util1_1` for its next available utility we get the
-    ``one`` utility::
-
-      >>> from zope.component import getNextUtility
-      >>> getNextUtility(util1_1, IMyUtility, 'myutil')
-      MyUtility('one')
-
-    Next we ask `util1` for its next utility and we should get the global version:
-
-      >>> getNextUtility(util1, IMyUtility, 'myutil')
-      MyUtility('global')
-
-    However, if we ask the global utility for the next one, an error is raised
-
-      >>> getNextUtility(gutil, IMyUtility,
-      ...                     'myutil') #doctest: +NORMALIZE_WHITESPACE
-      Traceback (most recent call last):
-      ...
-      ComponentLookupError:
-      No more utilities for <InterfaceClass zope.component.tests.IMyUtility>,
-      'myutil' have been found.
-
-    You can also use `queryNextUtility` and specify a default:
-
-      >>> from zope.component import queryNextUtility
-      >>> queryNextUtility(gutil, IMyUtility, 'myutil', 'default')
-      'default'
-
-    Let's now ensure that the function also works with multiple registries. First
-    we create another base registry:
-
-      >>> myregistry = Components()
-
-    We now set up another utility into that registry:
-
-      >>> custom_util = MyUtility('my_custom_util', myregistry)
-      >>> myregistry.registerUtility(custom_util, IMyUtility, 'my_custom_util')
-
-    We add it as a base to the local site manager:
-
-      >>> sm1.__bases__ = (myregistry,) + sm1.__bases__
-
-    Both the ``myregistry`` and global utilities should be available:
-
-      >>> queryNextUtility(sm1, IMyUtility, 'my_custom_util')
-      MyUtility('my_custom_util')
-      >>> queryNextUtility(sm1, IMyUtility, 'myutil')
-      MyUtility('global')
-
-    Note, if the context cannot be converted to a site manager, the default is
-    retruned:
-
-      >>> queryNextUtility(object(), IMyUtility, 'myutil', 'default')
-      'default'
-    """
-
-def dont_leak_utility_registrations_in__subscribers():
-    """
-
-    We've observed utilities getting left in _subscribers when they
-    get unregistered.
-
-    >>> import zope.interface.registry
-    >>> reg = zope.interface.registry.Components()
-    >>> class C:
-    ...     def __init__(self, name):
-    ...         self.name = name
-    ...     def __repr__(self):
-    ...         return "C(%s)" % self.name
-
-    >>> c1 = C(1)
-    >>> reg.registerUtility(c1, I1)
-    >>> reg.registerUtility(c1, I1)
-    >>> list(reg.getAllUtilitiesRegisteredFor(I1))
-    [C(1)]
-
-    >>> reg.unregisterUtility(provided=I1)
-    True
-    >>> list(reg.getAllUtilitiesRegisteredFor(I1))
-    []
-
-    >>> reg.registerUtility(c1, I1)
-    >>> reg.registerUtility(C(2), I1)
-
-    >>> list(reg.getAllUtilitiesRegisteredFor(I1))
-    [C(2)]
-
-    """
-
-def test_zcml_handler_site_manager():
-    """
-    The ZCML directives provided by zope.component use the ``getSiteManager``
-    method to get the registry where to register the components. This makes
-    possible to hook ``getSiteManager`` before loading a ZCML file:
-
-    >>> from zope.interface.registry import Components
-    >>> registry = Components()
-    >>> def dummy(context=None):
-    ...     return registry
-    >>> from zope.component import getSiteManager
-    >>> ignore = getSiteManager.sethook(dummy)
-
-    >>> from zope.component.testfiles.components import comp, IApp
-    >>> from zope.component.zcml import handler
-    >>> handler('registerUtility', comp, IApp, u'')
-    >>> registry.getUtility(IApp) is comp
-    True
-    >>> ignore = getSiteManager.reset()
-
-    """
-
-class StandaloneTests(unittest.TestCase):
-    def testStandalone(self):
-        import subprocess
-        import sys
-        import os
-        import tempfile
-        import pickle
-
-        executable = os.path.abspath(sys.executable)
-        program = os.path.join(os.path.dirname(__file__), 'standalonetests.py')
-        process = subprocess.Popen([executable, program],
-                                   stdout=subprocess.PIPE,
-                                   stderr=subprocess.STDOUT,
-                                   stdin=subprocess.PIPE)
-        pickle.dump(sys.path, process.stdin)
-        process.stdin.close()
-
-        try:
-            process.wait()
-        except OSError, e:
-            if e.errno != 4: # MacIntel raises apparently unimportant EINTR?
-                raise # TODO verify sanity of a pass on EINTR :-/
-        lines = process.stdout.readlines()
-        process.stdout.close()
-        success = True
-        # Interpret the result: We scan the output from the end backwards
-        # until we find either a line that says 'OK' (which means the tests
-        # ran successfully) or a line that starts with quite a few dashes
-        # (which means we didn't find a line that says 'OK' within the summary
-        # of the test runner and the tests did not run successfully.)
-        for l in reversed(lines):
-            l = l.strip()
-            if not l:
-                continue
-            if l.startswith('-----'):
-                break
-            if l.endswith('OK'):
-                sucess = True
-        if not success:
-            self.fail(''.join(lines))
-
-class HookableTests(unittest.TestCase):
-
-    def test_ctor_no_func(self):
-        from zope.component.hookable import hookable
-        self.assertRaises(TypeError, hookable)
-
-    def test_ctor_simple(self):
-        from zope.component.hookable import hookable
-        def foo():
-            pass
-        hooked = hookable(foo)
-        self.failUnless(hooked.original is foo)
-        self.failUnless(hooked.implementation is foo)
-
-    def test_ctor_extra_arg(self):
-        from zope.component.hookable import hookable
-        def foo():
-            pass
-        self.assertRaises(TypeError, hookable, foo, foo)
-
-    def test_ctor_extra_arg(self):
-        from zope.component.hookable import hookable
-        def foo():
-            pass
-        self.assertRaises(TypeError, hookable, foo, nonesuch=foo)
-
-    def test_sethook(self):
-        from zope.component.hookable import hookable
-        def foo():
-            pass
-        def bar():
-            pass
-        hooked = hookable(foo)
-        hooked.sethook(bar)
-        self.failUnless(hooked.original is foo)
-        self.failUnless(hooked.implementation is bar)
-
-    def test_reset(self):
-        from zope.component.hookable import hookable
-        def foo():
-            pass
-        def bar():
-            pass
-        hooked = hookable(foo)
-        hooked.sethook(bar)
-        hooked.reset()
-        self.failUnless(hooked.original is foo)
-        self.failUnless(hooked.implementation is foo)
-
-    def test_cant_assign_original(self):
-        from zope.component.hookable import hookable
-        def foo():
-            pass
-        def bar():
-            pass
-        hooked = hookable(foo)
-        try:
-            hooked.original = bar
-        except TypeError:
-            pass
-        except AttributeError:
-            pass
-        else:
-            self.fail('Assigned original')
-
-    def test_cant_delete_original(self):
-        from zope.component.hookable import hookable
-        def foo():
-            pass
-        hooked = hookable(foo)
-        try:
-            del hooked.original
-        except TypeError:
-            pass
-        except AttributeError:
-            pass
-        else:
-            self.fail('Deleted original')
-
-    def test_cant_assign_original(self):
-        from zope.component.hookable import hookable
-        def foo():
-            pass
-        def bar():
-            pass
-        hooked = hookable(foo)
-        try:
-            hooked.implementation = bar
-        except TypeError:
-            pass
-        except AttributeError:
-            pass
-        else:
-            self.fail('Assigned implementation')
-
-    def test_readonly_original(self):
-        from zope.component.hookable import hookable
-        def foo():
-            pass
-        hooked = hookable(foo)
-        try:
-            del hooked.implementation
-        except TypeError:
-            pass
-        except AttributeError:
-            pass
-        else:
-            self.fail('Deleted implementation')
-
-class Ob3(object):
-    interface.implements(IC)
-
-template = """<configure
-   xmlns='http://namespaces.zope.org/zope'
-   i18n_domain='zope'>
-   %s
-   </configure>"""
-
-
-class ResourceViewTests(PlacelessSetup, unittest.TestCase):
-
-    def setUp(self):
-        super(ResourceViewTests, self).setUp()
-        XMLConfig('meta.zcml', zope.component)()
-        XMLConfig('meta.zcml', zope.security)()
-
-    def testView(self):
-        ob = Ob3()
-        request = Request(IV)
-        self.assertEqual(
-            zope.component.queryMultiAdapter((ob, request), name=u'test'), None)
-
-        xmlconfig(StringIO(template %
-            '''
-            <view name="test"
-                  factory="zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IV"/>
-            '''
-            ))
-
-        self.assertEqual(
-            zope.component.queryMultiAdapter((ob, request),
-                                             name=u'test').__class__,
-            V1)
-
-
-    def testMultiView(self):
-        xmlconfig(StringIO(template %
-            '''
-            <view name="test"
-                  factory="zope.component.testfiles.adapter.A3"
-                  for="zope.component.testfiles.views.IC
-                       zope.component.testfiles.adapter.I1
-                       zope.component.testfiles.adapter.I2"
-                  type="zope.component.testfiles.views.IV"/>
-            '''
-            ))
-
-
-        ob = Ob3()
-        a1 = A1()
-        a2 = A2()
-        request = Request(IV)
-        view = zope.component.queryMultiAdapter((ob, a1, a2, request),
-                                                name=u'test')
-        self.assertEqual(view.__class__, A3)
-        self.assertEqual(view.context, (ob, a1, a2, request))
-
-
-    def testMultiView_fails_w_multiple_factories(self):
-        self.assertRaises(
-            ConfigurationError,
-            xmlconfig,
-            StringIO(template %
-              '''
-              <view name="test"
-                    factory="zope.component.testfiles.adapter.A3
-                             zope.component.testfiles.adapter.A2"
-                    for="zope.component.testfiles.views.IC
-                         zope.component.testfiles.adapter.I1
-                         zope.component.testfiles.adapter.I2"
-                    type="zope.component.testfiles.views.IV"/>
-              '''
-              )
-            )
-
-    def testView_w_multiple_factories(self):
-        xmlconfig(StringIO(template %
-            '''
-            <view name="test"
-                  factory="zope.component.testfiles.adapter.A1
-                           zope.component.testfiles.adapter.A2
-                           zope.component.testfiles.adapter.A3
-                           zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IV"/>
-            '''
-            ))
-
-        ob = Ob3()
-
-        # The view should be a V1 around an A3, around an A2, around
-        # an A1, anround ob:
-        view = zope.component.queryMultiAdapter((ob, Request(IV)), name=u'test')
-        self.assertEqual(view.__class__, V1)
-        a3 = view.context
-        self.assertEqual(a3.__class__, A3)
-        a2 = a3.context[0]
-        self.assertEqual(a2.__class__, A2)
-        a1 = a2.context[0]
-        self.assertEqual(a1.__class__, A1)
-        self.assertEqual(a1.context[0], ob)
-
-    def testView_fails_w_no_factories(self):
-        self.assertRaises(ConfigurationError,
-                          xmlconfig,
-                          StringIO(template %
-                                   '''
-                                   <view name="test"
-                                   factory=""
-                                   for="zope.component.testfiles.views.IC"
-                                   type="zope.component.testfiles.views.IV"/>
-                                   '''
-                                   ),
-                          )
-
-
-    def testViewThatProvidesAnInterface(self):
-        ob = Ob3()
-        self.assertEqual(
-            zope.component.queryMultiAdapter((ob, Request(IR)), IV, u'test'),
-            None)
-
-        xmlconfig(StringIO(template %
-            '''
-            <view name="test"
-                  factory="zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IR"
-                  />
-            '''
-            ))
-
-        self.assertEqual(
-            zope.component.queryMultiAdapter((ob, Request(IR)), IV, u'test'),
-            None)
-
-        xmlconfig(StringIO(template %
-            '''
-            <view name="test"
-                  factory="zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IR"
-                  provides="zope.component.testfiles.views.IV"
-                  />
-            '''
-            ))
-
-        v = zope.component.queryMultiAdapter((ob, Request(IR)), IV, u'test')
-        self.assertEqual(v.__class__, V1)
-
-
-    def testUnnamedViewThatProvidesAnInterface(self):
-        ob = Ob3()
-        self.assertEqual(
-            zope.component.queryMultiAdapter((ob, Request(IR)), IV), None)
-
-        xmlconfig(StringIO(template %
-            '''
-            <view factory="zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IR"
-                  />
-            '''
-            ))
-
-        v = zope.component.queryMultiAdapter((ob, Request(IR)), IV)
-        self.assertEqual(v, None)
-
-        xmlconfig(StringIO(template %
-            '''
-            <view factory="zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IR"
-                  provides="zope.component.testfiles.views.IV"
-                  />
-            '''
-            ))
-
-        v = zope.component.queryMultiAdapter((ob, Request(IR)), IV)
-        self.assertEqual(v.__class__, V1)
-
-    def testViewHavingARequiredClass(self):
-        xmlconfig(StringIO(template % (
-            '''
-            <view
-              for="zope.component.testfiles.components.Content"
-              type="zope.component.testfiles.views.IR"
-              factory="zope.component.testfiles.adapter.A1"
-              />
-            '''
-            )))
-
-        content = Content()
-        a1 = zope.component.getMultiAdapter((content, Request(IR)))
-        self.assert_(isinstance(a1, A1))
-
-        class MyContent:
-            interface.implements(IContent)
-
-        self.assertRaises(ComponentLookupError, zope.component.getMultiAdapter,
-                          (MyContent(), Request(IR)))
-
-    def testInterfaceProtectedView(self):
-        xmlconfig(StringIO(template %
-            '''
-            <view name="test"
-                  factory="zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IV"
-                  permission="zope.Public"
-              allowed_interface="zope.component.testfiles.views.IV"
-                  />
-            '''
-            ))
-
-        v = ProxyFactory(zope.component.getMultiAdapter((Ob3(), Request(IV)),
-                                                        name='test'))
-        self.assertEqual(v.index(), 'V1 here')
-        self.assertRaises(Exception, getattr, v, 'action')
-
-    def testAttributeProtectedView(self):
-        xmlconfig(StringIO(template %
-            '''
-            <view name="test"
-                  factory="zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IV"
-                  permission="zope.Public"
-                  allowed_attributes="action"
-                  />
-            '''
-            ))
-
-        v = ProxyFactory(zope.component.getMultiAdapter((Ob3(), Request(IV)),
-                                                        name='test'))
-        self.assertEqual(v.action(), 'done')
-        self.assertRaises(Exception, getattr, v, 'index')
-
-    def testInterfaceAndAttributeProtectedView(self):
-        xmlconfig(StringIO(template %
-            '''
-            <view name="test"
-                  factory="zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IV"
-                  permission="zope.Public"
-                  allowed_attributes="action"
-              allowed_interface="zope.component.testfiles.views.IV"
-                  />
-            '''
-            ))
-
-        v = zope.component.getMultiAdapter((Ob3(), Request(IV)), name='test')
-        self.assertEqual(v.index(), 'V1 here')
-        self.assertEqual(v.action(), 'done')
-
-    def testDuplicatedInterfaceAndAttributeProtectedView(self):
-        xmlconfig(StringIO(template %
-            '''
-            <view name="test"
-                  factory="zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IV"
-                  permission="zope.Public"
-                  allowed_attributes="action index"
-              allowed_interface="zope.component.testfiles.views.IV"
-                  />
-            '''
-            ))
-
-        v = zope.component.getMultiAdapter((Ob3(), Request(IV)), name='test')
-        self.assertEqual(v.index(), 'V1 here')
-        self.assertEqual(v.action(), 'done')
-
-    def testIncompleteProtectedViewNoPermission(self):
-        self.assertRaises(
-            ConfigurationError,
-            xmlconfig,
-            StringIO(template %
-            '''
-            <view name="test"
-                  factory="zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IV"
-                  allowed_attributes="action index"
-                  />
-            '''
-            ))
-
-    def testViewUndefinedPermission(self):
-        config = StringIO(template % (
-            '''
-            <view name="test"
-                  factory="zope.component.testfiles.views.V1"
-                  for="zope.component.testfiles.views.IC"
-                  type="zope.component.testfiles.views.IV"
-                  permission="zope.UndefinedPermission"
-                  allowed_attributes="action index"
-              allowed_interface="zope.component.testfiles.views.IV"
-                  />
-            '''
-            ))
-        self.assertRaises(ValueError, xmlconfig, config, testing=1)
-
-    def testResource(self):
-        ob = Ob3()
-        self.assertEqual(
-            zope.component.queryAdapter(Request(IV), name=u'test'), None)
-        xmlconfig(StringIO(template % (
-            '''
-            <resource name="test"
-                  factory="zope.component.testfiles.views.R1"
-                  type="zope.component.testfiles.views.IV"/>
-            '''
-            )))
-
-        self.assertEqual(
-            zope.component.queryAdapter(Request(IV), name=u'test').__class__,
-            R1)
-
-    def testResourceThatProvidesAnInterface(self):
-        ob = Ob3()
-        self.assertEqual(zope.component.queryAdapter(Request(IR), IV, u'test'),
-                         None)
-
-        xmlconfig(StringIO(template %
-            '''
-            <resource
-                name="test"
-                factory="zope.component.testfiles.views.R1"
-                type="zope.component.testfiles.views.IR"
-                />
-            '''
-            ))
-
-        v = zope.component.queryAdapter(Request(IR), IV, name=u'test')
-        self.assertEqual(v, None)
-
-        xmlconfig(StringIO(template %
-            '''
-            <resource
-                name="test"
-                factory="zope.component.testfiles.views.R1"
-                type="zope.component.testfiles.views.IR"
-                provides="zope.component.testfiles.views.IV"
-                />
-            '''
-            ))
-
-        v = zope.component.queryAdapter(Request(IR), IV, name=u'test')
-        self.assertEqual(v.__class__, R1)
-
-    def testUnnamedResourceThatProvidesAnInterface(self):
-        ob = Ob3()
-        self.assertEqual(zope.component.queryAdapter(Request(IR), IV), None)
-
-        xmlconfig(StringIO(template %
-            '''
-            <resource
-                factory="zope.component.testfiles.views.R1"
-                type="zope.component.testfiles.views.IR"
-                />
-            '''
-            ))
-
-        v = zope.component.queryAdapter(Request(IR), IV)
-        self.assertEqual(v, None)
-
-        xmlconfig(StringIO(template %
-            '''
-            <resource
-                factory="zope.component.testfiles.views.R1"
-                type="zope.component.testfiles.views.IR"
-                provides="zope.component.testfiles.views.IV"
-                />
-            '''
-            ))
-
-        v = zope.component.queryAdapter(Request(IR), IV)
-        self.assertEqual(v.__class__, R1)
-
-    def testResourceUndefinedPermission(self):
-
-        config = StringIO(template % (
-            '''
-            <resource name="test"
-                  factory="zope.component.testfiles.views.R1"
-                  type="zope.component.testfiles.views.IV"
-                  permission="zope.UndefinedPermission"/>
-            '''
-            ))
-        self.assertRaises(ValueError, xmlconfig, config, testing=1)
-
-
-class ConditionalSecurityLayer(UnitTests):
-
-    __name__ = 'ConditionalSecurity'
-    __bases__ = ()
-
-    def setUp(self):
-        setUp()
-        self.modules = {}
-        for m in ('zope.security', 'zope.proxy'):
-            self.modules[m] = sys.modules[m]
-            sys.modules[m] = None
-        import zope.component.zcml
-        reload(zope.component.zcml)
-
-    def tearDown(self):
-        tearDown()
-        for m in ('zope.security', 'zope.proxy'):
-            sys.modules[m] = self.modules[m]
-        import zope.component.zcml
-        reload(zope.component.zcml)
-
-
-def setUpRegistryTests(tests):
-    setUp()
-
-def tearDownRegistryTests(tests):
-    tearDown()
-    import zope.event
-    zope.event.subscribers.pop()
-
-def clearZCML(test=None):
-    tearDown()
-    setUp()
-    XMLConfig('meta.zcml', component)()
-
-def test_suite():
-    checker = renormalizing.RENormalizing([
-        (re.compile('at 0x[0-9a-fA-F]+'), 'at <SOME ADDRESS>'),
-        (re.compile(r"<type 'exceptions.(\w+)Error'>:"),
-                    r'exceptions.\1Error:'),
-        ])
-
-    zcml_conditional = doctest.DocFileSuite('zcml_conditional.txt', checker=checker)
-    zcml_conditional.layer = ConditionalSecurityLayer()
-
-    with_globs = dict(with_statement=__future__.with_statement)
-    hooks_conditional = doctest.DocFileSuite(
-        'hooks.txt', checker=checker, globs=with_globs)
-    hooks_conditional.layer = ConditionalSecurityLayer()
-
-    return unittest.TestSuite((
-        doctest.DocTestSuite(setUp=setUp, tearDown=tearDown),
-        unittest.makeSuite(HookableTests),
-        doctest.DocTestSuite('zope.component.interface',
-                             setUp=setUp, tearDown=tearDown),
-        doctest.DocTestSuite('zope.component.nexttesting'),
-        doctest.DocFileSuite('README.txt',
-                             setUp=setUp, tearDown=tearDown),
-        doctest.DocFileSuite('socketexample.txt',
-                             setUp=setUp, tearDown=tearDown),
-        doctest.DocFileSuite('factory.txt',
-                             setUp=setUp, tearDown=tearDown),
-        doctest.DocFileSuite('hooks.txt', checker=checker,
-                             setUp=setUp, tearDown=tearDown,
-                             globs=with_globs),
-        doctest.DocFileSuite('event.txt',
-                             setUp=setUp, tearDown=tearDown),
-        doctest.DocTestSuite('zope.component.security'),
-        doctest.DocFileSuite('zcml.txt', checker=checker,
-                             setUp=setUp, tearDown=tearDown),
-        doctest.DocFileSuite('configure.txt',
-                             setUp=setUp, tearDown=tearDown),
-        doctest.DocFileSuite('testlayer.txt',
-                             optionflags=(doctest.ELLIPSIS +
-                                          doctest.NORMALIZE_WHITESPACE +
-                                          doctest.REPORT_NDIFF)),
-        zcml_conditional,
-        hooks_conditional,
-        unittest.makeSuite(StandaloneTests),
-        unittest.makeSuite(ResourceViewTests),
-        ))
-
-if __name__ == "__main__":
-    unittest.main(defaultTest='test_suite')

Modified: zope.component/trunk/src/zope/component/zcml.py
===================================================================
--- zope.component/trunk/src/zope/component/zcml.py	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/zcml.py	2012-06-29 14:47:56 UTC (rev 127192)
@@ -13,42 +13,49 @@
 ##############################################################################
 """Component Architecture configuration handlers
 """
-__docformat__ = "reStructuredText"
-
-import warnings
-import zope.component
-import zope.configuration.fields
-import zope.interface
-import zope.schema
-
-from zope.component.interface import provideInterface
 from zope.configuration.exceptions import ConfigurationError
+from zope.configuration.fields import Bool
+from zope.configuration.fields import GlobalInterface
+from zope.configuration.fields import GlobalObject
+from zope.configuration.fields import PythonIdentifier
+from zope.configuration.fields import Tokens
 from zope.i18nmessageid import MessageFactory
+from zope.interface import Interface
+from zope.interface import implementedBy
+from zope.interface import providedBy
+from zope.schema import TextLine
 
+from zope.component._api import getSiteManager
+from zope.component._declaration import adaptedBy
+from zope.component.interface import provideInterface
+from zope.component._compat import _BLANK
+
 try:
-    from zope.component.security import _checker, proxify, protectedFactory, \
-        securityAdapterFactory
     from zope.security.zcml import Permission
-except ImportError:
-    SECURITY_SUPPORT = False
-    from zope.schema import TextLine as Permission
+except ImportError: #pragma NO COVER
+    def _no_security(*args, **kw):
+        raise ConfigurationError("security proxied components are not "
+            "supported because zope.security is not available")
+    _checker = proxify = protectedFactory = security =_no_security
+    Permission = TextLine
 else:
-    SECURITY_SUPPORT = True
+    from zope.component.security import _checker
+    from zope.component.security import proxify
+    from zope.component.security import protectedFactory
+    from zope.component.security import securityAdapterFactory
 
 _ = MessageFactory('zope')
 
-def check_security_support():
-    if not SECURITY_SUPPORT:
-        raise ConfigurationError("security proxied components are not "
-            "supported because zope.security is not available")
+class ComponentConfigurationError(ValueError, ConfigurationError):
+    pass
 
 def handler(methodName, *args, **kwargs):
-    method = getattr(zope.component.getSiteManager(), methodName)
+    method = getattr(getSiteManager(), methodName)
     method(*args, **kwargs)
 
-class IBasicComponentInformation(zope.interface.Interface):
+class IBasicComponentInformation(Interface):
 
-    component = zope.configuration.fields.GlobalObject(
+    component = GlobalObject(
         title=_("Component to use"),
         description=_("Python name of the implementation object.  This"
                       " must identify an object in a module using the"
@@ -63,7 +70,7 @@
         required=False,
         )
 
-    factory = zope.configuration.fields.GlobalObject(
+    factory = GlobalObject(
         title=_("Factory"),
         description=_("Python name of a factory which can create the"
                       " implementation object.  This must identify an"
@@ -73,31 +80,31 @@
         required=False,
         )
 
-class IAdapterDirective(zope.interface.Interface):
+class IAdapterDirective(Interface):
     """
     Register an adapter
     """
 
-    factory = zope.configuration.fields.Tokens(
+    factory = Tokens(
         title=_("Adapter factory/factories"),
         description=_("A list of factories (usually just one) that create"
                       " the adapter instance."),
         required=True,
-        value_type=zope.configuration.fields.GlobalObject()
+        value_type=GlobalObject()
         )
 
-    provides = zope.configuration.fields.GlobalInterface(
+    provides = GlobalInterface(
         title=_("Interface the component provides"),
         description=_("This attribute specifies the interface the adapter"
                       " instance must provide."),
         required=False,
         )
 
-    for_ = zope.configuration.fields.Tokens(
+    for_ = Tokens(
         title=_("Specifications to be adapted"),
         description=_("This should be a list of interfaces or classes"),
         required=False,
-        value_type=zope.configuration.fields.GlobalObject(
+        value_type=GlobalObject(
           missing_value=object(),
           ),
         )
@@ -109,7 +116,7 @@
         required=False,
         )
 
-    name = zope.schema.TextLine(
+    name = TextLine(
         title=_("Name"),
         description=_("Adapters can have names.\n\n"
                       "This attribute allows you to specify the name for"
@@ -117,7 +124,7 @@
         required=False,
         )
 
-    trusted = zope.configuration.fields.Bool(
+    trusted = Bool(
         title=_("Trusted"),
         description=_("""Make the adapter a trusted adapter
 
@@ -131,7 +138,7 @@
         default=False,
         )
 
-    locate = zope.configuration.fields.Bool(
+    locate = Bool(
         title=_("Locate"),
         description=_("""Make the adapter a locatable adapter
 
@@ -158,7 +165,7 @@
 
     if for_ is None:
         if len(factory) == 1:
-            for_ = zope.component.adaptedBy(factory[0])
+            for_ = adaptedBy(factory[0])
 
         if for_ is None:
             raise TypeError("No for attribute was provided and can't "
@@ -168,7 +175,7 @@
 
     if provides is None:
         if len(factory) == 1:
-            p = list(zope.interface.implementedBy(factory[0]))
+            p = list(implementedBy(factory[0]))
             if len(p) == 1:
                 provides = p[0]
 
@@ -180,19 +187,18 @@
     if len(factories) == 1:
         factory = factories[0]
     elif len(factories) < 1:
-        raise ValueError("No factory specified")
+        raise ComponentConfigurationError("No factory specified")
     elif len(factories) > 1 and len(for_) != 1:
-        raise ValueError("Can't use multiple factories and multiple for")
+        raise ComponentConfigurationError(
+            "Can't use multiple factories and multiple for")
     else:
         factory = _rolledUpFactory(factories)
 
     if permission is not None:
-        check_security_support()
         factory = protectedFactory(factory, provides, permission)
 
     # invoke custom adapter factories
     if locate or permission is not None or trusted:
-        check_security_support()
         factory = securityAdapterFactory(factory, permission, locate, trusted)
 
     _context.action(
@@ -215,35 +221,35 @@
                     args = ('', iface)
                     )
 
-class ISubscriberDirective(zope.interface.Interface):
+class ISubscriberDirective(Interface):
     """
     Register a subscriber
     """
 
-    factory = zope.configuration.fields.GlobalObject(
+    factory = GlobalObject(
         title=_("Subscriber factory"),
         description=_("A factory used to create the subscriber instance."),
         required=False,
         )
 
-    handler = zope.configuration.fields.GlobalObject(
+    handler = GlobalObject(
         title=_("Handler"),
         description=_("A callable object that handles events."),
         required=False,
         )
 
-    provides = zope.configuration.fields.GlobalInterface(
+    provides = GlobalInterface(
         title=_("Interface the component provides"),
         description=_("This attribute specifies the interface the adapter"
                       " instance must provide."),
         required=False,
         )
 
-    for_ = zope.configuration.fields.Tokens(
+    for_ = Tokens(
         title=_("Interfaces or classes that this subscriber depends on"),
         description=_("This should be a list of interfaces or classes"),
         required=False,
-        value_type=zope.configuration.fields.GlobalObject(
+        value_type=GlobalObject(
           missing_value = object(),
           ),
         )
@@ -255,7 +261,7 @@
         required=False,
         )
 
-    trusted = zope.configuration.fields.Bool(
+    trusted = Bool(
         title=_("Trusted"),
         description=_("""Make the subscriber a trusted subscriber
 
@@ -269,7 +275,7 @@
         default=False,
         )
 
-    locate = zope.configuration.fields.Bool(
+    locate = Bool(
         title=_("Locate"),
         description=_("""Make the subscriber a locatable subscriber
 
@@ -298,20 +304,18 @@
                 "a factory")
 
     if for_ is None:
-        for_ = zope.component.adaptedBy(factory)
+        for_ = adaptedBy(factory)
         if for_ is None:
             raise TypeError("No for attribute was provided and can't "
                             "determine what the factory (or handler) adapts.")
 
     if permission is not None:
-        check_security_support()
         factory = protectedFactory(factory, provides, permission)
 
     for_ = tuple(for_)
 
     # invoke custom adapter factories
     if locate or permission is not None or trusted:
-        check_security_support()
         factory = securityAdapterFactory(factory, permission, locate, trusted)
 
     if handler is not None:
@@ -319,14 +323,14 @@
             discriminator = None,
             callable = _handler,
             args = ('registerHandler',
-                    handler, for_, u'', _context.info),
+                    handler, for_, _BLANK, _context.info),
             )
     else:
         _context.action(
             discriminator = None,
             callable = _handler,
             args = ('registerSubscriptionAdapter',
-                    factory, for_, provides, u'', _context.info),
+                    factory, for_, provides, _BLANK, _context.info),
             )
 
     if provides is not None:
@@ -348,13 +352,13 @@
 class IUtilityDirective(IBasicComponentInformation):
     """Register a utility."""
 
-    provides = zope.configuration.fields.GlobalInterface(
+    provides = GlobalInterface(
         title=_("Provided interface"),
         description=_("Interface provided by the utility."),
         required=False,
         )
 
-    name = zope.schema.TextLine(
+    name = TextLine(
         title=_("Name"),
         description=_("Name of the registration.  This is used by"
                       " application code when locating a utility."),
@@ -368,46 +372,45 @@
 
     if provides is None:
         if factory:
-            provides = list(zope.interface.implementedBy(factory))
+            provides = list(implementedBy(factory))
         else:
-            provides = list(zope.interface.providedBy(component))
+            provides = list(providedBy(component))
         if len(provides) == 1:
             provides = provides[0]
         else:
             raise TypeError("Missing 'provides' attribute")
 
     if permission is not None:
-        check_security_support()
         component = proxify(component, provides=provides, permission=permission)
 
     _context.action(
         discriminator = ('utility', provides, name),
         callable = handler,
-        args = ('registerUtility', component, provides, name),
+        args = ('registerUtility', component, provides, name, _context.info),
         kw = dict(factory=factory),
         )
     _context.action(
         discriminator = None,
         callable = provideInterface,
-        args = (provides.__module__ + '.' + provides.getName(), provides)
+        args = ('', provides),
         )
 
-class IInterfaceDirective(zope.interface.Interface):
+class IInterfaceDirective(Interface):
     """
     Define an interface
     """
 
-    interface = zope.configuration.fields.GlobalInterface(
+    interface = GlobalInterface(
         title=_("Interface"),
         required=True,
         )
 
-    type = zope.configuration.fields.GlobalInterface(
+    type = GlobalInterface(
         title=_("Interface type"),
         required=False,
         )
 
-    name = zope.schema.TextLine(
+    name = TextLine(
         title=_("Name"),
         required=False,
         )
@@ -419,15 +422,15 @@
         args = (name, interface, type)
         )
 
-class IBasicViewInformation(zope.interface.Interface):
+class IBasicViewInformation(Interface):
     """This is the basic information for all views."""
 
-    for_ = zope.configuration.fields.Tokens(
+    for_ = Tokens(
         title=_("Specifications of the objects to be viewed"),
         description=_("""This should be a list of interfaces or classes
         """),
         required=True,
-        value_type=zope.configuration.fields.GlobalObject(
+        value_type=GlobalObject(
           missing_value=object(),
           ),
         )
@@ -438,22 +441,13 @@
         required=False,
         )
 
-    class_ = zope.configuration.fields.GlobalObject(
+    class_ = GlobalObject(
         title=_("Class"),
         description=_("A class that provides attributes used by the view."),
         required=False,
         )
 
-    layer = zope.configuration.fields.GlobalInterface(
-        title=_("The layer the view is in."),
-        description=_("""
-        A skin is composed of layers. It is common to put skin
-        specific views in a layer named after the skin. If the 'layer'
-        attribute is not supplied, it defaults to 'default'."""),
-        required=False,
-        )
-
-    allowed_interface = zope.configuration.fields.Tokens(
+    allowed_interface = Tokens(
         title=_("Interface that is also allowed if user has permission."),
         description=_("""
         By default, 'permission' only applies to viewing the view and
@@ -464,10 +458,10 @@
         Multiple interfaces can be provided, separated by
         whitespace."""),
         required=False,
-        value_type=zope.configuration.fields.GlobalInterface(),
+        value_type=GlobalInterface(),
         )
 
-    allowed_attributes = zope.configuration.fields.Tokens(
+    allowed_attributes = Tokens(
         title=_("View attributes that are also allowed if the user"
                 " has permission."),
         description=_("""
@@ -476,31 +470,31 @@
         you can make the permission also apply to the extra attributes
         on the view object."""),
         required=False,
-        value_type=zope.configuration.fields.PythonIdentifier(),
+        value_type=PythonIdentifier(),
         )
 
-class IBasicResourceInformation(zope.interface.Interface):
+class IBasicResourceInformation(Interface):
     """
     Basic information for resources
     """
 
-    name = zope.schema.TextLine(
+    name = TextLine(
         title=_("The name of the resource."),
         description=_("The name shows up in URLs/paths. For example 'foo'."),
         required=True,
-        default=u'',
+        default=_BLANK,
         )
 
-    provides = zope.configuration.fields.GlobalInterface(
+    provides = GlobalInterface(
         title=_("The interface this component provides."),
         description=_("""
         A view can provide an interface.  This would be used for
         views that support other views."""),
         required=False,
-        default=zope.interface.Interface,
+        default=Interface,
         )
 
-    type = zope.configuration.fields.GlobalInterface(
+    type = GlobalInterface(
         title=_("Request type"),
         required=True
         )
@@ -509,28 +503,26 @@
 class IViewDirective(IBasicViewInformation, IBasicResourceInformation):
     """Register a view for a component"""
 
-    factory = zope.configuration.fields.Tokens(
+    factory = Tokens(
         title=_("Factory"),
         required=False,
-        value_type=zope.configuration.fields.GlobalObject(),
+        value_type=GlobalObject(),
         )
 
-def view(_context, factory, type, name, for_, layer=None,
-         permission=None, allowed_interface=None, allowed_attributes=None,
-         provides=zope.interface.Interface):
+def view(_context, factory, type, name, for_,
+         permission=None,
+         allowed_interface=None,
+         allowed_attributes=None,
+         provides=Interface,
+        ):
 
     if ((allowed_attributes or allowed_interface)
         and (not permission)):
-        raise ConfigurationError(
-            "Must use name attribute with allowed_interface or "
-            "allowed_attributes"
-            )
+        raise ComponentConfigurationError(
+            "'permission' required with 'allowed_interface' or "
+            "'allowed_attributes'")
 
-    if not factory:
-        raise ConfigurationError("No view factory specified.")
-
     if permission is not None:
-        check_security_support()
 
         checker = _checker(_context, permission,
                            allowed_interface, allowed_attributes)
@@ -549,7 +541,7 @@
 
 
     if not for_:
-        raise ValueError("No for interfaces specified");
+        raise ComponentConfigurationError("No for interfaces specified");
     for_ = tuple(for_)
 
     # Generate a single factory from multiple factories:
@@ -557,27 +549,18 @@
     if len(factories) == 1:
         factory = factories[0]
     elif len(factories) < 1:
-        raise ValueError("No factory specified")
+        raise ComponentConfigurationError("No view factory specified")
     elif len(factories) > 1 and len(for_) > 1:
-        raise ValueError("Can't use multiple factories and multiple for")
+        raise ComponentConfigurationError(
+            "Can't use multiple factories and multiple for")
     else:
         def factory(ob, request):
             for f in factories[:-1]:
                 ob = f(ob)
             return factories[-1](ob, request)
+        factory.factory = factories[0]
 
-    # BBB 2006/02/18, to be removed after 12 months
-    if layer is not None:
-        for_ = for_ + (layer,)
-        warnings.warn_explicit(
-            "The 'layer' argument of the 'view' directive has been "
-            "deprecated.  Use the 'type' argument instead. If you have "
-            "an existing 'type' argument IBrowserRequest, replace it with the "
-            "'layer' argument (the layer subclasses IBrowserRequest). "
-            "which subclasses BrowserRequest.",
-            DeprecationWarning, _context.info.file, _context.info.line)
-    else:
-        for_ = for_ + (type,)
+    for_ = for_ + (type,)
 
     _context.action(
         discriminator = ('view', for_, name, provides),
@@ -585,12 +568,6 @@
         args = ('registerAdapter',
                 factory, for_, provides, name, _context.info),
         )
-    if type is not None:
-        _context.action(
-            discriminator = None,
-            callable = provideInterface,
-            args = ('', type)
-            )
 
     _context.action(
         discriminator = None,
@@ -612,67 +589,52 @@
                          IBasicResourceInformation):
     """Register a resource"""
 
-    layer = zope.configuration.fields.GlobalInterface(
-        title=_("The layer the resource is in."),
-        required=False,
-        )
-
-    allowed_interface = zope.configuration.fields.Tokens(
+    allowed_interface = Tokens(
         title=_("Interface that is also allowed if user has permission."),
         required=False,
-        value_type=zope.configuration.fields.GlobalInterface(),
+        value_type=GlobalInterface(),
         )
 
-    allowed_attributes = zope.configuration.fields.Tokens(
+    allowed_attributes = Tokens(
         title=_("View attributes that are also allowed if user"
                 " has permission."),
         required=False,
-        value_type=zope.configuration.fields.PythonIdentifier(),
+        value_type=PythonIdentifier(),
         )
 
-def resource(_context, factory, type, name, layer=None,
+def resource(_context, factory, type, name,
              permission=None,
              allowed_interface=None, allowed_attributes=None,
-             provides=zope.interface.Interface):
+             provides=Interface):
 
     if ((allowed_attributes or allowed_interface)
         and (not permission)):
-        raise ConfigurationError(
+        raise ComponentConfigurationError(
             "Must use name attribute with allowed_interface or "
             "allowed_attributes"
             )
 
     if permission is not None:
-        check_security_support()
 
         checker = _checker(_context, permission,
                            allowed_interface, allowed_attributes)
 
         def proxyResource(request, factory=factory, checker=checker):
             return proxify(factory(request), checker)
+        proxyResource.factory = factory
 
         factory = proxyResource
 
-    if layer is not None:
-        warnings.warn_explicit(
-            "The 'layer' argument of the 'resource' directive has been "
-            "deprecated.  Use the 'type' argument instead.",
-            DeprecationWarning, _context.info.file, _context.info.line)
-        type = layer
-
     _context.action(
         discriminator = ('resource', name, type, provides),
         callable = handler,
         args = ('registerAdapter',
-                factory, (type,), provides, name, _context.info),
-        )
+                factory, (type,), provides, name, _context.info))
     _context.action(
         discriminator = None,
         callable = provideInterface,
-        args = (type.__module__ + '.' + type.__name__, type)
-               )
+        args = ('', type))
     _context.action(
         discriminator = None,
         callable = provideInterface,
-        args = (provides.__module__ + '.' + provides.__name__, type)
-               )
+        args = ('', provides))

Deleted: zope.component/trunk/src/zope/component/zcml.txt
===================================================================
--- zope.component/trunk/src/zope/component/zcml.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/zcml.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,1021 +0,0 @@
-ZCML directives
-===============
-
-Components may be registered using the registration API exposed by
-``zope.component`` (provideAdapter, provideUtility, etc.).  They may
-also be registered using configuration files.  The common way to do
-that is by using ZCML (Zope Configuration Markup Language), an XML
-spelling of component registration.
-
-In ZCML, each XML element is a *directive*.  There are different
-top-level directives that let us register components.  We will
-introduce them one by one here.
-
-This helper will let us easily execute ZCML snippets:
-
-  >>> from cStringIO import StringIO
-  >>> from zope.configuration.xmlconfig import xmlconfig
-  >>> def runSnippet(snippet):
-  ...     template = """\
-  ...     <configure xmlns='http://namespaces.zope.org/zope'
-  ...                i18n_domain="zope">
-  ...     %s
-  ...     </configure>"""
-  ...     xmlconfig(StringIO(template % snippet))
-
-adapter
--------
-
-Adapters play a key role in the Component Architecture.  In ZCML, they
-are registered with the <adapter /> directive.
-
-  >>> from zope.component.testfiles.adapter import A1, A2, A3, Handler
-  >>> from zope.component.testfiles.adapter import I1, I2, I3, IS
-  >>> from zope.component.testfiles.components import IContent, Content, Comp, comp
-
-Before we register the first test adapter, we can verify that adapter
-lookup doesn't work yet:
-
-  >>> from zope.component.tests import clearZCML
-  >>> clearZCML()
-  >>> from zope.component.testfiles.components import IApp
-  >>> IApp(Content(), None) is None
-  True
-
-Then we register the adapter and see that the lookup works:
-
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.components.Comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       />''')
-
-  >>> IApp(Content()).__class__
-  <class 'zope.component.testfiles.components.Comp'>
-
-It is also possible to give adapters names.  Then the combination of
-required interface, provided interface and name makes the adapter
-lookup unique.  The name is supplied using the ``name`` argument to
-the <adapter /> directive:
-
-  >>> from zope.component.tests import clearZCML
-  >>> clearZCML()
-  >>> import zope.component
-  >>> zope.component.queryAdapter(Content(), IApp, 'test') is None
-  True
-
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.components.Comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       name="test"
-  ...       />''')
-
-  >>> zope.component.getAdapter(Content(), IApp, 'test').__class__
-  <class 'zope.component.testfiles.components.Comp'>
-
-Adapter factories
-~~~~~~~~~~~~~~~~~
-
-It is possible to supply more than one adapter factory.  In this case,
-during adapter lookup each factory will be called and the return value
-will be given to the next factory.  The return value of the last
-factory is returned as the result of the adapter lookup.  For examle:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.adapter.A1
-  ...                zope.component.testfiles.adapter.A2
-  ...                zope.component.testfiles.adapter.A3"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       />''')
-
-The resulting adapter is an A3, around an A2, around an A1, around the
-adapted object:
-
-  >>> content = Content()
-  >>> a3 = IApp(content)
-  >>> a3.__class__ is A3
-  True
-
-  >>> a2 = a3.context[0]
-  >>> a2.__class__ is A2
-  True
-
-  >>> a1 = a2.context[0]
-  >>> a1.__class__ is A1
-  True
-
-  >>> a1.context[0] is content
-  True
-
-Of course, if no factory is provided at all, we will get an error:
-
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory=""
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-8.8
-      ValueError: No factory specified
-
-
-Declaring ``for`` and ``provides`` in Python
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The <adapter /> directive can figure out from the in-line Python
-declaration (using ``zope.component.adapts()`` or
-``zope.component.adapter()`` as well as ``zope.interface.implements``)
-what the adapter should be registered for and what it provides::
-
-  >>> clearZCML()
-  >>> IApp(Content(), None) is None
-  True
-
-  >>> runSnippet('''
-  ...   <adapter factory="zope.component.testfiles.components.Comp" />''')
-
-  >>> IApp(Content()).__class__
-  <class 'zope.component.testfiles.components.Comp'>
-
-Of course, if the adapter has no ``implements()`` declaration, ZCML
-can't figure out what it provides:
-
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.adapter.A4"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-7.8
-      TypeError: Missing 'provides' attribute
-
-On the other hand, if the factory implements more than one interface,
-ZCML can't figure out what it should provide either:
-
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.adapter.A5"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-7.8
-      TypeError: Missing 'provides' attribute
-
-A not so common edge case is registering adapters directly for
-classes, not for interfaces.  For example:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for="zope.component.testfiles.components.Content"
-  ...       provides="zope.component.testfiles.adapter.I1"
-  ...       factory="zope.component.testfiles.adapter.A1"
-  ...       />''')
-
-  >>> content = Content()
-  >>> a1 = zope.component.getAdapter(content, I1, '')
-  >>> isinstance(a1, A1)
-  True
-
-This time, any object providing ``IContent`` won't work if it's not an
-instance of the ``Content`` class:
-
-  >>> import zope.interface
-  >>> class MyContent:
-  ...     zope.interface.implements(IContent)
-  >>> zope.component.getAdapter(MyContent(), I1, '')  # doctest: +ELLIPSIS
-  Traceback (most recent call last):
-    ...
-  ComponentLookupError: ...
-
-Multi-adapters
-~~~~~~~~~~~~~~
-
-Conventional adapters adapt one object to provide another interface.
-Multi-adapters adapt several objects at once:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1
-  ...            zope.component.testfiles.adapter.I2"
-  ...       provides="zope.component.testfiles.adapter.I3"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       />''')
-
-  >>> content = Content()
-  >>> a1 = A1()
-  >>> a2 = A2()
-  >>> a3 = zope.component.queryMultiAdapter((content, a1, a2), I3)
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == (content, a1, a2)
-  True
-
-You can even adapt an empty list of objects (we call this a
-null-adapter):
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for=""
-  ...       provides="zope.component.testfiles.adapter.I3"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       />''')
-
-  >>> a3 = zope.component.queryMultiAdapter((), I3)
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == ()
-  True
-
-Even with multi-adapters, ZCML can figure out the ``for`` and
-``provides`` parameters from the Python declarations:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter factory="zope.component.testfiles.adapter.A3" />''')
-
-  >>> a3 = zope.component.queryMultiAdapter((content, a1, a2), I3)
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == (content, a1, a2)
-  True
-
-Chained factories are not supported for multi-adapters, though:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1
-  ...            zope.component.testfiles.adapter.I2"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       factory="zope.component.testfiles.adapter.A1
-  ...                zope.component.testfiles.adapter.A2"
-  ...       />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-11.8
-      ValueError: Can't use multiple factories and multiple for
-
-And neither for null-adapters:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for=""
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       factory="zope.component.testfiles.adapter.A1
-  ...                zope.component.testfiles.adapter.A2"
-  ...       />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-9.8
-      ValueError: Can't use multiple factories and multiple for
-
-Protected adapters
-~~~~~~~~~~~~~~~~~~
-
-Adapters can be protected with a permission.  First we have to define
-a permission for which we'll have to register the <permission />
-directive:
-
-  >>> clearZCML()
-  >>> IApp(Content(), None) is None
-  True
-
-  >>> import zope.security
-  >>> from zope.configuration.xmlconfig import XMLConfig
-  >>> XMLConfig('meta.zcml', zope.security)()
-  >>> runSnippet('''
-  ...   <permission
-  ...       id="y.x"
-  ...       title="XY"
-  ...       description="Allow XY."
-  ...       />
-  ...   <adapter
-  ...       factory="zope.component.testfiles.components.Comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       permission="y.x"
-  ...       />''')
-
-We see that the adapter is a location proxy now so that the
-appropriate permissions can be found from the context:
-
-  >>> IApp(Content()).__class__
-  <class 'zope.component.testfiles.components.Comp'>
-  >>> type(IApp(Content()))
-  <class 'zope.location.location.LocationProxy'>
-
-We can also go about it a different way.  Let's make a public adapter
-and wrap the adapter in a security proxy.  That often happens when
-an adapter is turned over to untrusted code:
-
-  >>> clearZCML()
-  >>> IApp(Content(), None) is None
-  True
-
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.components.Comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       permission="zope.Public"
-  ...       />''')
-
-  >>> from zope.security.checker import ProxyFactory
-  >>> adapter = ProxyFactory(IApp(Content()))
-  >>> from zope.security.proxy import getTestProxyItems
-  >>> items = [item[0] for item in getTestProxyItems(adapter)]
-  >>> items
-  ['a', 'f']
-
-  >>> from zope.security.proxy import removeSecurityProxy
-  >>> removeSecurityProxy(adapter).__class__ is Comp
-  True
-
-Of course, this still works when we let the ZCML directive handler
-figure out ``for`` and ``provides`` from the Python declarations:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.components.Comp"
-  ...       permission="zope.Public"
-  ...       />''')
-
-  >>> adapter = ProxyFactory(IApp(Content()))
-  >>> [item[0] for item in getTestProxyItems(adapter)]
-  ['a', 'f']
-  >>> removeSecurityProxy(adapter).__class__ is Comp
-  True
-
-It also works with multi adapters:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       provides="zope.component.testfiles.adapter.I3"
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1
-  ...            zope.component.testfiles.adapter.I2"
-  ...       permission="zope.Public"
-  ...       />''')
-
-  >>> content = Content()
-  >>> a1 = A1()
-  >>> a2 = A2()
-  >>> a3 = ProxyFactory(zope.component.queryMultiAdapter((content, a1, a2), I3))
-  >>> a3.__class__ == A3
-  True
-  >>> [item[0] for item in getTestProxyItems(a3)]
-  ['f1', 'f2', 'f3']
-
-It's probably not worth mentioning, but when we try to protect an
-adapter with a permission that doesn't exist, we'll obviously get an
-error:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.components.Comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       permission="zope.UndefinedPermission"
-  ...       />''')
-  Traceback (most recent call last):
-    ...
-  ConfigurationExecutionError: exceptions.ValueError: ('Undefined permission id', 'zope.UndefinedPermission')
-    in:
-    File "<string>", line 4.2-9.8
-    Could not read source.
-
-Trusted adapters
-~~~~~~~~~~~~~~~~
-
-Trusted adapters are adapters that are trusted to do anything with the
-objects they are given so that these objects are not security-proxied.
-They are registered using the ``trusted`` argument to the <adapter />
-directive:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       provides="zope.component.testfiles.adapter.I1"
-  ...       factory="zope.component.testfiles.adapter.A1"
-  ...       trusted="yes"
-  ...       />''')
-
-With an unproxied object, it's business as usual:
-
-  >>> ob = Content()
-  >>> type(I1(ob)) is A1
-  True
-
-With a security-proxied object, however, we get a security-proxied
-adapter:
-
-  >>> p = ProxyFactory(ob)
-  >>> a = I1(p)
-  >>> type(a)
-  <type 'zope.security._proxy._Proxy'>
-
-While the adapter is security-proxied, the object it adapts is now
-proxy-free.  The adapter has umlimited access to it:
-
-  >>> a = removeSecurityProxy(a)
-  >>> type(a) is A1
-  True
-  >>> a.context[0] is ob
-  True
-
-We can also protect the trusted adapter with a permission:
-
-  >>> clearZCML()
-  >>> XMLConfig('meta.zcml', zope.security)()
-  >>> runSnippet('''
-  ...   <permission
-  ...       id="y.x"
-  ...       title="XY"
-  ...       description="Allow XY."
-  ...       />
-  ...   <adapter
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       provides="zope.component.testfiles.adapter.I1"
-  ...       factory="zope.component.testfiles.adapter.A1"
-  ...       permission="y.x"
-  ...       trusted="yes"
-  ...       />''')
-
-Again, with an unproxied object, it's business as usual:
-
-  >>> ob = Content()
-  >>> type(I1(ob)) is A1
-  True
-
-With a security-proxied object, we again get a security-proxied
-adapter:
-
-  >>> p = ProxyFactory(ob)
-  >>> a = I1(p)
-  >>> type(a)
-  <type 'zope.security._proxy._Proxy'>
-
-Since we protected the adapter with a permission, we now encounter a
-location proxy behind the security proxy:
-
-  >>> a = removeSecurityProxy(a)
-  >>> type(a)
-  <class 'zope.location.location.LocationProxy'>
-  >>> a.context[0] is ob
-  True
-
-There's one exception to all of this: When you use the public
-permission (``zope.Public``), there will be no location proxy:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       provides="zope.component.testfiles.adapter.I1"
-  ...       factory="zope.component.testfiles.adapter.A1"
-  ...       permission="zope.Public"
-  ...       trusted="yes"
-  ...       />''')
-
-  >>> ob = Content()
-  >>> p = ProxyFactory(ob)
-  >>> a = I1(p)
-  >>> type(a)
-  <type 'zope.security._proxy._Proxy'>
-
-  >>> a = removeSecurityProxy(a)
-  >>> type(a) is A1
-  True
-
-We can also explicitply pass the ``locate`` argument to make sure we
-get location proxies:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       provides="zope.component.testfiles.adapter.I1"
-  ...       factory="zope.component.testfiles.adapter.A1"
-  ...       trusted="yes"
-  ...       locate="yes"
-  ...       />''')
-
-  >>> ob = Content()
-  >>> p = ProxyFactory(ob)
-  >>> a = I1(p)
-  >>> type(a)
-  <type 'zope.security._proxy._Proxy'>
-
-  >>> a = removeSecurityProxy(a)
-  >>> type(a)
-  <class 'zope.location.location.LocationProxy'>
-
-
-subscriber
-----------
-
-With the <subscriber /> directive you can register subscription
-adapters or event subscribers with the adapter registry.  Consider
-this very typical example of a <subscriber /> directive:
- 
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       provides="zope.component.testfiles.adapter.IS"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1"
-  ...       />''')
-
-  >>> content = Content()
-  >>> a1 = A1()
-
-  >>> subscribers = zope.component.subscribers((content, a1), IS)
-  >>> a3 = subscribers[0]
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == (content, a1)
-  True
-
-Note how ZCML provides some additional information when registering
-components, such as the ZCML filename and line numbers:
-
-  >>> sm = zope.component.getSiteManager()
-  >>> doc = [reg.info for reg in sm.registeredSubscriptionAdapters()
-  ...        if reg.provided is IS][0]
-  >>> print doc
-  File "<string>", line 4.2-9.8
-    Could not read source.
-
-The "fun" behind subscription adapters/subscribers is that when
-several ones are declared for the same for/provides, they are all
-found.  With regular adapters, the most specific one (and in doubt the
-one registered last) wins.  Consider these two subscribers:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       provides="zope.component.testfiles.adapter.IS"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1"
-  ...       />
-  ...   <subscriber
-  ...       provides="zope.component.testfiles.adapter.IS"
-  ...       factory="zope.component.testfiles.adapter.A2"
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1"
-  ...       />''')
-
-  >>> subscribers = zope.component.subscribers((content, a1), IS)
-  >>> len(subscribers)
-  2
-  >>> sorted([a.__class__.__name__ for a in subscribers])
-  ['A2', 'A3']
-
-Declaring ``for`` and ``provides`` in Python
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Like the <adapter /> directive, the <subscriber /> directive can
-figure out from the in-line Python declaration (using
-``zope.component.adapts()`` or ``zope.component.adapter()``) what the
-subscriber should be registered for:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       provides="zope.component.testfiles.adapter.IS"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       />''')
-
-  >>> content = Content()
-  >>> a2 = A2()
-  >>> subscribers = zope.component.subscribers((content, a1, a2), IS)
-
-  >>> a3 = subscribers[0]
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == (content, a1, a2)
-  True
-
-In the same way the directive can figure out what a subscriber
-provides:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber handler="zope.component.testfiles.adapter.A3" />''')
-
-  >>> sm = zope.component.getSiteManager()
-  >>> a3 = sm.adapters.subscriptions((IContent, I1, I2), None)[0]
-  >>> a3 is A3
-  True
-
-A not so common edge case is declaring subscribers directly for
-classes, not for interfaces.  For example:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       for="zope.component.testfiles.components.Content"
-  ...       provides="zope.component.testfiles.adapter.I1"
-  ...       factory="zope.component.testfiles.adapter.A1"
-  ...       />''')
-
-  >>> subs = list(zope.component.subscribers((Content(),), I1))
-  >>> isinstance(subs[0], A1)
-  True
-
-This time, any object providing ``IContent`` won't work if it's not an
-instance of the ``Content`` class:
-
-  >>> list(zope.component.subscribers((MyContent(),), I1))
-  []
-
-Protected subscribers
-~~~~~~~~~~~~~~~~~~~~~
-
-Subscribers can also be protected with a permission.  First we have to
-define a permission for which we'll have to register the <permission />
-directive:
-
-  >>> clearZCML()
-  >>> XMLConfig('meta.zcml', zope.security)()
-  >>> runSnippet('''
-  ...   <permission
-  ...       id="y.x"
-  ...       title="XY"
-  ...       description="Allow XY."
-  ...       />
-  ...   <subscriber
-  ...       provides="zope.component.testfiles.adapter.IS"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1"
-  ...       permission="y.x"
-  ...       />''')
-
-  >>> subscribers = zope.component.subscribers((content, a1), IS)
-  >>> a3 = subscribers[0]
-  >>> a3.__class__ is A3
-  True
-  >>> type(a3)
-  <class 'zope.location.location.LocationProxy'>
-  >>> a3.context == (content, a1)
-  True
-
-Trusted subscribers
-~~~~~~~~~~~~~~~~~~~
-
-Like trusted adapters, trusted subscribers are subscribers that are
-trusted to do anything with the objects they are given so that these
-objects are not security-proxied.  In analogy to the <adapter />
-directive, they are registered using the ``trusted`` argument to the
-<subscriber /> directive:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       provides="zope.component.testfiles.adapter.IS"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1"
-  ...       trusted="yes"
-  ...       />''')
-
-With an unproxied object, it's business as usual:
-
-  >>> subscribers = zope.component.subscribers((content, a1), IS)
-  >>> a3 = subscribers[0]
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == (content, a1)
-  True
-  >>> type(a3) is A3
-  True
-
-Now with a proxied object.  We will see that the subscriber has
-unproxied access to it, but the subscriber itself is proxied:
-
-  >>> p = ProxyFactory(content)
-  >>> a3 = zope.component.subscribers((p, a1), IS)[0]
-  >>> type(a3)
-  <type 'zope.security._proxy._Proxy'>
-
-There's no location proxy behind the security proxy:
-
-  >>> removeSecurityProxy(a3).context[0] is content
-  True
-  >>> type(removeSecurityProxy(a3)) is A3
-  True
-
-If you want the trusted subscriber to be located, you'll also have to
-use the ``locate`` argument:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       provides="zope.component.testfiles.adapter.IS"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1"
-  ...       trusted="yes"
-  ...       locate="yes"
-  ...       />''')
-
-Again, it's business as usual with an unproxied object:
-
-  >>> subscribers = zope.component.subscribers((content, a1), IS)
-  >>> a3 = subscribers[0]
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == (content, a1)
-  True
-  >>> type(a3) is A3
-  True
-
-With a proxied object, we again get a security-proxied subscriber:
-
-  >>> p = ProxyFactory(content)
-  >>> a3 = zope.component.subscribers((p, a1), IS)[0]
-
-  >>> type(a3)
-  <type 'zope.security._proxy._Proxy'>
-
-  >>> removeSecurityProxy(a3).context[0] is content
-  True
-
-However, thanks to the ``locate`` argument, we now have a location
-proxy behind the security proxy:
-
-  >>> type(removeSecurityProxy(a3))
-  <class 'zope.location.location.LocationProxy'>
-
-Event subscriber (handlers)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Sometimes, subscribers don't need to be adapters that actually provide
-anything.  It's enough that a callable is called for a certain event.
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1"
-  ...       handler="zope.component.testfiles.adapter.Handler"
-  ...       />''')
-
-In this case, simply getting the subscribers is enough to invoke them:
-
-  >>> list(zope.component.subscribers((content, a1), None))
-  []
-  >>> content.args == ((a1,),)
-  True
-
-
-utility
--------
-
-Apart from adapters (and subscription adapters), the Component
-Architecture knows a second kind of component: utilities.  They are
-registered using the <utility /> directive.
-
-Before we register the first test utility, we can verify that utility
-lookup doesn't work yet:
-
-  >>> clearZCML()
-  >>> zope.component.queryUtility(IApp) is None
-  True
-
-Then we register the utility:
-
-  >>> runSnippet('''
-  ...   <utility
-  ...       component="zope.component.testfiles.components.comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       />''')
-  >>> zope.component.getUtility(IApp) is comp
-  True
-
-Like adapters, utilities can also have names.  There can be more than
-one utility registered for a certain interface, as long as they each
-have a different name.
-
-First, we make sure that there's no utility yet:
-
-  >>> clearZCML()
-  >>> zope.component.queryUtility(IApp, 'test') is None
-  True
-
-Then we register it:
-
-  >>> runSnippet('''
-  ...   <utility
-  ...       component="zope.component.testfiles.components.comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       name="test"
-  ...       />''')
-  >>> zope.component.getUtility(IApp, 'test') is comp
-  True
-
-Utilities can also be registered from a factory.  In this case, the
-ZCML handler calls the factory (without any arguments) and registers
-the returned value as a utility.  Typically, you'd pass a class for
-the factory:
-
-  >>> clearZCML()
-  >>> zope.component.queryUtility(IApp) is None
-  True
-
-  >>> runSnippet('''
-  ...   <utility
-  ...       factory="zope.component.testfiles.components.Comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       />''')
-  >>> zope.component.getUtility(IApp).__class__ is Comp
-  True
-
-Declaring ``provides`` in Python
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Like other directives, <utility /> can also figure out which interface
-a utility provides from the Python declaration:
-
-  >>> clearZCML()
-  >>> zope.component.queryUtility(IApp) is None
-  True
-
-  >>> runSnippet('''
-  ...   <utility component="zope.component.testfiles.components.comp" />''')
-  >>> zope.component.getUtility(IApp) is comp
-  True
-
-It won't work if the component that is to be registered doesn't
-provide anything:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <utility component="zope.component.testfiles.adapter.a4" />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-4.61
-      TypeError: Missing 'provides' attribute
-
-Or if more than one interface is provided (then the ZCML directive
-handler doesn't know under which the utility should be registered):
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <utility component="zope.component.testfiles.adapter.a5" />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-4.61
-      TypeError: Missing 'provides' attribute
-
-We can repeat the same drill for utility factories:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <utility factory="zope.component.testfiles.components.Comp" />''')
-  >>> zope.component.getUtility(IApp).__class__ is Comp
-  True
-
-  >>> runSnippet('''
-  ...   <utility factory="zope.component.testfiles.adapter.A4" />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-4.59
-      TypeError: Missing 'provides' attribute
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <utility factory="zope.component.testfiles.adapter.A5" />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-4.59
-      TypeError: Missing 'provides' attribute
-
-Protected utilities
-~~~~~~~~~~~~~~~~~~~
-
-TODO::
-
-    def testProtectedUtility(self):
-        """Test that we can protect a utility.
-
-        Also:
-        Check that multiple configurations for the same utility and
-        don't interfere.
-        """
-        self.assertEqual(zope.component.queryUtility(IV), None)
-        xmlconfig(StringIO(template % (
-            '''
-            <permission id="tell.everyone" title="Yay" />
-            <utility
-              component="zope.component.testfiles.components.comp"
-              provides="zope.component.testfiles.components.IApp"
-              permission="tell.everyone"
-              />
-            <permission id="top.secret" title="shhhh" />
-            <utility
-              component="zope.component.testfiles.components.comp"
-              provides="zope.component.testfiles.components.IAppb"
-              permission="top.secret"
-              />
-            '''
-            )))
-
-        utility = ProxyFactory(zope.component.getUtility(IApp))
-        items = getTestProxyItems(utility)
-        self.assertEqual(items, [('a', 'tell.everyone'),
-                                 ('f', 'tell.everyone')
-                                 ])
-        self.assertEqual(removeSecurityProxy(utility), comp)
-
-    def testUtilityUndefinedPermission(self):
-        config = StringIO(template % (
-             '''
-             <utility
-              component="zope.component.testfiles.components.comp"
-              provides="zope.component.testfiles.components.IApp"
-              permission="zope.UndefinedPermission"
-              />
-            '''
-            ))
-        self.assertRaises(ValueError, xmlconfig, config,
-                          testing=1)
-
-interface
----------
-
-The <interface /> directive lets us register an interface.  Interfaces
-are registered as named utilities.  We therefore needn't go though all
-the lookup details again, it is sufficient to see whether the
-directive handler emits the right actions.
-
-First we provide a stub configuration context:
-
-  >>> import re, pprint
-  >>> atre = re.compile(' at [0-9a-fA-Fx]+')
-  >>> class Context(object):
-  ...    actions = ()
-  ...    def action(self, discriminator, callable, args):
-  ...        self.actions += ((discriminator, callable, args), )
-  ...    def __repr__(self):
-  ...        stream = StringIO()
-  ...        pprinter = pprint.PrettyPrinter(stream=stream, width=60)
-  ...        pprinter.pprint(self.actions)
-  ...        r = stream.getvalue()
-  ...        return (''.join(atre.split(r))).strip()
-  >>> context = Context()
-
-Then we provide a test interface that we'd like to register:
-
-  >>> from zope.interface import Interface
-  >>> class I(Interface):
-  ...     pass
-
-It doesn't yet provide ``ITestType``:
-
-  >>> from zope.component.tests import ITestType
-  >>> ITestType.providedBy(I)
-  False
-
-However, after calling the directive handler...
-
-  >>> from zope.component.zcml import interface
-  >>> interface(context, I, ITestType)
-  >>> context
-  ((None,
-    <function provideInterface>,
-    ('',
-     <InterfaceClass __builtin__.I>,
-     <InterfaceClass zope.component.tests.ITestType>)),)
-
-...it does provide ``ITestType``:
-
-  >>> from zope.interface.interfaces import IInterface
-  >>> ITestType.extends(IInterface)
-  True
-  >>> IInterface.providedBy(I)
-  True

Deleted: zope.component/trunk/src/zope/component/zcml_conditional.txt
===================================================================
--- zope.component/trunk/src/zope/component/zcml_conditional.txt	2012-06-29 14:47:49 UTC (rev 127191)
+++ zope.component/trunk/src/zope/component/zcml_conditional.txt	2012-06-29 14:47:56 UTC (rev 127192)
@@ -1,612 +0,0 @@
-ZCML directives without zope.security support
-=============================================
-
-This tests run without zope.security available:
-
-  >>> from zope.component.zcml import check_security_support
-  >>> check_security_support()
-  Traceback (most recent call last):
-  ...
-  ConfigurationError: security proxied components are not supported because zope.security is not available
-
-Components may be registered using the registration API exposed by
-``zope.component`` (provideAdapter, provideUtility, etc.).  They may
-also be registered using configuration files.  The common way to do
-that is by using ZCML (Zope Configuration Markup Language), an XML
-spelling of component registration.
-
-In ZCML, each XML element is a *directive*.  There are different
-top-level directives that let us register components.  We will
-introduce them one by one here.
-
-This helper will let us easily execute ZCML snippets:
-
-  >>> from cStringIO import StringIO
-  >>> from zope.configuration.xmlconfig import xmlconfig
-  >>> def runSnippet(snippet):
-  ...     template = """\
-  ...     <configure xmlns='http://namespaces.zope.org/zope'
-  ...                i18n_domain="zope">
-  ...     %s
-  ...     </configure>"""
-  ...     xmlconfig(StringIO(template % snippet))
-
-adapter
--------
-
-Adapters play a key role in the Component Architecture.  In ZCML, they
-are registered with the <adapter /> directive.
-
-  >>> from zope.component.testfiles.adapter import A1, A2, A3, Handler
-  >>> from zope.component.testfiles.adapter import I1, I2, I3, IS
-  >>> from zope.component.testfiles.components import IContent, Content, Comp, comp
-
-Before we register the first test adapter, we can verify that adapter
-lookup doesn't work yet:
-
-  >>> from zope.component.tests import clearZCML
-  >>> clearZCML()
-  >>> from zope.component.testfiles.components import IApp
-  >>> IApp(Content(), None) is None
-  True
-
-Then we register the adapter and see that the lookup works:
-
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.components.Comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       />''')
-
-  >>> IApp(Content()).__class__
-  <class 'zope.component.testfiles.components.Comp'>
-
-It is also possible to give adapters names.  Then the combination of
-required interface, provided interface and name makes the adapter
-lookup unique.  The name is supplied using the ``name`` argument to
-the <adapter /> directive:
-
-  >>> from zope.component.tests import clearZCML
-  >>> clearZCML()
-  >>> import zope.component
-  >>> zope.component.queryAdapter(Content(), IApp, 'test') is None
-  True
-
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.components.Comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       name="test"
-  ...       />''')
-
-  >>> zope.component.getAdapter(Content(), IApp, 'test').__class__
-  <class 'zope.component.testfiles.components.Comp'>
-
-Adapter factories
-~~~~~~~~~~~~~~~~~
-
-It is possible to supply more than one adapter factory.  In this case,
-during adapter lookup each factory will be called and the return value
-will be given to the next factory.  The return value of the last
-factory is returned as the result of the adapter lookup.  For examle:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.adapter.A1
-  ...                zope.component.testfiles.adapter.A2
-  ...                zope.component.testfiles.adapter.A3"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       />''')
-
-The resulting adapter is an A3, around an A2, around an A1, around the
-adapted object:
-
-  >>> content = Content()
-  >>> a3 = IApp(content)
-  >>> a3.__class__ is A3
-  True
-
-  >>> a2 = a3.context[0]
-  >>> a2.__class__ is A2
-  True
-
-  >>> a1 = a2.context[0]
-  >>> a1.__class__ is A1
-  True
-
-  >>> a1.context[0] is content
-  True
-
-Of course, if no factory is provided at all, we will get an error:
-
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory=""
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-8.8
-      ValueError: No factory specified
-
-Declaring ``for`` and ``provides`` in Python
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The <adapter /> directive can figure out from the in-line Python
-declaration (using ``zope.component.adapts()`` or
-``zope.component.adapter()`` as well as ``zope.interface.implements``)
-what the adapter should be registered for and what it provides::
-
-  >>> clearZCML()
-  >>> IApp(Content(), None) is None
-  True
-
-  >>> runSnippet('''
-  ...   <adapter factory="zope.component.testfiles.components.Comp" />''')
-
-  >>> IApp(Content()).__class__
-  <class 'zope.component.testfiles.components.Comp'>
-
-Of course, if the adapter has no ``implements()`` declaration, ZCML
-can't figure out what it provides:
-
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.adapter.A4"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-7.8
-      TypeError: Missing 'provides' attribute
-
-On the other hand, if the factory implements more than one interface,
-ZCML can't figure out what it should provide either:
-
-  >>> runSnippet('''
-  ...   <adapter
-  ...       factory="zope.component.testfiles.adapter.A5"
-  ...       for="zope.component.testfiles.components.IContent"
-  ...       />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-7.8
-      TypeError: Missing 'provides' attribute
-
-A not so common edge case is registering adapters directly for
-classes, not for interfaces.  For example:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for="zope.component.testfiles.components.Content"
-  ...       provides="zope.component.testfiles.adapter.I1"
-  ...       factory="zope.component.testfiles.adapter.A1"
-  ...       />''')
-
-  >>> content = Content()
-  >>> a1 = zope.component.getAdapter(content, I1, '')
-  >>> isinstance(a1, A1)
-  True
-
-This time, any object providing ``IContent`` won't work if it's not an
-instance of the ``Content`` class:
-
-  >>> import zope.interface
-  >>> class MyContent:
-  ...     zope.interface.implements(IContent)
-  >>> zope.component.getAdapter(MyContent(), I1, '')  # doctest: +ELLIPSIS
-  Traceback (most recent call last):
-    ...
-  ComponentLookupError: ...
-
-Multi-adapters
-~~~~~~~~~~~~~~
-
-Conventional adapters adapt one object to provide another interface.
-Multi-adapters adapt several objects at once:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1
-  ...            zope.component.testfiles.adapter.I2"
-  ...       provides="zope.component.testfiles.adapter.I3"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       />''')
-
-  >>> content = Content()
-  >>> a1 = A1()
-  >>> a2 = A2()
-  >>> a3 = zope.component.queryMultiAdapter((content, a1, a2), I3)
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == (content, a1, a2)
-  True
-
-You can even adapt an empty list of objects (we call this a
-null-adapter):
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for=""
-  ...       provides="zope.component.testfiles.adapter.I3"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       />''')
-
-  >>> a3 = zope.component.queryMultiAdapter((), I3)
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == ()
-  True
-
-Even with multi-adapters, ZCML can figure out the ``for`` and
-``provides`` parameters from the Python declarations:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter factory="zope.component.testfiles.adapter.A3" />''')
-
-  >>> a3 = zope.component.queryMultiAdapter((content, a1, a2), I3)
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == (content, a1, a2)
-  True
-
-Chained factories are not supported for multi-adapters, though:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1
-  ...            zope.component.testfiles.adapter.I2"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       factory="zope.component.testfiles.adapter.A1
-  ...                zope.component.testfiles.adapter.A2"
-  ...       />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-11.8
-      ValueError: Can't use multiple factories and multiple for
-
-And neither for null-adapters:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <adapter
-  ...       for=""
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       factory="zope.component.testfiles.adapter.A1
-  ...                zope.component.testfiles.adapter.A2"
-  ...       />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-9.8
-      ValueError: Can't use multiple factories and multiple for
-
-subscriber
-----------
-
-With the <subscriber /> directive you can register subscription
-adapters or event subscribers with the adapter registry.  Consider
-this very typical example of a <subscriber /> directive:
- 
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       provides="zope.component.testfiles.adapter.IS"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1"
-  ...       />''')
-
-  >>> content = Content()
-  >>> a1 = A1()
-
-  >>> subscribers = zope.component.subscribers((content, a1), IS)
-  >>> a3 = subscribers[0]
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == (content, a1)
-  True
-
-Note how ZCML provides some additional information when registering
-components, such as the ZCML filename and line numbers:
-
-  >>> sm = zope.component.getSiteManager()
-  >>> doc = [reg.info for reg in sm.registeredSubscriptionAdapters()
-  ...        if reg.provided is IS][0]
-  >>> print doc
-  File "<string>", line 4.2-9.8
-    Could not read source.
-
-The "fun" behind subscription adapters/subscribers is that when
-several ones are declared for the same for/provides, they are all
-found.  With regular adapters, the most specific one (and in doubt the
-one registered last) wins.  Consider these two subscribers:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       provides="zope.component.testfiles.adapter.IS"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1"
-  ...       />
-  ...   <subscriber
-  ...       provides="zope.component.testfiles.adapter.IS"
-  ...       factory="zope.component.testfiles.adapter.A2"
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1"
-  ...       />''')
-
-  >>> subscribers = zope.component.subscribers((content, a1), IS)
-  >>> len(subscribers)
-  2
-  >>> sorted([a.__class__.__name__ for a in subscribers])
-  ['A2', 'A3']
-
-Declaring ``for`` and ``provides`` in Python
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Like the <adapter /> directive, the <subscriber /> directive can
-figure out from the in-line Python declaration (using
-``zope.component.adapts()`` or ``zope.component.adapter()``) what the
-subscriber should be registered for:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       provides="zope.component.testfiles.adapter.IS"
-  ...       factory="zope.component.testfiles.adapter.A3"
-  ...       />''')
-
-  >>> content = Content()
-  >>> a2 = A2()
-  >>> subscribers = zope.component.subscribers((content, a1, a2), IS)
-
-  >>> a3 = subscribers[0]
-  >>> a3.__class__ is A3
-  True
-  >>> a3.context == (content, a1, a2)
-  True
-
-In the same way the directive can figure out what a subscriber
-provides:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber handler="zope.component.testfiles.adapter.A3" />''')
-
-  >>> sm = zope.component.getSiteManager()
-  >>> a3 = sm.adapters.subscriptions((IContent, I1, I2), None)[0]
-  >>> a3 is A3
-  True
-
-A not so common edge case is declaring subscribers directly for
-classes, not for interfaces.  For example:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       for="zope.component.testfiles.components.Content"
-  ...       provides="zope.component.testfiles.adapter.I1"
-  ...       factory="zope.component.testfiles.adapter.A1"
-  ...       />''')
-
-  >>> subs = list(zope.component.subscribers((Content(),), I1))
-  >>> isinstance(subs[0], A1)
-  True
-
-This time, any object providing ``IContent`` won't work if it's not an
-instance of the ``Content`` class:
-
-  >>> list(zope.component.subscribers((MyContent(),), I1))
-  []
-
-Event subscriber (handlers)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Sometimes, subscribers don't need to be adapters that actually provide
-anything.  It's enough that a callable is called for a certain event.
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <subscriber
-  ...       for="zope.component.testfiles.components.IContent
-  ...            zope.component.testfiles.adapter.I1"
-  ...       handler="zope.component.testfiles.adapter.Handler"
-  ...       />''')
-
-In this case, simply getting the subscribers is enough to invoke them:
-
-  >>> list(zope.component.subscribers((content, a1), None))
-  []
-  >>> content.args == ((a1,),)
-  True
-
-
-utility
--------
-
-Apart from adapters (and subscription adapters), the Component
-Architecture knows a second kind of component: utilities.  They are
-registered using the <utility /> directive.
-
-Before we register the first test utility, we can verify that utility
-lookup doesn't work yet:
-
-  >>> clearZCML()
-  >>> zope.component.queryUtility(IApp) is None
-  True
-
-Then we register the utility:
-
-  >>> runSnippet('''
-  ...   <utility
-  ...       component="zope.component.testfiles.components.comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       />''')
-  >>> zope.component.getUtility(IApp) is comp
-  True
-
-Like adapters, utilities can also have names.  There can be more than
-one utility registered for a certain interface, as long as they each
-have a different name.
-
-First, we make sure that there's no utility yet:
-
-  >>> clearZCML()
-  >>> zope.component.queryUtility(IApp, 'test') is None
-  True
-
-Then we register it:
-
-  >>> runSnippet('''
-  ...   <utility
-  ...       component="zope.component.testfiles.components.comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       name="test"
-  ...       />''')
-  >>> zope.component.getUtility(IApp, 'test') is comp
-  True
-
-Utilities can also be registered from a factory.  In this case, the
-ZCML handler calls the factory (without any arguments) and registers
-the returned value as a utility.  Typically, you'd pass a class for
-the factory:
-
-  >>> clearZCML()
-  >>> zope.component.queryUtility(IApp) is None
-  True
-
-  >>> runSnippet('''
-  ...   <utility
-  ...       factory="zope.component.testfiles.components.Comp"
-  ...       provides="zope.component.testfiles.components.IApp"
-  ...       />''')
-  >>> zope.component.getUtility(IApp).__class__ is Comp
-  True
-
-Declaring ``provides`` in Python
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Like other directives, <utility /> can also figure out which interface
-a utility provides from the Python declaration:
-
-  >>> clearZCML()
-  >>> zope.component.queryUtility(IApp) is None
-  True
-
-  >>> runSnippet('''
-  ...   <utility component="zope.component.testfiles.components.comp" />''')
-  >>> zope.component.getUtility(IApp) is comp
-  True
-
-It won't work if the component that is to be registered doesn't
-provide anything:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <utility component="zope.component.testfiles.adapter.a4" />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-4.61
-      TypeError: Missing 'provides' attribute
-
-Or if more than one interface is provided (then the ZCML directive
-handler doesn't know under which the utility should be registered):
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <utility component="zope.component.testfiles.adapter.a5" />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-4.61
-      TypeError: Missing 'provides' attribute
-
-We can repeat the same drill for utility factories:
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <utility factory="zope.component.testfiles.components.Comp" />''')
-  >>> zope.component.getUtility(IApp).__class__ is Comp
-  True
-
-  >>> runSnippet('''
-  ...   <utility factory="zope.component.testfiles.adapter.A4" />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-4.59
-      TypeError: Missing 'provides' attribute
-
-  >>> clearZCML()
-  >>> runSnippet('''
-  ...   <utility factory="zope.component.testfiles.adapter.A5" />''')
-  Traceback (most recent call last):
-    ...
-  ZopeXMLConfigurationError: File "<string>", line 4.2-4.59
-      TypeError: Missing 'provides' attribute
-
-interface
----------
-
-The <interface /> directive lets us register an interface.  Interfaces
-are registered as named utilities.  We therefore needn't go though all
-the lookup details again, it is sufficient to see whether the
-directive handler emits the right actions.
-
-First we provide a stub configuration context:
-
-  >>> import re, pprint
-  >>> atre = re.compile(' at [0-9a-fA-Fx]+')
-  >>> class Context(object):
-  ...    actions = ()
-  ...    def action(self, discriminator, callable, args):
-  ...        self.actions += ((discriminator, callable, args), )
-  ...    def __repr__(self):
-  ...        stream = StringIO()
-  ...        pprinter = pprint.PrettyPrinter(stream=stream, width=60)
-  ...        pprinter.pprint(self.actions)
-  ...        r = stream.getvalue()
-  ...        return (''.join(atre.split(r))).strip()
-  >>> context = Context()
-
-Then we provide a test interface that we'd like to register:
-
-  >>> from zope.interface import Interface
-  >>> class I(Interface):
-  ...     pass
-
-It doesn't yet provide ``ITestType``:
-
-  >>> from zope.component.tests import ITestType
-  >>> ITestType.providedBy(I)
-  False
-
-However, after calling the directive handler...
-
-  >>> from zope.component.zcml import interface
-  >>> interface(context, I, ITestType)
-  >>> context
-  ((None,
-    <function provideInterface>,
-    ('',
-     <InterfaceClass __builtin__.I>,
-     <InterfaceClass zope.component.tests.ITestType>)),)
-
-...it does provide ``ITestType``:
-
-  >>> from zope.interface.interfaces import IInterface
-  >>> ITestType.extends(IInterface)
-  True
-  >>> IInterface.providedBy(I)
-  True

Copied: zope.component/trunk/tox.ini (from rev 127144, zope.component/tseaver-test_cleanup/tox.ini)
===================================================================
--- zope.component/trunk/tox.ini	                        (rev 0)
+++ zope.component/trunk/tox.ini	2012-06-29 14:47:56 UTC (rev 127192)
@@ -0,0 +1,128 @@
+[tox]
+envlist = 
+# Jython support pending 2.7 support, due 2012-07-15 or so.  See:
+# http://fwierzbicki.blogspot.com/2012/03/adconion-to-fund-jython-27.html
+#   py26,py27,py32,jython,pypy,coverage,docs
+    py26,py26min,py27,pypy,py32,coverage,docs
+
+[testenv]
+deps =
+    zope.component
+    zope.testing
+    zope.hookable
+    ZODB3
+    zope.location
+    zope.proxy
+    zope.security
+    zope.configuration
+    zope.i18nmessageid
+commands = 
+    python setup.py test -q
+
+[testenv:jython]
+commands = 
+   jython setup.py test -q
+
+[nosy]
+prep =
+    pip uninstall -y zope.component
+    python -c "import shutil; shutil.copyfile('src/zope/__init__.py', '{envdir}/lib/python2.6/site-packages/zope/__init__.py')"
+    pip install -e .
+
+
+[testenv:py26min]
+basepython =
+    python2.6
+deps =
+    zope.component
+    zope.interface
+    zope.event
+    zope.hookable
+    zope.configuration
+    zope.schema
+    zope.i18nmessageid
+    nose
+commands = 
+    pip uninstall -y zope.component
+    python -c "import shutil; shutil.copyfile('src/zope/__init__.py', '{envdir}/lib/python2.6/site-packages/zope/__init__.py')"
+    pip install -e .
+    nosetests -I persistentregistry -I security
+
+
+[testenv:py32]
+deps =
+    zope.component
+    zope.interface
+    zope.event
+    zope.hookable
+    zope.configuration
+    zope.schema
+    zope.i18nmessageid
+    nose
+commands = 
+    pip uninstall -y zope.component
+    python -c "import shutil; shutil.copyfile('src/zope/__init__.py', '{envdir}/lib/python3.2/site-packages/zope/__init__.py')"
+    pip install -e .
+    nosetests -I persistentregistry -I security
+
+[testenv:pypy]
+deps =
+    zope.component
+    zope.interface
+    zope.event
+    zope.hookable
+    zope.configuration
+    zope.schema
+    zope.i18nmessageid
+    nose
+commands = 
+    pip uninstall -y zope.component
+    python -c "import shutil; shutil.copyfile('{toxinidir}/src/zope/__init__.py', '{envdir}/site-packages/zope/__init__.py')"
+    pip install -e .
+    nosetests -I persistentregistry -I security
+
+[testenv:coverage]
+basepython =
+    python2.6
+commands = 
+#   The installed version messes up nose's test discovery / coverage reporting
+#   So, we uninstall that from the environment, and then install the editable
+#   version, before running nosetests.
+    pip uninstall -y zope.component
+    python -c "import shutil; shutil.copyfile('src/zope/__init__.py', '{envdir}/lib/python2.6/site-packages/zope/__init__.py')"
+    pip install -e .
+    nosetests --with-xunit --with-xcoverage
+deps =
+    zope.component
+    zope.testing
+    zope.hookable
+    ZODB3
+    zope.location
+    zope.proxy
+    zope.security
+    zope.configuration
+    zope.i18nmessageid
+    nose
+    coverage
+    nosexcover
+
+[testenv:docs]
+basepython =
+    python2.6
+commands = 
+    sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html
+    sphinx-build -b doctest -d docs/_build/doctrees docs docs/_build/doctest
+deps =
+    zope.component
+    zope.testing
+    zope.hookable
+    ZODB3
+    zope.location
+    zope.proxy
+    zope.security
+    zope.configuration
+    zope.i18nmessageid
+    Sphinx
+    repoze.sphinx.autointerface
+#   Ugh.  Need this for docs/testlayer.rst
+    zope.testrunner



More information about the checkins mailing list