Apr 02, 2010
One of the Devil's APIs!
A tale about the importance of the name. When the name of a piece of code is important, and when a not well chosen API's name can lead to problems... at least for me.
The same bug! For the second time I found the same bug in an old piece of code... again the same silly bug!
Ok, that's my fault... again...
What I can say? I was young and zope.interface was a new entry in the Plone world... often when you begin playing with a new APIs you don't read documentation before... why read how to use a method called "getNameOfCurrentUser" or "convertToUnicode"?
I think that the name says all I need!
Even worst: you try the command and... it runs! You got the expected result, so why investigate further with documentation?
What I'm talking about? I'm talking of the Evil directlyProvides method!

Let's go back to those sad days
I have an object... I need the API that make possible to provide an additional interface... this is for sure a simple task for zope.interface library...
What I only know is this: a class implements an interface, and object provide it...
When I find an API called directlyProvides I try to understand it's meaning using it's name... may be calling this I'll make possible that my object provide my interface (why directly? I don't know... maybe because the interface is not inherited by the class... it's not implemented... I really don't know!).
Is my first idea right or not? Let's try. I can use this:
>>> from zope.interface import Interface, directlyProvides >>> >>> class IMyClass(Interface): ... pass ... >>> class MyClass(object): ... pass ... >>> o = MyClass() >>> IMyClass.providedBy(o) False >>> directlyProvides(o, IMyClass) >>> IMyClass.providedBy(o) True
So it works! I found my API!
The Devil, revealed
Going back to the real life... today I know the truth:
>>> print directlyProvides.__doc__ Declare interfaces declared directly for an object The arguments after the object are one or more interfaces or interface specifications (``IDeclaration`` objects). The interfaces given (including the interfaces in the specifications) replace interfaces previously declared for the object.
I'm not really sure of why this API exists (I hope for some good reason, of course...).
Today I also know that the real API I need is alsoProvides (you know... also this name is right... the problem is that I found directlyProvides before the last one...).
Only a doubt about the name itself... why they didn't called it like one of those?
- onlyProvides
- exclusivelyProvides
- willProvideThisAndNoMoreInterfaces
Lessons learned?
- Read the documentation! Check for the __doc__!
- Probably you don't need directlyProvides in Plone!