buildout.zc nested packages zcml quirk

Tom Blockley - September 29th, 2009

I came across this problem a couple of months ago, then promptly forgot about it until it happened to me again this morning.

We have a pretty good understanding of buildouts. If you don’t, you might want to read this great article: Understanding Buildouts

In a buildout config you will usually declare a set of eggs and zcml which you want to import, something like this:


eggs =
my.product
my.otherproduct
zcml =
my.product

Sometimes though, you may have a multilevel package, for example a product that provides optional management tools for an existing product. Instinctively you might register your management package after your main product, like this:


eggs =
my.product
my.product.management
my.otherproduct
zcml =
my.product
my.product.management

If you do that, your product will build out absolutely fine, but when you come to start an instance you will see an error something like this:


ZopeXMLConfigurationError: File
"/(...)/etc/package-includes/002-my.product-configure.zcml", line 1.0-1.64
IOError: [Errno 2] No such file or directory:
'/(...)/my.product.management/src/my/product/configure.zcml'

You’ll think, “this is a bit weird, there’s not supposed to be a configure.zcml there anyway – it’s in my/product/management where it’s supposed to be… isn’t it?”

Then you’ll probably spend a while searching the internet for hints, maybe adding a configure.zcml to that folder just in case and generally scratching your head. You might even try declaring the zcml includes the other way round, like this:


zcml =
my.product.management
my.product

This wont work either. In the end, when none of it works, you might stumble across the answer. Apparently you have to declare the egg includes the other way round instead:


eggs =
my.product.management
my.product

Re-run your buildout and your instance will start with no errors. Why? I don’t know, but if anyone has the answer, I’d love to know it!

3 Responses to “buildout.zc nested packages zcml quirk”

  1. Hanno Schlichting says:

    The real issue here is that you don’t properly use namespace packages. Something is either a namespace package or it is a package. It cannot be both.

    So if you have “my.product” as a real package you cannot also make it a namespace.

    It doesn’t blow up immediately, but as you noticed it does blow up in subtle ways later on.

  2. The other real issue is that you’re configuring your project through buildout.cfg.

    In this case, I’d suggest you create a policy product and use that to control all your dependencies (via isntall_requires in setup.py) and configuration (via statements in configure.zcml), as well as product installation in the Plone site (via statements in metadata.xml).

    These days, I have exactly one package in my ‘eggs’ line and declare everything else (including Plone) as a dependency of that package. This puts everything in one place and makes it much easier to deploy the same configuration in multiple buildouts.

    Martin

  3. Jean Jordaan says:

    “It doesn’t blow up immediately”

    -> could it be made to blow up? At least let buildout cry out in horror?

    “I have exactly one package in my ‘eggs’ line and declare everything else (including Plone) as a dependency of that package”

    -> this feels like working around buildout’s not-so-sweet spots, no? I.e. buildout.cfg is supposed to grab all the eggs you need, but sometimes it goes off the rails, so instead of letting it do its thing, you take over in your policy package.

Leave a Reply