Python Bytes - #444 Begone Python of Yore!
Episode Date: August 11, 2025Topics covered in this episode: Coverage.py regex pragmas * Python of Yore* * nox-uv* * A couple Django items* Extras Joke Watch on YouTube About the show Sponsored by DigitalOcean: pythonbytes....fm/digitalocean-gen-ai Use code DO4BYTES and get $200 in free credit 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 10am 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: Coverage.py regex pragmas Ned Batchelder The regex implementation of how coverage.py recognizes pragmas is pretty amazing. It’s extensible through plugins covdefaults adds a bunch of default exclusions, and also platform- and version-specific comment syntaxes. coverage-conditional-plugin gives you a way to create comment syntaxes for entire files, for whether other packages are installed, and so on. A change from last year (as part of coverage.py 7.6 allows multiline regexes, which let’s us do things like: Exclude an entire file with \\A(?s:.*# pragma: exclude file.*)\\Z Allow start and stop delimiters with # no cover: start(?s:.*?)# no cover: stop Exclude empty placeholder methods with ^\\s*(((async )?def .*?)?\\)(\\s*->.*?)?:\\s*)?\\.\\.\\.\\s*(#|$) See Ned’s article for explanations of these Michael #2: Python of Yore via Matthias Use YORE: ... comments to highlight CPython version dependencies. # YORE: EOL 3.8: Replace block with line 4. if sys.version_info < (3, 9): from astunparse import unparse else: from ast import unparse Then check when they go out of support: $ yore check --eol-within '5 months' ./src/griffe/agents/nodes/_values.py:11: Python 3.8 will reach its End of Life within approx. 4 months Even fix them with fix . Michael #3: nox-uv via John Hagen What nox-uv does is make it very simple to install uv extras and/or dependency groups into a nox session's virtual environment. The versions installed are constrained by uv's lockfile meaning that everything is deterministic and pinned. Dependency groups make it very easy to install only want is necessary for a session (e.g., only linting dependencies like Ruff, or main dependencies + mypy for type checking). Brian #4: A couple Django items Stop Using Django's squashmigrations: There's a Better Way Johnny Metz Resetting migrations is sometimes the right thing. Overly simplified summary: delete migrations and start over dj-lite Adam Hill Use SQLite in production with Django “Simplify deploying and maintaining production Django websites by using SQLite in production. dj-lite helps enable the best performance for SQLite for small to medium-sized projects. It requires Django 5.1+.” Extras Brian: Test & Code 237: FastAPI Cloud with Sebastian Ramirez will be out later today pythontest.com: pytest fixtures nuts and bolts - revisited A blog series that I wrote a long time ago. I’ve updated it into more managable bite-sized pieces, updated and tested with Python 3.13 and pytest 8 Michael: New course: Just Enough Python for Data Scientists My live stream about uv is now on YouTube Cursor CLI: Built to help you ship, right from your terminal. Joke: Copy/Paste
Transcript
Discussion (0)
Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
This is episode 444 recorded August 11th, 2025. I am Michael Kennedy.
And I'm Brian Oaken.
And this episode is brought to you by DigitalOcean and their generative AI features and tools,
and DigitalOcean more generally, but specifically by their Gen. AI tools, which we're going to talk about.
Brian's going to tell you about them.
So check that out at Pythonbytes.com slash DigitalOcean dash gen dash AI and use the code DO4 bytes, all caps, and get a $200 credit.
So if you're looking to try out DigitalOcean, you might as well use our code and get plenty of credits.
Also connect with us on the socials, Massadom, Blue Sky, YouTube, all of those things.
Links are in the show notes at the top.
And I highly recommend that you subscribe to our newsletter, which Brian sends out a really nice email pretty soon after the show.
is out. Diving further into the stuff that we talked about, maybe some additional resources
and links and insights and tools and all that. It's not just a email version of the show notes.
It's really cool. I enjoy getting it as well. Thanks, Ryan. I enjoy putting it together.
I enjoy hearing about whatever you've got to cover first. So let's, yeah, let's jump in there.
Speaking of coverage, let's talk about coverage. Ned Batchelder released,
this was, I guess this was in July, but just recently, a blog post,
called Coverage.Pyrejects pragmas. So that seems like a mouthful and in and probably please don't
run away because this is powerful. I know that pragmas and rejects isn't everybody's
I'm feeling like C++ is back again. So what does pragma mean? It's it's the the pound thing like
so let's say if you say like pragma exclude or something like that to say or no cove to say hey
for coverage, for this particular line of code,
don't worry about measuring the coverage on that.
However, so this is a great article,
and I did not realize,
I've been using coverage for years,
and I did not realize it was this powerful.
So coverage uses Reg X's to define pragma syntax.
And you don't really have to care about it
if you just want to, just for each individual thing,
you want to pop in.
And there is a way to say particular files,
just ignore the whole file.
However, this is pretty cool.
So what is he talking about?
He's talking about a couple things around it that allow you.
You can extend it using regular expressions, and you don't necessarily have to figure this out.
Other people have figured it out for you.
For instance, there are plugins for coverage that do a lot of this.
So there's Cove defaults, and this one's brought to us by, oh, Anthony Sotili.
Cool.
So Anthony has code cove defaults.
And so there's a whole bunch of defaults already in there to do things like exclude your dundermain.py file because if you're distributing a package, that might be just so you can test things.
You're probably not going, it's okay if coverage doesn't hit it.
A lot of stuff like that.
And then a whole bunch of regular expressions for things like type relating, typing relating code and excluding that.
That's pretty cool.
I didn't know that was there.
That's neat.
Another one is coverage conditional plugin, which does.
things like if you've got certain what does it do he talks about it it gives you a way to create
common syntaxes for entire files or entire packages whether a package is installed or different
operating systems things like that that's pretty neat also um but a change happened apparently
recently recently for me last year but um a change to coverage that allowed multi-line and this was
contributed by Daniel Dniz, multi-line pragmas,
or multi-line regular expressions,
so that it compares it for the whole file.
So one of the neat things about this
is you can do things like with this regular expression
that you can put in your no coverage stuff,
you can pop in pragma exclude file
and define a file there.
Instead of trying to figure out how to find the file
in your directory structure,
you can just pop this in to say this particular file,
we're not, I don't want to delete it yet,
but we're not, don't worry about this for testing.
That's pretty cool.
Right, my boss has been on me
about getting that code coverage percentage up.
So I wouldn't do it for that.
Oh, is that what it's for?
Okay, no, I like that.
I'm just teasing, I like the idea.
I actually like, I mean, I've heard a lot of people say,
hitting 100% isn't worthwhile,
but I think it is because coverage is so powerful.
You can, with all of this stuff, you can say,
I want to hit 100% of the code that I care about.
Not the stuff I don't care about,
but the things that the problem areas,
you can define this so that you can just focus
on the files and areas where you really want coverage.
And that needs to be 100%.
So that's my caveat for why I like 100%.
A couple other cool pragmas, start and stop.
So you can just say at the start and stop,
like add a comment to the top of a code block to say,
say yeah this junk we're not um i'm leaving it in here but it's not it's not running during
testing so don't cover it um so really powerful i really love a couple all of these um pretty great
oh this is a neat one so have you ever had like um these uh uh default like a placeholder method
where you just uh use three dots or something i'm using three dots a lot better more than pass
because um it kind of does the same thing um and you can just
say, yeah, this is here because it has to for some structural reason, but it's never going to run.
So don't worry about trying to cover it.
So that's pretty neat.
Yeah, that's cool.
Yeah, very cool.
Anyway, thanks, Ned, for teaching us how to use regular expressions for coverage.
Yeah, that's very neat.
All right.
I want to take you back to the times of knights, maidens, to the land of your.
No, this is totally different.
This comes to us from Matthias.
It is a package called your, however.
It's quite new. It's like an undiscovered gem sort of thing.
So when I first saw this, I'm like, huh, do I care about this?
I don't know if I care about this.
And then I looked more careful.
I'm like, that is kind of interesting.
It starts with a quote from chat GPT, the sage, which is always good.
But it's more productive to just jump down to some examples.
So basically what this is, is it's a tool a little bit like rough or flint or one of those things that works on.
Basically, it looks at your code, tells you if there are issues.
But this one is focused specifically on have you previously supported unsupported versions of Python
by doing stuff the old way, you know, be that typing or example is the abstract, the ASToon parser?
I don't know what that is.
Or the AST parser, yeah, abstracts and text tree.
If you want to use that and you're using 3-8 or before, you had to use the AS-Tune pars, I guess, from unpar.
or if you're in 3-9 or above, you can use AST from unpars.
So, right, you probably have this comment, like if the version of Python that I'm running on, it's less than this.
I'm going to do this one thing.
Otherwise, I'm going to do the other.
And so what you do here is you still write that code because that's how it is.
However, you put a comment, kind of like, you know, Picharm and VS code, if you put a capital to-do colon as a comment,
I don't know if you've noticed this, but probably.
Yeah.
If you say capital to-do colon and you write something, that shows up in a separate window, at least in Python, you say, show me my to-does.
And when you try to do a commit, I'll say, hey, you added some new to-does that are not done.
You sure you want to commit?
Like, you know, there's a whole integration with the tooling like that.
So this is the same type of deal.
So you say put a comment that is capital your colon, and then you say EOL, in this case, EOL 3.8, and you put a comment.
Oh.
And then a thing like replace block with line four.
Okay.
Okay, so you say, once 3.8 is gone and we stop supporting it, just do the straight import.
We don't have to do this test.
We don't have to do anything.
And then later, you can run in your code, you say your check, EOL within five months.
And it says, whenever you run it at the right time, Python 3 will reach its end of life approximately four months.
So it uses the comments to say, you've got sections of your code that depend are complicated because of Python versioning breaking changes.
Oh, cool.
Here they are, right?
And you can look for them, much like you can use Rough Check to say, show me issues with my code.
But what's even better, Rough Check has a dash-dash fix, and so does yours.
So you can say your fix, EOL within five months.
It'll actually rewrite that code and replace the block with line four and just go back to the straight import.
Remove the your comment, remove the version checks, all that.
Hmm.
What do you think?
Okay.
I like it.
For such a simple idea, I like it too.
Now, I would, I was, I'll have to play with this a little bit because it might be, it totally makes sense for Python like, you know, deprecating Python versions and stuff.
And the reason one of the cool things about like looking into the future is you might be working on a, you might be working on a release that you're not planning on releasing for another month.
So you're getting started cleaning those up.
But you, that might be your own stuff.
You might be like, you might be deprecating your own features.
So you might, I'm wondering if you can put like your for your own features, or is it just a Python EOL thing?
Yeah, that's what I've been thinking about as well.
It's like I would like it, not just necessarily for my features, but hey, Pydantic went from V1 to V2,
and that had super big deprecations for certain really common functions, right?
Like dumping to JSON and so on.
Yeah.
Oh, is it just the Python release cycle?
I don't know.
I'll have to look into that.
Yeah.
I think it's just Python version itself.
But who knows?
Okay.
Neat.
Yeah.
Very, very neat.
All right.
Also, neat is DigitalOcean.
Yeah, let me tell you about DigitalOcean.
This episode of Pythonbytes is brought to you by DigitalOcean.
DigitalOcean is a comprehensive cloud infrastructure that's simple to spin up even for the most complex workloads.
And it's a way better value than most cloud providers.
At DigitalOcean, companies can save up to 30% off their cloud bill.
DigitalOcean boasts 99.99% percent.
0.99% uptime SLAs and industry-leading pricing on bandwidth.
It's built to be the cloud backbone of businesses small and large.
And with GPU-powered virtual machines plus storage databases and network capabilities,
all-in-one platform, AI developers can confidently create apps using a platform that the
users love.
Devs have access to the complete set of infrastructure tools they need for both training
and inference so they can build
anything they dream up. DigitalOcean
provides full-service cloud infrastructure
that's simple to use, reliable,
no matter the use case,
scalable for any size business and
affordable at any budget.
VMs start at just $4 a month
and GPUs under a dollar per hour.
Wow. Easy to spin up infrastructure
built to simplify even the most
intense business demands. That's
DigitalOcean. And if you use
DO4 bytes,
DO the number four,
and B-Y-T-E-S, you get $200 in free credit to get started.
DigitalOcean is the cloud that's got you covered.
Please use our link when checking out their offer.
You'll find it in the podcast, Play or Show Notes,
and it's a clickable chapter URL as you're hearing this segment,
and it's also at the top of the episode page in Pythonbytes.fm,
and why wouldn't you, it's $200 credit.
Thank you to DigitalOcean for supporting Pythonbytes.
Indeed, indeed. Thank you.
Over to you.
What's next?
No, over to me.
Over to me.
Sorry, I'm retracting that statement.
I got the order wrong, right?
So we've talked about Knox before, right?
Yeah, you're a fan of Knox, aren't you?
Yeah.
So Knox is a command line tool like PiTest or Talks
that allows you to test against multiple versions of Python.
Right?
So super cool.
You can run it.
You can say like this might depend on whatever particular version of Python or whatever, right?
So the thing I want to tell you about is something
called UV. No, sorry, NOx dash UV. And this comes to us from John Hagan. And this is, this facilitates
Knox integration with UV for Python projects. To remember, UV is awesome at installing different
versions of Python rapidly. Like, you can install, go to a machine that has no Python whatsoever,
and you can pick your version of Python and have it installed and ready to use in under two seconds,
versus high envy, which builds it and takes minutes
or downloading the installer
or making sure you have all the versions
you're going to test with or whatever, right?
So that's really awesome.
And then also installing the dependencies
for these different versions of Python,
UV is ultra-fast at that as well.
So there's huge advantages to speeding up testing and CI
with UV.
And if you're using Knox to create a combinatorial matrix
of all the different versions of Python
you might work with, well, then UV speed
is only going to multiply across that, right?
Yeah.
Yeah.
So super cool.
So you can just say UV add group NOx and NOx UV and it'll add that in there.
And then within your NOx file, you import the session instead of from Knox.
You do it from NOx UV.
Set the back end to be UV.
And then for your session, you specify which versions of Python, which groups, etc.
Off it goes.
I feel like this should be your topic, honestly, Brian.
I think I stole it from you somehow effectively.
Why is that?
Just because you're so into testing.
And this is like right at the heart of it.
Okay.
What do you think?
Cool?
I think that's as neat.
Yeah, I'm using like UV almost everywhere now.
And I actually, I used to recommend people like just average folks that are just starting
Python or that just like need it for work.
I would recommend them go to just go to Python.org and download it.
And I'm still kind of doing that, but I'm leaning towards like trying to teach people how
to use UV in virtual environments because it's not going to be that long.
after they start using Python that they're going to want to use that anyway.
So, yeah.
Yeah, and recently we just covered this, that one of the main things UV did is now there's
a Python version in your path if you install a Python via UV, which it used to just be in
like some obscure place hidden in like your user profile sort of thing.
It was hard to run it outside of a virtual environment.
Yeah.
So, yeah.
Yeah, anyway, okay, cool.
Yeah, very cool.
Thanks, John, for sending that in.
Now, over to you, Brian.
All right.
So let's take a look.
I've got a couple short-ish jango items, so I thought I'd cover them together.
So the first comes from Johnny Mets, and it's stop using Django's squash migrations.
There's a better way.
And actually, I didn't know about squash migrations.
I'm kind of new to Django, the Django world, new-ish.
But I like this article because I watched a pro.
Kind of an old hat when I was, I was watching, doing a session with somebody that knows
Django way better than I do.
And I had a whole bunch of migrations because I was, I was fiddling with, you know,
fiddling with the database structure and everything.
And I was going back and forth, changing things.
And I had a bunch of migrations.
And he said, wait a second, just a second.
Let me do something.
And he just like, he did this.
So what am I doing?
What am I talking about?
So this is Johnny Metz.
who's recommending doing a clean reset.
So you fully migrate all your environments,
make sure everything's running well,
and then you delete all your migration files.
Seems crazy, but you delete them all
and generate a fresh migrations.
And then you've got just a new one.
So this creates a new 0-0-0-1 initial for each app.
And then some apps might get a,
those are two or higher.
So you do this on different,
it's gonna do it on different apps,
but then you, so okay, I'll just walk through it.
Fully migrate all your environments,
delete all your migrations,
generate fresh migrations,
then add data, data migrations,
temporarily disable automatic migrations during deployment,
reset migrations, okay, so it's not trivial,
then reenable automatic migrations.
So why would you do all of this?
This seems more complicated.
However, you get, you end up with like a really clean set.
So you've got like a very clean migration set at the end.
And I think, I don't know if this is, I'm not a Jago pro, but so I'm not sure if this is appropriate later on.
But especially after you've like hashed through the initial development, this is a great time to start clean and then, and then work from there.
So interesting Jango article.
It is an interesting idea.
And certainly, I think, if you've not pushed it to production, you know, you just like, instead of having the 100 migrations, you may have built over time as you built up the app before you push it out live, like just get that down to a single migration, get the database up and running, go from there.
Yeah.
Another, I'm not sure if it mentions it in here too, but I have been guess, yeah, I think it sets it up in here, but having jing migrations per application.
Anyway, the other one is this comes from Adam Hill.
is DJ Lite and this is a fairly new project and it is how to use SQLite in
production with Django so yes you can use SQLite with Django but there's
some tricks so he wrote an article called the definitive guide to using
Django with SQLite in production and then he decided to go ahead and he's
still recommending that but there's this plugin to make it
easier. So with this plugin, you've got a couple settings that you can change and it just
runs with it. So it's way easier setup if you want to use Django Lite or SQL Lite with
Django. And his, this little blurbs here at the top says that simplify, simplify deploying
and maintaining production Django websites using SQLite in production. DJ Lite helps enable
the best performance for SQLite for small to medium size projects. It requires Django
5.1 or above, but I think that, I think Jango Lite or SQLite is appropriate for a lot of
Django. A lot of people just start with Postgres, but anyway. Yeah, definitely. I think there's
certainly like defaults you can change or behaviors you can change about SQLite to make it
way more high performance, especially with concurrent read, right sort of things. Yeah. So, yeah,
very cool. And following up on the squash migrations, Pat Decker says,
Sounds like a similar familiar to get rebase, maybe.
Yeah, it does to me for sure.
Yeah.
Squashing.
Yeah, very similar.
Okay.
While you have the stage, how extra do you feel?
I got a couple extras, so we can just cover them.
So the first up is I've got a testing code episode in the queue.
It's in draft mode currently.
Fast API Cloud with Sebastian Ramirez.
And it was a real fun talk with Sebastian.
This was recorded.
I can't even remember when it was recorded.
Maybe it was a few weeks ago at least.
I feel bad getting so slow to get it out.
But a really interesting article about Fast API and about Fast API Cloud.
And Sebastian's just a joy to talk with.
So that'll be out later today.
I only have to re-record the ad for it, but not much left to do.
And then next up, PythonTest.com, a couple things.
I released a, I had a fixture, when was this, 2013 that I started.
So this is what, over 10 years?
years ago, that I wrote a four-part series on pie test fixtures. And I had been talking that I was
looking at analytics. And some of the stuff is still getting hit. So I went and reviewed it. And this
series was a mess. And I went ahead and I didn't rewrite it, but I went through everything and
split it up into a more multi-part series. A lot of these are really short. I just wanted to keep
one topic per blog post and make sure that it runs a lot of the stuff didn't even run on
current pie test and current python now it all runs with current pie test and python so
there's a nice fixture tutorial there um the other thing i wanted to bring up with python test
is there is a bunch of stuff so 2013 up through this year there was a bunch of stuff that was
like formatted badly and i have gone through and made sure everything is mostly correct so if you
see any i think everything's working now so if you see anything weird let me know i just as i was
reviewing this this morning i realized that in this particular post i refer to a fixture as fixture
b and it's really resource b so i'll have to fix that but you know things like that shouldn't be
too bad anyway that's all up to date do you have any updates or i have three extras and i think they're
really exciting they're going to be really cool for people so let me tell you about first
brand new course over at talk python i'm really excited about this one
Some of the most impactful courses that we create there are ones that take people from like zero to one or like one and one point five to two, you know, like the first sort of steps, right?
And so this new course is called just enough Python for data scientists.
Oh, nice.
Python is kind of a stand in for software engineering with Python, right?
So the idea of this course is if you've done work in Jupiter notebooks, but you kind of feel like, well, I just learn notebooks and a little bit of Python because I was at this research lab.
or in this course I took, but I don't really know Git very well.
I don't know refactoring super well.
Reproducibility is still an issue, those kinds of things.
So it covers like, what do you need to pay attention to in the dev world or the software world?
And what can you safely ignore, right?
Like, don't try to boil the ocean when you're getting started.
What can you just not pay attention to?
How do you write functions, create importable modules and packages to split up notebooks from like one large notebook
Excel into a bunch of usable, testable, more readable pieces, debugging, reproducibility with
like Docker and UV, and even a little bit of agentic AI for like data analysis to like
jumpstart your work.
So if people are interested in this, I highly recommend it.
It's an awesome course that I wrote over the last three or four weeks and I'm really happy
to have it out.
That's pretty exciting.
I like the topic.
Yeah, thanks.
Yeah.
All right.
Speaking of UV, I was just on with Will Vincent from Django Chat.
when was this?
This was live streamed
four days ago.
And we did a whole one hour
like paired presenting
sort of thing on UV
why people might use it.
Compatibility, what's new.
I even did a thing like
how to make your Docker builds
five times faster sort of thing.
Or 30 times faster
depending on what you're using PIP
it'll be 30 times faster.
So super neat.
Super neat stuff that people can check out
and that's just on YouTube.
So I'm going to link to that.
Cool.
And then last is I'm a favorite.
of cursor when I'm doing like super heavy AI programming obviously a big fan of
pie charm when I'm doing like focus development work right but if I'm just like I
just need some heavy-duty AI tools cursor and Claude code has been getting a
lot of traction lately because it's like this terminal-based thing you can use
it anywhere well cursor just came out with a cursor CLI that you could set up
that's that's pretty neat so use it in your IDE or any terminal cursor jet
brains Android Studio X code whatever so
Pretty neat. If you're, if you kind of like cursor, but you also are kind of a, prefer the terminal side of things. Check this out. It's in beta, but so far it seems pretty neat. If you have a subscription and just like integrates with that.
Neat. Yeah. Those are my extras. I have a joke for us as well. Oh, good. Yes. And I think this AI thing I just gave a shout out to perfectly, perfectly blends into this. Okay. Control C, control V remains eternal. But what kind of dev are you? This means something different, Brian. If you're a new school developer,
you copy and paste from chat, GPT.
If you're old school, you copy and paste from chat overflow.
And if you're ancient like you and me, you copy and paste from the documentation.
Wait, how do I copy and paste from a book?
Okay, I guess I'm so ancient that I'm not even on the chart.
Oh, that one takes a while because that's when you, remember people talk about,
oh, I saw that code in the magazine that I typed it in.
Yeah, that was me.
That's how you do it.
It's how you do it.
You copy and paste with the fingers, one character at a time.
Yeah.
Yeah.
Anyway, control Z, control V, still important, but changing over time.
Yeah.
All right.
Well, thanks for the episode.
Thanks for being here.
And thanks to everyone else for listening.
Thanks.
Bye.