one of these days I'll figure out how to write a setup.py on the first try