Jason in a Nutshell

All about programming and whatever else comes to mind

Archive for June, 2008

Python distutils and you: Part I

Posted by Jason Baker on June 4, 2008

In the past few days, I’ve grown a lot more familiar with python’s packaging options than I ever hoped to become. So, I thought I would share some of the things I learned in case anyone else runs across a need to use this in their GSoC projects (or any other project for that matter).

The setup script

This is the meat of python distutils. Surprisingly, there’s really not all to writing the setup.py script itself. Suppose I have a file called “foo.py” that I’d like to install on someone’s computer. Here’s what a setup.py script will look like: (examples shamelessly copied from the distutils documentation)

from distutils.core import setup
setup(name='foo',
      version='1.0',
      py_modules=['foo'],
      )

That wasn’t so difficult was it? All you need now is to put foo.py in the same directory as setup.py and you’re good to go!

Packages

Now suppose that instead of a single module, we want to put a whole package into our distribution (a package being a directory containing an __init__.py). That’s where the packages keyword comes into play. Just pass a list of package names to the setup function.

So, let’s assume we have a directory ‘foo’ in the same directory as our setup.py script. This directory contains the files __init__.py, bar.py, and bar3.py. Here’s how we would do that:

from distutils.core import setup
setup(name='foo',
      version='1.0',
      packages=['foo'],
      )

Now, suppose we want to get something we can distribute. That’s pretty easy. All you have to do is type

python setup.py sdist

That will create a directory called ‘dist’. If you look inside dist, you will see foo.tar.gz (or foo.zip for you windows users out there). Now all your user has to do is type in

sudo python setup.py install

and foo will go into the end user’s site-packages directory.

Scripts

Now this is all well and good if all we want to distribute is a library. But I’m packaging an application. Suppose I have a python file called ‘dofoo.py’ that that will import modules from foo when the end user runs it. Here’s how we would put that into the file:

from distutils.core import setup
setup(name='foo-program',
      version='1.0',
      packages=['foo'],
scripts=['dofoo.py'],
      )

What does this do? Well first of all, the installer will automagically change the shebang line in dofoo.py to the end user’s python location if the first line of it begins with #! and contains the word python. Secondly, dofoo.py will be installed to /usr/bin unless the end user puts it elsewhere. Ideally, the key is to focus on what functionality something provides here rather than where it will go in the user’s file system since the user has ultimate control over what goes where.

Conclusion

Well, the part about writing the setup.py script ended up being longer than I had originally intended. There is still a lot more metadata that can go into setup.py. But hopefully that should be sufficient to give you a general idea of what distutils is all about. Next time I plan on talking a little bit more about the manifest and possibly some more distribution options.

Advertisements

Posted in Programming | Tagged: , , , , | Leave a Comment »