Jeff Shell wrote:
I just believe - heavily - after many of my Zope 2 experiences that
configuration as done by ZCML should be as separate from the code
itself as possible. If it's going to be in the same programming
language, it needs to be made clear what it is, what can be done, and
what can NOT be done.
Ok, but you broke your own rule. Quoting your blog entry :
This code appears at module scope. You've hardcoded the configuration
of a utility. You did it again with some provideAdapter() calls.
You're doing configuration the same way Zope 2 does it. You created
nontrivial side effects that no one can control without changing your
code. Even worse, this is a public example which I myself promoted! I
apparently made a mistake. Upon reflection, I realize that your example
is dangerous and illegal, since it integrates poorly with Zope. You're
outright wrong and your blog should be shot!
Ok, not really. ;-) But this illustrates why the line between code and
configuration shouldn't be a brick wall. Your example would have been
much cleaner if you had written a function at module scope where you
perform all registrations for the module. Then users of your module
could choose to call your registrations or not.
... which is pretty much what you did in a later example, in
basicConfigure()!  Users can choose to call basicConfigure(), and if
they don't, they start with a squeaky clean configuration. See, this
idea is not really mine. *You* configured things in Python code. You
did it because it's natural and easier to explain. I'm suggesting a way
to let you write configuration code safely, so that those who follow
your example don't descend into a Zope 2 mess.
Not long after ZCML came into existence, I invented a way to configure
using Python code, and I think I posted some examples. I realize now
that the simple way I did it was wrong. What I'm suggesting now is to
retain the semantics of ZCML but switch the syntax. It would be
possible to automate the conversion of all existing ZCML files.
The XML implementation of Zope configuration is an overreaction to the
things that went wrong in Zope 2. Configuration in Zope 2 was bad
simply because there was no consistent method of configuring things.
Now that we have a fairly complete configuration system and a set of
conventions, sloppy configuration will no longer proliferate in the Zope
community, unless the system is too rigid. Your example broke
convention, with potentially harmful consequences for people who follow
your example, suggesting the system is currently too rigid.
I think you could achieve this with Python, but you'd need do document
the hell out of it and put in a smart and restrictive system that
would ensure that sloppy configuration didn't happen, that the
'configure.py' module was unused by anything but the configuration
system, and that the package it was in could be loaded as a Python
package/module without the 'configure.py' module (which would have the
most requirements on the configuration of the outside system) be
ignored or otherwise not "blow up" when trying to register against
something not defined.
Restrictions aren't necessary. If developers are simply told what the
convention is and why they should follow it, they'll follow it. Again,
the problem in Zope 2 was that there was no convention for
configuration, so everyone made one up.
Also, I'd like to point out that Python is not the best language for
housing a lot of complex configuration data. Perl and Ruby tend to be
a lot easier to use here, as the language kindof makes it easier to
write fake little mini-languages since they're a lot more free-form
syntactically. I'm sure there are others here that remember
maintaining nested tuples of tuples of tuples for Zope things like
__ac_permissions__. Those were not always easy to read or maintain.
Hmm. I think Python is actually pretty good for mini-languages,
particularly because the syntax is simple and well known. Also because
you get smart editors, debugging, familiarity, etc. for free.
ZCML has the benefits of using zope.schema to define and format the
fields used in configuration and turn them into meaningful objects.
We'd still have that.
The ability to use local dotted names: <foo for=".interfaces.IPony">
We'd still have that too, if we really want it. An import is a lot
The ability to see those things
_clearly_ defined in APIDOC because of their schema-ness.
If I need to
know whether I can pass only one interface reference in to a
particular ZCML attribute or if I can pass in multiple, I can actually
get that information and it's based on the schema, but still pass it
in as just a string in XML. How would that work in Python?
The same way. All configuration directives will still pass through schemas.
Would it be
the responsibility of the 'configure.py' maintainer to use tools to
expand things? Would the configuration machinery used try to be smart
about what's passed in to allow for both:
from interfaces import IThis, IThat
'..interfaces.IOther')). Would that be allowed?
Well, not exactly. Configuration functions should only add directives
to a configuration context. Configuration functions should not touch
the real configuration, since only the configuration machinery knows
enough to decide which directives actually apply. But this might be
from interfaces import IThis, IThat
That will work if the 'adapts' field of the schema representing the
zope:registerView directive can understand tuples.
* alternate syntax? Not Python, but maybe something python-"ish" but
geared towards entering the kind of data references that one has to
type a lot in configuration.
Ugh, no. Zope is not in the business of designing languages.
* for many of the core ZCML configuration directives, explain their
Python alternative. Not to promote its use when writing large systems,
shared toolkits or frameworks, but to show how to test or just to use
adapters and utilities in small applications that don't require the
full Zope toolkit.
Most successful large systems were once successful small systems. Thus
as small systems grow, the methods developers use for small systems will
find their way into large systems. Plone is a great example of this:
Plone probably uses every esoteric feature of Zope and CMF that I know
of, and most of those features were designed for small systems. So
there's really only room for one way of configuring things in Zope.
OK. This has been long and rambling. I blame the christmas lunch cocktails. :)
I hope you have a safe and happy Christmas.
Zope3-users mailing list