#388: Python 3.11 is here and it's fast Transcript
00:00 Python 311 is here. Keeping with the annual release cycle, the Python Core devs have released the latest version of Python, and this one is a big one. It has more friendly error messages and is massively faster than 310, being between 10 to 60% faster in general, which is a big deal for year over year release of a 30 year old platform. On this episode, we have Irit Katriel, Pablo Galindo Salgado, Mark Shannon, and Brand Bucher, all of whom participated in releasing Python this week. They're here on Talk Python to tell us all about that process and some of the highlight features. This is Talk Python to Me episode 388 recorded October 28, 2022. Welcome to Talk Python to Me, a weekly podcast on Python. This is your host, Michael Kennedy. Follow me on Twitter, where I'm @mkennedy and keep up with the show and listen to past episodes at Talkpython.FM and follow the show on Twitter via @talkpython. We've started streaming most of our episodes live on YouTube. Subscribe to our YouTube channel over@talkpython.com/YouTube to get notified about upcoming shows and be part of that episode. This episode is sponsored by Sentry. Don't let those errors go unnoticed. Use Sentry get started at Talkpython.FM/sentry. And it's brought to you by Command Line Heroes, an original podcast from Red Hat that chronicles the history of the software industry. Listen to an episode at Talkpython.FM/Heroes. Transcripts for this episode are sponsored by AssemblyAI, the API platform for State of the ART AI models that automatically transcribe and understand audio data at a large scale. To learn more, visit talkpython.FM/AssemblyAI. Hey, everyone. Welcome to talk python to me. It's great to have you all here. Irit, Brandt, Pablo, and Mark. It's going to be super fun to speak with all of you about Python 311. Before we get into it, I guess just real quickly, I know some of you have been on the show before, but not all of you. So let's just do a quick introduction about who you are and how you ended up here on the show. Eric, do you want to start first?
02:14 Yeah. Hi, I'm Irit Katriel. I'm a python Cordev. Earlier in the week, we streamed the release of Python 311, and on the back of that, Michael just invited us all here for chat.
02:26 Fantastic. Yeah, that was a great live stream, and we'll talk about that for sure in a second. But Brandt. Welcome back.
02:32 Hello.
02:32 My name is Brand Bucher. I have been cordev for like, two years now, and I work with Mark and Irit on the Faster CPython team at Microsoft.
02:40 Right on.
02:40 And it was on the show like, a month ago.
02:42 Yeah, you were talking about the Faster Python stuff, which we'll touch on again.
02:46 Hello, I'm Pablo Galino. I'm the infamous release manager. I released Python 311 and you can draw all your complaints to my email address. No, please don't do that. So I'm a CPython core dev. I'm also serving this year and last year on the Python Steering Council. And I also released I released my Python 310 and 311, which is now the best version of Python. Download it today. Apart from that, I do a bunch of parser stuff, but now we are not talking about that.
03:15 Yeah. Fantastic. Well, welcome, Mark. Welcome back.
03:17 Hi there. I'm out. Shannon. I'm the tech lead of the faster C python team. I work with Irit, Brandt. I've been a coredev for some number of years.
03:25 I don't recall you've been spending a couple of years working on this Faster CPython thing and very excited to see some of the fruits of those labors starting to show up and get in the hands of everyone with this release.
03:37 Yeah, it's good to have the stuff out, actually, in public, in people's hands. It's really rewarding to know that stuff you're working on is actually used and used by a lot of people.
03:45 Yeah, that is totally true. It's one thing to build software just by itself, that it's fun. But all of you are working on code that touches so many people. Think about there's layers, right? One layer is how many people use Python. Many millions. Millions. Does anyone know a reasonable estimate of this number?
04:04 I think I don't remember who came with the number, but I think they were estimating, like, 6 million Python developers, something like that. I mean, probably between zero and 10 million, let's say.
04:15 Yeah, that's a massive impact. And also maybe nervousness about pushing code out to that group. But then those people build software for others, right? If you're using Instagram or using YouTube or other things, right. It's also having massive knock on effects there. So thanks for putting all this together. Thanks for improving the tools that we all get to use. So, yeah, big news. The big news is that Python 311 is out, and as Irit had said, you all live streamed that release. So here we're all together, we're having an awesome chat about the features and what people can do to take advantage of it and why they might care about new features and want to learn them. But you did a little bit of that. But also, Pablo, you actually, step by step, did the release of CPython mostly live, right?
05:07 Yeah, I did. It was except the boring part.
05:11 This is something that I started last year because apparently I didn't have enough things to worry and I decided to make my life even more difficult. I'm an expert on that. Quite proficient.
05:22 I'm also an expert. I'm very bad at doing too many things.
05:26 You could be a release manager is the only requirement.
05:29 So, yeah, the idea is that the kind of releasing Python is a process that is quite complicated. It's also quite boring. So it's not like you need to have a galaxy brain kind of thing to do. It but it's just a lot of steps and it's easy to do it wrong and it's very anglamorous. So I said, oh, wow, I'm sure people really would like to see a very Anglomerous process happening in life. And then I said, let's do it and I ask around and I was surprised about how many people enjoy anglamorous processes. And then I did the release of Python 310 beta one, which turned out to be much funnier than I thought because we just broke that happened live. Yes.
06:09 You imported all the issues and did that migration, or was that separate?
06:13 You will think that is a good candidate. But no, that was not the thing that broke it. We renamed Master Domain on the CPython repo and the whole GitHub platform was down. What about that?
06:23 Wow.
06:24 Yeah, you can see those Ruby workers really struggling with the renaming all those forks.
06:31 I don't know, someone may confirm this, but I think we were the first big project to do the renaming. Something went wrong and it was very funny because I literally said, how funny will it be if now I get a 500? There you go. 500 on the screen. Yeah, it's recorded. Someone actually recorded that clip. Yeah. So I said, wow, man, this has been such exciting thing that I can break such a big project, let's do it more. So I decided also to stream the 310 release itself. And I said, well, technically, the final release is even more boring and longer, so that is actually probably not going to be even something that someone went to see. So I said, okay, let's not do it alone. So I invited a bunch of friends and core developers so they can actually talk about the things that they worked on the Python 3.10 release. And Brandon were there, so they can probably tell you how they found out. But apparently it was something that a lot of people enjoy. Because it's not only an opportunity to see how the sausage is made. Because I was just explaining all the commands and all the faces and whatnot. But when something became very boring. Then Brandt were there to save the day and explain the cool things they work on.
07:45 Which is a very good opportunity. Because when is the last time you could hear the author of the feature that you love talk about the feature that you love? That's fantastic. And it happened, right?
07:54 And not only did it happen, but as they were explaining the feature that they built, the action of it being delivered to the entire world was like all coming together in a pretty awesome way.
08:06 Exactly. And I could only do that just to refer also and create work. I could only do that because the first time I did the live thing, I was also doing all the pushing all the buttons and at the same time doing all the video stuff. I don't know whether it's over to the stream, but whatever. And the second time, we use the help of the Python discord team, which are fantastic, and they help us a lot.
08:32 They have this fantastic UI where all the questions that were asked on the chat there are on the screen and we couldn't use it. Do you know why? Because Facebook or now Meta decided to break DNS globally. What an incredible fit.
08:47 Just in time.
08:49 So, what I'm learning is if we need some sort of big cloud global outage, you all just need to lie.
08:59 Me today.
09:02 Now, we were like two big outages on Python release.
09:06 There is only a line that passes through two points, but it was a good statistic already. So we said, what else can we break? So there you go. We decided to do the 311 release again and then Mark was there as well, which increases the probability of things being broken by a lot.
09:26 Sorry, Mark, I had to joke. He also fixes them, so it's fine. And nothing broke, so kudos to Mark. Everything thanks to that. And we did the release, so we did the same thing. We explained the whole thing so people could see from the author themselves, like, why all the switches are very cool. And I did the numbering parts of the release. And then we have a bit of some dramas in backstage because my jubiki that I used to sign release broke and I freak out quite a lot. But I thankfully have a backup jubiki. So, no, I have crazy app because if I didn't have that, then I will have to stop the whole thing. But we didn't have to do that. It was just backstage. So, yeah, quite exciting. Nothing broke. Except my UV, I suppose. That's a sub thing that broke. It's not a global software, but I still mourn it. It's here.
10:15 Yeah, it served you well. But now it's life for Python 311.
10:21 Too much power. Like 311 was too powerful.
10:25 This is a dangerous job that you got.
10:28 Yeah.
10:29 But you've handed it off, right? This is your last time, last main release.
10:34 Yeah. I need to do the security and bug fix releases, but I don't need to do the ones that you need to chase people down and ask for picking. There was a bunch of things of the release that were quite boring. Like, normally we released the previous version before the final version. There is something called the Release Candidate, which is the last version that people need to try out before we do the final release. And ideally, that is the last version that we publish. Normally it means that you probably from that commit, but this was not the case. This is the first release that had 130 something commits on top of that. And I have to painstakingly pick andd it was not fun, but I did that before the release. It's like 2 hours. You need to fix conflicts and things like that. Yeah, very boring. But yeah, I started the stream with that already, so it was fine.
11:22 Yeah. Fantastic. Now, before we get into all the features, and I want to maybe just talk a little bit about some of the tools for actually doing the release, maybe start with you.
11:34 What does 311 mean for you all getting this out? What does that mean for the Python community, from your perspective?
11:41 Well, 311 is a huge release. There's a lot packed into it compared to the last few releases. There are no features. There's the performance work, it's just massive changes internally. It's just a huge release. And personally, I started working on exception groups about two years ago, so for me, it almost feels like finishing another PhD or something. It's a massive kind of effort. And here it is. It's done.
12:09 It was a big day Monday. I had a bottle of champagne ready for the stream. It was a celebration.
12:14 Yeah, it was. Brent, how about you?
12:16 I'm really excited about 311 because I think there's something for everyone, and I think you'd be hard pressed to find someone who doesn't want their code to run faster and who doesn't want better error messages, and then you have all these other improvements. On top of that, it's really nice to see both these new features, which are something that we get in most Python releases, but also just the stuff that's there for everyone else who just wants to upgrade Python and just have a better experience all around.
12:40 Yeah, I totally agree with that.
12:41 It's cool to see people's responses to that.
12:43 Too.
12:43 Because responses have been really positive. Which is another thing that I like about the livestream. Because we did live Q and A. And it has a chat and everything going on. And when you're starting at the same code base for. Like. A year. You're like.
12:55 Okay.
12:55 I'm pretty sure that what we've done here is really cool. But is it actually as awesome as I think it is? Have I just been staring at it for too long and released the world? And people are even more stoked about it than you are, and that's a really good feeling.
13:08 Yeah, it is awesome. Mark yeah.
13:11 Well, I guess I started on trying to get Python faster 15 years ago, I guess early Phd. Yeah.
13:16 With hot pie, right?
13:17 Yeah, that was a long line. This has been a long time coming, so yeah, it's amazing to have it actually out and starting to see the speed ups, and obviously we're keeping working on it, so it's pretty good.
13:29 Yeah, fantastic. You must be really proud, because, like you said, you have been proposing this for a really long time. You've had a lot of ideas, and finally you've got a group of people working on it. And Branch, you're all on the same team with Mark and Guido. Yes. And just making legitimate serious progress here. So you must be really proud to just sort of see this actually go out the door.
13:51 Yes, definitely.
13:52 Especially in Maine too. It's really nice that we're able to deliver this for everyone.
13:58 Yeah, for me, I see basically three things. Kind of like you said, Brent. I see that obviously there's these new features like exception groups, which are lovely and make the language better, but it also gets friendlier, especially for beginners, but for everyone, of course, with the better error messages and better reporting and trace backs and it gets faster and all the axes that seem to matter, it's really fantastic. Okay, so let's dive in. Pablo, let's go back just a little bit to the release process because people got to watch you do it, but they didn't actually see exactly what you're typing on your screen. The whole time it was more of about an event of it. Sometimes your screen was up, sometimes it wasn't. But there's an official Pep that talks about like, here's the recipe for doing this right?
14:44 That is correct. It's Pep 101 doing Python Releases And that is a curious document. It's peculiar document, talks about how it's done, but it's kind of weird. So the document is up to date. Like you can actually search 101 and it would show you the thing. So what is there is the actual process. It also contains these weird sentences, like, if you search for it, there is a bunch of places that says stop, stop.
15:12 Quite funny. And that is, if I recall correctly, Larry Hastings, that he wrote those things and he could search for those places and he knows that at that stage he needs to wait for something to happen or something. And we left it there. So there's a bunch of like weird artifacts and it's full of bullet points because at some stages you need to do some things and some others and things like that, and it says, okay, if you're running a beta release and you need to do these bunch of things and if you're running an alpha religion, you need to do a bunch of things. And I have done a state machine that goes through the whole thing because if you actually write it down is it, how is it called? The maintainability index of this process is insane. It just rejects your things, right? And I said I'm not doing this reading. So one thing I did, which is the thing that I was using at the Stream, my first work as a release manager, said, I'm not going to do this by hand. And that's the vision. And then I did this script that is on GitHub/Python/release tools. And it's my attempt at automating this process as much as possible, which unfortunately it still requires a bunch of manual steps because like, that life and things happen. But it's quite automatic, like, at least things that are not like final release. So alfa's and release candidates. And now that we are in back fixed releases, it mostly runs automatically, except that in the final release, everything fails because the final release for you. And then you need to fix things manually. So I think you saw me executing a bunch of those fixes. At some point. I had division by zero just to know that something was hit and I was seeing on the screen because people were like, division by zero. Why do you need that to release Python? I don't know. That's very complicated.
17:04 I could have asserted false. Come on, anything wouldn't work.
17:06 No, we divide by zero. I'm a physicist, so that's what I do.
17:09 Okay.
17:11 You studied black holes, right?
17:13 Yeah.
17:14 You were looking for some sort of like, infinite sort of thing there. Divided by zero.
17:18 I'm too tired for today. Let's just collapse the universe. Divided by zero. But Python was too friendly. Instead of collapsing the universe, it sold me an exception. Quite nice. Only 3.11. No, I'm joking.
17:32 This portion of Talk Python to me is brought to you by Sentry. How would you like to remove a little stress from your life? Do you worry that users may be encountering errors, slowdowns or crashes with your app right now? Would you even know it until they sent you that support email? How much better would it be to have the error or performance details immediately sent to you, including the call stack and values of local variables and the active user recorded in the report? With Sentry, this is not only possible, it's simple. In fact. We use sentry on all the talk python Web properties. We've actually fixed a bug triggered by a user and had the upgrade ready to roll out as we got the support email. And that was a great email to write back. Hey, we already saw your error and have already rolled out the fix. Imagine their surprise, surprise and delight your users. Create your Sentry account at Talkpython.FM/sentry And if you sign up with the code Talkpython all one word, it's good for two free months of Sentry's business plan, which will give you up to 20 times as many monthly events as well as other features. Create better software, delight your users, and support the podcast. Visit Talkpython Fm/sentry and use the coupon code Talkpython anyway.
18:48 Yes, you can follow this up and just enjoy the whole process on its glory, or you can see the script, but yeah, it's quite verbose. You can see that it's lots of places where everything can go wrong and you can panic. Now we know one more only your dubiki can break. So that's something that can happen as well. But it's quite annoying and that's the main job of the release manager goes through this annoying process.
19:13 Yeah, I see that. There are some parts in here. You should have a few more stops, I should say. Stop, stop. Make sure GitHub still works.
19:19 Stop, stop.
19:19 Make sure Azure still works.
19:22 Yeah. Don't cry, don't cry. At this stage, everyone is looking at you.
19:26 The one thing that is not in this part is that you also are in charge in theory of this extreme abstract mandate, which is that you are in charge of the stability of the release, whatever that means. That translates more than chasing people because they broke things. Another unfortunate event that we are trying to also fix a bit for the release is that most people turn to the release manager to solve problems. So they say, hey, this person says that we should do X, while this other person says that we should do Y. We need someone to decide.
19:58 Let's reach to the release manager.
20:00 This guy on the corner, like he doesn't know shit. So he's not the best person to fight it. But everybody was like, what do you think, Paulo? So we merge this. I don't know, man. This is some enem thing. Like, I don't know about this. I have no context whatsoever.
20:14 Your only concern is will it still build and ship?
20:19 What about these 2000 lines? Of course it sold this tiny bag. Well, maybe let's not merge that. But yeah, we are trying to also redirect all of this to the Steering Council, which also I am in the steering council, so apparently I'm not going to get rid of these questions. I'm joking. I enjoy all these questions, but as a release manager, I don't. So I like the key here is that the release manager should not take unilateral decisions on the volusion of these things because it has the release manager. So the reason the thing I was.
20:44 You are the one who delivers the code.
20:47 You could sneak a feature on it.
20:49 I don't decide important things. I just execute and chase people. And I'm disappointed. I just said, do I just fix it? But then if there is an important decision to be taken, that the thing comes steering council job, which is five people, because one person shouldn't decide these things. And this happens. Like, sometimes they say, hey, there is this PR when people are asking what should we do? And then this is my opinion as the member of the team can't do. And the other four members, maybe they say, well, actually that's not a good opinion. So what about this? You know, we ended up in a much better place because it was five people. Five persons doing a decision instead of one.
21:22 But yeah, amazing. Okay, so people want to follow along with the process. They can check out Pep 101.
21:28 Let's skip over here.
21:29 You also talked about the Python billboard that people can check out. But I think maybe we want to jump into our first feature.
21:36 As Eric said, there's a ton of features and things in here, but there's also maybe some top level ones that will be really important for a lot of folks. And you want to tell us about your work. You mentioned before the exception groups and exception staff.
21:49 This is kind of a major new feature that we added. And the idea is that sometimes you have a situation where you did several things and maybe more than one of them raised an exception and now you need to report that there was more than one error in whatever you did. And what you did could have been a bunch of asynchronous tasks, which is that was the use case that motivated this whole thing. But there are also current situations where just iterate over a few things and repeat them and accumulate exceptions and you want to kind of report all of them. And the Pep lists a bunch of examples of where this can happen. So people typically what they do is they'll take a list of exceptions, rapid and another exception, multi error, some other kind of wrapper and throw that and then you have to catch it and then you have to iterate over the list and look at the exceptions. But you don't have a method to handle the exceptions. Like you have tried accept like catch these but not catch exceptions, right?
22:48 Because then accept you might have accept socket error or you might have accept like file not found type of thing. But if those both happen, neither of those would run in Python 310, right? Because it's some kind of weird wrapper and it's not a socket exception, it's not a file exception, but it kind of contains both. And so in a sense both run, I don't know.
23:08 And then if you catch the wrapper and you do something with some of the exceptions, you better not forget to raise the rest because you're not handling them. So yeah, there are a lot of problems when you try to work around this and like what happened with Trio. So Trio had multi error, would raise this wrapper and it had to do a lot of complicated acrobatics just to have some error handling. So the motivation was, yeah, we have task groups in person 311, which are kind of like trio nurseries, kind of a structured collection of asynchronous tasks. And task groups won the cards they started like Yuri Salibanov who was kind of maintaining asynchronous at the beginning. He wrote a lot of asynchronous. He wanted to add task groups since 2017, 2018, something like that. And what was holding it up was error handling. There was no good way to handling errors. So now we have Accept Start, which is what generalizes accept and works with groups. So you can say accept star socket error and then it will just extract all the socket errors from the group and give you those and automatically rearrange everything else. That's basically the idea.
24:17 This is pretty interesting. We have try do your thing and then accept star one error type accept star, another error type, accept star, a set of errors, potentially. So what happens if I'm in this situation and say, the first error type and maybe something from the third error error catch clause is thrown in one of these task group exception groups.
24:40 Each exception in the group will be handcuffed by at most one of the clauses. So the first clause that matches its type will consume it and each clause executes once. So if there are more than one errors of that type, than what gets kind of bound in the accept error as E? What gets bound to E is a group of foo errors. So you get all the foo errors in a group, execute that clause and then move on to the next clause with whatever is not handled yet.
25:07 Interesting. So it might run two of the clauses, whereas in traditional exception handling it goes from top to bottom and it looks for an inheritance type of match and the first one that matches, that's it. But in this case with the star you could get multiple ones. I guess the star, to me, when I look at this, the star is reminiscent of Arg's star where you have unpacking. Yeah, yeah, exactly.
25:32 It's not exactly unpacking, but it was kind of the intention to make it look a bit like unpacking.
25:37 Nice. Yeah, this looks like a really cool feature. You talked about the task groups and trio and those things. So when I saw this, concurrent errors obviously come to mind because if I try to both write something to a database and call a web service asynchronously and I start both of those and they both crash or multiple ones crash. Which error? Do you want the database error or do you want the API error? You probably want to know about both of them, right? So that's a real natural reason to bring these together. But maybe you've also listed out some of the other reasons that you might run into this, maybe give people some other ideas.
26:09 So the example of in the socket module we have the create connection function. In that function, I was showing it in the stream. Iterates over all the configurations that you could try to connect with and then depending on what's going on on the other side, hopefully one of them works. But if none of them work, you have to report errors. And what we do in person 310 is we just raise the last exception. So you don't know what happened, really. You only know why the last attempt failed. You don't even know how many attempts were made to connect to how many configurations did we try. So that was a long standing open problem, kind of can we do better than just before the last error we closed it, we just added them.
26:50 Another place that comes to mind is maybe you're familiar with some of these retry libraries, like Retry, but I think there's others as. Well, where you put a decorator onto some function, you say, try this multiple times and if it fails, do like some sort of exponential back off because maybe the server is overloaded. Right. Those types of things would be really great. Like if it retries all the time it's supposed to and it fails, it'd be good to get all the errors, not just the last one or the first one or whatever it decided it was going to give you yes.
27:19 Kind of thing.
27:20 Yeah. Nice. Okay, well, congratulations on getting that feature out. That's great. What have we got next here? I think also related to this, I wanted to talk about this Pep 678.
27:32 That's a very small and simple feature that Zach had to dodge. Wrote this Pep. He was trying out exceptional groups. He was the first kind of user even before the PR was merged. He was trying it out. He was trying to integrate it with the hypothesis library. So there you write a test and the library executes it many times with different inputs and you get failures and some of the inputs, and you want to report all of them. So that's had an exception group, kind of an exception wrapper, kind of like Chia Multi. Early had his own version that he built in his library and he could associate each exception he attached to it. Which input generated this error, which is very important. You need to tell people what the input was and what happened with it. And he couldn't do that in a convenient way with exception groups. So we added this to base Exception. This is not a group feature. It's any exception. You can add strings, you could add notes, give it a string and you can call it as many times as you want and add notes to the exceptions. And they will appear in the choice back, in the default trace back that the interpreter prints. So that's all it is. It's a very simple feature, but it was received surprisingly well. People kind of like it that you can enrich an exception after you catch it. So you have the information that the error message and the type. You decide that when you raise the exception, but then sometimes when you catch them, there's some more information, some context, like what were they trying to do when this error happened?
29:01 Sure. Yeah. Because often you'll see, except some type of exception type, you'll deal with what you can, but you can't really handle it there. So you got to raise it again. And this is a place to add more information without completely wrapping it.
29:14 Right, right, exactly. A lot of people have to chain it, say, this race from that. So there will be situations where maybe you won't need to do that.
29:23 Yes, I'd love to see that go away.
29:26 Sort of template libraries and stuff on the web all the time. I see that there's all these different errors and you got to hunt through a bunch of stuff to figure out what happened.
29:33 Yeah, but also, think about, for instance, I think this is super useful, actually, for end users even like think about that you're doing some security to the database and then, I don't know, it may fail for 6 million reasons. And then you want to add what you're asking for.
29:48 Right.
29:48 So you add your query or your user or whatever because probably the exception that the postgres thing that is underneath is not going to contain your actual thing. So this actually may save you hours right. Because in many enterprise environments, you don't even have access to that sorry. To plot. So you cannot just go there and see what's going on. So it would be super cool that you say, if something fails I was trying to do this with this data, like with these things, if it fails now you can see what's going on and you don't even need to log in, which is I think it's quite cool.
30:24 Yeah, it's a great idea. Or if, you know, here's probably why this happened. As a library developer, look, this is the error, but here's a note. This is probably because you didn't initialize the connection before you call this. So make sure another area where I see this could be useful is I want to raise, like, the example you have in the docs type error, but it could also be value error or some other built in low level type. Really, this is just I want to raise that error, but it doesn't have a place for me to put additional information and so I want to kind of enrich that with more so not just catch at the data and then raise it again. But actually I want to use a base error type that doesn't let me put more details in it and then just raise that. Right. That would also work, I think.
31:08 So I think the intention was there was some discussions about using notes in the interpreter and I pushed back on it because I said, this is owned by the application. The interpreter shouldn't push the notes because people can wipe out the notes, they can change the order, they can do what they want. It's the applications, at least the way application owns it, you put whatever context you want to put.
31:29 Is there only one note? When I say add note, does that set the note or can I have a list of notes?
31:34 It's a list of notes.
31:35 Okay, got it.
31:36 And you can wipe it out if you want.
31:39 It's just a list attached to the exception. You can do what you want with it.
31:42 Really? Yeah. Okay. Yeah. It's a really great feature. I mean, I'm sure it was way less work than except Star, but it's also going to be really valuable, I think.
31:55 This portion of Talk Python to me is brought to you by Command Line Heroes, an original podcast from Red Hat, Command Line Heroes chronicles the history of the software industry. If you want to get the big picture on how macOS and Windows became dominant players, as well as how Linux brought its radical open source opinion to the scene, then season one is a fascinating lesson. In particular, check out OS Wars Part One and OS Wars Part Two, The Rise of Linux. Season Three is all about programming languages, and it kicks off with a topic near and dear to all the Talk Python listeners python's Tale. I even got to be a guest on that episode, as well as Emily Morehouse, who makes a connection between Python's technical extensibility and its inclusive community. I talk about how Python is both easy to learn and powerful enough to build apps like YouTube and Instagram. Indian Mueller highlights how the Python community took the lead on so many inclusive practices that are spreading in tech, including the rise of community led decision making. This award winning podcast is hosted by Saran Yipbarak. Saran is a fantastic host and the show is highly polished. Seriously, if you love the history of software development, jump over to talkpython.fm/Heroes and check it out for yourself. Thank you to Command Line Heroes for keeping the show going strong.
33:10 Let's talk about faster Python for a little bit. So, Mark, I had you in Guido back almost to the day a year ago. We're off by November 1, 2021, so not that long ago. Let's talk a little bit about the work that you're doing there. I guess the headline is that Python 3.11 is 10% to 60% to 50% faster than previous sort of on a reasonable range of applications. Is that the story?
33:39 Yes, somewhere between minus a few percent and plus 100, but it varies a huge amount.
33:46 Sure.
33:46 I mean, if you've got some application that basically spends all its time in NumPy or something like that, you're not really going to speed up at all. But if it's a pure Python, you'd expect it to be good 40, 50% faster. But it depends.
33:59 Right? That's a good point because a lot of people do make Python faster by writing C or Rust or other languages, and at that point it's out of your hands, right? Yeah.
34:09 So we're looking hopefully for 312 to start looking at the interface between Python and C CODE. So we should speed up code even. There's quite a lot of C code. We would spend up the time spent in the C code in doing the actual work in the C code but there's still quite a lot of marshaling of data that happens, and hopefully we'll streamline that. But the existence of C extensions is sort of in some ways limits the opportunity to speed things up, but it's also why Python is so popular in the first place, or one of the main reasons. So I definitely need to acknowledge it.
34:39 Yeah, absolutely. So, Brent, I'll definitely have you talk about the specializing interpreters, but Mark, maybe give us a rundown of some of the things from your plan that made it in here. I know some are aimed for 310, but they didn't make it until here. Right?
34:52 Yeah.
34:52 So the whole thing, that original plan I put up there was more of a just to get this discussion get discussion going sort of thing. And it's basically more or less a year off. So if you just shift everything one forward, I mean, there was a lot of discussion on speeding up the interpreter in the first iteration and then looking more to the data structures in the second thing. It's much more jumbled than that. We're doing sort of a bit of everything. So obviously I was planning on expanding a smaller team, so things are being a bit shuffled. So, yeah, there's specializing in temperature, obviously, that's kind of key. There's also quite a lot of stuff we've done with data structures. I mean, we shrunk the Python object. The Python object has been shrinking for years. I mean, I've got some numbers here. So, like, in two seven and three two, like an object with just four attributes would take 352 bites on a 64 bit machine. And for three level, we've got it down to 112. And for 312, 96. Well, before you get too excited, there's only 32 in C++, so, you know, we've got a bit of way to go.
35:51 Yeah. But you know, it's going in the right direction for sure.
35:56 Some people out there listening just say, like, okay, well, it's half the size roughly, and it's going to be less than that. So, yeah, we can use less memory, but maybe you could talk a little bit about how that affects things like L1, L 2, L3 cache hits, and other sort of it's more important than just, I need less Ram. Right?
36:14 Yeah.
36:14 So there are two things that happen.
36:18 Things are faster because the hardware is just happier. If you pack everything together, it's in a high level cache, so you're not getting these sort of long pauses as you hit the memory. And the other thing is just the data structures because there's less of them, there's less indirection. So, for example, to load an attribute, we've got it down for basically an older versions of Python. It was sort of effectively five memory reads, and they were dependent memory reads. You have to read one before the next one, and so on.
36:44 Go to the class, find it, go to the object, find its dictionary, find a pointer that's in the dictionary, and then go to that. Right.
36:50 Yeah, they're very much there. And that's down to more or less two now. Okay, obviously there's still interpretive overhead on that, so it's not quite that much faster. But it's getting there.
37:03 Yeah.
37:04 There's a data structure. The frames, the Python frames, every time you call a Python function. We used to just allocate a heap object for the frame, and all the stuff would go in there, and now they're all basically in a big, contiguous sort of block of memory. So it's just bumping a pointer rather than allocating, which is also faster. And frames are just more anyway, because of the zero cost exceptions, which I think we mentioned on the release thing. But yeah, this is well, let's tell.
37:31 People about zero cost exceptions. Okay. You have to pay for errors if you're not raising errors. Right?
37:37 Yeah, that's the idea. And that's why they call zero cost zero cost is in quotes in this, and there's a reason for that is just that's the name it has got. They're definitely not zero cost. The idea is that they're pretty low cost if you don't have an exception, but they tend to be even more expensive if you do get an exception, because you have to do more. Lookup, the important thing here is that there's lots of run time information we need to maintain, and we don't now. So that, again, shrinks the frames and just makes calls faster, because calls in Python were notoriously slow. So that's one thing we've sped up significantly.
38:08 Yeah. So the idea was, in previous releases of Python, just to enter a try block, even if it was successful, there was a little bit of overhead to set up the mechanisms of potentially handling the errors and the information you needed. Right, yeah.
38:22 And this wasn't just the overhead.
38:24 You defer more of that. Right, yeah.
38:25 I mean, it's actually not so much the overhead as the just the space you have to put that data in had to be allocated every time you made a call in case there was an exception. And then there was massively overallocated to the amount of space anyone ever needed. So just that was the big sort of advantage.
38:42 Nice. Yeah. This is fantastic. You don't want to discourage people from putting proper air handling in their code.
38:49 What do you think?
38:50 I see your name on this feature here in GitHub. What are your thoughts on it?
38:54 Yes, I think it's cool.
38:58 It was a nice touch that Mark implemented it when I wrote the prototype for exception groups and when the prep was approved. So that got away a little bit, but it was good.
39:12 I got intimately acquainted with zero cost exceptions through that exercise.
39:17 Well, it's for some people.
39:20 Yeah.
39:21 I tease Mark a lot about that, but no, I think it's a cool feature, and I followed up on that after we removed that. I was talking about this on Monday. We had to jump over the exception handler, and then I thought, Wait a minute, there's a jump. It's not zero. You have to jump over the exception handler if there's no exception. So now we identify exception handlers as cold blocks, and before we lay out the code of the function, we put all the code blocks in the end. So now if there's no exception, there isn't even an exception handler to jump over. That would be in 312.
39:59 Excellent.
40:00 They made zero cost even faster, so.
40:02 Now it's zero even smaller.
40:04 Yeah, it's asymptotically approaching zero.
40:08 Yeah, but it's kind of nice that we have this notion of cold blocks and hot blogs and we can maybe do other things with it. Kind of nice that all the happy part, that the fast code is kind of in the beginning of the functions by code block and in terms of caches and all that, you don't have to I think we bring a few benefits beyond just not having to jump.
40:30 Yeah, this is excellent. It's really great feature and pretty straightforward. All right, Brent, tell us about the specializing adaptive interpreter. That's a big deal. You and I spoke about that about six weeks ago, I think.
40:41 Yeah, basically the headline is the byte code changes while it's running to adapt to your code, which is really neat. So it's kind of finding places where we can do the same thing but using less work by like cheating a little bit, but cheating in a way that is not visible at all. A good example is something like a global load or a load from the builtin. So if I'm looking at the Len function that requires two dictionary lookups, every time I want to look at the Len function anywhere, I first need to check the global namespace and that's going to be a failed lookup. Then I need to check the built in dictionary and that's going to be a successful lookup. So every time I want to use Len or range or list or any of those built in, that's the cost that I have to pay. But people don't change the global namespace that often. And people change the built in namespace even less often, or at least they shouldn't be changing it very often.
41:33 I'm going to make false true and true false. Let's see what that does.
41:36 Cool.
41:37 And so you can make these observations where it's like, okay, well, if the set of keys in the global namespace hasn't changed since the last time this my code instruction ran, and I know that that look up is going to fail because if it failed last time, then the keys are the same, then it's going to fail this time as well. So we can just skip that. And same for the built in dictionary. If we know that the keys in that dictionary haven't changed, that actually means that the internal layout of the dictionary is the same. And we don't even need to look up Len in the builtin dictionary. We can reach directly to the last location where it was before and give you that instead of code as like an older code as a kind of a micro optimization. Whenever someone was using a built in and like a very hot Python loop. Sometimes you see them like, do this kind of quark trick where they make it a local variable by saying like, len equals len or something like that as part of the functions arguments, so that you turn it into a fast local load. And what we've essentially done is made ugly acts like that totally unnecessary, which.
42:40 Is what you have behind the scenes, transparently. Yeah, exactly.
42:43 That's just one example. We've done tons of specializations for all sorts of things ranging from calls to attribute lookups to attribute stores, etc. So, yeah, it's a really powerful thing.
42:56 What was it? 659
43:04 This interpreter is marked and he could tell you much more about it than I could.
43:07 Yes.
43:07 I just want to give you a chance to give a shout out about Specialist.
43:10 Yeah.
43:11 So this is why I was on your show a couple of weeks ago. So looking at bytecode disassembly is not fun. And so one thing that's kind of cool, if you upgrade to Python 311, you were in your code and you saw it got 10 20 30% faster. You might be wondering like, okay, where did it get faster? What is faster about my code? And so Specialist is basically a package that I made it's pip installable. It only works on 311 and basically if you run your code using Specialist instead of Python, so you just type Specialist, my project py or whatever, it will open a web browser and show you your code, but color highlighted to show you where the interpreter was able to specialize your code where it wasn't. And that's really neat. So you can see like, oh, actually, these are the attribute loads that got faster. These are the places where my global loads are being cached.
44:00 That's awesome. Yeah, this is a really cool project and it has some proactive features, not just informational aspects, I think. Anyway, if you run a profiler, it'll show you where your code's spending time, but it doesn't mean you should go change everything to make it faster. You should look like, oh, this loop or this one function is like the thing that maybe we should think about slightly changing the algorithm or the way we do a loop or something. It's a little bit similar here because the specializing adaptive interpreter only specializes some things like it doesn't specialize floats, interacting with INTs or those types of things, or I think division as well. And so there are certain ways you might be able to slightly change inside of a really hot loop, make something to float ahead of time if you know it's going to be involved in floating point operations. Right?
44:47 Yeah.
44:47 The idea is that this is show us how we can fix things so that you don't need to mess with your code.
44:53 I see. So this is in the future. Okay.
44:56 Yeah.
44:56 Awesome.
44:57 I would not necessarily encourage people to start tuning individual by code instructions in their code due to our implementation details.
45:04 Otherwise, you will end clean.
45:06 And see, I got to take all those decimal points back out of my code. No, just kidding.
45:10 Yeah, I want to get every single bytecode instruction green.
45:13 Some things will never specialize, and that's just an artifact of programs. But if we can specialize in health, and we typically do one line, maybe 20 bytecode instructions, if four of them get specialized successfully and two of them don't, generally that will still be passed.
45:28 Do you know what you should do for April Fool? Like, you should do a Python plugin that shows you the percentage of specialized instructions in your code, and people can fix the percentage so they can say, fail my test with if my code.
45:41 Is not if you despecialize it.
45:49 Yeah, it's like a coverage thing about this. So Paulo can tell you more about this, but his cool new trace backs, the whole reason specialist is able to do these cool column level highlighting of your source code is because we do have that fine grained position information under the hood. So we kind of just piggybacked on that feature in order to give you that. But I was kind of thinking, another thing, another April Fools project could be a column level coverage information. So to get to 100% coverage, you have to COVID every single column.
46:22 I feel like people might take that too seriously.
46:24 Even the white space not go.
46:28 Yes.
46:28 You think you're intense by having branch coverage turned on. Just wish you have column coverage turned on.
46:32 Yeah, you can only cover two white spaces per line, so you got to call that a lot. All right, I think that's a perfect segue over to one of the most tangible contributions from Pablo here. Maybe tell us about this new finegrained error locations and Trace backs. This is fantastic. This will save people being in debuggers or rewriting their code with tons of print statements to figure out what's going on, I think. Yeah.
46:55 Thank you very much. We put all the effort into this.
46:59 Man, I don't even remember my Pep. I don't know if Pep something something and it has a horrendous name.
47:06 657 Let's see.
47:08 Thanks.
47:10 Error locations and trace backs.
47:12 Yeah, the worst name, I think I was talking with Mark in the python print, and he was saying what it means, like, fine grain.
47:20 Is this very fine grain. I think we are renaming the Pep to Fancy Tracebacks. I think that's much better. Anyway, so this is a project I work together with about Hunter and Omar. So kudos to them as well, because they participated equally on this. And the idea is that we started this project to improve their messages in the interpreter and the general experience, not only for people, because when people talk about this, they normally refer to people starting to learn Python. But to be honest, most of these things also affect people that are experts. I always say that when I implemented the suggestions, I was the first one benefiting from them because they make out of typos and it says, you made this. So the idea that we have is that most of the time the lack of the interpreter shows you the position when the other happened. But it's quite limited because most of the time people tend to have, due to Python flexible syntax, a huge amount of complexity. Even in a single line in the PEP there's a bunch of examples like you access a bunch of keys in a dictionary and some of them doesn't work or is not there or is known or something like that and then it fails. Or sometimes you have like several function calls or several additions and it's quite difficult. And most of the time fixing these things involve going into a debugger like PDB and then trying to inspect every single object and say, okay, this dictionary doesn't have this key at this level. And like, you know, that sucks because debuggers are cool, but it's cool or not to use them, right? And we thought, what can we do here? And we arrived to this idea, actually also to mention everyone involved, this was originally inspired by some kind of prototype that Car from the PyPI team made very long ago when he saw like a kind of minimal version of this. And then I said, okay, can we do this? And what we do now is that we propagate because the parser or super cool peg parser knows position of all the tokens and things like that. So we are propagating that information through the interpreter and we store this information out in code objects. So aside, the fact of this actually that code objects are slightly bigger, although because code objects don't tend to be a huge percentage of your application, it doesn't really matter that much. Maybe PyC files are bigger, but you have a lot of disk space, I'm sure. And the idea is that we store this information in cold objects. So when you write an exception, we say what is the instruction that is placed this exception? And then once we know which is the instruction that placed the exception, then we go and say, okay, what is the position information that generated this instruction? And because we propagated it, we know. And then we can say okay, here's kind of like the lines, the columns that this instruction spans. So that kind of allows us to underline the specific location, but we go a bit further. Sorry. Go ahead, Michael.
50:19 I was going to say this is super valuable. The example you have in the Pep is you have a dictionary and you say bracket of key A and then the thing that comes back is another dictionary. So you say bracket B and then another dictionary bracket C and then bracket D and 310. The error is just like if one of those is missed as none says non type is object, is not subscriptable or maybe does not contain that key or some weird thing like that. But is it A-B-C or D? You have no idea, you're in a debugger printing them out separately or something. But now it just goes no, it's the C one, it's the third subscript one and that's just jump right to it. Okay, yeah.
50:57 So this error nontype is not subscribing. It's kind of like thanks for the info, it's like water is wet. Okay, thanks. It's not exactly useful. Exactly. So the reason is going to rain anyway. We did like the first version of this and then we realized that there was some kind of like it was cool, most people really like it, but especially for instance with the example with the dictionary that has many dictionaries inside, there was some confusion because it underlined the whole thing. And then you know the order of operations and also with complex mathematical expressions like you do A plus B plus C and the last addition fails. It needs to underline A plus B plus C because what happened is that it first added A plus B and that gives you something. But then you added to Z and what happened is that the last edition failed. But that includes A plus B. So you need to underline the whole thing. If you know the order of operations and I just underline A plus B plus C, you know that what will fail is the last one because that's the last one that is executed. But it's still confusing because specifically with the dictionary people were saying yeah, okay, but you're underlying three keys here, which is the one that failed. I mean, you can learn by experience that is the last one, but it was not a great experience. So we went a step further. So what we do is that once we know the kind of range in the line that solves the problem, we rebuild that chunk of expression and then we know, OK, so we know now that this expression has this AST and then we analyze the AST and then we say, okay, is this AST something that we can further improve the message? Like for instance, is this AST a bunch of kids access in a dictionary or a bunch of attribute access, or a bunch of function calls or maybe binary operations. And if it's the case, then we use a specialized like underlying squiggles.
52:48 And the dictionary ones have these different ones that marks which key access. It was known the same thing for binary operations and things like that. So we do this extra step at the end. That's a bunch of extra work, but it tries to improve even upon the kind of just underlying the line just so we can offer even more rich information. And I'm quite happy, I'm very pleased all. This.
53:12 Sorry, Mark, but I think it's the best feature of 311.
53:15 This is probably the second string when I say this, but it's true. Totally true. 100% true. So I'm very excited about this. I literally use this every day. Today I was deploying python.
53:26 This week, sorry, I was deploying Python 311 at Bloomberg and something wrong. And literally this inside my day. This saved me to just log in to some forsaken machine and understanding what's going on. What about that? So super cool. May happy. I hope that everybody that uses this and is happy reach to us and say, I'm happy. Because normally people reach to us when they are not happy and they say that you should reach to us and say, nice, I did this cool thing.
53:55 You should tweet a couple or something though. Don't open issues saying you're happy.
53:59 It's like literally just exactly. Just tweet a couple till there's a few carrots and a smiley face at him.
54:05 Tweet happy at Python address. Awesome is that we improve it a bit further. One of the things that happened is that sometimes the whole line is wrong. Because this is why you have the review. Sorry for the ones that we had before.
54:23 We are seeing some output, but doesn't matter. Don't worry, I will describe it. So, for instance, you're calling a function and that's the whole thing that is in the line. We used to underline the whole thing. So we'll say, okay, even if the whole line is failing. So it's not like a part of the line is failing. The whole thing is failing. We used to underline that and that apparently is still on the pipe. Maybe I should change that because I don't like that anymore. Because I want to suggest that. I mean, come on. If the whole line is failing and the line the whole line is actually not that useful and you're spending vertical space, so you need to scroll a lot. At the beginning, I say, yeah, but it's inconsistent. I don't like it. And I push back a bit, but like then more people say, Paulo, you're wrong. And then I say okay, I'm wrong. We improve this further.
55:09 But don't take this as an advice. Don't tell me that I'm wrong collectively, please.
55:16 Now, if the whole line is underline, we don't underline it because it doesn't really add any new information, right? So only if a part of the line contains the error, not the whole line. So this means that we are not going to consume a lot of vertical space for no region. And the last thing I wanted to say is that there is some people somewhere in the universe that may care about that extra disk space on their PYC files or they just really hate squiggles. I don't know if that is even physically possible. But there are very different undive set of people. You are one of those. There is a collection of different ways you can deactivate this feature. There is an environment variable with a super long name and there is minus x option when you launch the interpreter. So you can say Python minus x something something, I don't know how it's called, I think it's called Nullabagranger.
56:07 Incredible naming. And then you set another bucket ranges to one and it deactivates. The feature incredible. Like magic, it's gone. And you can reclaim your PYC files and you can even generate PYC files without this information. If when you're compiling PYC files you set this evil environment mobile. But don't do that listeners, don't do that. It's evil, just use it, it's great.
56:31 There's another kind of type of errors that I think we're going to get is about edge cases where the compiler doesn't get the line numbers right because all these kind of fine grained locations, it's all new and we're still ironing out from future.
56:47 There's a from future, I think that if you put like a bunch of things with the from future, just complaints on a random place.
56:53 Yes, today I found that one, but I've been looking at the compiler and line number location information and it's a bit off here. And then we have received bug reports from other people as well. The range look right? The range here looks too broad. So yeah, we're going to be ironing that out for, I guess for 312.
57:13 Yeah.
57:13 It's really nice when people are using betas and release candidates though. Because we were able to catch a lot of those before the release because there were a couple people. I forget exactly the name of the project. But they're working on like a code animation pool where it animates your code while it's running and they were using these new ranges to identify AST notes and stuff and so they did this thing. I guess. Where they run their toll. The entire standard library. Make sure it's correct. And so we got a bunch of bug reports that basically say, oh, this column information is off to this weird multi line attribute access or something.
57:43 You recall, I think you fix an error. It was super weird because it was like a method access and if the method access has some power or something like that, it was wrong. And if you added some extra letter it was fine.
58:00 Yeah, it was like if you split your method access across two lines, if you do like x.method or x.method or x.method on three lines or something, the way we trace those lines, we always trace the method when we're actually loading the method, even if it's on a different line. It's like where the actual method load started. And then we were doing some weird math to like figure out where the dot is so we would try to put on the same line as the dot. So we just like subtract one from the length of the name. There's all sorts of crazy stuff.
58:33 And that came from the grave because we fixed that and then it was wrong again because we were, like, miscalculating the name.
58:41 Oh, my goodness.
58:42 Yeah.
58:42 So all sorts of fun stuff like that.
58:44 Yeah. Amazing. Well, this is definitely one of the highlight features, for sure, and also the performance work they're all doing. All right. We're getting very short on time, so I think maybe super lightning round here, let me just say. We also got Toma Lib support built in. We've got the Async IoT task groups. trio nurseries. We've got new features for atomic grouping and regular expressions, self type. A lot of type things have been added. So we got the cell type periodic generics literal strings, which is very interesting. Lucas did a talk about that on the release livestream stuff for type DICT and data class transformations. So great stuff. Now, let's just really quickly round out what's the Python 311 story for Py Script. Piodide do you have anyone out there now? I don't know.
59:35 I suppose it works.
59:36 I think WebAssembly is now a tier two or tier three supported platform.
59:40 Right. So he has been making a lot of improvements to the build process, which is not easy. So close to pretend. Heims if you're listening, you're great. I suppose that PY Script can through Pyodide, this is how many layers is this?
59:56 Pyodide through this can leverage all these improvements because I don't know how the whole layer that we're seeing is working, butPyodide has a bunch of patches that you need to modify the Python so it builds nicely on well assembled platforms. I don't know the details on that. I just know that some of them are okayish, some of them are not okay, and quite difficult to maintain. And Peter Hans been making a lot of great effort to change here and there and put a lot of micros and if left and things like that. So Cpython bills easier. This probably translates that Pyodide I hope, can consume this bill in an initial way with less budgets. And I suppose that translates into Python, like just using the pyodide thing. But, yeah, I don't think that there is a huge amount of improvements, more than we are working towards official support that Brand was mentioning. We have this new system. It's super cool.
01:00:52 It has, like, unrelated fun facts. Mike's Dropping, one of the early developers, Pyodide is actually managing our team at Microsoft.
01:01:00 Oh, it's funny how the circle comes the background. Indeed.
01:01:04 How the turn tables right.
01:01:08 All right. We are out of time, but super exciting. I wish we had some champagne. And Pablo, we didn't even bring hats to celebrate Python 311, but I know.
01:01:17 Everyone out there is extremely but I have a Python 311.
01:01:21 Yes, it's a great new logo for 311 and stuff. Not in general, but just for the release. It's awesome. All right, before we get out here, let me just ask you one final question and then we'll call it a show. Notable PyPI package. Something I want to give a shout out to. We'll go top to bottom in the picture here.
01:01:37 Pablo package.
01:01:41 I'm going to say memory use Memory, the one only by the memory provider Soldier memory today, with memory that and.
01:01:50 The underlying errors, you'll be all good.
01:01:52 Exactly. Yeah. Combination.
01:01:56 Well, I've had some interaction with the author of Bytecode Version King because I was looking at things to do in the testing and the interpreter that I kind of like that. So this is a library from Python. Write bytecode.
01:02:09 Wow.
01:02:09 It's pretty neat. And he's struggling with zero cost exceptions.
01:02:13 But it's like in line assembly, but for Python.
01:02:18 Yeah, from the Python script, you can kind of write it a bytecode and get it to do another interesting stuff.
01:02:26 That's awesome. Brent, how about you?
01:02:27 Well, I'm partial towards specialist, but if I had to choose something else speaking of speed, I really like the scaling profiler. I've been using it a lot on my own projects, and it's awesome. I don't know how it's memory profiling compares to memory. I'm sure memory is better, but scaling is really nice for measuring the performance across both Python and C code, which is cool.
01:02:47 Excellent. Mark?
01:02:48 Well, it's not actually a PyPI package. I was going to say the Sys module, which is like the most fundamental model going on.
01:02:55 There's all sorts of fun things in there. You can change the recursion limit and see, you can muddle if you're interested in how Python works, it's actually quite a sort of fun thing to play with.
01:03:04 Thank you all for all the hard work. And I know there are many people who did a ton of work as well who are not on the show here, but you can represent them as well. So thanks all for being here. Final call to action. People want to get started. 311, what do you tell them? Is it ready for them to get going? What do you think?
01:03:20 It's awesome.
01:03:21 It's awesome. And also, now 311 comes with a bunch of wheels for all your packages because there has been a lot of good work in the people of third party areas. And now that people are using CI Build wheel, 311 was released with wheels for NumPy and Pandas and a bunch of other things that usually was failing massively because nobody could compile them on their crappy laptop. But now you don't need that. You can just download them and it works. So just use 311. There's no reason. Yeah, that's actually just boring. Nobody reason. You're boring. And you don't want to use 311. And don't use you shouldn't break anything.
01:03:54 Not even a package, much less GitHub.
01:03:58 And we need more benchmarks.
01:04:00 Well, that's true. Yes, absolutely.
01:04:02 That's how people can help us make things faster. It's more benchmarks. So there's a sort of standard python performance suite, but it's kind of a bunch of toy programs and so on. So if you've got something that might make a nice sort of benchmark, self contained, but sort of realistic program, then yeah, that's no.
01:04:19 All right, cool. Well, thanks again. Great work on it. Cam gear lock out in the audience says, Yay. CI build wheel. Yeah, absolutely. Great stuff. So thanks again, everyone. I'm super excited to start using 311 myself.
01:04:31 Thank you, Michael, for inviting us.
01:04:32 Yeah, it's great to have you here.
01:04:34 Thank you.
01:04:34 Thank you. Bye.
01:04:36 This has been another episode of Talk Python to me. Thank you to our sponsors. Be sure to check out what they're offering. It really helps support the show. Take some stress out of your life. Get notified immediately about errors and performance issues in your web or mobile applications with Sentry. Just visit Talkpython.fm/sentry and get started for free. And be sure to use the promo code talkpython all one word. Command Line Heroes is an original podcast from Red Hat that chronicles the history of the software industry, from the origins of the first high level programming languages to Python's Tale. Each episode is a fascinating look back at how we got to where we are. Listen to an episode at Talkpython.FM/Heroes. Want to level up your Python? We have one of the largest catalogs of Python video courses over at Talk Python. Our content ranges from true beginners to deeply advanced topics like memory and async. And best of all, there's not a subscription in sight. Check it out for yourself at training.Talkpython.FM Be sure to subscribe to the show, open your favorite podcast app and search for Python. We should be right at the top. You can also find the itunes feed, /itunes, the GooglePlay feed at /Play, and the Directrss feed at Rss on talkpython.FM.
01:05:50 We're live streaming most of our recordings these days. If you want to be part of the show and have your comments featured on the air, be sure to subscribe to our YouTube channel at talkpython.fm/youtube. This is your host, Michael Kennedy. Thanks so much for listening. I really appreciate it. Now get out there and write some Python code.