[Grok-dev] concerns about grokcore.component.provides
Gary Poster
gary.poster at gmail.com
Tue Sep 1 20:52:03 EDT 2009
Hi all.
The Launchpad team successfully made its first foray into grok land
today by switching some of lazr.restful to use it. It has turned out
nicely so far, and the next step is to make some custom martian
declarations. Thank you!
In the course of this, though, we came to a couple of concerns about
grokcore.component.provides that I'd like to share. I understand why
the decisions have been made the way they are, but I'd at least like
to share our thoughts.
Consider this only slightly contrived snippet, which is an example of
what you find repeatedly in our code with the new change:
class FeaturedCookbookLink(CookbookTopLevelObject):
"""A link to the currently featured cookbook."""
zope.interface.implements(ICookbookObject, ITopLevelEntryLink)
grokcore.component.provides(ITopLevelEntryLink)
First, as an old Zope 3 hand, I personally find the name
grokcore.component.provides very confusing. For the zope.interface
package, of course, "provides" describes what an instance directly
offers, while "implements" describes the special case of what a class
produces. I suspect the word "provides" was chosen for the
grokcore.component package because it mirrors the zcml registration of
an adapter. However, in context, I find it very confusing, especially
juxtaposed with the "implements" call.
Second, this looks an awful lot like a DRY "violation"--one of the
things I thought grok was particularly trying to avoid. Shouldn't you
be able to make a single spelling for the class, simultaneously
declaring that the interface is implemented and that it should be
registered as such? In other words, shouldn't this be equivalent to
the above?
class FeaturedCookbookLink(CookbookTopLevelObject):
"""A link to the currently featured cookbook."""
zope.interface.implements(ICookbookObject)
grokcore.component.provides(ITopLevelEntryLink)
I can grudgingly acknowledge an edge case of wanting to be able to
register an object for an interface that it does not implement, but
what an edge case! You want to make a promise one way, but carefully
avoid making the promise another? Declaring that a class implements
an interface is as much a matter of good faith as registering an
adapter--nothing is actually verified, unless you explicitly ask for
that.
I suppose it would be reasonable to allow someone to continue to spell
this edge case--you can in zope.interface/zope.component alone,
certainly--but I think that the best advertised spelling should
My main goal is to see if I can make someone--say, eventually,
Martijn ;-)--agree with us, and change things a bit. However, I feel
like I'm whining if I complain without trying to offer a solution, so
I'll try to make a couple. I'd be thrilled if someone else agreed
with our concerns, but came up with a better solution.
Option 1: you ignore my concern about naming, and just address the DRY
violation. grokcore.component.provides will automatically add the
interface to the class, so my second, theoretical example does in fact
produce the same thing as the first. Perhaps you add a flag or
another function that has the current behavior of not adding the
"implements" declaration.
Option 2: "grokcore.component.provides" is deprecated in favor of
"grokcore.component.instancesProvide". The new declaration has the
behavior I describe in option 1. It would result in this:
class FeaturedCookbookLink(CookbookTopLevelObject):
"""A link to the currently featured cookbook."""
zope.interface.implements(ICookbookObject)
grokcore.component.instancesProvide(ITopLevelEntryLink)
Thanks again for grokcore/martian. They have given us a nice win, and
we're interested in looking at them more.
Gary
More information about the Grok-dev
mailing list