[Checkins] SVN: zope.component/tseaver-test_cleanup/ Don't document differences when zope.security is absent as excutable snippts.
Tres Seaver
cvs-admin at zope.org
Sun Jun 17 18:31:49 UTC 2012
Log message for revision 126889:
Don't document differences when zope.security is absent as excutable snippts.
Changed:
_U zope.component/tseaver-test_cleanup/
U zope.component/tseaver-test_cleanup/docs/index.rst
D zope.component/tseaver-test_cleanup/docs/zcml_conditional.rst
-=-
Modified: zope.component/tseaver-test_cleanup/docs/index.rst
===================================================================
--- zope.component/tseaver-test_cleanup/docs/index.rst 2012-06-17 17:39:20 UTC (rev 126888)
+++ zope.component/tseaver-test_cleanup/docs/index.rst 2012-06-17 18:31:45 UTC (rev 126889)
@@ -16,7 +16,6 @@
configure
hooks
testlayer
- zcml_conditional
Indices and tables
==================
Deleted: zope.component/tseaver-test_cleanup/docs/zcml_conditional.rst
===================================================================
--- zope.component/tseaver-test_cleanup/docs/zcml_conditional.rst 2012-06-17 17:39:20 UTC (rev 126888)
+++ zope.component/tseaver-test_cleanup/docs/zcml_conditional.rst 2012-06-17 18:31:45 UTC (rev 126889)
@@ -1,611 +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.test_doctests 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:
-
- >>> 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.test_doctests 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.test_doctests.ITestType>)),)
-
-...it does provide ``ITestType``:
-
- >>> from zope.interface.interfaces import IInterface
- >>> ITestType.extends(IInterface)
- True
- >>> IInterface.providedBy(I)
- True
More information about the checkins
mailing list