Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to your earbuds.
This is episode 227, recorded March 31st. Nice. I'm Brian Okken.
I'm Michael Kennedy.
I'm Michaela Reyes.
Welcome, Michaela. It's great to have you here.
Thanks, Michael and Brian. I'm a big fan of both of your shows.
Oh, thank you.
Wonderful.
Yeah, that's really nice. And super cool you could drop in here and be part of this show.
And before we get on, maybe just tell folks about yourself.
What do I do? I'm a software developer for more than 10 years.
And then I'm also an organizer of the Python community in the Philippines.
So, yeah, that's about it.
Nice. Should we jump in?
Let's jump in.
All right. Well, the other day I was on Twitter.
Sorry, I made myself laugh.
So, Ned Batchelder put out a comment that said,
public service announcement, please do not remove old versions from PyPI
because it just causes work for people that have to go find your old versions on GitHub.
PyPI has a yank feature that you should use instead.
And I didn't know about this yank feature.
I didn't know about it either.
I thought you just have to live with leaving it there or you take it away and cause trouble.
Yeah. So, so this is pretty cool.
What it does is, and I should have had a screenshot of this up, but basically in PyPI,
when you go in and you go in and log into your account and you go to one of your,
the package that you want to take a version down from.
And when you go, actually, if you go to try to delete it, it'll pop up a comment that says,
hey, maybe you should yank this instead of deleting.
And this, apparently this just came out like last year or a year before.
I can't remember, but it's not terribly old and I missed it.
Yanking is about the same thing.
So yanking leaves it there, but it, it doesn't automatically grab that version,
even if it's within a range that you've specified.
The only way you PyPI will grab that version is if you specifically have that exact version specified to,
to grab.
And that way, if somebody has a pinned version to just that version, if you, if it's gone,
they just won't download anything.
So that's not nice.
It's just going to crash and, you know,
their Docker thing won't build or their system won't install or whatever.
Something bad, right?
Yeah.
But, and then, I also wanted to link to, Doug Hellman article, about,
so you've released a broken package.
What do you do now?
And his recommendation is just relax.
It happens.
Um, just push it out again, fix it and push it out.
And so I, I generally, I, I don't know if I've ever thought of the need to yank.
Cause most people probably won't pin the, the bad version unless it's,
unless they know it works for them.
So I guess I wouldn't worry about it too much.
It's interesting.
I guess this is new as well.
This is from May of 2019.
This yank feature according to the pep, at least something around that timeframe.
So it's pretty new, but it definitely seems like a right, a good feature.
Okay.
Have you heard of this?
I also haven't pushed anything on pipe yet.
Just internal, packages.
Yeah.
Then you just tell people, oh, this is broken.
Don't, don't use that one.
Yeah.
If you put it on, on pipe UI, then, you know, someone pip installs, pip freezes it.
They've, they've got it.
So I guess it depends how popular packages, but even if you have an unpopular one, you know,
you've got a, just a thousand downloads a day or something, or that's still a very high
likelihood that someone's going to grab it.
I just pushed up something recently.
I was excited that it got up to like 24 downloads a day.
No, I mean, that's, that's good.
I think I have nothing.
I have nothing in that scale.
I'm thinking, you know, if you're, you, if you're doing flask or Django or pandas and you
push a bad thing, like you're going to hear about it for a long time.
It's, it's going to be a high stress event.
Or as opposed to like the stuff that I have up there, no one would notice as long as I got
to it pretty quick.
I'll stick one of mine up in the, in the, the, extra section at the end.
Oh, okay.
Yeah.
Perfect.
Yeah.
I was, I was about to ask.
So SQLAlchemy, maybe you guys have heard of this.
I think it's about something to do with databases, something like that.
Yeah.
So SQLAlchemy obviously is the most popular ORM for talking to databases without writing
raw SQL, which I think for the most part, this is the way you should be doing it, right?
You should be programming with so many things.
Just change the connection string and it works.
It doesn't matter what underlying operating or underlying database you're talking to.
It'll figure it out.
Mostly we'll get to that, but big news.
Mike bears been working super hard to get SQLAlchemy 1.4 out.
And does it say here?
It says this is a ton of work that they put into over, I believe this is months of work.
And I think it came out last week, but we didn't have time to cover it.
So here it is.
And this is notable, not just because, Oh, look at some point releasing, there's a few
things, but there's a bunch of big changes for people that know about SQLAlchemy.
For example, this is the first one that it's moving towards SQLAlchemy 2.0, which is a big
change of the APIs and things like that.
So it introduces a bunch of new APIs, especially around async and await.
So this is the first SQLAlchemy that natively supports without some kind of external patching
thing.
Natively supports using the ORM to talk to the database using async and await, allow you to
plug into things like FastAPI and other places in a real scalable way.
So that's pretty cool.
And yeah, the fact that it's moving on to this, this 2.0 style is pretty interesting.
So yeah, big news, right?
Yeah.
Cool.
And there's a lot of changes around working with the ORM towards this new API.
So it used to be, you would create a session and then you would say session.query of the
class you want to query and then like filter and order by and all that kind of stuff.
And that stuff is gone, not removed, but it's not the new style and it's not the styles that
supports async and await.
So I'm pulling up here, this, this doc that shows like the before and after.
So if you wanted to get all the users used to say session.query of user all.
Now what you do is use this combination of select statements and then executing them.
I believe this comes out of the core of SQLAlchemy.
There's a way to do the core queries and then the ORM queries.
And I think it's leaning more on the way that the core work.
So now you would say session.execute, select a user.
And there's a few more steps for some reason.
Then you got to say .scalers.all.
If you don't do that, what you get back is like a bunch of tuples where some part of the
tuple on each entry is the thing you were looking for, I believe.
So it's not super different, but it is not even close to the same.
So that's, that's something that people should look at.
Let's see if I can find the async support here.
I'll just show you one thing that you also, I want to point out.
I said normally you can just change what database you talk to.
If you're doing the async API, you have to be more specific about it.
For example, if you just try to talk to SQLite, it'll crash and says the SQLite driver doesn't
support async.
Sorry, you can no longer use, you can't use that API to talk to SQLite.
But what you can do from this little, I've taken from one of my classes is you can use a different
connection string.
This is from my second FastAPI course.
You can say SQLite plus AIO SQLite and say, I want to use the AIO SQLite driver, not the
plain SQLite driver for my async connection.
Right.
Yeah.
So if you do that, then you're back to good.
Things go.
Yeah.
Things go as you would expect, which is really cool.
And then you've got to do things different.
Instead of creating an engine, you've got to create an async engine.
The way you work with the session object is now with the async with block.
There's a lot of interesting, like slight variations going on.
But, you know, basically it's really cool that you can now do SQLite or SQLAlchemy and SQLite,
I guess.
But especially SQLAlchemy against the databases using the ORM in an async and a wait friendly
way.
That's the big news.
That's really cool.
Yeah.
I actually think that changes to the ORM are kind of neat.
Yeah.
No, I'm not saying I dislike them.
They're just, you're not just going to be able to put in a wait in front of what you used
to do.
It's a different API.
You got to kind of go through and figure it out.
But it's fine.
It's good.
I'm really happy to see it.
Michaela, do you do anything with SQLAlchemy?
Yeah, it looks the new query style is more understandable, I guess.
But I'm just worried about those who are using the old version in production.
Yeah.
I don't know if it's going to go away in SQLAlchemy 2.
I'm not sure what the story is there, what the future plans are.
But if you want to take advantage of the async and wait stuff, you've got to go do new things.
But there's not going to be a lot of old code.
I mean, there's going to be no old code doing the old async way because it just wasn't supported
at all.
Right.
So it should be okay.
Yeah.
All right.
Well, that's that for that one.
And I think you're up next, right?
On your item.
I found this Django tenants package back in 2017.
And then I was just surprised that it's still being maintained when I looked at it.
So it's a multi-tenancy implementation for Django, typically used for SaaS websites.
So it's like, what's a good use case?
Let's say you have a restaurant with franchise.
And then you have a lot of people.
For example, your main web app is my website.com.
And then you have a lot of people.
It uses PostGear SQL schemas.
So for each tenant, it has a different.
It will use a different schema for each tenant.
Okay.
Yeah.
This is really neat.
Because that is such a big challenge.
I know a couple of people that have sites that they build.
That their customer wants to log in.
Multiple logins for them.
And when they go in there, they want to see their data.
But you don't want to have a copy of the website for everyone.
You want to have one website that you maintain.
And it's always filtered to, well, what company are you in?
You get to see the data related to that company, that account.
As someone else comes in.
Yeah.
And this is super cool.
Yeah.
Because the data leaks can cost you lawsuits.
Yeah.
I mean, you could do it yourself, right?
Every single query, you could say whatever the query is.
And your company ID equals or account ID equals whatever it is.
But if you forget one time, you're in the news in a bad way.
Yeah.
This is very cool.
Yeah.
I was always curious about how people.
I mean, I'm sure there's other ways too.
But I was curious about how people would do that to build this house off of Django.
It's interesting.
And it's based on domains.
So like tenant1.domain.com, tenant2.domain.com, and so on.
Yeah.
So I like it.
I mean, if you're doing Django stuff, it seems like it makes a lot of sense.
And this goes down to the actual Django ORM models, right?
Yeah.
Cool.
Well, I don't have any use case for this.
I don't think right now.
But I can certainly see that a lot of people out there would.
I mean, like I said, if you've got a group of people associated with one customer and another
group of people associated with another customer and you want to make sure that only their data
is all kind of shared, but not overly shared, then this is a cool use case.
Yeah.
Nice.
Well, that's a really good find.
Yeah.
Cool.
Awesome.
All right.
Brian, you ready to commit?
Oh.
Race condition.
Yeah.
So I think we've talked about pre-commit.
I'm pretty sure we have.
Definitely talked about pre-commit hooks in the small, but not necessarily in the framework
style.
I don't know.
Yeah.
So pre-commit, well, this is the documentation for pre-commit, the normal pre-commit everybody
knows and loves.
And if you don't know it and love it, you should probably check it out because I wanted to bring
up a couple of things.
One of them is that it's a lot more than just, so I am along with a lot of other people
ran across pre-commit with things like, I want to remember to run black and, you know,
I know I'm going to run my tests.
So I may as well just check, make sure that all the tests pass before I check stuff in.
And maybe I'll run the linter and just go ahead and run black over something.
And then I don't have to worry about it too much.
Things like that before you commit.
And that's where the pre-commit got its name.
But there's a lot more hooks than commit or the pre-commit hook.
With the pre-commit tool, you can hook into pre-merge and post-merge and all sorts of entry
points around version control.
So it's a very powerful tool.
And there's a thing when people build up a whole bunch of tooling around it.
And you can also get best in class little hook snippets from other people to plug into
it, which is really great.
But if I'm sharing it across a whole bunch of different projects, I kind of have to copy
that into all the repos.
But you don't really have to anymore because now there's a pre-commit CI.
So it's a continuous integration type version like a lot of other, like, I don't know, like
Travis used to be or something or other sort of CI tools.
This is another CI tool chain that you can use.
And it'll run.
You can set up pre-commit hooks and run it over a project.
And one of the nice things about it is you can have a whole bunch of different things set
up and configured and run it against multiple projects and have that just set up in a different
place.
So this is a really, really kind of a cool tool.
And I've been trying it out on a couple of projects.
So yeah.
So we have pre-commit, pre-commit framework, which lets you use pre-commit hooks.
There's a lot of layers.
It's like turtles all the way down.
You can have pre-commit, you can have pre-commit hooks for Git, but they might be written in
all different languages like Node or Rust or Python or whatever.
And getting those installed and running can be a pain.
So there's the pre-commit framework, which lets you not worry about that stuff and just
run all these pre-commit hooks from different sources.
This is another thing on top of that.
This is the pre-commit continuous integration server.
So people have heard of pre-commit before.
This is like extra new stuff that Anthony Sotili has been working on, right?
Yeah.
And he's been doing this on the side for a little while to try to, it's a, it's believe
it's, well, I've signed up.
Uh, with, through GitHub and I think it's free for open source projects.
I don't know the details.
Um, but, yeah, anyway, I, I think it's a neat idea.
Um, I occasionally get, so one of the things that's nice about it, obviously I'm going
to run pre-commit the, the hooks, but if somebody merges something into my code, they can, they
can choose not to do that and do a merge request.
And this, this allows all those hooks to run on all the merge requests.
So I'm, I'm a big fan of putting stuff in CI because I've seen so many scenarios,
where people are part of some of the people on the team are really excited about this and
really want to work with it.
And other people, they don't even want to be bothered to figure out what it is, but they're
in attention to, it means the builds break and other stuff goes wrong for the people who are
trying to keep, I don't know, the linter happy, the unit test running or whatever it is.
Right.
And so if you're relying upon pre-commit hooks, this means that everybody gets their pre-commit,
their, their commit hooks and stuff run and validated, not just the people who didn't, you
know, ignore them or whatever.
Yeah.
Um, like for one example is like, just like black, for instance, if you like to run black
over your stuff before you check it in, you can just not even see it before, people
do it.
And one of the nice things about this is that it can, it can change, create a new
merge request.
So one of the things it'll do is if somebody does a pull request or merge request, whatever,
uh, against your project and you want this stuff run, like for instance, some of them will
actually change your code.
Black's one that changes your code.
So this takes the old merge request, runs black on it and then creates a new merge
request with the changes.
Uh, so that's nice.
Yeah.
Cool.
Okay.
Are you using the, pre-commit hooks or anything like that with your teams?
Uh, no, I'm just aware of black, but when Brian explained it, it's, it's, yeah, it's
similar to it.
Although it's, something that you put on GitHub.
Did I understand it?
Right.
Well, or, or, or, or whatever your.
The continuous integration version that we're just covering does, you can put it on
GitHub, but the, and pre-commit works with GitHub projects as well.
Um, but it's a, something you run locally.
So you have it, it's, it's run by get pre-commit hooks are triggering the, the hooks that you
can configure.
Yeah.
That's a, yes, it's turtles all the way down.
Um, yeah.
So Brian, I don't know if you have any awareness to this or not, but I'll ask you anyway, just
tell me if you don't know, would it still make sense to run, put the pre-commit framework
locally and have it try to do it locally before it happens in GitHub.
So maybe you get a better, more immediate feedback on it or.
Yeah.
Just like depend on the one on the CI server.
Of course I do.
Um, so that, because I, I want to catch it before I push it up for my own stuff.
But if somebody's, wants to, you know, do a pull request, I don't even want
to look at their code if it doesn't pass.
I mean, I mean, it might be a cool idea, but, but if it's, if, if, you know, it's a lot
of work if somebody pushes something and all the tests are broken and whatever.
Yeah.
And then we're like, you don't want to go back and say, Oh, I'll accept your PR, but you
have to go and run black against it.
And then I'll accept it.
Like just make it automatic.
Yeah.
Just make it automatic.
So.
Yeah.
Super cool.
All right.
And the next one here comes to us from David Smith.
And he, like many of our listeners are, is it very helpful?
Sends in things periodically.
Says, Hey, I happen across this thing at sneak S N Y K.io.
And I'm not sure how new this is, but it's quite neat.
So over here we have the sneak package advisor and it's not just for Python.
It's for many of the things, I guess, three of the things, the moment, NPM, IPI and Docker.
And what you can do is you can go over here.
I'll just focus on IPI for now.
And you can put in packages like they have Django there listed.
So let's put Django in and see what happens.
And it will tell you what is the package health score?
What is the security story?
Have there been issues?
Have they been fixed?
How often is this being worked on?
So many times people who are new to Python or even not new to Python, but new to an area
like, you know what?
I want to start using async and await with an ORM.
What are my options?
I've been using SQLAlchemy and imagine it didn't get as update.
I got to switch to something else.
What are my choices?
Here's four.
How do I know which one of those four is still alive, healthy, et cetera, et cetera.
So you come in here and you can see some information about it.
I'm going to say that this is not necessarily the best.
Let me see if I can find Django without.
One of the things I'm seeing that makes me kind of wonder, I clicked on maybe the wrong
one.
I clicked on a specific version and it said it was not very popular.
I'm like, that can't be right for Django.
It's an unpopular package.
So it tells you things like, what is the popularity?
And for Django, so this is a key ecosystem project, like too big to fail, sort of.
What is its maintenance story?
It's healthy.
Does it have known security concerns?
No.
Is this community active or whatever?
And then also it's cool.
It has, you might also look at these other packages.
Like Django is getting 97 Flask.
It shows right there.
Flask is a 93 out of a hundred in its score and you could open it up and see why there's
a bunch of graphs around here as well.
You can see like the commit frequency, the open issues, open PRs.
When was the last commit?
GitHub forks, all sorts of stuff around here.
So number of contributors go down there and see that actually the community shows like the
recent people.
Does it have a code of conduct that it could discover, right?
Does it have funding that have a contributing doc?
What were the recent security issues?
All sorts of stuff.
You know, I'm not going to go through all of it, but there's a bunch of cool things you
can just pull up about other packages and compare them against each other.
You can pull up like Flask if you want and see that side by side and so on.
So what do you guys think?
Yeah.
Cool, right?
Yeah.
Yeah, I think it's neat.
It's similar to Django packages.org.
Oh, yeah.
Django packages.org.
Which is, like you said, a similar idea, but just for like an auth layer for Django or a
special admin back in for Django.
But this is more like for the whole community.
Yeah, for the whole Python.
Oh, or it supports other languages too, right?
Yeah.
Sort of.
It supports Node and Docker, right?
So, yeah, I think the idea is probably that more stuff is coming along, but I do like
this, you know, if everything else being equal and you can't decide, put two projects in here
and, you know, see what it says, right?
You can see, like to me, one of the big warning signs of an open source project is if there's
a bunch of PRs that are like six months old, nobody's even bothered to respond.
You know, somebody's gone to the effort of, I've actually tried to improve this.
I've done the work.
I've written the test.
Here it is.
Will you just accept it or tell me what else I got to do?
And they're not even willing to respond.
Like that is a huge red flag.
And that kind of stuff will come up here as well.
And hey, Anthony Shaw out there in the live stream is if you sign up with your GitHub creds,
Snyk will check your project requirements.txt for you and raise PRs if there's security issues.
Yeah.
Oh, nice.
And if you use PyCharm, the PyCharm security extension, it has Snyk is integrated in.
Oh, and Anthony, who makes then a PyCharm security extension?
Is that?
That's right.
Anthony does that one.
Awesome.
Yeah, that's really good work, Anthony.
Thanks for that extra information as well.
So you can just search a project on there.
Yeah.
Put me on the spot.
Search my cards.
What is it?
No, pytest dash check.
pytest.
pytest check.
Gotcha.
Oh, let's see what we get.
What are we going to get?
Hold on.
You're doing pretty good.
You got a 65.
I mean, look, you are recognized.
Look at this.
And you are sustainable with no known security issues.
I'm saying this is the same bad, man.
I mean, there are fewer committers than Django, to be fair.
But still.
Yeah.
Still, it's quite good, right?
But I'm surprised that there's 10 contributors.
This is just something that I.
It's pretty good.
It's probably my oldest package.
So that's.
Okay.
No, this is pretty good.
I mean, it has no known security issues.
That's pretty good.
And you could even embed a little package health score if you wanted to.
Right.
Well, let's get.
Let's figure out how I can get it up.
Yeah.
Get that into the 90s and then embed it.
Get up in the 90s.
How about that?
Perfect.
Fantastic.
All right.
Who's next?
I guess, Kayla, you're next.
So.
Yeah.
There you go.
Tell us about this one.
So this one has been contributed by one of the shows on Twitter fans.
And then when I first looked at it, I thought it's just another tool that tries to do away with JavaScript.
But then when I tried it out, I guess I kind of had an appreciation for it because it can be used for.
Yeah.
I imagine for hobby projects, like for people who.
Oh, wait.
Let me just explain what it's for.
It allows you to build simple applications or browser based GUI applications without the need to write HTML and JavaScript.
So it has input and output modules.
It's also based on Tornado when I check the requirements.
Oh, that's really cool.
So if you were going to write a script, just a terminal CLI type application.
Yeah.
And it would ask questions like input.
What is your height in centimeters?
Input.
What is your weight?
And it would convert that to a float.
And then you would print out the information.
So this has really similar stuff.
Like the input doesn't come from the built-in one.
It comes from PyWebIO.input.
And that'll actually create a text box.
And because you say the type, you'll even get validation.
Like, oh, this has to be a number.
That's pretty neat.
Yeah.
I think it can be used for hobby projects.
Like for people who know how to write Python code, but don't want to write HTML and JavaScript.
And it also as a teaching tool for, let's say, you're teaching kids the concept of input and output and don't want them to just use the terminal.
Yeah.
You know, it's really interesting.
My daughter wanted to learn Python and get into programming and stuff.
And I tried to show her stuff in the terminal.
She was just, no.
Yeah.
And then we started playing with Anvil, which has a similar, like really simple way to just get like graphical stuff on the screen.
And she was all about it.
She played with it for hours, creating little apps and quizzes for people and stuff.
And it doesn't seem like a big difference, but that visual aspect, I think it's pretty big.
I think people are, you know, it makes a big difference.
Yeah.
I was, so I probably use something like this for maybe build scripts, for instance, used by a team.
So sometimes you have like, you know, just a few questions you need to ask somebody.
Yeah.
And you can do that easily on a web form or something like that.
But if it's like a script that you're running on the command line and some people don't want to run to have interactive command line.
I don't understand that actually personally.
But there's definitely people on my team that will not voluntarily run a command line script.
Yeah, absolutely.
And it looks like it integrates into existing web frameworks, which is cool.
Yeah.
But it also, the way it runs, it looks like you might be able to actually package it up with PyInstaller and just go here, double click this.
And it'll come up with something.
Yeah.
The only limitation I see is that once you want to style the HTML code, but that's far, way far in the future.
I mean, once you start doing that.
Yeah.
You probably got to do CSS or something like that, right?
Yeah.
Cool.
That's a good pick.
Very nice.
Thanks to the contributor on Twitter.
Yeah.
Absolutely.
All right.
That's it for me, Brian.
You got anything else?
Well, I had teased about just saying that, well, we already talked about PyChix.
test check a little bit.
So the new package that I just put up last week, I guess, I went ahead and misunderstood.
There's a package called pytestPoo, which is a brilliant package that I thought I had it wrong.
I thought it put little like poo emojis for failed tests.
Turns out it didn't.
What it does is you had to mark a test with like poo.
And then it just showed those whether it passed or failed.
And I said, well, I thought, well, we kind of need a distinguisher.
So also, I don't think I could get my team to use poo emojis.
So I created pytestYuck because I'm a kid of the Mr. Yuck generation, I guess.
And so what it does is you mark a test with Yuck.
And if it passes, you get a green queasy face.
And if it fails, it actually throws up.
So this is a new and its download stats are the only day that recorded was 24 downloads.
So that's actually pretty good for its first day.
That's I'm going to say that's good.
It was probably all me.
But and then, I don't know, a month ago or so, I did pytestSourcePaths, which just allows
you to specify import paths for so that your test can find your code.
And then, as we already showed, pytestCheck is the one that's been out for years.
It just allows multiple failures.
So those are my packages.
No, those are really cool.
And you've been busy.
Yeah.
I'll try the Yuck package later.
Nice.
All right.
I got a few real quick things to throw out there at the end here as well.
Marco Gorelli sent over this project that he's working on called AbsoluteFi Imports.
So if you've got a package that's using relative imports and you would rather to
convert it over.
So all the dot and from dot or from dot dot, whatever, import something and turn those into
Absolute Imports.
It's like one line.
To me, it's a little bit like Flint.
Run that against your project.
It turns all the string formatting to f-strings.
This will do that.
But for the imports, take them from relative to absolute.
So that might be helpful.
People got some code to migrate and they want to do it like this.
And then notice Anthony Shaw was in the audience, but I was already going to cover this.
Last week, was it Kelly?
Or it is?
Who said, oh, when I talked about Beanie, the MongoDB ORM, she's like, oh, I thought you're
talking about Beanie Babies.
And then somebody threw out that Anthony Shaw should make a Beanie Baby plugin.
And it looks like he's already made a Beanie Baby bear.
Isn't that amazing?
He had this up like the same day.
Well done, Anthony.
Thanks for keeping it interactive.
That's awesome.
Yeah, that's good.
Yeah, cool.
And we've talked about supply chain issues and hacks and whatnot.
Well, this one should take people's breath away.
Like, I mean, you were like, oh, you don't want to install from this other install source
rather than from like main source on python.org or whatever I was talking about the other day.
Right.
I'm like, I'm building from source at this point.
This is driving me crazy.
Well, PHP didn't want to use GitHub.
They wanted to have their own like sort of GitHub like thing with their own authentication
and all that kind of stuff.
Well, somebody broke into that and literally put a backdoor into PHP itself.
Think about that.
79% of the websites in the world run on PHP and the runtime itself had a backdoor in it.
Just for a little while.
But yeah, I mean, just for a little while.
Yeah.
Like, so there's, we can even cut a little bit of a diff here in this Ars Technica article
I'm linking to like, excuse me, what does this line do?
This line executes PHP code from within the user agent.
If the string, if the user agent includes zero DM.
So you just put your user aid, you just put the hack you want to run in your user agent
and do a request to the server and off it goes.
That's nuts.
That's not good.
So thankfully that's not Python.
And then this one, this one was you, Michaela, right?
Yeah.
It's the last day.
It's the last day of the March membership drive for the PSF.
I mean, they said that you can be a member any time of the year, but it's the last day for
their 2000 goal member for March.
Yeah.
Super cool.
Hopefully they're doing well over here.
Yeah.
So people, please be part of that.
If, yeah, if you want to be great to support them that way.
All right.
And I got to say, Michael, thanks for bringing up Flint.
I was actually forgot about that and I need it.
And, and.
F L Y N T.
Love it.
Yes.
Y N T.
I was Googling it for a while until I found it.
Yeah.
Nice.
Yeah.
I've turned that loose on some, most of the Python code I have to live with and any frequency
I have to go back to.
It's like, just find all the strings and make them f-strings.
Then I'll go look at it.
Lovely.
I love it.
Okay.
All right.
Speaking of love and stuff.
How about a joke?
I love one.
All right.
So this one comes not to us, but was found and Ricardo Ferreria put this out on Twitter.
So I thought this would be fun.
Like we've talked about comments before and we've even had those jokes where it's like all
about the comments, right?
It's all the crazy things people put in their comments, like, you know, hash, I really need
to find a better job type of comments.
So this one is more visual.
I know some people are more visual and commenting what they're doing.
So Brian, this is like a, like a smart speaker or like a, like a, some kind of conference
phone.
And on the phone, it's got some buttons and they have little icons, like a mute microphone,
like a phone number one to like maybe place the call up down volumes have like louder volume,
less loud volume.
Maybe describe the comments for our listeners.
Well, there's dashed lines to go to each button with like a manual or something, right?
With it, with like the, the same icon that's on the device, just next to it.
Just, yeah, exactly.
This is like just the, the, you know, slash, slash or hash or whatever of the, you know,
logger, logger equals new logger was the comment, you know, hash logger.
This is the same, but, for documenting the user interface.
Yeah, that's definitely like the, the, you know, string user comment, the user.
Exactly.
Beautiful.
Nice.
Yeah.
Well, super fun to BS about Python again with you this week.
Thanks Michaela for joining us.
Thanks Brian and Michael.
Yeah, it was really great to have you here.
Thanks for coming.
Good to see you as always, Brian.
Bye.
Bye guys.
Thank you for listening to Python Bytes.
Follow the show on Twitter via at Python Bytes.
That's Python Bytes as in B-Y-T-E-S.
And get the full show notes at pythonbytes.fm.
If you have a news item you want featured, just visit pythonbytes.fm and send it our way.
Always on the lookout for sharing something cool.
On behalf of myself and Brian Okken, this is Michael Kennedy.
Thank you for listening and sharing this podcast with your friends and colleagues.