[Zope3-Users] Re: ZCML, practicality, purity (was "Excellent perspective...")

Shane Hathaway shane at hathawaymix.org
Fri Dec 23 05:09:08 EST 2005


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 [1]:

   zope.component.provideUtility(greyhounds, name='greyhound')

[1] 
http://griddlenoise.blogspot.com/2005/12/zope-component-architecture-interfaces.html

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()! [2]  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.

[2] 
http://griddlenoise.blogspot.com/2005/12/zope-component-architecture-one-way-to.html

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">
> <far class="..zoo.Butterstick">.

We'd still have that too, if we really want it.  An import is a lot 
cleaner, though.

> The ability to see those things
> _clearly_ defined in APIDOC because of their schema-ness.

Check.

> 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
> configure.registerView(for=IThis, adapts=(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 
allowed:

def configure(context):
     from interfaces import IThis, IThat
     context.zope.registerView(
         for=IThis,
         adapts=(IThat, '..interfaces.IOther'))

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.

Shane


More information about the Zope3-users mailing list