Pipenv and Poetry: Benchmarks & Ergonomics II
Welcome!
I started working on Pipenv and Poetry: Benchmarks & Ergonomics at the begining of 2019, so it seemed only fitting that I provide an update before 2020–'here near the year rear', if you will.
In that time, Python has become the 2nd most popular language on GitHub, and Blog posts about Python dependency management continue to prompt lengthy disucssions online.
Python dependency management is a hot topic even in the tiny corner of the Internet that is this blog. My first Pipenv vs Poetry comparison is my most popular post by ~27%, and two of my three top posts relate to Poetry. And it's no wonder. There are so many ways to manage Python packages and versions that it's hard to keep them straight.
There's the classic pip + Virtualenv setup, recommended by the likes of Django. pip, you say? Not to be confused with pipx, which installs Python applications in isolated environments. Virtualenv, you say? Don't confuse that for virtualenvwrapper, which provides helpful wrapper comands around Virtualenv.
Oh, and about Virtualenv: it's been partly integrated into the Python standard library as venv.
Looking for different versions of Python to put into those virtual environments? There's a tool for that, too: pyenv.
In the scientific computing and machine learning part of the Python galaxy, Conda and its little ssssssissssster Miniconda are all the rage, but they aren't just Python package managers because they manage system dependencies and packages for other languages, too.
Whew! With that embarassment of riches, it's no wonder people are still looking for guidance on how to manage Python packages in 2019.
But enough about those eight (!) tools for managing Python versions and their packages. Let's take a look at how Pipenv and Poetry stack up after eight months of development, first at their current versions, then ergonomic enhancements, and finally benchmarks.
Eight months of releases (?)
In my last post on this subject, I referred to Pipenv and Poetry as "maturing next-generation Python dependency management tools".
This time around, while Poetry has had nearly a page of releases toward its v1.0.0, Pipenv has been waiting on a new release since November 26, 2018.
Poor Pipenv.
While Poetry has seen meaningful usability improvements in the past eight months, any improvements in Pipenv's >660 commits since its last release have yet to make it to users.
This post compares the latest Pipenv and Poetry versions–and in Pipenv's case, 'late' might be a triple entendre.
Feature | Pipenv | Poetry |
---|---|---|
Version compared | 2018.11.26 | 1.0.0b5 |
Ergonomic Enhancements
Installing dependencies
As of Poetry v1.0.0a3, it's possible to disable Poetry's default behaviour of installing the local project as a dependency using:
poetry install --no-root
The benchmarks that follow will include this flag for a truer comparison of Poetry and Pipenv install speeds.
Since my last post, Poetry has also gained the ability to skip installing dev dependencies using the --no-dev
flag.
For Pipenv and Poetry, these commands are functionally equivalent:
pipenv install --dev
poetry install --no-root
Poetry shell
As of v1.0.0b2, The Poetry shell no longer exists on Ctrl+C when using fish.
This is thanks to changing how Poetry was launching a shell to how Pipenv does.
Benchmarks
These benchmarks are meant to compare the relative speed of common commands used during development. Each of the commands is benchmarked using time
, running on my AMD Ryzen 5 1600.
For this round of benchmarking, I increased the number of dependencies to mirror a Django REST Framework project with good development tooling. This should yield benchmarking figures more in line with what you'd see in a real project.
Dependencies | Dev Dependencies |
---|---|
django | black |
django-redis | bpython |
djangorestframework | django-debug-toolbar |
pendulum | factory_boy |
psycopg2-binary | flake8 |
redis | flake8-mypy |
mypy | |
pytest | |
pytest-watch |
Benchmark results
The output of each command is pretty well unchanged since my last post on this topic, so I've excluded that this time around.
The faster command is indicated in bold.
Task | Poetry | Pipenv |
---|---|---|
Full install (without lockfile) | 70.93s | 38.42s |
Full install (with lockfile) | 62.35s | 22.75s |
Add dependency: flake8-markdown | 3.55s | 19.99s |
Lock dependencies | 3.49s | 11.15s |
Remove dependency | 2.97s | 13.93s |
Not much has changed since last time. Pipenv is still faster for full installs, which makes for speedier CI/CD. Poetry is still faster for everything else, making it feel snappier during development.
Wrap-up
Here's my wrap-up from last time:
Poetry's version 1.0 is set to address the two areas where I preferred Pipenv: being able to export a
requirements.txt
file, and being able to avoid installing a package as a dependency of itself.
If Poetry keeps it up, once version 1.0 is released, I can see myself reaching for it in every new project I start.
Until that point, Pipenv could speed up, remove orphaned dependencies on
uninstall
, and win me back.
Wouldn't that be romantic?
Well, Poetry has kept it up, and it delivered every feature on my wishlist. With the ergonomic improvements since my last comparison, Poetry has become my tool of choice for any new projects, whether they're applications or packages.
That isn't to say that everyone should move on from Pipenv. This blog still uses Pipenv because it does the trick and I haven't had enough of a reason to change to Poetry to bother. Plus, the Python Heroku buildpack still doesn't support Poetry, so Pipenv may still be a better fit for anyone with a buildpack-based deployment (e.g., Heroku, Dokku, CapRover).
To the majority of most users, however, I recommend Poetry for its active development and broader applicability as both a dependency manager and package manager.
In short: Pipenv vs Poetry? Pick Poetry.