Overview of Namespaces
A survey of the various namespaces used by packages that integrate with Grok. This may help you understand a package's origin and its relation to other packages that use the same namespace.
First a general disclaimer: the namespace doesn't really mean all that much. The goal of having a namespace is to make it easier to create a package of some name without conflicting with another package.
If we had no namespaces, conflicts between library names could easily happen. If a developer named their package "resource" there would be a good chance some other developer would wish to name their package the same way, and without namespaces there would be no way to distinguish between the two.
- the namespace used originally by the Zope 3 project. Now the namespace of the Zope Toolkit. Generally these are core framework packages, although there's a lot of packages that are not. Do not use it unless you have written a proposal to the zope-dev mailing list and this proposal has been accepted. zope.* packages must live in the Zope repository, be licensed under the ZPL and be covered by the Zope Contributor Agreement.
- the idea was to make the Zope 3-specific things reside here, the more general things in zope.*. This wasn't maintained very well, as nobody quite agrees on what is what anyway. Now it is a mostly deprecated namespace that contains the old Zope 3 ZMI user interface code. We've been moving more general code out of it into zope.*
- bits of Grok that we've split out of it into more reusable libraries. The five.grok project uses the same libraries to enable Grok support in Zope 2.
- user interfaces for Grok. The admin UI and the introspector end up here.
- Extension code for Grok. Often depends on Grok itself, but note that due to Grok's splitting up into pieces this code only needs to depend on grokcore.* packages, and could be seen as more generally reusable.
- a space for Zope Corporation to create packages in. There's a diverse collection of code in this namespace.
- A space where the Zope 3 community started to place packages. A diverse collection of code. These packages are normally ZPL licensed and found in the Zope repository.
- I started using this for some Zope 3 extensions back in 2005 or so. I've continued to use this namespace in the last few years as well for some more code I've written. Again, a diverse collection of packages.
- Souheil has been using this namespace. Much of it, I understand, is to support CMS-like applications on top of Grok. Designed also be more generally reusable.
- the Repoze project is working in its own repository and generally Repoze-related libraries are in there. Contains WSGI-related packages, the BFG web application framework, and other utility code for using Zope in a WSGI environment.
- a general namespace used by the Plone community. Again, some of it is designed to be more generally useful, a lot of it ties into Plone, however. These packages should live in the Collective repository and be released under the GPL or another open source license. The namespace implies community ownership and invites anyone with Collective commit access (i.e. anyone who wants it) to collaborate and help maintain it.
- a namespace used by Launchpad developers at Canonical. Some of it is designed to plug into Zope Toolkit applications.
- generally used as a namespace to place in compatibility code, to help use Zope Toolkit or Grok related libraries in Zope 2. These packages tend to live in the Zope repository.
- some packages developed by the Plone project. Much of this relies either on Zope 2 and/or Plone, but some of it is designed to be more generally useful. These packages should live in the main Plone repository, be GPL licensed (unless the Plone Foundation Board has explicitly given permission for an alternative license, normally BSD), and thus covered by the Plone Contributor Agreement. The name implies that this is or is intended one day to be part of Plone core. If in doubt, it's best to ask on the plone-developers mailing list before releasing a package under this namespace.
- This is a sub-namespace of the plone.* namespace and the same rules apply. The plone.app.* namespace is used for package that are part of "Plone-the-application", i.e. strongly dependent on Plone's user interface, default content types and so on. The difference between plone.* and plone.app.* is that packages directly under the plone.* namespace should work independently of Plone as a whole, and so be re-usable by other users of Python, Zope and/or CMF. A plone.* package is not allowed to import from any plone.app.* package, Products.CMFPlone, Products.ATContentTypes or other Plone-the-application-specific packages. You will sometimes see pairs of packages - like plone.portlets and plone.app.portlets - where the plone.* package is re-usable outside Plone and the plone.app.* package provides Plone-specific integration and additions.
- This namespace is used for standard portlets that ship with Plone. You will also see collective.portlet.*. The rules for plone.portlet.* are the same as those for plone.app.*. The rules for collective.portlet.* are the same as those for collective.*.
- This name is used by the default in the Plone theme paster template. It should be used for Plone theme products that are released as open source.
- A tongue-in-cheek namespace used for development and debugging tools such as mr.developer, mr.bent, mr.freeze and mr.git. These tend to live in the Plone Collective repository.
There are no hard and fast rules for package naming, but there are some rules of thumb based on accepted practices from Plone and other projects.
- A namespace is just that: a way to organise your code. Packages in the same namespace should be conceptually related.
- Understand the purpose of namespace before you use it. If in doubt, ask on the grok-dev mailing list or in the IRC chat room.
- Your last chance to get the namespace right is when you make the first public release. Changing package names after it has been used in the wild is a major pain and should be avoided if at all possible. Everyone who's ever tried to rename a released package have come to regret it. Changing the egg name is slightly less harmful, but will also cause a lot of confusion.
- For internal/customer projects, use your company name as the namespace. For example, the code written for the fictional "Optilux" chain of cinemas in the Professional Plone Development Book is all contained in the optilux.* namespace.
- There is no shame in releasing a package as open source even if it has an "internal" name. Witness things like jarn.mkrelease or zest.releaser. Think of it as a bit of free marketing.
- Only use a "shared" namespace if you really intend the code to be community owned. This is a corollary to the previous three points.
- Avoid using namespace packages as a way to delineate words in a package with multiple names.
- Avoid deep nesting - two levels is almost always enough. Some programmers have an urge to define everything in deeply nested hierarchies and end up with packages like collective.generic.skel.common (apologies - I'm pretty sure this is a worthwhile package with an unfortunate name). This type of name is both verbose and cumbersome (e.g. if you have many imports from the package). Furthermore, big hierarchies tend to break down over time as the boundaries between different packages blur. These days, the consensus is that two levels of nesting are preferred.
- Pick meaningful names. Speaking of collective.generic.skel.common - it's difficult to guess what that package may do looking at the name. Two of the four names are generic (erm...) and near synonymous. Ask yourself "how would I describe in one sentence what this namespace is for?", and then "could anyone have guessed that by looking at the name?".
- If in doubt, ask other developers on a mailing list.
Thanks to Martijn Faassen and Martin Aspeli for contributing much of the material in this document.