Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to
your earbuds. This is episode 407, recorded October 28, 2024. And I am Brian Okken.
And I'm Michael Kennedy.
And this week we're sponsored by ourselves. So please check out our offerings. There's all of
the fabulous courses at Talk Python Training there. And then over at pythontest.com,
we've got the complete pytest course and also the short course, Hello pytest.
And also thank you to our Patreon supporters who we don't do a shout out enough to,
but thank you very much. We appreciate it. If you'd like to connect with the show,
we'd love to hear from you. You can connect with us on Fostadon. We're at mkedeny,
at Brian Okken, and at Python Bytes, all at Fostadon. And also those links are in the show notes,
as well as in at pythonbytes.fm. You can find out when the next upcoming episode is going to be.
And I was going to mention this later. I'll just go ahead and mention it right now.
Next week on November 4th, we are going to be recording early. So it'll be at 730 in the
morning instead of our normal time. And that's Pacific time instead of our normal 10 a.m. Pacific
because of work for me. Anyway, so that's what's going on next week. But at pythonbytes.fm,
you can sign up for our newsletter. You can get the show notes. You can sign up to and look to see
when the next live recording is. But right now, I'd like to hear from Michael to see what you had
to talk about.
Shall we teleport, transport to the future? Brian, I want you to imagine a time when it is not so gloomy
and rainy about 11 months from now, when we have a new version of python that comes onto the scene 314.
And that future can be for you now in a limited sense because 314 alpha one is now available.
The pi version of pi, thorn.
That's right. So that's the first alpha one release. And there will be seven in theory,
you know, by plan, at least unless something goes wrong. This is the first of seven alpha releases
before we go beta, before we go release candidate, and then we finally ship. Right. So it has some of
the new ideas, but not all of the new ideas. It comes with performance improvements and actually quite a bit
more, which is pretty interesting. So if you read the blog post announcement, well, it looks like,
okay, so we've got this new PEP called deferred evaluation of annotations. Now, I think this was
meant to land in 311 or 312, something like that. And all of the frameworks and libraries that thought
typing should matter. Like fast step behind.
Yes. And typer and pydantic and so on. And I count myself as a big fan of all of those libraries.
Those all those people are like, Hey, hold on, hold on. This is not just a thing for my pie.
These types are not just for my pie. And if you take away their evaluation, all of our awesome
frameworks go away. And I think that would be a massive step back for Python. A lot of people
agreed, made some changes. So that wasn't done as far, at least in a limited way. But you know,
having these type annotations does have a performance cost of say an import, potentially,
it does have weird issues where you've got indirect or sort of half defined types that you want to
talk about. I have a function or a method on a class, and I want to say it returns one of those
classes or, you know, it's like an equals. It takes another one of these classes and it tells you if
it's equal to it. So you had to do weird tricks like typing dot self, or you could have quotes,
the name of a type that's not defined yet, but eventually someday it will be defined if you
get around to looking for it. So this will allow you to not worry about those types of things.
And there's a new API if you consume them, if you were Pydantic or FastAPI or whatever,
there's a new way to say, let me read the annotation metadata about this. That's slightly different,
but it's still there. Okay. Improved error messages. We all love improving, further improved
error messages. So there's that. And then, so that sounds like when you read it like, okay,
that's the thing. But actually, if you go and look, where's the link? The release notes are
in here somewhere. So you click here and you, there's a release notes. Oh, really? Where did it go?
Maybe I haven't had notes. But anyway, Brian, there's a ton of changes, a ton of changes from there.
I think, oh, I know where it is. They don't call it release notes. Here's how you do it.
You click on the PEP and then you scroll down until you get past the PEP and it has other changes.
So yeah. So there's, if you go to either of those links, it'll tell you about their message,
tell you about the PEP. But then there's, if you look at the scroll bar, a bunch of stuff below that.
For example, incorrect use. Yeah. I think that's actually the news, not the stuff that was called out.
Incorrect usage of await and asynchronous comprehensions is now detected. I don't know exactly what you could have
done wrong before, but if you're doing it wrong, I guess. Anyway, if you're doing it wrong.
Well, apparently like assert await one. Yeah. So I think what the issue is, you could await a thing
that is not awaitable potentially in the list comprehension. So now you'll get a warning.
Okay. Is it warning or error?
Syntax error.
Yeah. Syntax error. But you can disable the syntax error because apparently it used to work. If you want to
just keep doing that, that's fine. Let's see. Some stuff about dunder debug. The numerical things. Now,
have a float dot from number and complex dot from number, which converts to a float type or a complex
type, which is somewhat interesting. So the thing is, this is not a parsing operation. It takes one
number and converts it. And if you give it a string, it'll be an error. So this is like, I just want to
make sure I'm always working in numbers and convert them in probably a more efficient way.
Oh, better than like a cast thing. Yeah. Yeah. Yeah. Where the cast is just
with a type annotation type of deal. Whereas this is a true transformation, right?
Nice. So we get the new annotation lib, which talks about, which provides those features that I talked about for
PEP 749, the deferred type annotations. Arg pars, get some updates. AST, concurrent features,
C types, decimal, daytime, disk, fractions, functools, HTTP. It's funny. You know, HTTP, this was something
nice. You can say Python dash M HTTP, that server, I think is it, whatever. So if you have just
a directory and you're like, I need to have this as a web view. For example, if you have a, an HTML file
there and it says, I want to open up forward slash some CSS file or forward slash some JavaScript file
or something along those lines. If you just open it, it goes, I don't know what these files are. Right. But if this
web server were to serve it, it would easily work. So you could just type Python dash M space,
ACP dot server, enter, and it'll pull up a little web, like no, no op web server that you can then
actually interact with that stuff with. So it now has a dark mode. Okay.
Oh, you should have led with that, man. That's cool.
Yeah. This is contributed by Jorick Hanson. And I thought, okay, Jorick must be a huge fan of dark
mode to want.
As am I. Yes. Yeah.
Right. Okay. Jason, get some updates. Operator ops,
Pathlib, Pathlib, actually the changes to Pathlib are interesting. I'm going through this list to
point out, like there's a lot of changes just in this alpha one release, but Pathlib now has,
add methods like new functionality to Pathlib to recursively copy and move files and directories.
Oh yes. I'm here for this. Yeah. Copy. Copy is a file or directory tree to a destination. Copy
into copies into a destination directory, move and then move into. That's awesome.
That's good. So Barney Gale did that. Thank you. PDB, pickle,
PyDoc, sim table, sys, and unit tests. It ain't dead. No, it ain't.
Anyway.
In space.
So there's also optimizations. For example, asyncio is now implemented using doubly linked list
implementations. Hat tip for the, comp side data structures.
Level up there for native tasks, which speeds up execution by 10% on standards, standard high
performance benchmarks and reduces memory usage. So who wouldn't want that? That sounds great.
Exactly.
Exactly. All right. There's more you can read about it. And I just touched on it. Like each
thing I said had a paragraph or list of bullet points you could go into if you wanted. So that's it. Now
back to the future, back to the present, whatever, back to their current time.
Yeah. Or the fast time. So just last week on October 21st, episode 406, we talked about,
we talked about a lot of stuff, but one of the things was PEP 735 with dependency groups in
pyproject.toml and I didn't know when we could play with them. And the answer is now because,
um, because uv decided to do that right away. So, uv just had a, put a change in,
in, in, in, in version 0.4.27, in the change log, they say, they're the dependency groups are
supported, which is super cool. there's even a PEP support for PEP 735. I couldn't believe this
was so fast. It was like just a few days after we talked about it. so they must listen to the
podcast. That's pretty awesome. Yeah, probably. And this was like, oh yeah, three days ago, the,
it was merged in. so this is pretty cool. So there's a whole bunch of added stuff. And so I went
off and played with it. so there's, there's a --group is that added to uv add and uv remove.
So the, when you add dependencies or remove dependencies, you can say group and it puts
them in groups, the --dev and things like that. There's a couple of those, those,
so --dev used to be an extra dependency. Now it's a dependency group called dev. And,
and so --dev is the same as saying --group dev. it's more clear in the,
in, in the list, in the documentation, if the documentation is updated. So there's a couple
of things where it, it isn't quite updated. So, there's a lot of, it was very clear on how to
add dependencies to dependency groups with uv. Now you can see, you say uv add or, uv remove,
um, that, that works great. but how do you install them then? So that's what I tried to play with.
So, also, the, the documentation for default groups is up so you can,
click around in the uv talks about, default groups and dependency groups. and here we have
like the dev for pitests. Of course, you're going to have pitests in your dev dependencies. and
there's the, there's the little tip for the, the --dev flags. Okay. So I'm like, okay,
so how do I install stuff? So I expected what I expected to have work is to say uv pip install dash dash
--group dev and be able to just install those and not the project. Well, that doesn't
work yet. So, there is a issue, filed by Hinnick and the, of this, this should work and it
doesn't, pip install group, but the, the issue is that they want to, they want to be like the same
compatibility with the interface for pit. So they're just waiting for a pipe EA to define what that interface
uses. And that's fair. So, so we've got all these dependencies and you can't install stuff, right?
No, not quite. So I asked, I also asked on LinkedIn, if anybody knew and, Tushar,
responded saying, Hey, the docs, which they don't, but it says uv sync group will work. So I checked out
the docs and I can't find it. The sync doesn't talk about groups, but it does work. I tried it. You could,
so essentially this works. So, so what do you do? You create, you have a, you say you added a
dependency group, then you can say uv sync. And if you add the group like --group,
and then the group name, and you can add a bunch of those, then your virtual environment will sync
to match what your project says. So basically that's how you can install. You can use sync to install your
stuff, long winded, but that's a, that's how you can do it. So nice. Oh, that's awesome.
Anyway. Yeah. So this lets you say, unlike a requirements.dev, it lets you say,
here's a separate set of dependencies that I need for a certain action or set of tasks on my project.
It doesn't necessarily pull in the base dependencies, right? That's the big, the big difference.
Well, that's the, that's the idea, but with UV, it's different. So with uv currently with using
sync, it will pull in your base dependencies and the extras. you can't do just the group yet.
Got it. Cause it's not defined. It's not agreed upon yet. How to say it.
Right. So, the syntax is there though. So you can play with syntax and I'm, it's very
comfortable. I'm actually, I probably, there would be very seldom, like for me, I'm okay with this being,
having to install the project and then the dependencies, but there's just, there are times
where you just want to install a group, like to build the documentation or something like that.
Yeah. I'm, I'm fine with it as well. You know, one that might be, on most people wouldn't
guess for, but in the ML space, some of these dependencies are massive. For example, if you want
to use the large English model for spacey, you specify that as specified as a dependency, you don't
Python, maybe you run it as a Python call. Anyway, that, that thing is like 500 megs or something.
Right. So you might want to just not download it and install that as well.
Right. Especially if a, if you have like a modular CI system where one of the build stages is like,
uh, built in documentation or linting, static linting or something like that, you might not
want to pull in the world just to do one of your stages. So yeah, that's a great, great case. Okay.
Let's dive into the next thing, huh? Okay. Dive comes to us unknowingly by Mike feeder.
let's see. Yeah. Mike Fiedler. So he mentioned this in a group discussion that I was also looking at.
I don't know that he sent it in specifically for us, but here it is. I'm taking it because
it's a cool idea. So here's the thing. If you have some sort of container system, like a Docker image,
you have a bunch of steps. And when you apply the way you make the containers, as you go to a Docker
file and you put in lines, like do this action, then this action, then this action. And they can be,
they're usually some kind of Linux command, or maybe you'll copy these files or run this Python command
once you've copied the right stuff over. And so they can be big, like apt install this one thing,
but this one thing has 20 dependencies, or you might be running, install the development requirements or a
compiler that you didn't need. So you might end up with slow builds and large images. What do you do
about that? You run this dive thing on it. So this thing's pretty cool. So what it does is there's a little,
a animated graphic you can have here if you go to the GitHub page and, you know, hat tip for anything
UI, please animated GIF would be awesome, wouldn't it? So anyway, you can have this here. And the idea is,
it basically allows you to see every layer. So each line of code that you've run, like make a directory,
copy these files, uv pip install -r requirements, or something along those lines. And each line you click on,
it gives you all the files, like a tree that you can explore with the file size of the, of the
image, the resulting image, and then also kind of a delta. So as you click around, it'll say these files
were added, these files were changed, these files were deleted on this step. So you can see this is the
reason this file is here because on line four, we ran this command, which added these files. Why is that?
Oh, that's cool.
Isn't it? Right?
Yeah.
So if you were shipping containers around, shipping images around, you know, like pushing it to Docker
Hub and then pulling it somewhere else, like you should definitely look at this. It's not something
I'll probably care about because I just build my containers on the server, then use them, which is
also a way to do it. But if you ship them around and you care about their size or they're building slow
or whatever, this is awesome. Check this out.
Also for security concerns to make sure things don't get added that you don't know about.
Right. Or even just, I want to make sure that there's no compilers on here because if somebody
were to break into the container and they could use the compiler, then they could say, upload some
C++ code, compile it and run it. Right. You know, the so-called living off the land sort of issues
after somebody breaks into a thing. So you just say dive space your image, or you can alias it to,
this is pretty nice actually. So there's something I've started doing with some of the tools if I'm
already on a system that has Docker. So you can do this with glances. You can do this with dive.
You can do this with other things as one way to do this is I could brew install dive onto my Mac,
but then who knows what that's doing to my computer. I'm running arbitrary code off the internet. I
probably trust it, but you know, right. So what you can do is you can alias. So you can run this from
Docker and then you can alias dive to just be the sequence of Docker commands that you want to run. So
even dive itself runs in Docker and then it talks to the other Docker container that you pointed at,
and that's it, which is a really nice pattern that's getting to be more popular.
It's Docker inception.
It's, it's Dockers all the way down, but yeah, you just create an alias and then it's just Docker run
dash it, remove the image, map the volume it needs over and then off it goes. Yeah, it's really cool.
All right. What else real quick? I'll wrap this up. so it'll show your image broken down by layer.
Like I said, what's changed. It has a metric like cyclomatic complexity equivalent, but for Docker,
they made this up, I believe an estimated image efficiency. The lower left pane of the base layer
shows an experimental metric that'll guess how much wasted space your image contains. That's kind of
interesting. you could do a quick build analytic, a bit, a quick build test. So instead of going and
building the thing and then running dive, you can say dive build and it'll actually build the thing
and then test it instantly. So it was like one line. And then there's CI integration, for, you know,
basically doing some of this stuff in CI and ways in which you can make it fail the CI if it fails
some metrics and so on. Oh, that's cool. Yeah. Pat Decker out there says, I've been using
dive for a while. Neat. Awesome. Glad to hear the testimony. Yeah. So yeah. And people can check
out obviously it's, it's open source written and go 46,000 get up stars. So it's, pretty well
known and used. That's pretty nice. Also, I like the, this CI integration because if I can't get it
from to a feature from the command line, it doesn't exist. I was concerned. So anyway, cool. Nice.
I've, I've got to just, I guess a little like blast. We talked about the future. Let's talk about the past
a little bit. I had a question. I haven't talked about pytest metadata for a while,
but I had a question just this last week. Somebody, got ahold of me and said, Hey,
um, I'm, I've got these, these, pytest CI system, the pytest CI system put together. I'd like to,
I'd like to send some extra data from the test environment to, to the, to the report server.
Is there a way to get metadata, like extra metadata and pytest to like add it to the, to the results and
then put it somewhere else in the, in the result system. And I said, well, have you checked out the
plugin called pytest metadata? It does exactly that. so I guess I'm just reminding everybody
that pytest metadata is a really cool plugin. It does exactly what you would think it would do.
It bundles metadata with your results, or at least that's exactly what I think it would do.
it isn't testing your metadata. It's adding metadata to the, to the results.
So some of the things that does right off the bat, which is kind of fun, is it automatically stuffs in,
uh, for the account, right? Yep. Four different keys. It's key value pairs for the metadata. It does
the Python version, the platform. So Python version is like, you know, whatever Python version,
the platform is a string that, that we get out from Python to say what kind of like, you know,
for macOS it's Darwin or something else. and then, the packages, it lists all the pytest,
all the pytest packages that are there. and then actually it says the description pytest packages.
I think it's, I'm gonna have to check this out. I'm not sure if it's all packages that are available
or just the ones associated with it. Yeah. The name says pytest, but the example
lists more than pytest, right? Yeah. Yeah. So I'm not sure. but then there's plugins,
and it lists all the, the pytest plugins that are there, that you have, bundled,
but I don't really use it for that. I mean, that's interesting, but really I add stuff. So we've got
like my, I I'm often the, the target environment that I'm testing. What version is that? What, what,
what extra packages are on that? So if I'm, I'm testing, you know, embedded systems, so I'm,
I'm checking information about the system. I'm testing and adding that to the metadata frequently,
but you can do whatever you want, but this adding is cool and it's really easy to do.
You can add it during, you can even add it at the beginning, like on command line,
if you know it at command line, but within the test, you can do it within, within a fixture,
within a test as well. You're going to add metadata and it's reported. It's reported in the command
line. If you do dash, the, the --verbose that gets, or dash B, will it, it adds like
reports all the metadata, but it also comes out in the J unit XML. and, and a lot of,
JSON results and other plugins, will pull this metadata out also because it's a very widely used
plugin. so, very useful if you want to pass that along. it's, it was, I believe it was
generated specifically for the, by test HTML, plugin because it's a same contributor,
Dave Hunt and others, but, but it's, the metadata is used even without the HTML,
um, in the, in our top pie test plugins list. the metadata is number five and HTML is number six.
So they're both very popular, but, metadata is popular by itself. So yeah,
very cool. I love it. That's a great idea. Anyway. So that's, those are our items.
I have a couple extras or one extra. Do you have any extras?
Hit them. Okay. Yeah. I got a few, but they're quick as well. I'll, it makes sense to start
right here because I did make some changes to the plugin list. So just the other day, I was looking
through, the top pie test plugins list on over on python test.com and notice that there was stuff
in there that I don't like talking about because they're deprecated and even the developers don't
want you to use them. So I've started to start filtering those. So I'm sorry, I'm going to go
through the list and check out to see if they're deprecated ones, because, you can already find
this information out if you want to find out with the, with the list of, what, which ones I'm
pulling out, but why would you want to do that? You want, we want to know, the top
pie test plugins that I should look at. And if there's ones you shouldn't don't. So yeah,
those are coming out. And then I thought, you know, I've, I've been wondering to do,
a new series. I'm on, the testing code podcast. And I thought, why not look at these plugins? So
I'm, I'm not going to go through the entire list. Plus it changes like every month, a little bit,
but I'm going to go through some of these and pull out some that I think people should know
about. So I'm going to do like a series of plugin episodes. So that'll be coming up. How about you?
Any extras? A couple. Let's see what we got. So let's start here. So Hugo van Camande said,
guess what? Pillow, you know, the Python image library, 11.0.0 is out with not just support for
Python 3.13, but free threaded Python wheels. So you're doing a bunch of image processing.
You want to speed that up, the free threaded Python T or whatever it is you run is good.
Drop support for three, eight, cause that's so old school or moved a bunch of stuff and then added,
uh, many things. So if you go look here, I believe you look at the, look at all the changes in this.
So pretty, pretty awesome. How much has changed here? So if you do stuff with images and Python,
use pillow, there's a new one. That's a big release. But if you're like, what could I do with images in
Python? Well, check out pillow. It does a lot. So that's cool. We have, you know, you've heard
of pip install anti-gravity. You've heard pip install this or sorry, import this and import anti-gravity.
But what about pip install Deutschland? And what does that do? So this comes from Grandknapp says,
"Hello, Michael and Brian, here's a recommendation for the 14% of your listeners who are in Germany."
I remember I talked about that as analytics from Imam a while ago. And it says, "Just pip install Deutschland
for lots of useful German datasets regularly updated." And so you go over here and it's got things like,
"Do you want to go and find addresses, barrier lines, building areas, building borders, I suppose,
and so on." My, German construction terms are not that good, but anyway, something along these lines,
right? and you basically, it just has data for all these different components or things you might
want to know about in Germany, which is pretty cool. Yeah, that's pretty cool. That's a lot more than just
buildings. There's, there's a, there's quite a bit there, isn't there? Yeah. Yeah. Addresses,
history points, underground stuff. It's got Autobahn information. Yeah. Yeah. We need a pip install for
a lot of countries like pip install USA. It chants a little USA, USA, USA, then it installs it.
All right. America, America, America's got borders. Okay. So, and another big thing that's fun is I just
released a talk Python blog. So I've got my personal blog and there's tons of RSS at talk Python, like for
the podcast and stuff, as you would guess, but a dedicated blog so I can post interesting things
and series that I plan on working on that are more talk Python related, not just for my personal blog.
So anyway, it's got a couple of posts already and yeah, I tried to go for the super clean, super
readable version here, Brian. So trying to make it just, yeah, thanks. So this is built. Yeah, go ahead.
I was going to ask you what it's built with. Well, it's built with Hugo, which is a glorious
static site builder. But what's interesting is it's hosted under talk Python.fm/blog, not like blog.talkpython.fm.
And I'm using engine X to point different sub URLs to different sections. So like most of talk Python
is a Python app, obviously, but then this part is Hugo and they just kind of coexist under the same
URL structure, which is fun. Okay, nice. Yeah, I might write about that actually at some point. But
yeah, it's built with Hugo, kind of like our own stuff, right? Our own personal things.
Yeah, I'm just having some Hugo. I'm having Hugo issues, but...
Are you? Well, I'm still having Hugo love, so it's okay. We'll even it out there. All right. I got a
joke for you, but I can't find... This is a cartoon I saw, but I can't find it again. I thought I bookmarked
it in our thing that bookmarks it and the title of it is there, but the URL to it is not. It just says dog
joke. I'm like, huh, I wonder where that is. And I've tried to search for it. I can't find it,
but I can tell you the joke, okay? Okay. Are you ready? Yes. Imagine, imagine if you will,
a little girl just getting her first puppy. The dad is brought it home and they're out in the backyard
and he's about to share some wise advice with his daughter to help her become accustomed to having a
puppy and all the new responsibilities and so on, right? Yeah. So he, he, she's just sitting there like
gleefully petting the new puppy and says, now they're thinking of a name for it, right? He says,
now, sweetie, you need to think very carefully about the name for this puppy because you're
going to have to remember it for the rest of your life and enter it on every webpage that has a stupid
security question. Yeah. So that's the advice of the dad. Remember this name of your first pet
because you're going to have to remember that for the rest of your life. Yeah. That was the joke.
That's good. No picture because I can't find it. I've got a dog joke. So we, let's, let's add another
joke. So let's do it. Okay. So kind of a dog joke. So a guy walks into a library and he's,
looking for a book and he's, and he walks up to the, the librarian says, says, there's a
particular book I'm looking for, but I can't remember the name of it. it's a, it's, it's a,
it's a book about Pavlov's dog and Schrodinger's cat. And the librarian says that rings a bell,
but I'm not sure whether we have it here or not. Perfect. Pretty good. A lot of science in there.
A lot of some social science, some hard science. I love it. Yeah. Yeah. All right. Some uncertainty.
Yeah. Yeah. Might be there. Might be there. And it rings a bell. cool. Well, awesome episode
again. I think so. Thank you, Michael. And thank you everybody for listening. So I guess we'll,
uh, talk next week. Bye. Yep. Bye.