Aside: I let my need to stop the reading journal project for a while make me pause my blog posting as well. That was unintentional. I still plan to post 100 posts this year even if that series needs to wait.

My first open source contributions are old enough to have a beer in the US by now, as is my first python code. But I’ve always found it awkward and disruptive to patch, and contribute a patch back to a library that I’m using in a python project, especially when I’m working with virtualenv or similar setups. With poetry and git, I’ve finally settled on one I like, and I’m capturing it here for easy reference next time.

Poetry is, by quite some distance, my favorite way to manage python dependencies these days. But for modifying open source dependencies and contributing changes back, my workflow has always been awkward. I’ve often resorted to temporarily “vendoring” a project, or to awkward virtual environment manipulations. Here’s an easier way.

It’s a familiar situation. You’re trying to get something done, and you see a library that will help. After reviewing the documentation, you run poetry add foo to take foo as a dependency and use it in your project. You happily continue using it and solving your problem until you hit a bug, a missing feature you need, an annoying typo in a method name that you just can’t stand, or something. Now you want to put together a fix, and the source is available, so it should be easy.

When you ran poetry add foo, that put a line in your pyproject.toml file like this:

foo = "^5.1.1"

If copy the want to use a package in a git remote, poetry makes that relatively easy:

foo = { git = "ssh://git@github.com/myorganization/myprivaterepo.git", branch = "my_fix_for_bar" }

And that’s good enough for simple fixes, but sometimes in order to put together a good patchset, you need to iterate a bit in ways that get awkward if you have to push to a remote in order to test your ideas out.

For those cases, the easiest approach is to get the source into your own git repo, clone that locally, create a branch, and work there. You can then update your pyproject.toml to read:

foo = {path = "/local/path/to/checked/out/foo", develop = true}

and run pip remove foo from a poetry shell followed by poetry install.

Your live changes will be testable from your real project without bouncing them off a remote, and you can commit, push, and “pull request”, “merge request”, “git-send-email”, or contribute back however works best for the upstream.


I’m trying on Kev Quirk’s “100 Days To Offload” idea. You can see details and join yourself by visiting 100daystooffload.com.

This is day 9.