Lately I am finding that it is worthwhile to separate projects into their own packages, but since they are all in the same domain, I want to have them share elements for importing purposes. Enter namespacing, which I believe is a little-used feature of setuptools that people should take a serious look at.
What is namspacing? Well, if you are familiar with creating packages, you know that often times they share similar traits, which means it would be nice to have sort of a global package where they all reside, but then you would not be able to install the components of said package independently. Lets say we have a solar system package, and inside it are elements for each planet. You might import from them like this:
from solarsystem.earth import echosystem
from solarsystem.venus import atmosphere
But what if you didn’t want to package simulations of all the planets, because sometimes you just want to install one or two of them at a time. Namespacing gives you a way of creating packages which are related to each other, but do not clash.
First off, you are going to need setuptools if you don’t already have it. Download the script here and run it with python. This will install the ubiquitous setuptools package which contains easy_install.
The easiest way I have found to create a namespace package is to use zopeskel, which provides a basic_namespace template for your project. First, we easy_install zopeskel:
easy_install zopeskel
Now we can list the templates that paster provides. Paster is a tool which provides a developer with an easy way to create templates for packages, as well as other useful utilities for python file management. (Paster is automatically installed by zopeskel)
$ paster create –list-templates
Available templates:
archetype: A Plone project that uses Archetypes
basic_namespace: A project with a namespace package
basic_package: A basic setuptools-enabled package
basic_zope: A Zope project
nested_namespace: A project with two nested namespaces.
paste_deploy: A web application deployed through paste.deploy
plone: A Plone project
plone2.5_buildout: A buildout for Plone 2.5 projects
plone2.5_theme: A Theme for Plone 2.5
plone2_theme: A Theme Product for Plone 2.1 & Plone 2.5
plone3_buildout: A buildout for Plone 3 projects
plone3_portlet: A Plone 3 portlet
plone3_theme: A Theme for Plone 3.0
plone_app: A Plone App project
plone_hosting: Plone hosting: buildout with ZEO and any Plone version
plone_pas: A Plone PAS project
recipe: A recipe project for zc.buildout
silva_buildout: A buildout for Silva projects
At the top of the list is basic_namespace, which we will be using. For example, lets make a solarsystem.mars package:
paster create -t basic_namespace solarsystem.mars
Paster will then prompt you with a series of questions, of which the first two are the most important:
Selected and implied templates:
ZopeSkel#basic_namespace A project with a namespace package
Variables:
egg: solarsystem.mars
package: solarsystemmars
project: solarsystem.mars
Enter namespace_package (Namespace package (like plone)) [’plone’]: solarsystem
Enter package (The package contained namespace package (like example)) [’example’]: mars
After you answer the rest of the questions, it will create a directory structure that looks something like:
solarsystem.mars/
|– README.txt
|– docs
| `– HISTORY.txt
|– setup.cfg
|– setup.py
|– solarsystem
| |– __init__.py
| `– mars
| `– __init__.py
|– solarsystem.mars.egg-info
| |– PKG-INFO
| |– SOURCES.txt
| |– dependency_links.txt
| |– entry_points.txt
| |– namespace_packages.txt
| |– not-zip-safe
| |– paster_plugins.txt
| |– requires.txt
| `– top_level.txt
`– zopeskel.txt
At which point, you are ready to create a development install of your project. Simply change to the directory:
cd solarsystem.mars
and:
python setup.py develop
Code for your new module would go in the solarsystem/mars/ folder, inside the new package. Any python you have installed this new package will
now be able to:
import solarsystem.mars
Namespacing is a great way to organize your work into digestible morsels, which can be installed one by one as needed by your perspective users. It is a great way to take advantage of all of the tools which have been created to make distribution and versioning easier.