Setting up a Python package

2017-12-27

or, Adventures in Yak Shaving

I started working on a python package that I might eventually want to publish. I consulted the PyPI documentation to make sure I set up the directory structure correctly, and along the way I encountered a mention of pip install -e, the command that lets you install packages in the works in editable form. (To your virtualenv, of course.) "Neat," I think, "but that looks like a lot of setup. I would have to add configuration files and whatnot to get this to be recognized as a package. I'll leave that for later."

Foreshadowing

After a little bit of code, I decide to write some tests with pytest. It's a great way to make sure my code is doing what I expect, and unlike my old practice of tinkering in an interpreter, writing pytest functions saves my test for later so that I'm alerted if they ever break. The more I use it, the more I find myself wondering, "Why didn't I start using this sooner?" The only wrinkle has to do with my directory structure:

/path/to/package/
                package/
                    __init__.py
                    ...
                test/
                    test_1.py
                    test_2.py
                    ...
                    files_for_testing/
                        ...

The scripts all have relative paths pointing to the test files, so I run pytest inside the test directory. This means my package is not in python's path when I run it. Up to now, I've been adding the project directory to the PYTHONPATH environment variable in the shell, but I've been looking for a way to do that more pythonically. "Why not have the test scripts add to sys.path?" I muse.

Of course, having had internet access for decades now, I recall details with the consistency of a butterfly, and so I turn to google to find out where in sys.path to insert the relevant directory. In doing so, I find an overly detailed discussion on stack exchange where user agf helpfully chides:

you need to be using virtualenv .... That's why people consider insert(0, to be wrong -- it's an incomplete, stopgap solution to the problem of managing multiple environments.

So now I guess I might as well get back to shaving the yak and set up my package for pip. I was trying to avoid the extraneous work to focus on the main project, but it turns out that I might as well do some of it. It should save me time in the future, right? I think that's how it's supposed to work.

Or maybe I'll just wind up like poor Hal:

It's inevitable, really.