Scriv on Test & Code

Thursday 25 May 2023

Brian Okken and I recorded a podcast some time ago (September 2022) about my scriv project and other adjacent topics: Avoid merge conflicts on your CHANGELOG with “scriv”.

We talked about:

  • How scriv works
  • The importance of keeping information in git (not just GitHub)
  • The difference between commits and a changelog
  • The value of hand-written changelogs
  • Other projects of mine: dinghy, cog, coverage
  • Boston Python
  • Versioning schemes: semver, calver, randver(!?)

Because this was recorded in September, a few things are slightly out of date. I mention that Python 3.11 is coming out in October, but that meant last October, not this year’s. When Brian asks me what else is going on, I don’t mention the PyCon 2023 keynote, because I hadn’t even gotten the invitation back then.

It’s always a good time chatting with Brian. Give it a listen.

PyCon 2023 keynote

Thursday 4 May 2023

A few weeks ago, I had the pleasure of delivering the opening keynote at PyCon 2023. I’ve put up a text-and-slides version of the presentation: People: The API User’s Guide. The video is not yet available, but it will be soon.

When Mariatta invited me to do the keynote in January, I accepted, then knew that I would have a hard time thinking about anything else for the three months until the conference. My talk prep is always like this: I worry endlessly over tiny details. The sentences I’m planning to say become earworms in my head. I fiddle with the CSS of my HTML-based slides.

This period of preparation is stressful: I alternate between excitement at how great it’s going to be, and anxiety because I have nothing useful to say, or the flow is terrible and disjoint. When I express my worries, my wife says, “your talks always go great,” and I respond, “but only because I worry about them!”

In truth, I had started thinking about the ideas in this keynote about five years ago. Literally some of the bubble chats on the slides existed in that form in 2018. Over the years, I considered different ways of presenting them. When the keynote invitation came, I knew I’d be talking about the People API User’s Guide.

One of the most fun parts of preparing was working on the cartoons with my son Ben. I’m constantly amazed at his ability to craft a line that looks simple but expresses complex subtleties of emotion. He’s a freelance illustrator, you should hire him!

Giving the talk was exhilarating, and I talked to so many people afterward who liked it. PyCon is the kind of technical conference that welcomes non-technical talks like this.

Afterward, it’s hard not to go over what I did on stage that was different than planned. I ad-libbed a lot, some of it good, some of it meh. There were things I intended to say that I forgot. But that is all in the past now. Other types of performers have chances to do the same show multiple times, and so can hone their performance. But I don’t know how they survive it: do they have lines running through their head all the time? How do they ever set it aside?

Once something like this is done, it’s difficult to predict where it will go. In my experience, some talks reverberate and get recommended to others long after they are done. Others seem good in the moment, but don’t echo much. Only time will tell. Whatever happens, it was definitely a high-point for me.

PyCon 2023

Wednesday 26 April 2023

I’m on the plane home from PyCon 2023 in Salt Lake City, thinking about the last week. PyCon recaps often say the same things, and this is no exception, but PyCon is an intense experience that should be noted. My notes here feel a bit disjointed, but I’m trying to just relate some impressions, not craft a narrative.

In some ways, this was the expected PyCon experience: lots of friends old and new, lots of good conversations, both technical and personal.

But this year was also different because I delivered the opening keynote. I talked about How to Talk to People, which may seem like an odd keynote topic for a technical conference, but that’s the way PyCon is: there’s a lot of discussion of people and the interactions among them. (The video of the keynote isn’t available yet, I’ll post it when it is.)

The Python community is not perfect. As with any large community, there is conflict and drama, and not everyone stays. But the Python community is famous for being more welcoming and inclusive than you’d expect for a technical community.

PyCon is the kind of technical conference that welcomes things like a keynote about How To Talk To People. I had a lot of positive feedback, it was extremely gratifying.

But even beside being a keynote speaker, there are dozens of unexpected but authentic connections happening. A woman approached me and told me that in 2018, I saw her at PyCon and she seemed at loose ends, so I invited her to come to dinner with our group. She said that now at every PyCon she remembers that moment, because it was a tangible action that pulled her in and visibly welcomed her as a specific individual.

Similarly, I had a chat with a well-known member of the community, a person with a broad and visible presence in the Python world beyond the conference. They said that they remember the time at a previous PyCon they were walking down the hall, and I was sitting on a bench, and I called out to them by name, “as if we were best friends,” as they put it. Again, that was a moment they felt they moved from an outer ring more toward the center.

Of course, the only reason I knew who this person was back then was because they had already been gaining visibility, but it’s easy for people to underestimate the effect they are having on others. People don’t realize that writing blog posts, or making podcasts, or publishing libraries is a way to be known in the community. It may seem like a small activity when you are by yourself making it or writing it, but people see it, and people start to know you.

In an open source world like Python, you don’t need a corporate marketing department megaphone to make a difference. You don’t need to work at one of the big sponsors to be “big.” If you do good work, people will start to know you.

This year Mariatta was the chair of the conference, and she brought an intense authenticity to the plenaries. Each keynote was introduced with a personal story about why she wanted to give that person the stage. She said I wouldn’t remember, and I didn’t, that she and I first talked in the PyLadies Slack workspace when she was anxious before her first presentation, and I told her it was a good talk.

I’m telling these stories about reaching out to people not to pat myself on the back, but to show that a small kindness to someone, even a “nobody,” can have unexpected ripples across years. I said a small thing once to Mariatta and it helped her take a first step that eventually led to her being a Python core contributor and the chair of PyCon. You never know where things will lead.

For me that first interaction with Mariatta led to a keynote speech, and an ice cream selfie:

Me and Mariatta with ice cream

I haven’t been to a PyCon since 2018. The vibe is the same: people working together and collaborating. I talked to some attendees who contrasted it to other tech conferences which felt more like a gathering of competitors. They commented that even the big sponsors of PyCon (Meta, Google, Microsoft, etc.) didn’t seem at odds with each other.

One thing that I kept noticing all weekend was people who were missing. I kept remembering someone that I thought of as a fixture at PyCon who wasn’t there. I don’t know if it’s because I haven’t been in five years, or if lingering pandemic caution is keeping people home, or if it’s just the usual conflicts with the rest of life.

I had chances to hang out with specific people I wanted to meet, and also conversations with people I didn’t know until we started talking. Some non-technical topics included the war in Ukraine, Christianity, cancer, as well as less intense topics like comparative cuisine. It turns out people from Brazil have never seen a tater tot (“is this made of rice?”).

One off-topic tradition continued: juggling open spaces. We had one official one (posted on the board) Saturday, and another impromptu one during the sprints on Monday. It’s a good ice-breaker to meet people, and it’s fun to see both hidden talents and brave newbs trying it out.

I definitely should have had some Sleepy Snake merch, because people asked me about my t-shirt a number of times. A missed marketing opportunity!

One dynamic unique to our tail-of-the-pandemic times: I met two of my Boston Python co-organizers in person for the first time in Salt Lake. Emily Charles and Glenn Lehman both joined Boston Python during the pandemic and became organizers, and I had never met them face-to-face before. We’ve had plenty of good interaction over Zoom, so it was like meeting old friends for the first time. But again, in our online open source world, that happens a lot. At least one person said to me, “good to meet you; have we met before?”

One sprint day on Monday had a recurring dynamic that I always forget. I think of coverage.py as hard to get started with. But people show up willing to at least consider the rock face with me, and we make a dent in some things. Even if the contributions are small, at the very least it’s a chance to meet some new people and have some nerd discussions along the way. Small contributions are helpful! Sitting with people interested in the project gives me a chance to see it through new eyes, and have some energy reflected back to me, recharging me to do some work on it myself. Thanks to the people who joined me even when I disappeared for a few hours for ice cream and juggling!

A challenging aspect of PyCon is to make the most of your time there. Another challenge is to somehow keep the energy going as you re-enter your regular world, filled with other concerns and activities. If I come up with any clever approaches, I’ll let you know.

Beginner sprint on coverage.py

Tuesday 21 March 2023

I participated in the PyCascades sprint day yesterday, offering up coverage.py as a project. I was pretty sure it wasn’t beginner-friendly, but the sprint was useful because it pointed out specific ways that it was not, and we fixed some of them.

The sprint was all-remote, and we had about a half-dozen people online. They dug in energetically, trying to set up a development environment. The first thing we realized together was that the Contributing page needed updating: it didn’t mention making a GitHub fork, it over-emphasized virtualenvs without explaining them, and it was too focused on specific versions of Python.

Phebe Polk fixed that with one of the merged pull requests for the day: #1591 Update contribution instructions.

Another confusing point was that people might come to the coverage.py README page with two different goals: people wanting to use the tool, and people wanting to contribute to the tool. This may seem like a small point, but any friction is worth eliminating, and it was done with a small pull request by Kassandra Keeton.

Separately, Neil Pilgrim saw I had both a setup.cfg and pyproject.toml, so he moved my pytest settings from the old-style file to the new: build: Migrate pytest configuration to pyproject.toml.

One other problem people encountered was due to my docs build including sphinxcontrib.spelling. That’s there for spell checking, but it relies on an OS-native installation of enchant that most new contributors won’t have. It was a simple matter to use the extension only when spell checking, unblocking the default execution of tox environments, and removing one more speed bump.

My biggest learning through this process was about hashed pins in my dependency files. They are a security feature, but get in the way when people install on different operating systems or versions of Python. I’m convinced now they are a bad idea for coverage.py. I haven’t made any changes, but I ranted in an issue about it. There are more details there if you are interested.

I’m still eager to hear about people’s experience with starting to use coverage.py or contribute to it. It’s not an easy project to make changes to, but at least we can make it easier to get to the point of looking at the code.

The sprint didn’t go exactly in the direction I thought it would, but I enjoyed talking over these issues with people, hanging out with them, and fixing some friction points along the way.

Watchgha

Monday 13 March 2023

I wrote a simple thing to watch the progress of GitHub Actions: watchgha.

I started by using gh run list, and tailoring the output, but that required running the command obsessively to see the changes. Then I tried gh run watch, but I didn’t like the way it worked. You had to pick one action to watch, but my branch has two actions that run automatically, and I need to know when both are done. Plus, it lists all of the steps, which makes my complex action matrix fill more than a screen, so I can’t even see the progress.

So I wrote my own. It buckets together the start times of the runs to present them as a coherent run triggered by a single event. It keeps showing runs as long as they have a new action to show. It presents the steps in a compact form, and collapses jobs and runs once they succeed.

Give it a try and let me know if it works for you.

Screen shot of watching the progress of GitHub Actions

Late initialization, reconsidered

Tuesday 14 February 2023

A few days ago I posted Late initialization with mypy, and people gave me feedback, and I realized they were right. The placebo solution described there is clever, but too clever. It circumvents the value of static type checking.

The comments on the blog post were telling me this, but what helped most was a Mastodon thread with Glyph, especially when he said:

I am using “correct” to say “type-time semantics consistently matching runtime semantics.”

The placebo works to say “there’s always a thing,” but it’s not a real thing. A more useful and clearer solution is to admit that sometimes there isn’t a thing, and to be explicit about that.

I actually took a slightly middle-ground approach. Some of the “sometimes” attributes already had null implementations I could use, but I removed all of the explicit “Placebo” classes.

Older: