Don’t let the title scare you; I’m not going anywhere in particular. But the last ~year has seen a couple of big changes that I wanted to briefly share.

A personal note

My mother, with whom I was very close, passed away somewhat suddenly last July (also my birthday month, now ruined forever). She’d been diagnosed with surprise lung cancer the preceding December – despite a lifetime of exactly zero risk factors for lung cancer – and had been managing it during the spring with some new anti-cancer meds.

Unfortunately, since the cancer had already metastasized by the time it was detected, she was on both borrowed time and blood thinners; the blood thinners had to be switched around a few times to support a relapse-related biopsy; and something about that switching (or perhaps simple bad luck) triggered a significant stroke which put her in the hospital. She was gone a few days later.

As you may imagine, this experience has added to an already near-terminal pile of stress and sadness from the ongoing Situations™ that we all live under lately, and has rather lessened my desire to have Internet randos pissing & moaning on my open-source issue trackers.

So if I’m shorter than usual (notice to some of you: that’s your one freebie for the day) or you find a pointless complaint Github comment unceremoniously deleted…this is one reason why.

If you’ve got a mom and are on good terms with her: please give her a call/hug. You never know when she’ll be taken away from you.

A Python note

Nearly two years ago, I announced my intention to drop Python 2 support across all my projects. As of a week ago, this effort is complete!


Yes! The last to get updated were my “big three” – Invoke, Paramiko, and Fabric – which got major revision bumps to denote their removal of Python 2 and Python <3.6 support (along with other changes) over the last couple weeks.

Considering my employer’s Python environments are also generally Python 3-only (minus a few holdouts which I am not personally responsible for) this means I am now privileged to assume support for things like f-strings. It feels good!

If I’d held out another 10-11 months, I could have claimed to be writing Python 2 for a full 20 years – thankfully, I resisted the urge. But yes: goodbye, Python 2; so long, and thanks for all the fish!

Python 3.6 is EOL, Jeff!

I appreciate you looking out for my well-being, but I am in fact capable of reading!

Less snarkily / more usefully: 3.6 was a useful cutoff today for a number of factors, but I’m not planning to repeat my mistakes to a high degree. I’d guess that I will end up trailing the official Python EOL dates by a couple of years or so, at most.

Factors pressuring me to drop Python versions:

  • Requiring custom code to handle old versions. Now that everything <3.6 is out the window, this is nonexistent or very minimal.
  • Dependencies which I or my users really want newer versions of for feature/security reasons, whose newer versions break on older Pythons. So far, there aren’t any of these on my radar besides a few which emit deprecation warnings on 3.6. Easily muted by those who care to.
  • Irritatingly large CI test matrixes. Already, 3.6-3.11 is 6 cells minimum, though thankfully CircleCI makes it pretty easy to avoid running a full dot-product in situations where I have additional matrix dimensions. (E.g. if I care to do things like test the oldest and newest versions of a crucial dependency, I might only do that on the oldest and newest Python versions too.)
  • Ridicule from other OSS maintainers. Thankfully, most such offenders are unreasonably tall and thus their ridicule just flies right over my head!

Factors pressuring me to keep Python versions around: eh, there’s clearly still a LOT of folks on operating systems whose python3 -V spits out 3.6.*. No, they can’t all build their own Python, use pyenv, use containers, or etc.

Anyway - where from here?

See my roadmap as usual, but tl;dr – features! at long last! I’m unreasonably excited to write a much less naive/creaky authentication flow for Paramiko, for example, and to add wholly new functionality to Fabric/Invoke.

Also: presumably shorter time periods between major revisions. Not short periods, and I plan to experiment more with “maybe serve a new API or implementation alongside the old one for a while???". But also not being too afraid of it when it makes sense. Smaller backwards incompatible versions are much easier for users to swallow than the really big ones.

Overall, my earnest hope is that dropping the Python 2 albatross from my neck will invigorate me a bit more going forwards – at least when the still-frequent thoughts of my mom, and the preexisting condition of my burnout, aren’t getting in the way.

Thanks for reading!