Let me point out though why you might want to consider using setuptools instead of doing it wrong.
Part of the PEP 8 and PEP 328 is that absolute imports are used as often as possible. The idea is that you specify exactly which module needs to be imported to make the code work. Even if the code is relocated, it still works. It also means that the system can arrange the files any way it wants, so long the Python interpreter sees the same structure for the modules. This lets distro developers and operating system designers put Python modules wherever they feel necessary, as well as letting tools like virtualenv override the OS defaults on a per user or per application basis.
However, if you use an 'alternative' directory structure in your project, you might find yourself running into trouble. Say you have a module you're building called 'foo'. In your source directory, you have some directory /src/foo/some_code.py . There's also some script /run_foo.py at the top level of the source tree. If there is a line in run_foo.py that calls 'from foo import some_code', Python will raise an exception that the module foo cannot be found.
One common, although very wrong and messy solution is to catch said ImportError. In the corresponding catch block, there is alot of code to check to see where the code is being run. Then it digs into the internals of the module import system in Python so that it pretends it can really see the module foo and all its submodules. This is a rather unfortunate way of writing code, because it really limits what you can do in the source tree. For every script that you have, you may have to copy and paste this code. Furthermore, if you change the layout in the source tree, you may break all your scripts and have to change them manually. Finally, you have to question the sanity of putting file system specific code in a program. There are clear places where such code makes sense, but tinkering with the filesystem and path environment is not one of them.
Luckily, setuptools can do all this work for you. It can translate any on disk file system layout, such as /src/foo/some_code.py to foo.some_code for you. It can also direct installation to work properly. It can even modify your Python path environment so you can work directly out of your source tree. Any changes you make will show up automatically. Finally, we can isolate all the code into one place. The entire mapping is just a simple dictionary in one file, which is analogous to a configure.ac file.
I may post something later about where setuptools fails, and how we might be able to work around it.