Chris McDonough wrote: [snip]
It tries to address the following problem.
Currently people seem to get wrapped around the axle and confused by the purpose of "the ZCA", which currently implies at least two different things:
- Machinery to perform complex registrations and lookups using interfaces in the form of a registry.
- A global API that presents a view of the world: "there are these things called utilities and adapters, and this API is how you do adaptation and utility lookup".
These two things are conceptually distinct.
It shouldn't be necessary to need to understand the concept of "utility" and "adapter" to use a registry. A registry is just machinery that uses interfaces as registration markers for the benefit of later arbitrary lookups, not necessarily just for "finding utilities" or "finding and calling adapter factories". For instance, you might use the registry to register some callable that accepts *no* arguments with, say, two "requires" arguments. You shouldn't need to call this an "adapter", because it's not one; you just want to register something and get it back when you ask nicely.
Agreed, but isn't this registry in zope.interface already? I mean zope.interface.adapter.AdapterRegistry? I've used this for the "not-really-adapting-as-I-don't-want-to-call" in a library of mine recently (traject). You factored out the registry functionality, but there are still plenty of references to utilities in it, for instance. As far as I understand it that would be putting too much into zope.registry already?
The API of a registry should be able to evolve separately from the API of its consumers (the global ZCA API is only one consumer). The current registry API permits the concepts of utility and adapter to bleed into the implementation, but this needn't be the case forever. We could provide (and document) a very simple registry base class with a normalized API that didn't have any of this conceptual baggage; it would be extremely popular, I think.
Likewise, it should be possible to use a different registry implementation to service the ZCA global API. This is possible right now via getSiteManager.sethook, of course.
You factored various related things together - perhaps it would make sense to do this refactoring within zope.component?
I'm +1 on making zope.event part of zope.component and deprecating zope.event.
Speculating, would it instead make sense to move zope.registry functionality into zope.interface? The only additional dependency is zope.event. At first glance the answer would be "no" as it really introduces various component architecture concepts...
It might make sense to me to put a very simple component registry in zope.interface: it already has the concept of "adapter" baked in.
Yeah, I think this makes more sense. So, we have a number of projects: * interface API - the stuff around calling interface I sketched out elsewhere. I think this is relatively low-hanging fruit. On the other hand it breaks backwards compatibility. I wouldn't want this project to depend on the other improvements, and I don't think it has to, so I'd like to see this as zope.component 4.0. * improving and move code that's general enough from zope.component into zope.interface. What this would look like I'm not quite sure about yet, as zope.registry at first glance contains a lot of knowledge about utilities and such still. There are backwards compatibility issues surrounding persistence but hopefully less around the APIs themselves. * an improved registration API for zope.component. This would affect a lot of code that does registration. Documentation projects should go along with all of those. Regards, Martijn