Ongoing Development and Testing

But then I realized all was not quite right. I could install new releases of
my package -- but I couldn't run it from the source directory any more.
How could I test changes without needing to rebuild the package for
every little change I made?

Fortunately, it turned out to be fairly easy. Set PYTHONPATH to a
directory that includes all the modules you normally want to test.
For example, inside my bin directory I have a python directory
where I can symlink any development modules I might need:

mkdir ~/bin/python
ln -s ~/src/metapho/metapho ~/bin/python/

Then add the directory at the beginning of PYTHONPATH:

export PYTHONPATH=$HOME/bin/python

With that, I could test from the development directory again,
without needing to rebuild and install a package every time.

Cleaning up files used in building

Building a package leaves some extra files and directories around,
and git status will whine at you since they're not
version controlled. Of course, you could gitignore them, but it's
better to clean them up after you no longer need them.

(Obviously, that includes file types beyond what you need for just
cleaning up after package building. Adjust the list as needed.)

Then in the setup() function, add these lines:

cmdclass={
'clean': CleanCommand,
}

Now you can type

python setup.py clean

and it will remove all the extra files.

Keeping version strings in sync

It's so easy to update the __version__ string in your module and
forget that you also have to do it in setup.py, or vice versa.
Much better to make sure they're always in sync.

I found several version of that using system("grep..."),
but I decided to write my own that doesn't depend on system().
(Yes, I should do the same thing with that CleanCommand, I know.)

def get_version():
'''Read the pytopo module versions from pytopo/__init__.py'''
with open("pytopo/__init__.py") as fp:
for line in fp:
line = line.strip()
if line.startswith("__version__"):
parts = line.split("=")
if len(parts) > 1:
return parts[1].strip()

Then in setup():

version=get_version(),

Much better! Now you only have to update __version__ inside your module
and setup.py will automatically use it.

Using your README for a package long description

setup has a long_description for the package, but you probably
already have some sort of README in your package. You can use it for
your long description this way: