aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.txt
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.txt')
-rw-r--r--lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.txt829
1 files changed, 0 insertions, 829 deletions
diff --git a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.txt b/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.txt
deleted file mode 100644
index e5bc7b34..00000000
--- a/lib/python2.7/site-packages/zope.interface-3.6.4-py2.7-linux-x86_64.egg/zope/interface/README.txt
+++ /dev/null
@@ -1,829 +0,0 @@
-==========
-Interfaces
-==========
-
-Interfaces are objects that specify (document) the external behavior
-of objects that "provide" them. An interface specifies behavior
-through:
-
-- Informal documentation in a doc string
-
-- Attribute definitions
-
-- Invariants, which are conditions that must hold for objects that
- provide the interface
-
-Attribute definitions specify specific attributes. They define the
-attribute name and provide documentation and constraints of attribute
-values. Attribute definitions can take a number of forms, as we'll
-see below.
-
-Defining interfaces
-===================
-
-Interfaces are defined using Python class statements::
-
- >>> import zope.interface
- >>> class IFoo(zope.interface.Interface):
- ... """Foo blah blah"""
- ...
- ... x = zope.interface.Attribute("""X blah blah""")
- ...
- ... def bar(q, r=None):
- ... """bar blah blah"""
-
-In the example above, we've created an interface, `IFoo`. We
-subclassed `zope.interface.Interface`, which is an ancestor interface for
-all interfaces, much as `object` is an ancestor of all new-style
-classes [#create]_. The interface is not a class, it's an Interface,
-an instance of `InterfaceClass`::
-
- >>> type(IFoo)
- <class 'zope.interface.interface.InterfaceClass'>
-
-We can ask for the interface's documentation::
-
- >>> IFoo.__doc__
- 'Foo blah blah'
-
-and its name::
-
- >>> IFoo.__name__
- 'IFoo'
-
-and even its module::
-
- >>> IFoo.__module__
- '__main__'
-
-The interface defined two attributes:
-
-`x`
- This is the simplest form of attribute definition. It has a name
- and a doc string. It doesn't formally specify anything else.
-
-`bar`
- This is a method. A method is defined via a function definition. A
- method is simply an attribute constrained to be a callable with a
- particular signature, as provided by the function definition.
-
- Note that `bar` doesn't take a `self` argument. Interfaces document
- how an object is *used*. When calling instance methods, you don't
- pass a `self` argument, so a `self` argument isn't included in the
- interface signature. The `self` argument in instance methods is
- really an implementation detail of Python instances. Other objects,
- besides instances can provide interfaces and their methods might not
- be instance methods. For example, modules can provide interfaces and
- their methods are usually just functions. Even instances can have
- methods that are not instance methods.
-
-You can access the attributes defined by an interface using mapping
-syntax::
-
- >>> x = IFoo['x']
- >>> type(x)
- <class 'zope.interface.interface.Attribute'>
- >>> x.__name__
- 'x'
- >>> x.__doc__
- 'X blah blah'
-
- >>> IFoo.get('x').__name__
- 'x'
-
- >>> IFoo.get('y')
-
-You can use `in` to determine if an interface defines a name::
-
- >>> 'x' in IFoo
- True
-
-You can iterate over interfaces to get the names they define::
-
- >>> names = list(IFoo)
- >>> names.sort()
- >>> names
- ['bar', 'x']
-
-Remember that interfaces aren't classes. You can't access attribute
-definitions as attributes of interfaces::
-
- >>> IFoo.x
- Traceback (most recent call last):
- File "<stdin>", line 1, in ?
- AttributeError: 'InterfaceClass' object has no attribute 'x'
-
-Methods provide access to the method signature::
-
- >>> bar = IFoo['bar']
- >>> bar.getSignatureString()
- '(q, r=None)'
-
-TODO
- Methods really should have a better API. This is something that
- needs to be improved.
-
-Declaring interfaces
-====================
-
-Having defined interfaces, we can *declare* that objects provide
-them. Before we describe the details, lets define some terms:
-
-*provide*
- We say that objects *provide* interfaces. If an object provides an
- interface, then the interface specifies the behavior of the
- object. In other words, interfaces specify the behavior of the
- objects that provide them.
-
-*implement*
- We normally say that classes *implement* interfaces. If a class
- implements an interface, then the instances of the class provide
- the interface. Objects provide interfaces that their classes
- implement [#factory]_. (Objects can provide interfaces directly,
- in addition to what their classes implement.)
-
- It is important to note that classes don't usually provide the
- interfaces that they implement.
-
- We can generalize this to factories. For any callable object we
- can declare that it produces objects that provide some interfaces
- by saying that the factory implements the interfaces.
-
-Now that we've defined these terms, we can talk about the API for
-declaring interfaces.
-
-Declaring implemented interfaces
---------------------------------
-
-The most common way to declare interfaces is using the implements
-function in a class statement::
-
- >>> class Foo:
- ... zope.interface.implements(IFoo)
- ...
- ... def __init__(self, x=None):
- ... self.x = x
- ...
- ... def bar(self, q, r=None):
- ... return q, r, self.x
- ...
- ... def __repr__(self):
- ... return "Foo(%s)" % self.x
-
-
-In this example, we declared that `Foo` implements `IFoo`. This means
-that instances of `Foo` provide `IFoo`. Having made this declaration,
-there are several ways we can introspect the declarations. First, we
-can ask an interface whether it is implemented by a class::
-
- >>> IFoo.implementedBy(Foo)
- True
-
-And we can ask whether an interface is provided by an object::
-
- >>> foo = Foo()
- >>> IFoo.providedBy(foo)
- True
-
-Of course, `Foo` doesn't provide `IFoo`, it implements it::
-
- >>> IFoo.providedBy(Foo)
- False
-
-We can also ask what interfaces are implemented by an object::
-
- >>> list(zope.interface.implementedBy(Foo))
- [<InterfaceClass __main__.IFoo>]
-
-It's an error to ask for interfaces implemented by a non-callable
-object::
-
- >>> IFoo.implementedBy(foo)
- Traceback (most recent call last):
- ...
- TypeError: ('ImplementedBy called for non-factory', Foo(None))
-
- >>> list(zope.interface.implementedBy(foo))
- Traceback (most recent call last):
- ...
- TypeError: ('ImplementedBy called for non-factory', Foo(None))
-
-Similarly, we can ask what interfaces are provided by an object::
-
- >>> list(zope.interface.providedBy(foo))
- [<InterfaceClass __main__.IFoo>]
- >>> list(zope.interface.providedBy(Foo))
- []
-
-We can declare interfaces implemented by other factories (besides
-classes). We do this using a Python-2.4-style decorator named
-`implementer`. In versions of Python before 2.4, this looks like::
-
- >>> def yfoo(y):
- ... foo = Foo()
- ... foo.y = y
- ... return foo
- >>> yfoo = zope.interface.implementer(IFoo)(yfoo)
-
- >>> list(zope.interface.implementedBy(yfoo))
- [<InterfaceClass __main__.IFoo>]
-
-Note that the implementer decorator may modify it's argument. Callers
-should not assume that a new object is created.
-
-Using implementer also works on callable objects. This is used by
-zope.formlib, as an example.
-
- >>> class yfactory:
- ... def __call__(self, y):
- ... foo = Foo()
- ... foo.y = y
- ... return foo
- >>> yfoo = yfactory()
- >>> yfoo = zope.interface.implementer(IFoo)(yfoo)
-
- >>> list(zope.interface.implementedBy(yfoo))
- [<InterfaceClass __main__.IFoo>]
-
-XXX: Double check and update these version numbers:
-
-In zope.interface 3.5.2 and lower, the implementor decorator can not
-be used for classes, but in 3.6.0 and higher it can:
-
- >>> Foo = zope.interface.implementer(IFoo)(Foo)
- >>> list(zope.interface.providedBy(Foo()))
- [<InterfaceClass __main__.IFoo>]
-
-Note that class decorators using the @implementor(IFoo) syntax are only
-supported in Python 2.6 and later.
-
-
-Declaring provided interfaces
------------------------------
-
-We can declare interfaces directly provided by objects. Suppose that
-we want to document what the `__init__` method of the `Foo` class
-does. It's not *really* part of `IFoo`. You wouldn't normally call
-the `__init__` method on Foo instances. Rather, the `__init__` method
-is part of the `Foo`'s `__call__` method::
-
- >>> class IFooFactory(zope.interface.Interface):
- ... """Create foos"""
- ...
- ... def __call__(x=None):
- ... """Create a foo
- ...
- ... The argument provides the initial value for x ...
- ... """
-
-It's the class that provides this interface, so we declare the
-interface on the class::
-
- >>> zope.interface.directlyProvides(Foo, IFooFactory)
-
-And then, we'll see that Foo provides some interfaces::
-
- >>> list(zope.interface.providedBy(Foo))
- [<InterfaceClass __main__.IFooFactory>]
- >>> IFooFactory.providedBy(Foo)
- True
-
-Declaring class interfaces is common enough that there's a special
-declaration function for it, `classProvides`, that allows the
-declaration from within a class statement::
-
- >>> class Foo2:
- ... zope.interface.implements(IFoo)
- ... zope.interface.classProvides(IFooFactory)
- ...
- ... def __init__(self, x=None):
- ... self.x = x
- ...
- ... def bar(self, q, r=None):
- ... return q, r, self.x
- ...
- ... def __repr__(self):
- ... return "Foo(%s)" % self.x
-
- >>> list(zope.interface.providedBy(Foo2))
- [<InterfaceClass __main__.IFooFactory>]
- >>> IFooFactory.providedBy(Foo2)
- True
-
-There's a similar function, `moduleProvides`, that supports interface
-declarations from within module definitions. For example, see the use
-of `moduleProvides` call in `zope.interface.__init__`, which declares that
-the package `zope.interface` provides `IInterfaceDeclaration`.
-
-Sometimes, we want to declare interfaces on instances, even though
-those instances get interfaces from their classes. Suppose we create
-a new interface, `ISpecial`::
-
- >>> class ISpecial(zope.interface.Interface):
- ... reason = zope.interface.Attribute("Reason why we're special")
- ... def brag():
- ... "Brag about being special"
-
-We can make an existing foo instance special by providing `reason`
-and `brag` attributes::
-
- >>> foo.reason = 'I just am'
- >>> def brag():
- ... return "I'm special!"
- >>> foo.brag = brag
- >>> foo.reason
- 'I just am'
- >>> foo.brag()
- "I'm special!"
-
-and by declaring the interface::
-
- >>> zope.interface.directlyProvides(foo, ISpecial)
-
-then the new interface is included in the provided interfaces::
-
- >>> ISpecial.providedBy(foo)
- True
- >>> list(zope.interface.providedBy(foo))
- [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
-
-We can find out what interfaces are directly provided by an object::
-
- >>> list(zope.interface.directlyProvidedBy(foo))
- [<InterfaceClass __main__.ISpecial>]
-
- >>> newfoo = Foo()
- >>> list(zope.interface.directlyProvidedBy(newfoo))
- []
-
-Inherited declarations
-----------------------
-
-Normally, declarations are inherited::
-
- >>> class SpecialFoo(Foo):
- ... zope.interface.implements(ISpecial)
- ... reason = 'I just am'
- ... def brag(self):
- ... return "I'm special because %s" % self.reason
-
- >>> list(zope.interface.implementedBy(SpecialFoo))
- [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
-
- >>> list(zope.interface.providedBy(SpecialFoo()))
- [<InterfaceClass __main__.ISpecial>, <InterfaceClass __main__.IFoo>]
-
-Sometimes, you don't want to inherit declarations. In that case, you
-can use `implementsOnly`, instead of `implements`::
-
- >>> class Special(Foo):
- ... zope.interface.implementsOnly(ISpecial)
- ... reason = 'I just am'
- ... def brag(self):
- ... return "I'm special because %s" % self.reason
-
- >>> list(zope.interface.implementedBy(Special))
- [<InterfaceClass __main__.ISpecial>]
-
- >>> list(zope.interface.providedBy(Special()))
- [<InterfaceClass __main__.ISpecial>]
-
-External declarations
----------------------
-
-Normally, we make implementation declarations as part of a class
-definition. Sometimes, we may want to make declarations from outside
-the class definition. For example, we might want to declare interfaces
-for classes that we didn't write. The function `classImplements` can
-be used for this purpose::
-
- >>> class C:
- ... pass
-
- >>> zope.interface.classImplements(C, IFoo)
- >>> list(zope.interface.implementedBy(C))
- [<InterfaceClass __main__.IFoo>]
-
-We can use `classImplementsOnly` to exclude inherited interfaces::
-
- >>> class C(Foo):
- ... pass
-
- >>> zope.interface.classImplementsOnly(C, ISpecial)
- >>> list(zope.interface.implementedBy(C))
- [<InterfaceClass __main__.ISpecial>]
-
-
-
-Declaration Objects
--------------------
-
-When we declare interfaces, we create *declaration* objects. When we
-query declarations, declaration objects are returned::
-
- >>> type(zope.interface.implementedBy(Special))
- <class 'zope.interface.declarations.Implements'>
-
-Declaration objects and interface objects are similar in many ways. In
-fact, they share a common base class. The important thing to realize
-about them is that they can be used where interfaces are expected in
-declarations. Here's a silly example::
-
- >>> class Special2(Foo):
- ... zope.interface.implementsOnly(
- ... zope.interface.implementedBy(Foo),
- ... ISpecial,
- ... )
- ... reason = 'I just am'
- ... def brag(self):
- ... return "I'm special because %s" % self.reason
-
-The declaration here is almost the same as
-``zope.interface.implements(ISpecial)``, except that the order of
-interfaces in the resulting declaration is different::
-
- >>> list(zope.interface.implementedBy(Special2))
- [<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.ISpecial>]
-
-
-Interface Inheritance
-=====================
-
-Interfaces can extend other interfaces. They do this simply by listing
-the other interfaces as base interfaces::
-
- >>> class IBlat(zope.interface.Interface):
- ... """Blat blah blah"""
- ...
- ... y = zope.interface.Attribute("y blah blah")
- ... def eek():
- ... """eek blah blah"""
-
- >>> IBlat.__bases__
- (<InterfaceClass zope.interface.Interface>,)
-
- >>> class IBaz(IFoo, IBlat):
- ... """Baz blah"""
- ... def eek(a=1):
- ... """eek in baz blah"""
- ...
-
- >>> IBaz.__bases__
- (<InterfaceClass __main__.IFoo>, <InterfaceClass __main__.IBlat>)
-
- >>> names = list(IBaz)
- >>> names.sort()
- >>> names
- ['bar', 'eek', 'x', 'y']
-
-Note that `IBaz` overrides eek::
-
- >>> IBlat['eek'].__doc__
- 'eek blah blah'
- >>> IBaz['eek'].__doc__
- 'eek in baz blah'
-
-We were careful to override eek in a compatible way. When extending
-an interface, the extending interface should be compatible [#compat]_
-with the extended interfaces.
-
-We can ask whether one interface extends another::
-
- >>> IBaz.extends(IFoo)
- True
- >>> IBlat.extends(IFoo)
- False
-
-Note that interfaces don't extend themselves::
-
- >>> IBaz.extends(IBaz)
- False
-
-Sometimes we wish they did, but we can, instead use `isOrExtends`::
-
- >>> IBaz.isOrExtends(IBaz)
- True
- >>> IBaz.isOrExtends(IFoo)
- True
- >>> IFoo.isOrExtends(IBaz)
- False
-
-When we iterate over an interface, we get all of the names it defines,
-including names defined by base interfaces. Sometimes, we want *just*
-the names defined by the interface directly. We bane use the `names`
-method for that::
-
- >>> list(IBaz.names())
- ['eek']
-
-Inheritance of attribute specifications
----------------------------------------
-
-An interface may override attribute definitions from base interfaces.
-If two base interfaces define the same attribute, the attribute is
-inherited from the most specific interface. For example, with::
-
- >>> class IBase(zope.interface.Interface):
- ...
- ... def foo():
- ... "base foo doc"
-
- >>> class IBase1(IBase):
- ... pass
-
- >>> class IBase2(IBase):
- ...
- ... def foo():
- ... "base2 foo doc"
-
- >>> class ISub(IBase1, IBase2):
- ... pass
-
-ISub's definition of foo is the one from IBase2, since IBase2 is more
-specific that IBase::
-
- >>> ISub['foo'].__doc__
- 'base2 foo doc'
-
-Note that this differs from a depth-first search.
-
-Sometimes, it's useful to ask whether an interface defines an
-attribute directly. You can use the direct method to get a directly
-defined definitions::
-
- >>> IBase.direct('foo').__doc__
- 'base foo doc'
-
- >>> ISub.direct('foo')
-
-Specifications
---------------
-
-Interfaces and declarations are both special cases of specifications.
-What we described above for interface inheritance applies to both
-declarations and specifications. Declarations actually extend the
-interfaces that they declare::
-
- >>> class Baz(object):
- ... zope.interface.implements(IBaz)
-
- >>> baz_implements = zope.interface.implementedBy(Baz)
- >>> baz_implements.__bases__
- (<InterfaceClass __main__.IBaz>, <implementedBy ...object>)
-
- >>> baz_implements.extends(IFoo)
- True
-
- >>> baz_implements.isOrExtends(IFoo)
- True
- >>> baz_implements.isOrExtends(baz_implements)
- True
-
-Specifications (interfaces and declarations) provide an `__sro__`
-that lists the specification and all of it's ancestors::
-
- >>> baz_implements.__sro__
- (<implementedBy __main__.Baz>,
- <InterfaceClass __main__.IBaz>,
- <InterfaceClass __main__.IFoo>,
- <InterfaceClass __main__.IBlat>,
- <InterfaceClass zope.interface.Interface>,
- <implementedBy ...object>)
-
-
-Tagged Values
-=============
-
-Interfaces and attribute descriptions support an extension mechanism,
-borrowed from UML, called "tagged values" that lets us store extra
-data::
-
- >>> IFoo.setTaggedValue('date-modified', '2004-04-01')
- >>> IFoo.setTaggedValue('author', 'Jim Fulton')
- >>> IFoo.getTaggedValue('date-modified')
- '2004-04-01'
- >>> IFoo.queryTaggedValue('date-modified')
- '2004-04-01'
- >>> IFoo.queryTaggedValue('datemodified')
- >>> tags = list(IFoo.getTaggedValueTags())
- >>> tags.sort()
- >>> tags
- ['author', 'date-modified']
-
-Function attributes are converted to tagged values when method
-attribute definitions are created::
-
- >>> class IBazFactory(zope.interface.Interface):
- ... def __call__():
- ... "create one"
- ... __call__.return_type = IBaz
-
- >>> IBazFactory['__call__'].getTaggedValue('return_type')
- <InterfaceClass __main__.IBaz>
-
-Tagged values can also be defined from within an interface definition::
-
- >>> class IWithTaggedValues(zope.interface.Interface):
- ... zope.interface.taggedValue('squish', 'squash')
- >>> IWithTaggedValues.getTaggedValue('squish')
- 'squash'
-
-Invariants
-==========
-
-Interfaces can express conditions that must hold for objects that
-provide them. These conditions are expressed using one or more
-invariants. Invariants are callable objects that will be called with
-an object that provides an interface. An invariant raises an `Invalid`
-exception if the condition doesn't hold. Here's an example::
-
- >>> class RangeError(zope.interface.Invalid):
- ... """A range has invalid limits"""
- ... def __repr__(self):
- ... return "RangeError(%r)" % self.args
-
- >>> def range_invariant(ob):
- ... if ob.max < ob.min:
- ... raise RangeError(ob)
-
-Given this invariant, we can use it in an interface definition::
-
- >>> class IRange(zope.interface.Interface):
- ... min = zope.interface.Attribute("Lower bound")
- ... max = zope.interface.Attribute("Upper bound")
- ...
- ... zope.interface.invariant(range_invariant)
-
-Interfaces have a method for checking their invariants::
-
- >>> class Range(object):
- ... zope.interface.implements(IRange)
- ...
- ... def __init__(self, min, max):
- ... self.min, self.max = min, max
- ...
- ... def __repr__(self):
- ... return "Range(%s, %s)" % (self.min, self.max)
-
- >>> IRange.validateInvariants(Range(1,2))
- >>> IRange.validateInvariants(Range(1,1))
- >>> IRange.validateInvariants(Range(2,1))
- Traceback (most recent call last):
- ...
- RangeError: Range(2, 1)
-
-If you have multiple invariants, you may not want to stop checking
-after the first error. If you pass a list to `validateInvariants`,
-then a single `Invalid` exception will be raised with the list of
-exceptions as it's argument::
-
- >>> from zope.interface.exceptions import Invalid
- >>> errors = []
- >>> try:
- ... IRange.validateInvariants(Range(2,1), errors)
- ... except Invalid, e:
- ... str(e)
- '[RangeError(Range(2, 1))]'
-
-And the list will be filled with the individual exceptions::
-
- >>> errors
- [RangeError(Range(2, 1))]
-
-
- >>> del errors[:]
-
-Adaptation
-==========
-
-Interfaces can be called to perform adaptation.
-
-The semantics are based on those of the PEP 246 adapt function.
-
-If an object cannot be adapted, then a TypeError is raised::
-
- >>> class I(zope.interface.Interface):
- ... pass
-
- >>> I(0)
- Traceback (most recent call last):
- ...
- TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>)
-
-
-
-unless an alternate value is provided as a second positional argument::
-
- >>> I(0, 'bob')
- 'bob'
-
-If an object already implements the interface, then it will be returned::
-
- >>> class C(object):
- ... zope.interface.implements(I)
-
- >>> obj = C()
- >>> I(obj) is obj
- True
-
-If an object implements __conform__, then it will be used::
-
- >>> class C(object):
- ... zope.interface.implements(I)
- ... def __conform__(self, proto):
- ... return 0
-
- >>> I(C())
- 0
-
-Adapter hooks (see __adapt__) will also be used, if present::
-
- >>> from zope.interface.interface import adapter_hooks
- >>> def adapt_0_to_42(iface, obj):
- ... if obj == 0:
- ... return 42
-
- >>> adapter_hooks.append(adapt_0_to_42)
- >>> I(0)
- 42
-
- >>> adapter_hooks.remove(adapt_0_to_42)
- >>> I(0)
- Traceback (most recent call last):
- ...
- TypeError: ('Could not adapt', 0, <InterfaceClass __main__.I>)
-
-__adapt__
----------
-
- >>> class I(zope.interface.Interface):
- ... pass
-
-Interfaces implement the PEP 246 __adapt__ method.
-
-This method is normally not called directly. It is called by the PEP
-246 adapt framework and by the interface __call__ operator.
-
-The adapt method is responsible for adapting an object to the
-reciever.
-
-The default version returns None::
-
- >>> I.__adapt__(0)
-
-unless the object given provides the interface::
-
- >>> class C(object):
- ... zope.interface.implements(I)
-
- >>> obj = C()
- >>> I.__adapt__(obj) is obj
- True
-
-Adapter hooks can be provided (or removed) to provide custom
-adaptation. We'll install a silly hook that adapts 0 to 42.
-We install a hook by simply adding it to the adapter_hooks
-list::
-
- >>> from zope.interface.interface import adapter_hooks
- >>> def adapt_0_to_42(iface, obj):
- ... if obj == 0:
- ... return 42
-
- >>> adapter_hooks.append(adapt_0_to_42)
- >>> I.__adapt__(0)
- 42
-
-Hooks must either return an adapter, or None if no adapter can
-be found.
-
-Hooks can be uninstalled by removing them from the list::
-
- >>> adapter_hooks.remove(adapt_0_to_42)
- >>> I.__adapt__(0)
-
-
-.. [#create] The main reason we subclass `Interface` is to cause the
- Python class statement to create an interface, rather
- than a class.
-
- It's possible to create interfaces by calling a special
- interface class directly. Doing this, it's possible
- (and, on rare occasions, useful) to create interfaces
- that don't descend from `Interface`. Using this
- technique is beyond the scope of this document.
-
-.. [#factory] Classes are factories. They can be called to create
- their instances. We expect that we will eventually
- extend the concept of implementation to other kinds of
- factories, so that we can declare the interfaces
- provided by the objects created.
-
-.. [#compat] The goal is substitutability. An object that provides an
- extending interface should be substitutable for an object
- that provides the extended interface. In our example, an
- object that provides IBaz should be usable whereever an
- object that provides IBlat is expected.
-
- The interface implementation doesn't enforce this.
- but maybe it should do some checks.