summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Madden <jamadden@gmail.com>2020-03-17 07:06:54 -0500
committerJason Madden <jamadden@gmail.com>2020-03-17 07:06:54 -0500
commit771721fccf4c88c798f850d7830af6448aca2232 (patch)
treef5304070dd1a6dfc21242e7a60590e6fd1ee13a1
parentd0c6a5967af074b1a7d60a1bb20d9337263b9571 (diff)
downloadzope-interface-issue136-issue134.tar.gz
Documentation clarifications.issue136-issue134
- docs/adapter.rst Subscriptions are returned from least to most specific, not the other way around; the docs were incorrect. Add additional examples, and use more verbose names in current examples, to clarify this. Fixes #136. - interfaces.py names() and namesAndDescriptions() just return a collection, not a sequence. Fixes #134.
-rw-r--r--docs/adapter.rst288
-rw-r--r--src/zope/interface/interfaces.py4
2 files changed, 151 insertions, 141 deletions
diff --git a/docs/adapter.rst b/docs/adapter.rst
index 50fcf8c..0e8528b 100644
--- a/docs/adapter.rst
+++ b/docs/adapter.rst
@@ -24,27 +24,27 @@ Let's look at a simple example, using a single required specification:
>>> from zope.interface.adapter import AdapterRegistry
>>> import zope.interface
- >>> class IRequire1(zope.interface.Interface):
+ >>> class IRequireBase(zope.interface.Interface):
... pass
- >>> class IProvide1(zope.interface.Interface):
+ >>> class IProvideBase(zope.interface.Interface):
... pass
- >>> class IProvide2(IProvide1):
+ >>> class IProvideChild(IProvideBase):
... pass
>>> registry = AdapterRegistry()
-We'll register an object that depends on ``IRequire1`` and "provides" ``IProvide2``:
+We'll register an object that depends on ``IRequireBase`` and "provides" ``IProvideChild``:
.. doctest::
- >>> registry.register([IRequire1], IProvide2, '', 12)
+ >>> registry.register([IRequireBase], IProvideChild, '', 'Base->Child')
Given the registration, we can look it up again:
.. doctest::
- >>> registry.lookup([IRequire1], IProvide2, '')
- 12
+ >>> registry.lookup([IRequireBase], IProvideChild, '')
+ 'Base->Child'
Note that we used an integer in the example. In real applications,
one would use some objects that actually depend on or provide
@@ -58,21 +58,21 @@ specification that extends the specification that it depends on:
.. doctest::
- >>> class IRequire2(IRequire1):
+ >>> class IRequireChild(IRequireBase):
... pass
- >>> registry.lookup([IRequire2], IProvide2, '')
- 12
+ >>> registry.lookup([IRequireChild], IProvideChild, '')
+ 'Base->Child'
We can use a class implementation specification to look up the object:
.. doctest::
- >>> @zope.interface.implementer(IRequire2)
+ >>> @zope.interface.implementer(IRequireChild)
... class C2:
... pass
- >>> registry.lookup([zope.interface.implementedBy(C2)], IProvide2, '')
- 12
+ >>> registry.lookup([zope.interface.implementedBy(C2)], IProvideChild, '')
+ 'Base->Child'
and it can be looked up for interfaces that its provided interface
@@ -80,23 +80,23 @@ extends:
.. doctest::
- >>> registry.lookup([IRequire1], IProvide1, '')
- 12
- >>> registry.lookup([IRequire2], IProvide1, '')
- 12
+ >>> registry.lookup([IRequireBase], IProvideBase, '')
+ 'Base->Child'
+ >>> registry.lookup([IRequireChild], IProvideBase, '')
+ 'Base->Child'
But if you require a specification that doesn't extend the specification the
object depends on, you won't get anything:
.. doctest::
- >>> registry.lookup([zope.interface.Interface], IProvide1, '')
+ >>> registry.lookup([zope.interface.Interface], IProvideBase, '')
By the way, you can pass a default value to lookup:
.. doctest::
- >>> registry.lookup([zope.interface.Interface], IProvide1, '', 42)
+ >>> registry.lookup([zope.interface.Interface], IProvideBase, '', 42)
42
If you try to get an interface the object doesn't provide, you also
@@ -104,47 +104,47 @@ won't get anything:
.. doctest::
- >>> class IProvide3(IProvide2):
+ >>> class IProvideGrandchild(IProvideChild):
... pass
- >>> registry.lookup([IRequire1], IProvide3, '')
+ >>> registry.lookup([IRequireBase], IProvideGrandchild, '')
You also won't get anything if you use the wrong name:
.. doctest::
- >>> registry.lookup([IRequire1], IProvide1, 'bob')
- >>> registry.register([IRequire1], IProvide2, 'bob', "Bob's 12")
- >>> registry.lookup([IRequire1], IProvide1, 'bob')
+ >>> registry.lookup([IRequireBase], IProvideBase, 'bob')
+ >>> registry.register([IRequireBase], IProvideChild, 'bob', "Bob's 12")
+ >>> registry.lookup([IRequireBase], IProvideBase, 'bob')
"Bob's 12"
You can leave the name off when doing a lookup:
.. doctest::
- >>> registry.lookup([IRequire1], IProvide1)
- 12
+ >>> registry.lookup([IRequireBase], IProvideBase)
+ 'Base->Child'
-If we register an object that provides ``IProvide1``:
+If we register an object that provides ``IProvideBase``:
.. doctest::
- >>> registry.register([IRequire1], IProvide1, '', 11)
+ >>> registry.register([IRequireBase], IProvideBase, '', 'Base->Base')
-then that object will be prefered over ``O(12)``:
+then that object will be prefered over ``O('Base->Child')``:
.. doctest::
- >>> registry.lookup([IRequire1], IProvide1, '')
- 11
+ >>> registry.lookup([IRequireBase], IProvideBase, '')
+ 'Base->Base'
-Also, if we register an object for ``IRequire2``, then that will be preferred
-when using ``IRequire2``:
+Also, if we register an object for ``IRequireChild``, then that will be preferred
+when using ``IRequireChild``:
.. doctest::
- >>> registry.register([IRequire2], IProvide1, '', 21)
- >>> registry.lookup([IRequire2], IProvide1, '')
- 21
+ >>> registry.register([IRequireChild], IProvideBase, '', 'Child->Base')
+ >>> registry.lookup([IRequireChild], IProvideBase, '')
+ 'Child->Base'
Finding out what, if anything, is registered
--------------------------------------------
@@ -155,20 +155,20 @@ exact match:
.. doctest::
- >>> print(registry.registered([IRequire1], IProvide1))
- 11
+ >>> print(registry.registered([IRequireBase], IProvideBase))
+ Base->Base
- >>> print(registry.registered([IRequire1], IProvide2))
- 12
+ >>> print(registry.registered([IRequireBase], IProvideChild))
+ Base->Child
- >>> print(registry.registered([IRequire1], IProvide2, 'bob'))
+ >>> print(registry.registered([IRequireBase], IProvideChild, 'bob'))
Bob's 12
- >>> print(registry.registered([IRequire2], IProvide1))
- 21
+ >>> print(registry.registered([IRequireChild], IProvideBase))
+ Child->Base
- >>> print(registry.registered([IRequire2], IProvide2))
+ >>> print(registry.registered([IRequireChild], IProvideChild))
None
In the last example, ``None`` was returned because nothing was registered
@@ -182,10 +182,10 @@ version of lookup that takes a single required interface:
.. doctest::
- >>> registry.lookup1(IRequire2, IProvide1, '')
- 21
- >>> registry.lookup1(IRequire2, IProvide1)
- 21
+ >>> registry.lookup1(IRequireChild, IProvideBase, '')
+ 'Child->Base'
+ >>> registry.lookup1(IRequireChild, IProvideBase)
+ 'Child->Base'
Actual Adaptation
-----------------
@@ -205,12 +205,12 @@ factories:
... class X(object):
... pass
- >>> @zope.interface.implementer(IProvide1)
+ >>> @zope.interface.implementer(IProvideBase)
... class Y(object):
... def __init__(self, context):
... self.context = context
- >>> registry.register([IR], IProvide1, '', Y)
+ >>> registry.register([IR], IProvideBase, '', Y)
In this case, we registered a class as the factory. Now we can call
``queryAdapter`` to get the adapted object:
@@ -218,7 +218,7 @@ In this case, we registered a class as the factory. Now we can call
.. doctest::
>>> x = X()
- >>> y = registry.queryAdapter(x, IProvide1)
+ >>> y = registry.queryAdapter(x, IProvideBase)
>>> y.__class__.__name__
'Y'
>>> y.context is x
@@ -231,8 +231,8 @@ We can register and lookup by name too:
>>> class Y2(Y):
... pass
- >>> registry.register([IR], IProvide1, 'bob', Y2)
- >>> y = registry.queryAdapter(x, IProvide1, 'bob')
+ >>> registry.register([IR], IProvideBase, 'bob', Y2)
+ >>> y = registry.queryAdapter(x, IProvideBase, 'bob')
>>> y.__class__.__name__
'Y2'
>>> y.context is x
@@ -251,10 +251,10 @@ Passing ``super`` objects works as expected to find less specific adapters:
... def query_next(self):
... return registry.queryAdapter(
... super(type(self.context), self.context),
- ... IProvide1)
- >>> registry.register([IDerived], IProvide1, '', DerivedAdapter)
+ ... IProvideBase)
+ >>> registry.register([IDerived], IProvideBase, '', DerivedAdapter)
>>> derived = Derived()
- >>> adapter = registry.queryAdapter(derived, IProvide1)
+ >>> adapter = registry.queryAdapter(derived, IProvideBase)
>>> adapter.__class__.__name__
'DerivedAdapter'
>>> adapter = adapter.query_next()
@@ -277,14 +277,14 @@ the state of the object being adapted:
... class Object(object):
... name = 'object'
- >>> registry.register([IR], IProvide1, 'conditional', factory)
+ >>> registry.register([IR], IProvideBase, 'conditional', factory)
>>> obj = Object()
- >>> registry.queryAdapter(obj, IProvide1, 'conditional')
+ >>> registry.queryAdapter(obj, IProvideBase, 'conditional')
'adapter'
>>> obj.name = 'no object'
- >>> registry.queryAdapter(obj, IProvide1, 'conditional') is None
+ >>> registry.queryAdapter(obj, IProvideBase, 'conditional') is None
True
- >>> registry.queryAdapter(obj, IProvide1, 'conditional', 'default')
+ >>> registry.queryAdapter(obj, IProvideBase, 'conditional', 'default')
'default'
An alternate method that provides the same function as ``queryAdapter()`` is
@@ -292,12 +292,12 @@ An alternate method that provides the same function as ``queryAdapter()`` is
.. doctest::
- >>> y = registry.adapter_hook(IProvide1, x)
+ >>> y = registry.adapter_hook(IProvideBase, x)
>>> y.__class__.__name__
'Y'
>>> y.context is x
True
- >>> y = registry.adapter_hook(IProvide1, x, 'bob')
+ >>> y = registry.adapter_hook(IProvideBase, x, 'bob')
>>> y.__class__.__name__
'Y2'
>>> y.context is x
@@ -316,7 +316,7 @@ For that, provide ``None`` as the required interface:
.. doctest::
- >>> registry.register([None], IProvide1, '', 1)
+ >>> registry.register([None], IProvideBase, '', 1)
then we can use that adapter for interfaces we don't have specific
adapters for:
@@ -325,15 +325,15 @@ adapters for:
>>> class IQ(zope.interface.Interface):
... pass
- >>> registry.lookup([IQ], IProvide1, '')
+ >>> registry.lookup([IQ], IProvideBase, '')
1
Of course, specific adapters are still used when applicable:
.. doctest::
- >>> registry.lookup([IRequire2], IProvide1, '')
- 21
+ >>> registry.lookup([IRequireChild], IProvideBase, '')
+ 'Child->Base'
Class adapters
@@ -344,8 +344,8 @@ same as registering them for a class:
.. doctest::
- >>> registry.register([zope.interface.implementedBy(C2)], IProvide1, '', 'C21')
- >>> registry.lookup([zope.interface.implementedBy(C2)], IProvide1, '')
+ >>> registry.register([zope.interface.implementedBy(C2)], IProvideBase, '', 'C21')
+ >>> registry.lookup([zope.interface.implementedBy(C2)], IProvideBase, '')
'C21'
Dict adapters
@@ -368,9 +368,9 @@ You can unregister by registering ``None``, rather than an object:
.. doctest::
- >>> registry.register([zope.interface.implementedBy(C2)], IProvide1, '', None)
- >>> registry.lookup([zope.interface.implementedBy(C2)], IProvide1, '')
- 21
+ >>> registry.register([zope.interface.implementedBy(C2)], IProvideBase, '', None)
+ >>> registry.lookup([zope.interface.implementedBy(C2)], IProvideBase, '')
+ 'Child->Base'
Of course, this means that ``None`` can't be registered. This is an
exception to the statement, made earlier, that the registry doesn't
@@ -383,25 +383,25 @@ You can adapt multiple specifications:
.. doctest::
- >>> registry.register([IRequire1, IQ], IProvide2, '', '1q2')
- >>> registry.lookup([IRequire1, IQ], IProvide2, '')
+ >>> registry.register([IRequireBase, IQ], IProvideChild, '', '1q2')
+ >>> registry.lookup([IRequireBase, IQ], IProvideChild, '')
'1q2'
- >>> registry.lookup([IRequire2, IQ], IProvide1, '')
+ >>> registry.lookup([IRequireChild, IQ], IProvideBase, '')
'1q2'
>>> class IS(zope.interface.Interface):
... pass
- >>> registry.lookup([IRequire2, IS], IProvide1, '')
+ >>> registry.lookup([IRequireChild, IS], IProvideBase, '')
>>> class IQ2(IQ):
... pass
- >>> registry.lookup([IRequire2, IQ2], IProvide1, '')
+ >>> registry.lookup([IRequireChild, IQ2], IProvideBase, '')
'1q2'
- >>> registry.register([IRequire1, IQ2], IProvide2, '', '1q22')
- >>> registry.lookup([IRequire2, IQ2], IProvide1, '')
- '1q22'
+ >>> registry.register([IRequireBase, IQ2], IProvideChild, '', '(Base,Q2)->Child')
+ >>> registry.lookup([IRequireChild, IQ2], IProvideBase, '')
+ '(Base,Q2)->Child'
Multi-adaptation
----------------
@@ -458,9 +458,9 @@ As with single adapters, you can define default adapters by specifying
.. doctest::
- >>> registry.register([None, IQ], IProvide2, '', 'q2')
- >>> registry.lookup([IS, IQ], IProvide2, '')
- 'q2'
+ >>> registry.register([None, IQ], IProvideChild, '', '(None,Q)->Child')
+ >>> registry.lookup([IS, IQ], IProvideChild, '')
+ '(None,Q)->Child'
Null Adapters
=============
@@ -469,11 +469,11 @@ You can also adapt **no** specification:
.. doctest::
- >>> registry.register([], IProvide2, '', 2)
- >>> registry.lookup([], IProvide2, '')
- 2
- >>> registry.lookup([], IProvide1, '')
- 2
+ >>> registry.register([], IProvideChild, '', '[]->Child')
+ >>> registry.lookup([], IProvideChild, '')
+ '[]->Child'
+ >>> registry.lookup([], IProvideBase, '')
+ '[]->Child'
Listing named adapters
----------------------
@@ -483,27 +483,27 @@ adapters for given interfaces:
.. doctest::
- >>> adapters = list(registry.lookupAll([IRequire1], IProvide1))
+ >>> adapters = list(registry.lookupAll([IRequireBase], IProvideBase))
>>> adapters.sort()
- >>> assert adapters == [(u'', 11), (u'bob', "Bob's 12")]
+ >>> assert adapters == [(u'', 'Base->Base'), (u'bob', "Bob's 12")]
This works for multi-adapters too:
.. doctest::
- >>> registry.register([IRequire1, IQ2], IProvide2, 'bob', '1q2 for bob')
- >>> adapters = list(registry.lookupAll([IRequire2, IQ2], IProvide1))
+ >>> registry.register([IRequireBase, IQ2], IProvideChild, 'bob', '(Base,Q2)->Child for bob')
+ >>> adapters = list(registry.lookupAll([IRequireChild, IQ2], IProvideBase))
>>> adapters.sort()
- >>> assert adapters == [(u'', '1q22'), (u'bob', '1q2 for bob')]
+ >>> assert adapters == [(u'', '(Base,Q2)->Child'), (u'bob', '(Base,Q2)->Child for bob')]
And even null adapters:
.. doctest::
- >>> registry.register([], IProvide2, 'bob', 3)
- >>> adapters = list(registry.lookupAll([], IProvide1))
+ >>> registry.register([], IProvideChild, 'bob', 3)
+ >>> adapters = list(registry.lookupAll([], IProvideBase))
>>> adapters.sort()
- >>> assert adapters == [(u'', 2), (u'bob', 3)]
+ >>> assert adapters == [(u'', '[]->Child'), (u'bob', 3)]
Subscriptions
=============
@@ -516,9 +516,9 @@ the subscribed objects:
.. doctest::
- >>> registry.subscribe([IRequire1], IProvide2, 'sub12 1')
- >>> registry.subscriptions([IRequire1], IProvide2)
- ['sub12 1']
+ >>> registry.subscribe([IRequireBase], IProvideChild, 'Base->Child (1)')
+ >>> registry.subscriptions([IRequireBase], IProvideChild)
+ ['Base->Child (1)']
Note that, unlike regular adapters, subscriptions are unnamed.
@@ -526,9 +526,9 @@ You can have multiple subscribers for the same specification:
.. doctest::
- >>> registry.subscribe([IRequire1], IProvide2, 'sub12 2')
- >>> registry.subscriptions([IRequire1], IProvide2)
- ['sub12 1', 'sub12 2']
+ >>> registry.subscribe([IRequireBase], IProvideChild, 'Base->Child (2)')
+ >>> registry.subscriptions([IRequireBase], IProvideChild)
+ ['Base->Child (1)', 'Base->Child (2)']
If subscribers are registered for the same required interfaces, they
are returned in the order of definition.
@@ -537,62 +537,72 @@ You can register subscribers for all specifications using ``None``:
.. doctest::
- >>> registry.subscribe([None], IProvide1, 'sub_1')
- >>> registry.subscriptions([IRequire2], IProvide1)
- ['sub_1', 'sub12 1', 'sub12 2']
+ >>> registry.subscribe([None], IProvideBase, 'None->Base')
+ >>> registry.subscriptions([IRequireChild], IProvideBase)
+ ['None->Base', 'Base->Child (1)', 'Base->Child (2)']
+
+Note that the new subscriber is returned first.
+
+Subscribers defined for less specific required interfaces are returned
+before subscribers for more specific interfaces:
-Note that the new subscriber is returned first. Subscribers defined
-for less general required interfaces are returned before subscribers
-for more general interfaces.
+.. doctest::
+
+ >>> class IRequireGrandchild(IRequireChild):
+ ... pass
+ >>> registry.subscribe([IRequireChild], IProvideBase, 'Child->Base')
+ >>> registry.subscribe([IRequireGrandchild], IProvideBase, 'Grandchild->Base')
+ >>> registry.subscriptions([IRequireGrandchild], IProvideBase)
+ ['None->Base', 'Base->Child (1)', 'Base->Child (2)', 'Child->Base', 'Grandchild->Base']
Subscriptions may be combined over multiple compatible specifications:
.. doctest::
- >>> registry.subscriptions([IRequire2], IProvide1)
- ['sub_1', 'sub12 1', 'sub12 2']
- >>> registry.subscribe([IRequire1], IProvide1, 'sub11')
- >>> registry.subscriptions([IRequire2], IProvide1)
- ['sub_1', 'sub12 1', 'sub12 2', 'sub11']
- >>> registry.subscribe([IRequire2], IProvide2, 'sub22')
- >>> registry.subscriptions([IRequire2], IProvide1)
- ['sub_1', 'sub12 1', 'sub12 2', 'sub11', 'sub22']
- >>> registry.subscriptions([IRequire2], IProvide2)
- ['sub12 1', 'sub12 2', 'sub22']
+ >>> registry.subscriptions([IRequireChild], IProvideBase)
+ ['None->Base', 'Base->Child (1)', 'Base->Child (2)', 'Child->Base']
+ >>> registry.subscribe([IRequireBase], IProvideBase, 'Base->Base')
+ >>> registry.subscriptions([IRequireChild], IProvideBase)
+ ['None->Base', 'Base->Child (1)', 'Base->Child (2)', 'Base->Base', 'Child->Base']
+ >>> registry.subscribe([IRequireChild], IProvideChild, 'Child->Child')
+ >>> registry.subscriptions([IRequireChild], IProvideBase)
+ ['None->Base', 'Base->Child (1)', 'Base->Child (2)', 'Base->Base', 'Child->Child', 'Child->Base']
+ >>> registry.subscriptions([IRequireChild], IProvideChild)
+ ['Base->Child (1)', 'Base->Child (2)', 'Child->Child']
Subscriptions can be on multiple specifications:
.. doctest::
- >>> registry.subscribe([IRequire1, IQ], IProvide2, 'sub1q2')
- >>> registry.subscriptions([IRequire1, IQ], IProvide2)
- ['sub1q2']
+ >>> registry.subscribe([IRequireBase, IQ], IProvideChild, '(Base,Q)->Child')
+ >>> registry.subscriptions([IRequireBase, IQ], IProvideChild)
+ ['(Base,Q)->Child']
As with single subscriptions and non-subscription adapters, you can
specify ``None`` for the first required interface, to specify a default:
.. doctest::
- >>> registry.subscribe([None, IQ], IProvide2, 'sub_q2')
- >>> registry.subscriptions([IS, IQ], IProvide2)
- ['sub_q2']
- >>> registry.subscriptions([IRequire1, IQ], IProvide2)
- ['sub_q2', 'sub1q2']
+ >>> registry.subscribe([None, IQ], IProvideChild, '(None,Q)->Child')
+ >>> registry.subscriptions([IS, IQ], IProvideChild)
+ ['(None,Q)->Child']
+ >>> registry.subscriptions([IRequireBase, IQ], IProvideChild)
+ ['(None,Q)->Child', '(Base,Q)->Child']
You can have subscriptions that are independent of any specifications:
.. doctest::
- >>> list(registry.subscriptions([], IProvide1))
+ >>> list(registry.subscriptions([], IProvideBase))
[]
- >>> registry.subscribe([], IProvide2, 'sub2')
- >>> registry.subscriptions([], IProvide1)
+ >>> registry.subscribe([], IProvideChild, 'sub2')
+ >>> registry.subscriptions([], IProvideBase)
['sub2']
- >>> registry.subscribe([], IProvide1, 'sub1')
- >>> registry.subscriptions([], IProvide1)
+ >>> registry.subscribe([], IProvideBase, 'sub1')
+ >>> registry.subscriptions([], IProvideBase)
['sub2', 'sub1']
- >>> registry.subscriptions([], IProvide2)
+ >>> registry.subscriptions([], IProvideChild)
['sub2']
Unregistering subscribers
@@ -603,18 +613,18 @@ can unregister a *specific* subscriber:
.. doctest::
- >>> registry.unsubscribe([IRequire1], IProvide1, 'sub11')
- >>> registry.subscriptions([IRequire1], IProvide1)
- ['sub_1', 'sub12 1', 'sub12 2']
+ >>> registry.unsubscribe([IRequireBase], IProvideBase, 'Base->Base')
+ >>> registry.subscriptions([IRequireBase], IProvideBase)
+ ['None->Base', 'Base->Child (1)', 'Base->Child (2)']
If we don't specify a value, then *all* subscribers matching the given
interfaces will be unsubscribed:
.. doctest::
- >>> registry.unsubscribe([IRequire1], IProvide2)
- >>> registry.subscriptions([IRequire1], IProvide1)
- ['sub_1']
+ >>> registry.unsubscribe([IRequireBase], IProvideChild)
+ >>> registry.subscriptions([IRequireBase], IProvideBase)
+ ['None->Base']
Subscription adapters
@@ -665,8 +675,8 @@ To register a handler, simply provide ``None`` as the provided interface:
>>> def handler(event):
... print('handler', event)
- >>> registry.subscribe([IRequire1], None, handler)
- >>> registry.subscriptions([IRequire1], None) == [handler]
+ >>> registry.subscribe([IRequireBase], None, handler)
+ >>> registry.subscriptions([IRequireBase], None) == [handler]
True
diff --git a/src/zope/interface/interfaces.py b/src/zope/interface/interfaces.py
index bf0d6c7..702280b 100644
--- a/src/zope/interface/interfaces.py
+++ b/src/zope/interface/interfaces.py
@@ -269,7 +269,7 @@ class IInterface(ISpecification, IElement):
def names(all=False):
"""Get the interface attribute names
- Return a sequence of the names of the attributes, including
+ Return a collection of the names of the attributes, including
methods, included in the interface definition.
Normally, only directly defined attributes are included. If
@@ -280,7 +280,7 @@ class IInterface(ISpecification, IElement):
def namesAndDescriptions(all=False):
"""Get the interface attribute names and descriptions
- Return a sequence of the names and descriptions of the
+ Return a collection of the names and descriptions of the
attributes, including methods, as name-value pairs, included
in the interface definition.