Python Bytes - #470 A Jolting Episode
Episode Date: February 23, 2026Topics covered in this episode: Better Python tests with inline-snapshot jolt Battery intelligence for your laptop Markdown code formatting with ruff act - run your GitHub actions locally Extras Jo...ke Watch on YouTube About the show Sponsored by us! Support our work through: Our courses at Talk Python Training The Complete pytest Course Patreon Supporters Connect with the hosts Michael: @mkennedy@fosstodon.org / @mkennedy.codes (bsky) Brian: @brianokken@fosstodon.org / @brianokken.bsky.social Show: @pythonbytes@fosstodon.org / @pythonbytes.fm (bsky) Join us on YouTube at pythonbytes.fm/live to be part of the audience. Usually Monday at 11am PT. Older video versions available there too. Finally, if you want an artisanal, hand-crafted digest of every week of the show notes in email form? Add your name and email to our friends of the show list, we'll never share it. Brian #1: Better Python tests with inline-snapshot Alex Hall, on Pydantic blog Great for testing complex data structures Allows you to write a test like this: from inline_snapshot import snapshot def test_user_creation(): user = create_user(id=123, name="test_user") assert user.dict() == snapshot({}) Then run pytest --inline-snapshot=fix And the library updates the test source code to look like this: def test_user_creation(): user = create_user(id=123, name="test_user") assert user.dict() == snapshot({ "id": 123, "name": "test_user", "status": "active" }) Now, when you run the code without “fix” the collected data is used for comparison Awesome to be able to visually inspect the test data right there in the test code. Projects mentioned inline-snapshot pytest-examples syrupy dirty-equals executing Michael #2: jolt Battery intelligence for your laptop Support for both macOS and Linux Battery Status — Charge percentage, time remaining, health, and cycle count Power Monitoring — System power draw with CPU/GPU breakdown Process Tracking — Processes sorted by energy impact with color-coded severity Historical Graphs — Track battery and power trends over time Themes — 10+ built-in themes with dark/light auto-detection Background Daemon — Collect historical data even when the TUI isn't running Process Management — Kill energy-hungry processes directly Brian #3: Markdown code formatting with ruff Suggested by Matthias Schoettle ruff can now format code within markdown files Will format valid Python code in code blocks marked with python, py, python3 or py3. Also recognizes pyi as Python type stub files. Includes the ability to turn off formatting with comment [HTML_REMOVED] , [HTML_REMOVED] blocks. Requires preview mode [tool.ruff.lint] preview = true Michael #4: act - run your GitHub actions locally Run your GitHub Actions locally! Why would you want to do this? Two reasons: Fast Feedback - Rather than having to commit/push every time you want to test out the changes you are making to your .github/workflows/ files (or for any changes to embedded GitHub actions), you can use act to run the actions locally. The environment variables and filesystem are all configured to match what GitHub provides. Local Task Runner - I love make. However, I also hate repeating myself. With act, you can use the GitHub Actions defined in your .github/workflows/ to replace your Makefile! When you run act it reads in your GitHub Actions from .github/workflows/ and determines the set of actions that need to be run. Uses the Docker API to either pull or build the necessary images, as defined in your workflow files and finally determines the execution path based on the dependencies that were defined. Once it has the execution path, it then uses the Docker API to run containers for each action based on the images prepared earlier. The environment variables and filesystem are all configured to match what GitHub provides. Extras Michael: Winter is coming: Frozendict accepted Django ORM stand-alone Command Book app announcement post Joke: Plug ‘n Paste
Transcript
Discussion (0)
Hello and welcome to Python Bites, where we deliver Python news and headlines directly to your earbuds.
This is, what episode?
Episode 470.
I know what we're doing.
And it is Monday, February 23rd, 2026.
I'm Michael Kennedy.
And I'm Brian Ockin.
This episode is brought to you by us.
We have many interesting things available or in the works that we're going to be announcing.
I know, Brian, you're working on your lean TDD book.
I just released Command Book, which I, I'm a lot.
Ironically, it's not actually a book.
But other things,
and obviously our courses and so on.
So seriously,
we put this stuff out here
because we think it's a perfect compliment
to the podcast,
and we'd really love if you'd consider
just part of your learning,
reading, and so on.
Also, consider signing up to the newsletter.
We've got a bunch of people enjoying the newsletter.
We put a lot of effort into it
to generate extra info,
background info,
more links,
not just,
hey, we're emailing our show notes out.
Isn't that inventive?
Now, we're doing extra.
And Brian is spearheading that.
So thank you for doing that, Brian.
And, yeah, connect with us on the social.
Subscribe here on YouTube if you're interested in catching the live show.
Just go Python by set of film slash live, click the link, crush the bell.
You know, so that way you actually get a pop-up when we're streaming live like we are right now.
And with that, I think I want to talk about inline snapshots.
What do you think, Brian?
Yeah, sure.
Let's zoom in.
I don't know.
Sure.
Zoom somehow.
Somehow, somehow.
So I'm going to cover, and this is a fun article, actually, from the Pidentic blog, from Alex Hall.
And the article is Better Python Test with Inline Snapshot.
And actually, it's that, but it's also kind of a peek at how Pidentic is doing some of their testing.
And, you know, it would be, it's not a bad idea to try to emulate Pidantic because they've been doing great.
So anyway, the, let's dive into what they're talking about here.
The problem is the maintaining test data for, for complex data structures and how you compare.
So their example is like create a user with an ID of 23 and or 120, anyway, test a name and an ID.
And then checking to make sure that it's really is, you know, getting the data, the object and
validating that it's correct, that some action happened.
This is all cool and all, but it's not really, it's hard to fill that in.
And if you have tests like that all over the place, it's hard to make sure that they're
up to date and everything.
So there's a lot of ways that people have done, attack this problem before.
Like they give a shout out to Syrupe, which is a cool project also.
And so one of the issues, okay, so one of the issues is, let's see you've got a bunch
of stuff. You know these systems
working right now. This is kind of how
the workflow is you know it's working or
because of other testing or manual testing
or whatever. And you want to like just
save a bunch of, have some
tests and save what the output
is and then test against that.
Like a known
input and
you know it's working. So grab the output
and compare the two. And that's the
sort of the model. And with Syrupe,
it saves that in an external
file. But with Inline Snapshot,
it saves it right in your test.
So I'm going to take a look.
You start out with like an empty snapshot with an empty bracket.
And then you run the test with inline snapshot equals fix.
So it's like fixing the snapshot or fixing them in place.
And then it actually goes out and changes your test and fills in that little template bracket with data that you can compare with whatever you want.
And that's actually pretty awesome.
It just like turns the user like some data structure into a dictionary or whatever, take a data structure, snapshot that.
And then you can run with it.
There's a few reasons why I kind of really love this.
One of the things is just maintenance.
If you're like before and after a big change, refactoring, you can like set some of these up and then like refactor and then go back and make sure everything's, you didn't intend to change anything.
You want to make sure things change.
And then sometimes you do want to change like lots of the data structure.
And then you can like having this right in line with your test,
you can have that like go through a code review and manually inspect the test and say,
yes, this is actually what I want it to look like.
The danger is if you don't manually inspect, then you're not going to,
you're just believing whatever's there.
Then your test just become a change detector test and nothing else.
There's, you know, sometimes there's a place for that.
So anyway, a great article about snapshot testing.
But I also do want to shout out to a lot of the other tools that they bring up in this article.
So I'm going to go through some of them.
There's the Pytest examples, which is the plug-in that they're talking about with this inline examples.
There is in-lides, wait, no, this is another tool.
So Pytest Examples is another tool that they've got.
And that's pretty cool.
The inline snapshot is this tool that we're talking about.
And then there's syrupy, which isn't a bad tool.
And if that's better for your workflow, take a look at that as well.
And that's very popular.
And then there's a dirty equals, which is a fun.
I should probably cover this at some other point if I haven't already.
A fun almost equal sort of a thing.
So you can do things like, is the number positive?
And there's a whole bunch of other extra things around.
comparisons that are not exact comparisons that are kind of fun.
And then a shout out to a thing called executing,
which is being able to,
it says a mini package that lets you get information about what frame is,
what the frame is currently doing.
So about their current execution frame in Python,
which is,
I've never had a need for that,
but it's kind of interesting.
So anyway,
shout out to that,
great article.
Lots of tools.
That might be interesting for like low effort logging and stuff,
you know,
enhancing test output or just logging.
in general is like, I got an error.
I want to just say, well, what parameters were supplied to this function and who called
it, maybe something like that, just automatically add that to the test output or something
like that.
Yeah, there might be some cool fun things for logging the execution frame.
Yeah, yeah.
Nice.
That's a bunch of cool tools.
I love the idea, too.
I like this.
Now, let's jump over here.
I want to talk, I want to shock you, Brian, with this.
I want to talk about jolt.
Okay.
So Jolt is a toee, a pretty sweet toy actually, which is battery intelligence for your laptop.
Okay, so this is not really a Python tool, but it's certainly a tool that Python people could love.
It's kind of a developer-oriented thing, right?
So it says battery intelligence for your laptop, real-time power monitoring, process, energy tracking,
battery health insights, all in your terminal, and it works on MacOS and Linux.
Sorry, Windows folks.
You may be able to do this in Windows subsystem for Linux, though.
I wouldn't bet on it.
I'm not sure.
So it's easy.
Just brew install it or whatever, however you like.
And it's,
I've got kind of a picture here,
but honestly,
the picture's not as inspiring.
It's maybe the reality.
So before I tell you more,
let me switch over to my laptop,
which actually has it running here.
And notice,
it's got a huge green bar,
which is how much battery I got left.
But it also tells you,
I'm on battery.
It's been on battery for three hours and 27 minutes,
and it has three hours and 40 minutes left.
Yes, it's a MacBook Air.
It should last longer.
but it's doing a lot of stuff, as you'll see.
It gives you stuff about the health.
Like, how many times has it been charged?
176.
What is the temperature?
What is its current energy draw,
or how much energy actually contained in it?
And it's health.
It shows you power of your machine.
So right now my laptop is using 8.8 watts of power.
The CPU is 1.5.
The GPU is basically nothing.
I bet you it's mostly screen if I had to guess.
And then it gives you all your processes.
So you can see the Vivaldi is the most significant impact here
at like 57% CPU,
because I have it screen sharing back.
That's why we can look at it, right?
It's got Claude.
It's got Firefox.
Port Killer, which I talked about.
I had Port Killer open last night to do a cloud flare tunnel for a project and just didn't
shut it down.
And it's like parsing the state of the system a lot to get its things, which is cool.
And it's got this like moving graph at the bottom of your energy consumption temperature.
You can like toggle through these things.
How do I can like toggle to like battery percentage over time, watt over time?
There's like all these things you can do.
What do you think?
I think this is great.
I'm going to go install this on my laptop right away.
Yeah, it's just brew install jolt-ish.
Let me actually read it so it doesn't give you something terrible
if you were to actually do that.
You know what I mean?
Yeah.
It is you got to do a tap.
Whatever it is you tap.
You got to do brew install Jordan D slash tap slash jolt, not just straight jolt.
Anyway, I think it's pretty neat.
So, yeah, there it is.
And apparently it can work in Windows.
We've got, somebody said, just installed.
Pat.
Pat Decker just installed it under WSL and Windows and it doesn't work.
Pat, thank you for the real-time follow up.
That's fantastic.
And to get it installed, use curl install.
Sure.
Yeah, I probably would have done that on Linux as well.
Yeah, so this looks great.
Just as like a what is my system doing,
even though it's kind of centered around battery, it's pretty cool actually.
Yeah, and like with laptops, that's most,
what you care about is like, how is this impacting my battery?
Yeah, exactly, exactly.
Anyway, people can check that out.
I thought it's a little bit of just a tool rather than a library, but I thought it was
fun.
Yeah, nice.
It's not rough.
It wasn't that rough anyway.
It's not that rough.
Yeah, so let's talk about rough.
Nice, nice transition there.
So we, of course, have talked about rough several times and lots of other things around it.
But we're going to talk about it a little bit more because Matias,
And sorry, Matisse, I'm not going to try to pronounce your last name.
So a listener sent us in, said, hey, you should check this out.
Because now you can format, because if you do rough check for it's linting, but it does a lot of formatting as well.
Or it can.
But you can also do rough format.
And so both of those things, you can now point those at, I think it's for both of them, can point it at markdown files.
So, yes.
Yes.
And so for, I mean, it's not just documentation because I'm like we're writing books and stuff like that with Markdown.
So I'm definitely going to point this at some some book, book types code and blogs, of course, lots of blog, which we're written in Markdown.
Anyway, so some of the, some of the cool features of this is that you can, you can also turn it off for parts of it.
So if there's like, if you want to show it, but an example of bad code.
You probably don't want rough to reformat that for you.
So there's ways to turn it off.
That's interesting.
Don't do this.
And it gets fixed.
You're like, no.
Yeah.
So there's some tricks around it, though.
So for turning it off, there's format off and on.
And apparently there's like some other, there's something else that you could turn it off and on.
But like, if you're in the habit of just doing code blocks with just three ticks, it's not going to cut it.
Because it's looking for what, it's looking for those.
what are those identifiers?
I don't know what you call that,
the little thing after the three texts
to tell you what language.
Yeah, whatever the language designation is.
Yes, but there's a few.
They do PY, Python, Python 3,
PY3.
Interesting.
It probably does that because it needs to know
what language it is to decide how to format it.
Yeah.
It shouldn't try to format like, you know,
Rust as if it's Python, I guess.
Yeah, exactly.
Also, these semicolins are unnecessary.
took them away. And the way, the way rough works is, uh, is through, uh, pulling it into the
abstract abstract syntax tree and outputting it again. So it has to actually be valid Python. If you
have invalid Python that won't parse, it's not going to, it's not going to figure that out. Um,
so, um, it won't, I don't think it errors. It just doesn't do those. So if you're, okay,
anyway, and there's a preview mode. That's kind of neat that you can, you can say, hey, what would
you do for this.
But frankly, I would just have it and get and let it go.
And then you can do the diffs to see what it did.
So cool, cool thing there.
And I'm pretty excited about that.
One of the interesting bits is that it also does P-Y-I files.
So it will format what are those type type files.
Yeah.
So just a fun little tool.
The caveat is this feature is only available in
preview mode, and I didn't know what that meant, so I had to look it up. So preview mode
means, it doesn't mean you have to install anything different, but you have to enable preview
mode by setting in one of your settings files. You have to say preview. It was true.
Oh, interesting, like your Rough Tomol or Pyproject.comal or.
Yeah, or you can pass dash-dash preview in the command line, apparently. So, okay, to get that.
Or you could download the source and recompile rough and then make that the default.
Sure.
You're just kidding.
Yeah.
There's a thousand ways to skin the cat as it goes.
Please don't skin my cat.
As morbid as that statement may be, there are many ways to do it.
It's terrible.
All right.
So let's go to the cloud.
Do the cloud.
So I want to talk about GitHub actions.
So here's the deal.
I have some GitHub actions.
Maybe they format my markdown.
Maybe they run my test.
Maybe they check against other things.
Maybe they integrate with.
Who knows what, right?
There's a ton of GitHub actions.
So how do you do that?
Well, maybe you create a few.
feature branch and you commit and then you wait for your project to not be busy and the GitHub
runner to pick it up and run it. Then you pay your fee for the GitHub runner to run your thing
while you're waiting your computer's idle. You could use Jolt to see it like that. It's not
do anything. So there's this thing I found called act. Neck. Necktose slash act. So neck
toast is the person create. It's a little bit popular. 69,000 GitHub stores or 2,000 forks.
Wow. Have I hadn't heard of it? Have you heard of this? I think. It rings a bell.
Okay. Maybe we even cover it like 10 years ago. Anyway, so the idea is you can run your GitHub actions locally on your computer using nearly the same infrastructure. So you don't have to pay for them. You don't have to wait on them. You don't have to. One of the problems is you've got to make a commit. Like maybe you're not ready to commit. You're like, I actually want to see what the GitHub action result would be before I do commit it. You know what I mean? Yeah. Yeah. So what you do is that this thing reads your GitHub workflow and your environment variables and all that based on what you have set there.
And then it uses a local hash runner.
So basically sets up a Docker thing to run.
Right.
So if I scroll down here a little bit, says Rezo,
set it out.
Then it uses the Gitter, the Docker API to pull the necessary image
to find any workflow files.
You can see the little thing running right down below.
And then sets up the execution paths.
Then it runs each container based on all the stuff
that you have set in your action, right?
So it just basically runs here and off it goes.
You can see like it gets you little like reports
on how that went and so on.
Did they pass and so on?
So I think this is pretty cool.
Yeah, I think it's cool too.
I wonder if there's something like this for GitLab.
GetLab Act.
I wonder how similar the actions are.
I've not set up GitHub actions very much on GitHub and not at all on GitLab.
And so maybe if they're basically file compatible is good enough because this doesn't actually
use anything about GitHub either.
It just says what are the what are the Docker images and
commands and stuff like that.
So it may work.
Yeah.
So this is definitely cool.
It is kind of a pain to try to debug GitHub actions,
figure out what's going on.
So yeah, definitely check this out.
Awesome.
So what is the story on the extras?
Do we have extras?
I just have one, and I didn't before we started the show.
I know.
I thought you had no extras, but now I'm hearing you have extras.
There were none in the notes.
So I'll just do a quick one.
So you brought up the book, Lean TDD at the beginning of the one of the books.
Yeah, one that's actually a book.
So I had started, yeah, so Lean TDD, I just want to give a status update.
Not much has happened.
There's a lot happening, but it's all up here.
So one of the reasons why I released it, so the first draft is done and it's out, and it's
actually not really a first draft.
It's probably second or third that's released.
but I'm reading it now and I definitely want to change the first couple chapters.
And it's in, yeah, I know it's a dry subject.
But if I'm having trouble reading it because it's a little dry, now I should be selling it more of like, no, it's super exciting.
No, it's, it needs to be more exciting than it is because I am excited about the topic.
But the initial start of it is is a little rough to get started in the book.
So I do want to like make it a little more exciting.
And so there's there's been a lot of notes, but it's all been on paper.
So I am still working on it.
It doesn't look like that.
If you, if you've grabbed a copy, thank you.
It's helped motivate me.
I've had quite a few people grab copies.
And things are moving.
It just doesn't look like it from the outside.
So anyway.
And Mike, Mike the man says, you're going to write Lean BDD?
well, behavior-driven development and acceptance test-driven development are covered in the book.
I kind of lump those together as well.
And if you're, Mike, if you're a BDD kind of person, I'd love to talk with you more about it.
That's my extra, is not much news.
Okay.
Yeah, very, very cool.
Neat.
I know how this goes.
You're like, it's good.
They're like, no, no, no, I've got to do this again.
I have this project that rewrote it three times already.
It's driving me crazy.
But I think it's good now.
It's finally third time.
All right, Savannah Ostrowski says, stoked to share that the steering counsel has accepted PEP 814.
What is PEP 814, you might ask?
Well, that means winter is coming.
Winter is coming.
Why?
Well, because PEP 814 is Frozen Dict.
Frozen Dict.
That was a bad joke.
No, it was so bad it was good, I think.
No, anyway.
The idea is that we've got frozen set.
we've got other types of frozen items containers and data structures but we didn't have frozen
dictionary so the idea is it's a read only right so you create a thing you want to be able to
return it from a function or share it and have an absolute guarantee that people are not changing
it right adding or moving items keys and so on i don't think that really applies to stuff referenced in
there so if you put a list as a value and then you go and like get the point of the list you probably can
still change it, but, you know, like, I guess it depends.
If you fill it with only other frozen stuff, it's frozen all the way down.
But it's really cool because it allows better concurrency.
This is something we're going to be paying more attention to in the future as Python T starts
to, you know, like, well, I hate all this locking we have to do in these race conditions.
Like, well, if you can't change it, you don't need to lock on it, you know what I mean?
So that's very cool.
I don't want to add any more than that, but it will be in Python 315.
Okay.
Now in the audience, Kiva Burb says that's, oh, that is X, X,
We'll definitely be using this all the time for default params.
Oh, you know what?
That is a really interesting idea for default prams.
Yes.
I hadn't really considered it there.
Yes.
Yeah.
Okay.
And then a little bit of Django.
Also, please wear pants.
I guess it's just, I don't know what that references, but.
I don't either.
Okay.
So Jeff Triplett posted on Massadon in response to Apollo Melichori saying I just published
the first article in a new series of my blog, Django ORM standalone.
And Jeff and Mario and I were just talking about this, like, that same week.
And, like, would it be cool if you could use the Django ORM without Django, right?
So maybe I've got a Jango project.
Would I also have a little library?
I just want to run and also talk to the database.
And I don't want to have a separate data access layer.
I just want to have my models and a script.
And I don't care about the web side of things.
So basically, that's Django standalone, right?
Because any large project is going to have to start to have, like, different flavors and
utilities and aspects, maybe daimons.
They don't all have to run the web app, you know?
They all shouldn't run the web app.
So anyway, give it a little shout out to this article here.
Yeah, or even, like, if you want to do fast API plus using the Django Orm.
Yeah, exactly.
If you want to use the ORM on another web for it, like maybe you really love the Django Orim,
but you also love Flask.
Well, here you go.
Let's do it.
That's exciting.
Okay.
I talked about Command Book, this sort of long-running, this.
this home for long-running terminal commands?
Like commands I want to run for three hours.
Like start up the web server and the Damon and the tail and just leave it.
And if I accidentally close my terminal, I don't want them to go away.
I don't want cluttering up my terminal, right?
Fun little app.
There's a free version, free aspect and paid aspect, personal license, and beyond.
But I finally got around to writing up the motivation.
Like, why does this exist?
Here's how it works.
Here's why I created it and so on.
So I link to the blog post.
It says a five-minute read according to my own website.
Oh, you should do that.
Plus like a little how-to guide and everything and make a book out of it.
It could be a command book book.
A command book book.
Or command book squared.
I mean, let's go.
How do you want to do this?
Yeah.
I don't want to do this.
All right.
I think we're ready for our joke.
And this joke is called plug and paste.
Is it a plug and play?
Do people still talk about plug and play anymore?
I don't know.
It was like Windows 95 was such a thing.
Yeah, that was like the big thing.
Like now with plug and play, you can just plug in the USB thing.
Anyway, sort of like that.
So here's the joke.
And let me set the stage.
Like, you know how people say, oh, we only use 20% of our brain or 30% of our brain
and think how incredible humans could be if we could harness all of the power of the brain?
And I'm not really sure I really buy into that.
Like, do you really need to be using the running part of your brain and the part that controls thinking
and the part that controls language?
Like, that doesn't actually add capability.
Anyway, so that's what it's based on.
So there's this person sort of looking up like, well, what if we could use 100% of our brain
And I think this is more work at work at work at Freeman says at work at work at
At work at work at work at work on it.
At work. A customer just tried to copy a document unplug the mouse and place pay
Plug it back into another computer and paste it.
Maybe we uh we got a little more foundational stuff to work on there if we could use 100% of our brain.
Yeah.
What about 10%?
Can we use 10%?
Yeah.
You know that that that whole like a hundred percent of your brain thing is not real like that.
I can totally see that that that like that.
Like people were saying, like, oh, you, on the average, people only use, like, a small percentage of brain that's not true.
We use all of it.
Yeah.
It's too costly to feed our brain if we weren't using all of it.
But, I mean, not everybody uses all of it.
I would say there's a range of engagement throughout society.
I think they're using it all.
They're just, like, most of it's just doing reruns of the Simpsons, I think.
Well, yeah, yeah, yeah.
That's probably true.
I find that like when somebody, if the photons from TikTok hit a person's face,
it's just, it's like a beam that shuts down about half of the brain.
Like as the photons just strike the skin.
I was listening to, we're tangenting, yeah, but I was listening to a podcast and there was an ad for TikTok on the podcast,
advertising how safe it is for kids because of all the safety features they've got.
And I'm like, that's insane.
It is insane.
So anyway.
Yeah, it's, that's a whole rant we can go on.
But I think that, I think like TikTok into this short form stuff,
it's like really hurting people's attention span and ability to engage,
poor extended periods of time.
Just watch my own kids.
Yeah, yeah.
Yeah, I'll have to find the article.
I just found out that my wife found an article about how Gen Z is the first generation
that's got a lower IQ than their parents.
I don't know.
But, you know, on average.
I would say maybe the test are just given wrong.
Could they be given the IQ test?
Could it be given as a TikTok series instead of?
And then it would be, actually, they might crush it.
Seriously, I think it's like it might not be an intelligence.
It might be a concentration thing.
It could be.
Yeah.
I don't know.
But it's not a great sign.
Anyway.
I don't know.
How do we get into this?
I don't know.
I don't know.
How do you say your brain?
All right.
We're going to go use 100% of the brain to get this podcast.
ready and ship to the world. Everyone, thanks for being here. Thanks. Bye. Bye.
