Python Bytes - #424 We Will Test in Production
Episode Date: March 17, 2025Topics covered in this episode: The weird quirk with rounding in Python Python interpreter adds tail calls Remove punctuation from a string with translate and maketrans Extra, extra, extra Extras J...oke 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 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: The weird quirk with rounding in Python Tom Nijhof-Verheesb With numbers ending in .5, Python always rounds to an even number. round(0.5) → 0 round(1.5) → 2 etc This follows IEEE 754 You can use decimal if you need a different behavior. Michael #2: Python interpreter adds tail calls Ken Jin, a member of the project, has merged a new set of changes that have been benchmarked as improving performance by 10% for some architectures. "Speedup is roughly equal to 2 minor CPython releases worth of improvements. For example, CPython 3.12 roughly sped up by 5%.” Brian #3: Remove punctuation from a string with translate and maketrans Rodrigo “Don't use the method replace to remove punctuation from a Python string. Instead, use the method translate.” Michael #4: Extra, extra, extra Animation v Coding, hello world to transformers TypeScript rewritten in Go Firefox lies PyCon’s Startup Row Python in Production Book Extras Joke: Startrek Testing
Transcript
Discussion (0)
Hello and welcome to Python Bites where we deliver Python news and headlines directly to your earbuds. This is episode
424 recorded March 17th, 2025. I'm Michael Kennedy and I'm Brian Ocken and this episode is brought to you by us
Check out all of our things courses at Python tests com
Python dot FM all the places if you want to get in touch with us, social media is probably the best
place. I have a couple of things sent to me on social media. I don't know about you, Brian, but
a couple that I'll be covering today. So that's always fun. Find us on Blue Sky, find us on
Mastodon. It doesn't matter. Doesn't matter what server you're on. Everyone talks to everyone on
Mastodon. So you can find the links for all those at the top of the show. And we're refining and improving our newsletter format.
It's getting better and better and more valuable, I think.
It's got a nice little TLDR.
Grab the links, grab the joke,
and then dive into it if you want.
And yeah, so buy them by set FM,
smash that newsletter button and get signed up.
I think people are getting a lot of value out of it. It's
really nice, Brian.
Yeah, I think it's great. Also, yeah, we've mentioned this before, but I really love the
what you should know if we cover a topic that you're not quite understand, don't quite understand
what that topic is all about. You can check some of the background links in those. So
that's cool.
Absolutely. I totally agree. And thank you to our Patreon supporters as well. Now, let
us begin. Let us begin, Brian, with your first item. What you got for us?
I have a weird quirk around rounding in Python. And actually, this is just apparently normal.
This is a feature, but I didn't know about it or I had forgotten about it. So we're linking to the weird quirk around rounding in Python. And
the weird quirk is really just if your number ends in 0.5, like 1.5, 2.5, things like that.
If you round it, it'll become even. It always goes even. So I didn't know this, but apparently it works better that way.
And that's part of the IEEE standard 754.
So 0.5 rounds to zero, 1.5 rounds to two,
and so forth and so on.
Negative numbers also.
So negative 1.5 will round to negative two.
So did you know this?
I did not know this. I do not accept this. I don't accept this as a mathematician, formerly,
but by lots of training and education. I do not accept. So what do you always round it
even numbers.
So the normally like when I, I had spent a long time since I'd been in primary school, but isn't the like hand math
thing that you round up if it's like 1.5?
You round, it goes to the closest whole number.
Wait, but at.5 there isn't a closest, it's right in the middle.
Ah, I see.
So if it was.1.5000001, it goes up.
Yeah.
It goes up yeah it goes up I see so it's it's basically deciding at the
where's the decimal rep the decimal representation of the cutoff so four
point in my world four point nine nine nine nine nine non repeating but as many
nines as you care to put goes down and point five and above goes up oh if it's
one point four you round down in regular math, right?
If it's 1.4999, you round down.
If it's 1.4999999, as many as you want.
All the extra decimals don't matter.
It's only with like the actual, just one,
if it's 0.5, zero, all zeros.
So it's like 0.5, 1.5.
That's a tie then, there is no closest zeros. So this is like 0.5, 1.5. That's a tie then there is no closest
integer. So where does it go? And I thought in math that we always just like half goes
up.
Yeah, that's what I thought too.
But so it doesn't it makes it make and there's reasons around it because if you if you average
you want the average to be like if you averaged a bunch of these, you want it to be five like average. You have a bunch of random numbers like zero through 10 or one through. Yeah. I don't
know. It's going to, you want it to be five. But it's not, it's a little bit off. So the, this,
this standard makes the average work. However, if you really want the normal way that we've been taught in grade
school, there's a there's a decimal feature that you can have it be round half up. So
you can make it work normal, but apparently it's doing the right thing. You just didn't
know that was the right thing. So anyway, it's a feature. It's also known as bankers
rounding or Dutch rounding, apparently that's learned something new there
And being that Guido is Dutch. Maybe that has something. I don't know. So
Just if you're rounding numbers, you should be aware of this. That's it really
Yeah, you want an easy way to put it back to like grade school rounding all you have to do is
Just say int of your number plus 0.5. Int plus 0.5, okay. So if it's 1.5 plus 0.5 it's 2
and as a decimal but then you turn it to an int it's 2. Oh right. So it's basically
just a truncate. Yeah it truncates it. The 0.5 is like okay bump it up. If it's
0.5 or above bump it to the next number then chop it off.cates it. The 0.5 is like, OK, bump it up. If it's 0.5 or above, bump it to the next number, then chop it off.
Yeah.
Weird.
I wonder why we do it different with it anyway.
I don't know.
Interesting.
Thanks, Tom, for the article.
A lot of stuff.
OK.
What do you got for us?
Well, I've got some pretty interesting things
here in terms of Python performance improvements.
So Brian, are you a fan of recursion?
Not really.
I'm not either.
But I was against my will forced to take two programming
courses in college.
One was Fortran and one was Lisp.
In Lisp or Scheme, it's all about recursion, right?
Yeah.
Like there's no, the way you do loops is to do recursion
and so on.
And in certain, not in Scheme, but in other languages,
you can pretty quickly run out of stack space
by doing recursion.
And you might have gotten a stack overflow exception.
That's the name.
That's the name.
What does this even mean?
So there's ways to rewrite that at the runtime level
to say the reason you run out of stack space is every function call
gets its own new stack frame allocated and all of its locals
and all that kind of stuff.
What if we could just say, reuse the existing stack space,
grabbing some of the local variables that are being passed
and just kind of reusing them, long as you find a way
to save the data to kind of go up the stack
and you hit return or something like that that right? Yeah. And to my limited
experience that's what tail calls do. So if you've heard about adding like doing
tail recursion to make your recursion much faster that's because not every
single it's basically every single step in the loop you don't have to recreate
the function frame so that's really good. And so the idea here,
the news is that the faster CPython project has added tail calls to Python.
This is not exactly the same thing because it doesn't exactly have to do
with recursion. It has to do with stepping through the bytecode
instructions. Okay? Okay. traditionally, there have been different ways
in which Python does that.
And the article from lwn.net says,
Python's mini interpreters.
So when you run a Python program,
it converts it to bytecode.
Yes, we know this.
It says, however, there's actually
a couple of ways in which this could be executed.
There's the switch-based interpreter version.
And then there's a go-to, what do they
call it? The go-to, computed go-to statements version, okay? Which they say is a micro op
interpreter. This is relatively new. Like you maybe have seen the giant switch statement and by giant
I mean 3,500 lines of C, switch statement, single switch statement within a for loop that says
for each, you know, go to the next byte instruction, switch on what it is, do that, right?
That has still stuck around because certain compilers don't support what's called a computed
go to statement or dynamic go to statements, which sounds terrible, but it's a compiler
level thing, not a human code level thing.
Go to statements are bad for people, but they're not necessarily bad for compilers.
So the reason the old one is around is some of the compilers can't take it, but the new one's a little bit better.
So the idea here is that, I'm going to give credit to it. So Ken Jin, member of the Faster CPython project, has merged a new
set of changes that have up to 10%... actually up to 40% performance improvements on average,
a geometric mean of 10% improvements, which is pretty awesome. So the idea is that we can change
the way that that go-to, that computed go-to-based interpreter works using
tail calls. So kind of like I described for recursion, it's reusing the stack frame as
an optimization. So modern compilers like Clang and GCC can do tail call optimizations
opportunistically, but until recently they weren't 100% guaranteed. You know, like some
compilers have that level like dash 01, 02.
Like you put it up too high and stuff starts to break, you're like, huh, that's weird.
You think that would just work.
But right.
And I think that's kind of the case is here.
And apparently it's more stable so they can rely on it.
So basically there's this new interpreter.
And as the article points out, like it might seem crazy to add a third interpreter to Python and it seems like a lot of work, right?
Yeah, but if you go down to the bottom it says somewhere that
Jin's change is only about 200 lines of Python code which generates the
Interpreter and generates the code for the tail calling version. So it's actually not very much effort at all
So what it does is it'll say like does your compiler support this faster version of behaviors? If it does, we'll give you a faster
Python. I think that's pretty awesome. Yeah, yeah, yeah, I think. Yeah, I think so. Yeah, long as it
works. And so this is already merged into Python 3.14, which is pretty excellent. And it does say,
look, if you're on an older build of Python
or you're building Python yourself with an old compiler,
you're gonna get the slow version.
Like, okay, if you care about faster Python,
compile it with modern compilers
or download a one with a binary.
I bet you UV is already on top of this,
you know what I mean?
So 314 already has this in it?
That's what it says. Okay, cool.
It says merged.
Jin's work has been merged and should be available
to end users and Python 314 expected.
Whoa, Halloween 2025.
But what's really interesting here is
Jin measured the performance impact of the change
as a 10% on average, but up to 40%
on some benchmark speed improvement
and then framed it this way,
which I thought was really interesting.
The speedup is roughly equal to two CPython releases
worth of improvements.
So like 311 to 313 in this just 200 lines of Python code,
which is amazing.
For example, CPython 312 roughly sped up by 5%.
So yeah, year over year sort of thing.
So just this one change in 314 is going to be pretty mega.
It's awesome. Yeah. Yeah. No, this is really cool. I'm, I'm just,
when I first heard about this,
I was excited that maybe we get tail recursion optimization in Python,
but we don't. So I'm okay with that. It would be good to have,
but let's not encourage them. Now I use recurs without it. It would be good to have But let's not encourage them. No, I use recursion sometimes look if you've got hierarchical data structures recursion is magical, right?
It's like it exactly matches what you do with that hierarchy as you kind of traverse it
But in rate but in life though, I think I've only used to recursion and tail optimization in college
Yeah, so but I don't do sort of because I don't do recursive sort of things very much.
That's all right.
Yeah, yeah.
Andrew out there points out,
I was overly excited to see this
when I first saw these headlines,
thinking Python itself was getting tail call optimization.
Very nice, nonetheless, going to motivate me
to get Clang builds working with the required options.
Yeah, absolutely cool. Like I said, I hope the UV folks are on this cause
UV, V, E and V, and we just get 10% faster. Like let's go.
I'm here for.
Yeah. And I actually, I think that because of UV,
we're getting more people trying new versions of Python faster because all you
have to do is create a virtual environment and pick a picket and you get it.
Dash dash Python three dot 14 B or whatever it is. However you specify it. Yeah-dash-python-3.14b or whatever it is,
however you specify it, yeah.
Yeah, so.
Absolutely.
All right, back to you.
Okay, well, let's see.
We've got something from Rodrigo.
Rodrigo and I'm, get her out, anyway.
Rodrigo, from MathsPP.
Maths, okay, I'm gonna have to work on this one.
But he puts out a lot of great stuff.
He's writing about Python and very active on Blue Sky.
And I think I don't, maybe somehow I missed this.
This is, he's using translate and make trans together.
He said, don't use the method replace
to remove punctuation from a Python string.
Use translate instead,
it's much more efficient and more general.
And his example, which I had to like parse a little bit
to figure this out.
So basically like his example of hello world
with a comma and an exclamation point,
we want to strip that all the punctuation out.
How do you do that?
Well, you can use make trans,
which is translates from one string,
like some things in a string to another set of characters in a string. It's kind of a
weird function, but he's giving it nothing. So the translate from and to are empty. But
he's also giving the third parameter is stuff to just strip out. And the way of make trans
does does that is it translates a,
takes all of the characters in the third argument
and replaces them with none.
And those just end up getting removed.
And for the third character,
he's using string.punctuation.
So he's creating a MakeTrans, a translation table
that all it does is remove punctuation.
And that's what we want,
passing it to trans
and you get a string.
And it still seems like maybe there might,
there should be an easier way in Python to do this,
but you know, that's pretty cool.
I like it.
So he also has an article that talks about
not exactly this thing, but he's got an article
about string translate and make trans methods
if you wanna dive deeper into those, or you can just
use this little trick.
So very interesting news to me, you know, it's a little bit like when I learned
that strip, if I have like STR, if I want to take STR off of the word string and
just leave ing, right?
If you say L strip and you put the, the string STR in there, I always thought it would find that string and take it out.
But no, that just takes the Ss and the Ts and the Rs.
So R2S would also be right.
So there's remove prefix and remove suffix
and stuff like that.
And this one's a little bit like that.
Like, huh, it didn't quite do what I thought,
but apparently there's another way.
Yeah.
And one of the interesting things about MakeTrans
that always throws me is it's an ordering thing.
So you go like from and to,
and it utilizes the fact that strings are iterable.
And that's not something I normally think about
unless I'm, I guess when I'm parsing stuff
and I'm parsing a file or parsing a line,
I like it, I utilize the fact that they're
iterable but normally I don't iterate it over characters of a string. That's seems like
maybe that's too easy to get wrong. But anyway.
Yeah, perhaps.
All right. What you got for us next? Oh, we're done.
Well, I got extra, extra, extra, extra.
Extra, lots of extras.
Yay, because we had some short topics.
So let's get some extras.
Get some extras.
So first of all, this was sent in by several people,
including Owen Lamont, thank you for that.
And this is a nine minute video
of animation versus coding.
And it's the weirdest,
I don't even know what to make of it
it's an insane amount of work that these people put into it i'll just play a little bit of it
as as we're talking brian and so the idea here is it's like an animation of somebody writing code
and seeing how it kind of interacts and then the computer kind of comes alive and there's a battle
with the computer the computer will like fire up turtle and all sorts of stuff and it ends up in the end
like creating AI's
to run around and
Doing all sorts of stuff and I think
Spoiler I think the person character wins by like controlling the computer. Yeah, I'm not entirely sure the outcome
I totally forget but it it features Pygame, Pandas, PyTorch.
I mean, it's nuts.
So anyway, if you're looking for some entertainment,
that's worth checking out.
That's pretty cool.
I'm gonna watch that.
It's a 10 minute video though.
Yeah.
If you're eating lunch or something,
you're like, I need a little break from programming.
Let me watch a video about programming.
I can do that.
Yeah.
All right.
Next up in the news, I brought this up more as a parallel,
as other places are doing this too, right?
So one of the concerns and benefits
of a lot of these new tools is they
are written in Rust for Python, right?
So why is UV fast?
Mostly algorithms, but also Rust.
Why is rough fast?
Mostly Rust, probably also algorithms.
You know what I mean?
Like things like that, right?
Why are we running our website on Grannion?
Rust, Hyper, all those sorts of things.
So the folks over at TypeScript,
Anders Halsberg, the creator of it in the Microsoft team,
just made TypeScript, which is a typed JavaScript thing.
And I believe the runtime behind it as well,
I think there's some kind of runtime.
I haven't done much with TypeScript that way,
but certainly like its compiler and its language LSP
for editors and stuff like that,
10 times faster by rewriting it in Go.
Oh, geez.
So that's interesting.
And they said, look, we tried a bunch of different
languages. We tried Rust, we tried C, we tried Go, we tried, I think, Zig. They mentioned
a lot of languages. And he said, look, Go allows us to align the memory stuff as you
do in native languages, like align the memory structures exactly right for the compiler
and stuff like that or something. So anyway, I know a lot of people
listening also do JavaScript and TypeScript stuff and I think it's, you know, here's another 10
minute video to watch that's kind of interesting. 13 minutes technically. So that's like the
everything that uses TypeScript would be faster than or? So that's what I'm not, there is some
kind of runtime that they're doing something with that they rewrote.
Like, TypeScript used to compile itself with TypeScript.
But there's also something that runs
that does the language server.
I feel like it's a little like Node.
But like I said, I'm far out over my skis at this point.
I think when you talk about stuff that runs it, mostly
that's in the browser.
And then that's going to be just the JavaScript engine.
Because the now Go go based transpiler compiler will
compile the JavaScript and then it's run natively natively you know anyway
pretty interesting I thought it was worth throwing out there because it's
like oh Python's getting overrun by rust what's what in the world's going on like
this is a trend of more places not just Python it's what I kind of want to point
out here yeah they made different choices for different reasons,
but it's still pretty interesting.
Thanks for showing me that, YouTube.
All right, this next section I entitled Firefox lies.
So, Brian, it's very exciting.
This weekend was the first Formula One race of the year,
and they're gonna have something like 23 more.
And it was amazing.
If you haven't watched it, I won't spoil it,
but it was one of the best Formula One races I've watched in a very long time. It was full of drama,
full of interesting things. It was good. So what does this have to do with Firefox? So
I tried to watch it. I subscribed to F1 TV so that I can watch all the races, all the
replays, all the qualifiers, all that kind of stuff. Instead of getting cable, which
is a complete ripoff, you know, paying 200 bucks a month, I paid like 80 bucks
once and I watch all those with replays and whatever, right? I tried to watch that with
Firefox. Do you know what it said? Your browser is out of date and unsupported. You cannot
watch this website. You must go away because you don't have chrome basically and I said, huh, I seriously doubt it
I seriously doubt that Firefox won't work fu f1 I said
And I said no we're doing it
We'll watch it in Firefox because I have all this blocking turned on in my other favorite browser
Vivaldi, right and I don't want to turn off the blocking and stuff
So I have like kind of my bare Firefox is the the one that allows all the badness through so I can
watch stuff that you know Peacock and F1 and so on so when they say you can't
watch them like no I can watch it so what I did is I the link I'll link to
how you do this but I just went up and just told Firefox its user agent is the
latest version of Chrome. Hence Firefox lies.
Went back, I went back to F1 TV.
Welcome. Which replay would you like to watch?
Boom. Perfect. Played perfectly.
There's nothing wrong with Firefox.
The people are just too lazy to test against it.
And so they're like, well, you got to have Chrome.
Like, all right, fine. I have Chrome.
Oh, look, it works.
This is the same reason that Vivaldi works.
Vivaldi, you cannot know the market share of Vivaldi
per user agent, like some of the sites that track user
agent frequency and stuff.
Because they just say the same thing.
They just say, my user agent is the latest version of Chrome
so that it works.
Because if everybody had to also say, we also support Vivaldi,
it would say crap like that all the time. Yeah. And so if you love Firefox or any other
browser really but I have instructions for Firefox and you run into the
problems just make it lie. I'm really I'm really really loving Zen and we talked
about that a few times and I'm considering making my Zen claim to be
the latest fire latest Chrome as well. Yeah one of the that's one of the
reasons why I like Vivaldi as well because
especially in corporations, a lot of internal tools, they don't want to, I mean that's a lot
of work for internal tools to test everything. So they just usually test against Chrome and so
with Vivaldi I can just use internal tools just fine. Yeah, it's indistinguishable, it doesn't
know. Why wouldn't it be?
It's literally the same embedded engine
in the terms of a vault.
It literally is Chrome.
It just doesn't have all this come baggery to it.
Yeah.
All right, this extra is getting long.
Go quick.
All right, startup row.
Startup row applications are open.
Does your startup qualify for startup row?
Here's some criteria.
Use Python.
Your startup is less than 2.5 years old,
you have less than 25 employees, et cetera, et cetera.
You will come to the conference and so on.
This is a really cool program.
And if you have a startup and you wanna get some awareness,
consider applying to this.
So this is at PyCon on Sundays.
There's, they take away all of the booths and everything like that. And then we have
a couple rows of startups that you can make.
Yes. I think it even might be Thursday through Saturday. I think it might be during the expo.
Oh, during the expo.
Last year, it was in a corner, but it was, I think it was during the expo.
Oh, right. Yeah.
Yeah. You basically get a booth as like a $10,000 equivalent booth as if you were another advertiser there
But it's to promote your python-based startup. So people should check that out
I actually did an interview two years ago coming up on two years ago called a stroll down startup lane
Or I went interviewed all the people all the different startups like 10 minutes per startup or something like that. Nice
Last last of the extras. I am publishing a book Brian something like that. Nice. Yeah. Last of the extras.
I am publishing a book, Brian.
Wow, neat.
Yeah, thanks.
Talk Python in Production.
So the subtitle is A Cloud-Agnostic Guide
to Building, Scaling,
and Managing Your Own Python Infrastructure.
So I've talked a lot about different ways
we're doing different things with infrastructure,
but here's a book.
It's about 250 pages.
That goes into all the details of like how you can run efficient,
high performance, but not complex, not expensive Python infrastructure.
And you can buy, you can read about the first third of it online and it says buy the book,
but you can't quite buy the book.
Just today I'm still trying to get it all ready to go.
So right now you can subscribe to get notified when you can buy the book.
And in a week or two, you will be able to buy the book at Amazon and probably Gumroad,
is what I'm thinking.
Okay, I like Gumroad.
Yeah.
Anyway, so the link to that is in the show notes.
And hopefully people will check that out.
Cool.
Yeah.
All right.
That's it for my extras.
You got any extra extras?
No, I wanted to announce the changes to the course, but I, um, um,
but I'm still working on it. Life getting in the way. So yeah,
I hear you. Well until then people don't necessarily have to test, right?
Don't need work on your testing. Yes, they do. Yeah. No,
they can just test in production. So the joke is a star check one.
This comes to us by Greg Mediola.
Thank you.
Says as Goran says, we will test in production and die with glorious honor.
And it's got like a cool little meme over a Star Trek Klingon character.
Yeah.
Yeah.
But it's usually your customers that will die in glorious honor.
They die first and then you wither.
Yeah. Okay. Yeah, okay. So what I'm hearing is you're saying you don't actually support this advice.
I don't.
But there is a certain car company that seems to have pieces of their cars flying off.
Does it look a little like a spaceship?
Yeah, it does.
And apparently they just glued some of this stuff
onto the side.
Anyway.
You know, I was in Nashville with my kids the last summer
and we were driving along in our rental car,
which was not one of these space shippy things.
There was apparently a thing that goes along the column
has like a fancy cover, like a bodywork.
Yeah.
The columns that hold up the roof and along the windshield.
And it just peeled back, ripped off and started whacking against the car on the highway.
And this was on our way to the airport.
So one of my kids had to reach out and hold the bodywork in place for about 15 minutes.
And she was kind of done holding the body so we got
to the airport that's crazy so bad so bad did you get did you get charged for
the damage to the car no I kind of like mushed it back I said the house the car
it was fine that piece a little bit loose you might want to check it bye yeah
no it was okay. Anyway.
Anyway.
Yeah.
Test in production.
Test in production.
No, don't protest in production.
Test before production.
Absolutely.
But do, do listen to the show every week.
We'll be back next Monday at 10 probably.
Most likely.
Tell your friends.
Until then.
Thank you everyone.
Bye.
Bye.