I am using zope.interface in a twisted based project. I have found two
interrelated unwanted side effects of
zope.interface.implements. Here is a summary and self contained examples
that show the problem:
1) The __provides__ attribute propagates * up* an inheritance tree to
classes that know nothing of zope.interface.
2) The __provides__ attribute is a descriptor that will sometime raise an
AttributeError even though it is listed in dir(cls). This means that things
like inspect.getmembers doesn't work. Because __provides__ propagates *up*
an inheritance tree, inspect.getmember has stopped working on all of my
classes even though they are plain old objects.
Example 1: showing how __provides__ propagates up an inheritance tree
import zope.interface as zi
print "At this point _provides__ is NOT in dir(A): ", dir(A)
print "And hasattr returns False: ", hasattr(A, '__provides__')
# Inheriting from A gives A additional attributes like __provides__!
# But A is just a plain old object.
print "But now, __provides__ is in dir(A): ", dir(A)
# hasattr(A, '__provides__') also returns True
if hasattr(A, '__provides__'):
print "A (which is just an object) has been infected with __provides__"
Example 2: showing how __provides__ messes up dir and inspect.getmembers