[Zope3-dev] Questions about Interface.Implements
Steve Alexander
steve@cat-box.net
Fri, 08 Nov 2002 12:06:50 +0000
Hi Jim,
In the process of writing his tools for documentation, Kapil has found
some problems with the functions in Interface.Implements.
I'd like to spend a little time fixing these up, and writing some unit
tests to exercise them some more. I have some questions though:
1: visitImplements has a docstring that says:
"This does not, and should not, visit superinterfaces."
Does this mean that the following is correct?
class I1(Interface): pass
class I2(I1): pass
l = []
visitImplements(I2, None, l.append)
# l == [I2]
2: Does visitImplements accurately describe the valid contents of an
__implements__ ?
Here's my interpretation:
The implements attribute:
An implements attribute of an object O is O.__implements__, unless
isinstance(O, ClassTypes), in which case it is O.__class_implements__.
Value of the implements attribute:
An implements attribute may be of one of the following types:
* an Interface (that is, a class derived from Interface.Interface)
* a string
* the special value CLASS_INTERFACES
* a tuple containing any of the things mentioned in these four
bullet-points
You can find the interfaces given by an implements attribute thus:
obj = the object that has the implements attribute
ia = the implements attribute
def simple_flatten(x):
if x is an interface:
return [x]
if x is a string:
return simple_flatten(
someFunctionThatReturnsAnInterfaceForAString(x)
)
if x is a tuple:
l = []
for i in x:
l += simple_flatten(x)
return l
if x is CLASS_INTERFACES:
if obj has a __class__ attribute:
return simple_flatten(
getImplementsOfInstances(obj.__class__)
)
else:
return []
# if there has been no return statement so far...
raise BadImplements
interfaces_given_by_implements_attribute = simple_flatten(ia)
Notes:
Although a string can act as an interface, a unicode cannot.
Strings are not considered interfaces in themselves. They are
keys to allow a real interface to be looked up. This interface
can be anything you'd put in an implements attribute.
3: flattenInterfaces
The flattenInterfaces function is supposed to work like the
simple_flatten pseudocode above, except that we also need to
consider the bases for each interface we come across.
if x is an interface:
return [x] + simple_flatten(x.getBases())
There is an option to remove duplicates from the results of
calling simple_flatten before returning this as the
results of flattenInterfaces.
This removal of duplicates should work similarly to Python2.2's
method resolution order for new-style classes.
4: Proposed work
* Improve the unit tests to thoroughly exercise the different
possibilities for an implements attribute
* Improve the unit tests to cover both flattenInterfaces and
visitImplements
* Refactor flattenInterfaces and visitImplements to share the
same code for walking an implements attribute, taking into
account that only flattenInterfaces uses getBases.
--
Steve Alexander