< Benji York is doing good work
Zope and scaling down >

[Comments] (2) Towards a common structure of Zope 3 extensions:

Quite a few Zope 3 extensions are starting to appear. This is great. There is all the great work done within the Z3ECM svn repository. There's Infrae's hurry library of little Zope 3 odds and ends. Then there are various Zope 3 extensions written by Zope corporation, such as zc.catalog and zope.formlib. There's also various work done in the Zope 3 base svn repository.

Various patterns are emerging in the way these extensions are structured. I want to suggest a common pattern we all adhere to, and the reasons why. My aim is to suggest a common Pythonic structure, so that we don't do our homegrown Zope thing.

Warning

The word "package" in this text means what you check out from SVN. It's also what you can distribute to others in a tarball. It's what linux distributors use to create their distribution packages. It's also what you can use to create a Python egg (see more later).

The word "python package" in this text means what is importable in Python. It has the __init__.py. It's like a Python module, but bigger.

These packages are not necessarily identical, and in fact I'll argue they shouldn't be identical. When I say "package" I mean the former distribution package, when I say "python package" I'll mean the latter.

Why is a common package layout important?

Developers know where to look when they start using a new package. Distributors and packagers (such as linux distributors) know where to look and what to do. System administrators need to know only a single trick to install Python packages into Zope, not a different one for each package. Eventual metadistributions like what Zope 3 ECM may become will be easier to build.

Furthermore, distutils is now the standard for python packages. This involves a setup.py script the package root which can be used to build and install Python packages. It can also be used to create distributions of Python packages. Distutils presumes having a place where the setup.py can live.

Recently Phillip Eby has been doing a lot of great work with Python eggs, setuptools and easy_install. Briefly:

We need to structure our Zope 3 packages so they're easy to use with eggs. I expect Zope 3 core will start using eggs pretty soon, so let's prepare our extensions.

Package namespaces

Some packages create their own Python package namespace (hurry, zc) by utilizing a namespace package with an empty __init__.py. Others expect to live within the zope namespace of Zope 3, probably in the hope that this package will one day be core. Some packages just sit in the top level, creating a new namespace all for themselves, other packages cohere under a common namespace.

Recommendations:

Structure of a package

Some packages conflate the concept of distribution package and Python package. Thus, the Python modules are just in the top level of the distribution package, which has an __init__.py.

This is not good if you want your package to be released to the world, or possibly even be picked up by a Linux distributor. When I download a release tarball of some interesting Python extension, I expect to be able to unpack it, and not find all the source right there. No, I expect a nice README.txt, a INSTALL.txt, a setup.py, and perhaps a testrunner and a doc directory. I don't want to be bothered with lots of files of the source code itself.

The source code, that which ends up being importable somehow, that which ends up on the PYTHONPATH somehow, is in a separate subdirectory. This is often called src, like with Zope 3. An alternative structure also frequently used and useful if your package will have everything in a single Python namespace package anyway is to make this Python namespace package the immediate subdirectory.

It's actually the layout of Zope 3 SVN. It's also the layout of, say, Twisted, and PEAK, and CherryPy, and many, many other Python packages.

By using such a structure, it's trivial to create a simple release: you just do an svn export, tar it up, and you're done. It also become easy to create eggs, and the like.

Recommendations:


Comments:

Posted by Phillip J. Eby at Fri Oct 07 2005 23:09

Just a thought: setuptools uses the term "project" to refer to what you're calling a "distribution package". The term "project", along with others that setuptools uses, can be found at:

http://mail.python.org/pipermail/distutils-sig/2005-June/004652.html

Note, too, by the way, that setuptools supports namespace packages like 'zope' and 'zope.app', in that you can create projects that contain subpackages of existing packages, and they are automatically merged via __path__ munging at runtime. Thus, you can split even the Zope core into multiple eggs, as an alternative to zpkg-style building - *without* needing symlinks or special installation hacks. It "just works". This feature was specifically designed to allow breaking up sumo frameworks like Zope, Twisted, and PEAK. See the setuptools doc on namespace packages for more details.

Posted by Martijn Faassen at Sat Oct 08 2005 00:05

Project is a good name. Note that I actually know that
setuptools allows you to shunt in packages into a namespace package (sssh! :), but that I still think it's not a good idea for people to put packages not managed in the Zope 3 repository into the zope namespace. It will be good help us break up Zope though.


[Main]

Unless otherwise noted, all content licensed by Martijn Faassen
under a Creative Commons License.