Python build systems/dependency management

2019 Edition

20 Aug '19

It’s 2019, and we have PEP 518 “Specifying Minimum Build System Requirements for Python Projects”, and projects like Pipenv and Poetry. Everything’s great, and Python build systems/dependency management is solved, right?

Pipenv

First up, Pipenv. Generally, I really like the workflow. But then there’s issue #1050; you can’t specify Python versions using semantic versioning. Say you want 3.6 or higher, because of f-strings. Pipenv refuses to implement this. The result is it’s okay for applications, where you could reasonably specify a single version because you control deployments/the environments, but utterly impractical for libraries. I write both, so next up.

Poetry

Ah, Poetry. I was put off by the flashy website, but did eventually try it. It was supposed to be so easy.

So it’s 2019, Python 2 is almost EOL. Yet Poetry refused to use Python 3 on my system. See issues #522 and #721. The TL;DR is, if you aren’t using pyenv, you’re stuffed. And I’m not, because I don’t like messing with my Python versions. Whatever Python 3 Homebrew provides is fine, the CI will test the rest. My collaborators might not be, either. And I don’t expect it, pyenv isn’t “simple” (maybe simpler). Oh, did they mention pyenv doesn’t work on Windows?

Basically, if you use the default install method, which is the equivalent of curl ... | bash, it installs to Python 2. But even if you force it to use Python 3, it doesn’t work. Taking a step back, PEP 394 is “The python Command on Unix-Like Systems”, and specifies python2 and python3 for the respective versions. But Poetry will always use just python, even if you ask for Python 3 in pyproject.toml:

[RuntimeError]
The current Python version (2.7.15) is not
supported by the project (^3.6)
Please activate a compatible Python version.

Yaaaaaassss, I love issue reports for external tooling. User harrybiddle sums it up perfectly in his comment:

As a first-time poetry user I ran into exactly this! When you search the documentation and past issues, the answer you always recieve is “just use pyenv”.

But I think this places an unnecessary restriction: it basically means you can’t use poetry for a modern Python project unless you also commit to (a) using pyenv, (b) manually changing the shebang of poetry yourself, or (c) running poetry within a Python3 virtual environment. Pipenv behaves better here: if Python 3 is required for the project it’ll find it if it’s installed and use it.

Sure, we could argue that this is out of the scope of poetry, but it’s one of the first issues I hit and I’m sure others will too.

harrybiddle on issue #721

Oh, and the workaround on the issue no longer works. But okay, with a quick alias, I can hack around it.

No, the real rub is issue #34. I use pip install -e . a lot. Maybe it isn’t the right way to do things, but it’s really good when testing a Python app that uses an entry point. First I’m told -e . isn’t necessary, although the maintainer does come around. Fair enough, no harm, no foul.

Apparently, poetry install should do the equivalent of pip install -e . now. Well, I’m running 0.12.17, and it seems to not work. Because there’s bug with poetry shell (issues #497 and #571), so the virtualenv isn’t actually sourced when running that command, i.e. $PATH remains unchanged.

Naturally, the old workaround, source $(poetry env info -p)/bin/activate, also no longer works because the env command is gone. Now you have to do something like source $(poetry debug:info | awk '/Path/ { print $3 }')/bin/activate and hope the output format doesn’t change.

Look, I couldn’t maintain something like Poetry. And the current maintainer seems to be struggling with it, too. There’s over 400 open issues at the time of writing. At the same time, I can’t really expect people with less Python experience to embrace these hacks.

pip

Good old pip. At the end of the day, this still works:

$ python3 -m venv env
$ source env/bin/activate
$ pip install -e .

Yes, it has some issues with resolving dependencies sometimes. Yes, the requirements.txt are annoying. But at the same time, using pre-commit can abstract dev dependencies away for e.g. linting. It’s simple and it works. I can teach people virtualenv discipline. (I still don’t know how to easily re-create the virtualenv Poetry creates.)

So I’ll be keeping an eye out on Poetry, but for now, setup.py + pip seems hard to beat.

Python

Newer Older