Distutils and module distributions

We've already seen some of what it takes to package an application. Packaging means combining the source code and other files for one or more Python modules into a single file that can be distributed to other Python developers. This could be a ZIP file or a Python egg.

We've already seen some of what setuptools can do. The distutils module is included with Python and is the official packaging tool that setuptools is built on. Set uptools is an extension to distutils, not an official part of Python.

One of the biggest differences between distutils and setuptools is that setuptools generates eggs, while distutils does not. Using distutils, developers create distributions as opposed to eggs. These distributions can take a couple of forms, namely source and built. Source distributions are generally just archived and compressed copies of a module's directories and source code. This is useful for distributing your modules to other developers.

Built distributions (or binary distributions) compile your modules into an executable format specific to a destination-build platform. This could be Window (.exe), Red Hat Linux (.rpm), or a variety of other formats.

Another noteworthy difference between distutils distributions and those created by setuptools is that distutils is unaware of dependencies and is unable to download them anyway, even if it knew about them. This feature is likely responsible for setuptools and easy_install's popularity, despite not being an official part of Python.

To make use of distutils to distribute our modules, we need to write a setup script called setup.py, just as we did using setuptools. A lot the setup.py code is compatible with distutils and setuptools. Here is the simple example setup script from the distutils documentation:

from distutils.core import setup

setup(name='foo',
    version='1.0',
    py_modules=['foo'],)

This simple setup script includes two keyword arguments of metadata about our distribution, name and version, and a simple list of individual modules we want to include in our distribution. In this case, the foo module will be included and will correspond to a file called foo.py at the same level in the filesystem as our setup script.

This works for a single file or a short list of Python modules. But what about the case of packaging several packages, each with many modules? Distutils handles this as well:

setup(name='foo',
    version='1.0',
    packages=['foo', 'bar'],
    package_dir={'': 'src},)

Will look for modules in src/foo/ and src/bar/ relative to the setup script location and include them in the distribution output.

With this setup script in place and pointing to the appropriate modules or packages, we can run:

$ python setup.py sdist

The sdist command will generate a source distribution for our modules in a .tar.gz format. To create a built distribution we would use the following syntax for a Red Hat Linux .RPM file:

$ python setup.py bdist_rpm

Or, to create a Windows-compatible .EXE installation file we would use the following:

$ python setup.py bdist_windows

Installing distributions

In addition to providing distributions for developers to easily exchange modules between themselves, the distutils setup script allows users to install modules as well. This is done by passing the install command to the setup script:

$ python setup.py install

Usually, the process of installing a package like this involves downloading the .tar.gz source distribution, un-archiving the contents to the filesystem, and running the setup.py script as above.

Installing a package in this way places the Python modules included in our distribution into the user's site-packages. If they are running their default system Python, the package will be installed system-wide. If they are using virtualenv, for example, and have an active environment, the distribution will be installed to that environment.

Distutils metadata and PyPI

Even though distutils does not provide a mechanism for installing packages by directly downloading from PyPI, you can still define meta-data inside your setup.py script and use it to register and upload your distribution with the Python Package Index.

Uploading the distribution to PyPI also acts as a form of publishing your project. By providing version, author, and dependency metadata in setup.py, these requirements will be included on your distributions web page at the package index.

Registering and uploading your distribution with PyPI is done using the register setup.py command:

$ python setup.py register

Registering your distribution will transmit any metadata defined in setup.py, such as version and author's e-mail address, and create a project page for it in the index. This page will list all metadata you supplied in your setup.py. You can update a distribution's metadata by registering it again, with corrected metadata keyword arguments in your setup script.

You will be required to have a PyPI account before you can register your distributions. You can do this directly in the setup.py register command by choosing the second menu option when prompted.

Once your package is registered, you can upload it using the upload command:

$ python setup.py sdist bdist_wininst upload

This upload command will package and upload a source distribution as well as a built Windows install distribution. Both will be listed under the appropriate metadata in the PyPI.

Easy_install

Python packages deployed to PyPI using setuptools have an additional advantage: super-simple installation using the easy_install tool. This is a utility that with a single command, will find, download, and install a Python package from the package index. To install Django, for example, one can attempt it from the command line like so:

$ easy_install Django

This will download the latest released version of Django from PyPI and install it into the current Python environment, whether it is the system environment or a virtual environment. In this way it works very much like setup.py, with the enhanced function of automatically locating and downloading the appropriate package.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset