Distutils is the recommended method for distributing python modules and packages (a selection of modules). However, it is quite difficult to figure out how to use it. Here I present some examples. You should look at these examples before starting your project, as you are encouraged to lay your project out using standard directories as described below.
Please tell me if there are any errors on this page, or if one of the examples doesn't work for you.
Lay your project out as follows:
setup.py README license.txt src/ mypkg/ __init__.py module_a.py module_b.py
Use the following setup.py:
from distutils.core import setup setup(name="mypkg", version="1.0", author="Noel O'Boyle", author_email="baoilleach@users.sf.net", url="http://www.redbrick.dcu.ie/~noel/", packages=['mypkg'], package_dir = {'mypkg':'src/mypkg'} )
To create a source distribution, type:
python setup.py sdist
A file, mypkg-1.0.tar.gz, is created in the dist directory, which you can distribute. To test whether it works, try to install from it:
cd dist tar zxvf mypkg-1.0.tar.gz cd mypkg-1.0 python setup.py install python >>> import mypkg
What about if some of the .py modules are in a subdirectory of the main package? For example:
setup.py README license.txt src/ mypkg/ __init__.py module_a.py plugins/ __init__.py module_b.py
Use the following setup.py:
from distutils.core import setup setup(name="mypkg", version="1.0", author="Noel O'Boyle", author_email="baoilleach@users.sf.net", url="http://www.redbrick.dcu.ie/~noel/", packages=['mypkg','mypkg.plugins'], package_dir = {'mypkg':'src/mypkg'} )
What if you have help files, images, or some other type of non .py file? It took me a while to figure out, but here are two solutions.
Method 1 uses the package_data option. Unfortunately, the distutils that comes with Python 2.3 doesn't understand the package_data command. You either need to use Python 2.4, or install the latest version of distutils for Python 2.3. To do this, get the latest version of distutils from CVS. Once you have checked it out of CVS, use the standard "python setup.py install" to install it. To use the new version, rather than the one in the standard library, you will need to set your PYTHONPATH to include the site-packages directory (this is because PYTHONPATH is checked before the standard library is checked).
In the following directory layout, note the new file "MANIFEST.in", and the new data directory, "src/mypkg/images":
setup.py README MANIFEST.in license.txt src/ mypkg/ __init__.py module_a.py index.html images/ shamrock.png
Use the following setup.py:
from distutils.core import setup setup(name="mypkg", version="1.0", author="Noel O'Boyle", author_email="baoilleach@users.sf.net", url="http://www.redbrick.dcu.ie/~noel/", packages=['mypkg'], package_dir = {'mypkg':'src/mypkg'}, package_data = {'mypkg':['images/*.png','*.html']} )
You also need to use the following MANIFEST.in or source distributions are not built properly (don't ask me why):
include src/mypkg/images/*.png include src/mypkg/*.html
Method 2 should work for both Python 2.3 and 2.4. It involves finding out where the data files should be copied to, and then copying them there explicity. In this case, you need to use the same MANIFEST.in as for Method 1, and use setup.py the following setup.py:
from distutils.core import setup from distutils import dir_util,file_util import sys mydist = setup( name="mypkg", version="1.0", author="Noel O'Boyle", author_email="baoilleach@users.sf.net", url="http://www.redbrick.dcu.ie/~noel/", packages=['mypkg'], package_dir = {'mypkg':'src/mypkg'}, ) if "install" in sys.argv: wheretoinstall = mydist.command_obj['install'].install_purelib for dirname in ['images']: dir_util.copy_tree(os.path.join("src","mypkg",dirname),os.path.join(wheretoinstall,"mypkg",dirname)) for filename in ['index.html']: file_util.copy_file(os.path.join("src","mypkg",filename),os.path.join(wheretoinstall,"mypkg"))