Wednesday, April 15, 2009

Zope Interfaces and Python Abstract Base Classes

Jim Fulton (the architect of Zope 2, Zope 3, zc.buildout, and so on) and I talked briefly on the first day of the sprints about whether we could take advantage of the Python 2.6/3.0 Abstract Base Classes (ABCs), either replacing Zope interfaces or somehow using them to our advantage.

So I don't misrepresent him, I'll state my conclusions. Ask Jim for his.

Unfortunately, I came to the conclusion that ABCs, as of their current implementation, are anemic and largely uninteresting from zope.component's perspective. Some points:

  • The basic ABC mechanism simply allows hooks into isinstance and issubclass, so that you can ask, for instance, ``isinstance(x, Y)``, and ``Y.__instancecheck__(x)`` is consulted, if the method exists. Jim said we could make zope.interface interfaces implement these hooks. That didn't seem very interesting to me: to me, ``isinstance(x, Y)`` is a very different semantic question than ``Y.providedBy(x)`` and the difference is valuable. Same for ``issubclass(X, Y)`` versus ``Y.implementedBy(X)``. I'd rather not have zope.interface muddy that water.
  • The abc module allows you to create abstract base classes. To declare that a class is a concrete implementation of the ABC, you can either have the concrete class subclass the ABC; or, you can call the ABC's ``register`` method. In the current implementation, the registration is one-way, stored on the ABC. Therefore, you can ask an ABC, via various internals, what its "subclasses" are; but you cannot ask a class or instance about the ABCs it subclasses or is an instance of. zope.component needs to be able to ask what a class implements, or what an instance provides.
  • The zope.interface implementation is highly optimized, and relies on cacheing results for speed. The abc module is not geared for speed.
  • I wondered if we could at least leverage the default Python ABCs, describing mappings and sequences, to create interfaces from them, deprecating the ones in zope.interface.common. Jim seemed disinterested in that, saying that he hadn't found ours useful. I have found them useful--as a shortcut to describing a contract based on a mapping or a sequence, usually--so that still seems like a possible win to me.

Jim pointed out that zope.interface scribbled its metadata on classes, which some people found distasteful, and at least the abc module didn't do that. This characteristic of ABCs might please some people. A global data structure might be another way for zope.interface to do its work while answering that concern, if that ever became something we wanted to solve.

So in conclusion, the basic mechanism and the module were not really of interest to me; I felt that the library of ABCs might at least be interesting, but Jim disagreed.

Too bad. But hey, maybe we can throw out the Zope testrunner in favor of nose! :-) Jim proposed that idea, and thought it might be doable, with a little extension trick to make nose support Zope layers....

Back from PyCon 2009...a week ago.

I came back about a week ago from PyCon 2009...and went straight into getting our house ready to offer for sale, and then performing Anima Mundi by Mark Scearce in Raleigh, NC with my wife, Karyn, and some old and new friends. Good stuff, but exhausting.

I have quite a few notes from PyCon. My first mission there was to announce some of Launchpad's recent open-source work, in particular lazr.restful. I am excited about that, and have things to say, but I'm going to wait to blog on that just a bit longer. The docs need some work, at the least.

While, of course, the Django contingent at PyCon was very large, I was pleasantly surprised that the Zope/Plone community had a good showing. There were a few talks from the community, and BoFs included "I'm not ashamed to be a Zope programmer," "I love Zope," "I hate Zope" (the same crowd attended both the love and hate variants, I'm told), and a generic "Zope" BoF. The sprinting was enthusiastic and lively, and some cross pollination with some of the other non-Django frameworks also added some excitement and interest. The huge international Plone community using and sharing generic Zope libraries also has increased energy behind the Zope libraries.

Perhaps the most interesting generic Zope conversation I had was an attempt to identify what unifies the "Zope" projects. Thanks to efforts to bring Zope 3 libraries to Zope 2 and Plone, there is arguably more of a common theme across projects than in the past. There was some consensus that the following two ideas unify Zope projects.

  • Zope provides an unusual degree of low-level pluggability and interchangeability thanks to a contract-based component system.
  • Zope usually used a graph traversal approach to converting URLs to code, which has an advantage in that it is arguably easier to convert code back to URLs (walk back up the graph) than other approaches that do not have a natural reciprocal.

(For thoughts on the second point, see my old blog post.)

I have several specific PyCon reports that I'll post separately. All in all, I very much enjoyed the conference, though much more for the conversations and the sprints than the talks.

Speaking at OSCON 2009: Launchpad Foundations

My speaking proposal for OSCON 2009 was accepted: "Launchpad Foundations: Learning to Leverage a Component Architecture". Here's the quick blurb:

Study gains and losses in how Launchpad, a collaboration web service for the open-source community, used a Python component library from Zope 3 to help manage a large project. Discuss when the approach might be appropriate. Code examples include automatic REST web service generation. Demonstrate how the component architecture might be leveraged in popular frameworks such as Django.

Go to the details page for the full blurb. It should be interesting and fun to prepare. I'm interested in seeing if I can fit in references to some of the work that the pypefitters guys have been doing as well. WSGI plus zope.component seem like a pretty good pluggable base combination for web applications to me.