[Zope-dev] Dependencies for ZCML

Tres Seaver tseaver at palladion.com
Thu Mar 12 14:25:29 EDT 2009


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Martijn Faassen wrote:

> Tres Seaver wrote:
> [snip]
>> - -1 on having "configuration dependecies," including having mandatory
>> tests that ZCML will load:
> 
> You mean mandatory ZCML loaded by tests? You seem to write the reverse 
> here, and I don't understand what that could mean.

Sorry, I meant "mandatory tests which load ZCML."  I'm actually against
ever loading ZCML in tests at all.

>>  "mandatory configuration is a contradiction
>> in terms."  I therefore don't believe that tests which try to load ZCML
>> are useful, at least for "library" pacakges (as opposed to "applications").
> 
> Yeah, I know you're a purist on this topic.
> 
> Here are some observations on configuration, mandatory or not, and ZCML.
> 
> Sometimes you can only test a library when a particular utility or 
> adapter or event handler is registered. The library uses this utility or 
> adapter in its own logic and while the utility or adapter is intended to 
> be replaceable (to make the library pluggable), it is mandatory to 
> actually register a component that fulfills the interface requirements 
> in order to use the library at all.

Such tests should supply a stub version of the component:  they should
*never* rely on a "real" version.

> As a convenience to the users of this library, that library's 
> configure.zcml will provide default implementations (which may be the 
> right ones in most cases). This is a useful pattern.

That pattern does not lead to good testing.

> I'll note another pattern. A library could define an interface, and a 
> few event handlers that react on this interface. Now if you use that 
> interface on your own objects, your object will trigger those event 
> handlers.

Not if I don't register the handlers.  Choosing to register them is
*not* the purview of a library writer.

> Your interest as a library user is not directly in those event 
> handlers and you may be unaware of their existence, but they do maintain 
> something that is important to you as a user (an index, for example).

Registering such machinery is the job of the application writer, not the
library writer:  it is *policy*.

> So  this is an example of registrations that should be loaded in order to 
> use the library, and there's not even much interest here in overriding 
> those registrations - mandatory configuration.

That would defat the whole point of the events machinery, which is to
decouple things.  If you can't use a package at all without reigstering
some event handler, then the package isn't a library, it is an application.

> Now when testing these libraries you could do three things:
> 
> * not use ZCML at all and recreate the effect of these registrations in 
> Python code.

+1.

> * use the ZCML in the package's configure.zcml. (perhaps through 
> ftesting.zcml)

- -lots.

> * construct ZCML in the tests itself and load it.

- -0 (I don't see a win over just doing it in Python).

> In fact there's a fourth way you could go and use martian-style 
> patterns, where you can manually 'grok' a component in tests that 
> inherits a particular base class.
> 
> We could argue that all ZCML in use in tests should be rewritten to 
> manual registrations from Python code. Is this indeed a useful exercise? 

Yes.

> Doesn't that in some cases make tests harder to understand, as 
> lower-level APIs are in use that are not as recognizable as the 
> equivalent ZCML directives? (say, registering an event) Don't we place a 
> burden on the test writers to learn these APIs while they could use the 
> ones abstracted away behind ZCML instead?

No.  Relying on "real" ZCML in testing, as is using the "real"
components is an anti-pattern:  it makes tests fragile, couples the
packages tightly, etc.

> I will also repeat my observation that if a package has ZCML in it that 
> never gets loaded by the tests of that package, that means that there 
> are no automatic tests for this ZCML. There is something in this package 
> that is not tested and can only be tested indirectly. Isn't that 
> something we try to avoid?

*I* don't care about testing ZCML at the package level:  I don't think
it is useful, and I find that it actively screws up "real" tests.
Testing the "real" configuration is something which makes sense for
applications, not reusable library packages.

> What do we gain dependency-wise by avoiding the loading of ZCML during 
> tests but do manual registrations instead?

We don't try to re-use the "real" components which that ZCMl would
register, and therefore don't depend on the other package at all.

> We *may* get rid of 
> dependencies on zope.configuration. If the definition of ZCML directives 
> were always strictly separated from the functionality that these 
> directives manipulate, then this would often be the case. In reality 
> this is frequently not so, however. We may also get rid of such "ZCML 
> directive definition only" packages, for instance zope.componentzcml.
> 
>> Any ZCML file which needs something like zope.component or zope.security
>> to be present should signalt that by either including the meta.zcml
>> (e.g., to define directives) or nesting the dependent directives inside
>> a "conditional" block, whose predicate documents the requirement.
> 
> You're saying that we should be an include of the zope.component 
> 'meta.zcml' in *all* ZCML files that register an adapter? This is 
> certainly not happening always now. That's like import before usage in 
> Python modules, right?

Yes.  If you are going to try to make ZCML reusable, then it can't make
assumptions about another package having done meta-registrations on its
behalf.

> I'll note that martian-based code actually does use that pattern - any 
> package based on grokcore.* for instance automatically follows this 
> pattern.
> 
> I'll also note that with martian-based configuration the situation is 
> clear for setup.py: the dependencies needed for configuration are always 
> normal dependencies of a package.
> 
> With ZCML-based configuration the situation is far less clear.
> 
> So what does all of this mean for Dan's question? I don't know yet.
> 
> I think we should observe some packages. We strive for library-like 
> packages. More library-like packages should likely not have to do a lot 
> of work in their configure.zcml, but the amount of work is not always 
> zero. Dan, do you have any examples of packages where you are wondering 
> about what to do? Let's examine then and reason about how they could be 
> organized.

I don't think "library" packages have ZCML in them at all, except as
examples, because trying to reusing ZCML doesn't actually win
unambiguosly over copying it.


Tres.
- --
===================================================================
Tres Seaver          +1 540-429-0999          tseaver at palladion.com
Palladion Software   "Excellence by Design"    http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFJuVOZ+gerLs4ltQ4RAmYqAJ0d2XMSXSV7YFg40lmAzSmAlMNA9QCeKfof
kIRv8VvmcFehqJLkI7T3U9w=
=FEjR
-----END PGP SIGNATURE-----



More information about the Zope-Dev mailing list