Transcript #335: Should you get your mojo on?
Return to episode page view on github00:00 Hello and welcome to Python Bytes where we deliver Python news and headlines directly to your earbuds.
00:04 This is episode 335. Is that right? Yeah. Recorded May 9, 2023 and I'm Brian Okken.
00:11 I'm Michael Kennedy.
00:12 And we've got a sponsor, Influx TV. Thanks, Influx. We'll hear more about them later.
00:17 If you'd like to connect with us and talk to us in sort of real time or async,
00:22 we've got all of us are on Mastodon. All of us, all two of us.
00:26 But at M. Kennedy, at Fostadon, at Brian Okken, and at Python Bytes, we're all on Fostadon.
00:33 So you raise a philosophical issue. The United States, the laws may have gone too far to be business friendly in some ways.
00:40 And businesses have the same rights as a person. Does a podcast? I don't know.
00:44 You said all three of us are on. Oh, yeah.
00:48 Does the podcast have pronouns? What rights does our podcast have? I'm very curious now.
00:54 But maybe we've got to think about that later.
00:56 My podcast identifies as a podcast.
00:59 It identifies as MP3.
01:01 Well, so let's kick off the wonderful show with a cool topic.
01:07 Yes. Talking about trust.
01:09 So Brian, one of the ways in which you automatically publish or even within your system publish things to PyPI is you take your one and only permanent API key and you put it in that in whatever location that is.
01:26 So some people will go and publish from GitHub through GitHub actions.
01:31 And in the action, it says, here's where your username goes.
01:33 Here's where your API key goes.
01:35 And it may be a little known fact that people, I'm not sure if you're aware of this, but if you're on the command line and you do get actions like get pull and it says, oh, enter your username.
01:45 Boom. Enter your username.
01:46 Enter your password.
01:47 You can enter that API key and that will allow you to do like full CLI access, presumably, depending on.
01:53 Actually, that's the GitHub one.
01:55 So I'm crisscrossing these.
01:56 But nonetheless, putting your PyPI API key into GitHub actions and other CI, CD places and scripts, not ideal.
02:06 Right.
02:06 Yeah.
02:07 So last month, a couple of weeks ago, Dustin Ingram, one of the folks at PyPI said, we're introducing trusted publishers.
02:17 So starting today, PyPI package maintainers can adopt a new, more secure publishing method that does not require long lived passwords or API tokens to be shared with external systems, such as GitHub actions and others.
02:31 Okay.
02:32 So what you can do instead is you can create like an open ID OAuth type of connection between PyPI for your account and GitHub.
02:41 Yeah.
02:41 And when you do that, then when that, that action runs, instead of saying, what is the API key?
02:47 It says, let me through open ID connect exchange, say, we trust each other for this user.
02:54 Give me a 30 second valid token that I can use, or I'm making up 30 seconds, but give me a token that I can use a short lived token that just for this publish or just for this interaction is authenticated.
03:08 And then we'll immediately expire.
03:09 Oh, yeah.
03:11 Cool.
03:11 Yeah.
03:11 That's pretty cool.
03:12 Right?
03:12 yeah.
03:14 So basically you just connect those and you're good to go.
03:16 The, these API tokens, because they're regenerated and short lived never need to be, or should be stored.
03:23 They are not shared.
03:24 They rotate automatically because they are invalid.
03:27 They invalidate themselves.
03:29 And, this is not quite as obvious, but if somebody says this user logged in and published this version of a package to PyPI and there's one API key, well, I don't know.
03:41 Was that really the user?
03:42 Where were they?
03:43 Were they on vacation when they were that IP address or is that a hacker?
03:47 Was that a CI system?
03:48 We don't know.
03:49 But because this actually understands what system is requesting the token.
03:53 They say that it provides a verifiable link between a published package and its source, which I think is pretty cool.
04:01 Think?
04:01 Although what if somebody hacks into my GitHub actions?
04:04 Yeah.
04:05 Well, it only goes one level out in the ring of trust.
04:09 Right.
04:09 Okay.
04:10 So yeah, that, I mean, that is possible for sure.
04:11 speaking of what, if somebody, hacks into my GitHub actions, you can see in the doc that the blog posts that they publish.
04:18 It shows this is the part that you add permissions ID, right?
04:22 ID token is right.
04:23 And that's it versus here is your, username and password.
04:27 Right.
04:28 So that's cool.
04:29 It says additional security hardening is available.
04:32 You can further increase the security of your release workflow by configuring trusted publishers only to release from a specific GitHub action environment.
04:41 I don't do anything with that, to that degree with the GitHub actions, but basically with GitHub action environments, you can, set rules and workflows around that environment, such as requiring manual approval for each run.
04:56 By a set of trusted people who are repository maintainers.
05:01 Right.
05:01 So even if it gets hacked, you know, it's not enough that the organization, the GitHub organization has a workflow that will push it.
05:08 You might be able to, you might want to set it up so that it says in order to push, high test check out of this environment automatically, when we're going to production, right?
05:18 Shipping a build, it's got a, you've got to go push a button as Brian Okken on GitHub.
05:22 Okay.
05:23 Interesting.
05:23 Okay.
05:24 That is, optional, but strongly recommended.
05:28 And finally, right now, from my understanding, it says just works with GitHub actions.
05:32 However, it, this infrastructure to make this possible is now in place.
05:36 So it can be integrated with many more things.
05:38 So introducing trusted publishers.
05:41 If you maintain important packages, this might be worth looking at.
05:45 That's pretty cool.
05:46 Thanks.
05:46 Indeed.
05:47 Yeah.
05:47 Over to you.
05:49 Well, this, this, this topic is on fire.
05:53 it is on fire.
05:55 So, modular released a, a state, you know, a video and a statement.
06:00 I think it was on the second of the month.
06:02 so it's been almost a week, but you know, time moves fast in the software world.
06:08 So, Mojo modular announced Mojo.
06:11 Mojo is a new programming language for all AI developers.
06:15 And although I'm not an AI developer, we are all AI developers.
06:20 I think, either you're in the machine or you are, controlling it.
06:26 Take your pick.
06:27 Yes, exactly.
06:28 so anyway, so what is Mojo?
06:30 So there, and also I want to thank everybody that suggested this.
06:33 We got like a whole bunch of people suggested this set.
06:36 Have you seen this?
06:37 And don't feel bad if you, if you see a new, new topic and you think, yeah, somebody's
06:41 probably already told, told you guys tell us anyway, we like it.
06:44 And anyway, so Mojo, a new programming language.
06:47 Well, what is it?
06:48 So it is kind of like Python ish.
06:52 It looks like Python.
06:53 So it actually, supposedly one of the goals is it's going to be a super set of things.
06:58 So it's not there yet, but it has, it's, they want to do, kind of like Python, but extra
07:04 stuff that's C++ ish, like structs and, and, and, and strict types and everything.
07:11 Is this like your programming world has crashed together?
07:14 And it's now trying to become one.
07:16 I hope so.
07:17 The tectonic plates of Brian Okken's programming experience.
07:22 I'm pretty excited about it.
07:23 Actually not, not for AI stuff, but for hardware things.
07:26 I think that this, this would be kind of fun.
07:28 So, well, so what's the big deal?
07:31 It's, compiled and fast, in, in the order of like thousands of times faster,
07:38 in some cases, supposedly.
07:40 So, but so what, one of the things we're going to link to the Mojo, webpage where,
07:46 how you can get started.
07:47 It's hard to get started right now, but we'll get to that.
07:50 so there's a, there's also a fast AI, like announcement blog post, but also
07:57 a video with Jeremy Howard.
07:59 it's a really fascinating read.
08:02 And why is this kind of, where's this coming from?
08:05 Are you, if you're not familiar with modular, which I wasn't really, these are the same
08:09 people that kind of brought us LLVM.
08:12 so yeah, Chris Lattner and crew.
08:15 Yeah.
08:15 So there's, there's, there's a lot of excitement around it.
08:19 and, it's not an LLVM.
08:22 It is.
08:23 So I had to look this up.
08:24 LLVMs are what low level virtual machine is what it started out with, but we kind of know
08:30 it is almost all languages are built on top of it right now.
08:33 So Mojo is not that it's multi-level intermediate representation.
08:38 It's a M I L M L I R instead.
08:41 So, do I care?
08:43 Probably not, but, it's a, so anyway, there's a announcement.
08:48 It probably doesn't mean it has a lot of targets that it can compile for, right?
08:52 Giving you that intermediate flexibility.
08:54 Yeah.
08:54 and it's in, it doesn't have some of the, there are some limitations with the LLVM that
09:00 it doesn't have because it's a little different.
09:02 so I don't completely know it, but there's, it's kind of a fun video.
09:07 I've been playing with it just a little bit.
09:10 So if you, right now, what's the stage of it?
09:14 You can't get it for your local machine.
09:16 So you, you have to site, you have to like, if you want to go to the normal page,
09:21 you say, get started.
09:22 And it has you sign up on a list waiting list.
09:25 And luckily I got in.
09:27 Yay.
09:27 so I got to play with it and, the, a little bit.
09:32 So when you, when you drop into it and play with it, you get a Jupyter notebook thing.
09:36 and the Jupyter notebooks are already filled out with like a hello world and, or hello mojo.
09:42 And you get to walk through it and you get to see some of the different stuff.
09:48 So it's got definitions or defs, but you have these let statements.
09:52 So you can, that's different.
09:54 we don't have to do let's and, and vars in, declarations in Python.
09:59 So it's, you can do normal Python.
10:02 Kind of the neat thing about having it be kind of like Python is you're kind of used to it already.
10:07 You don't have to learn something new, but also it's compatible with external libraries.
10:11 So you can, hook in things that are already built in pure Python that can be hooked into.
10:15 That's the part where I'm curious about.
10:18 Can I just forget about all this other machine language, low level stuff.
10:22 And can I just use this to compile my Python?
10:25 Don't know that yet.
10:26 yeah, I don't know what the integration with other libraries is.
10:30 Like the example had, clearly indicated like NumPy integration.
10:34 Yeah.
10:35 But can I use Flask with it?
10:37 For example, right?
10:38 I don't know.
10:39 Yeah.
10:40 Don't know.
10:40 Yeah.
10:41 I don't know either.
10:42 this is very exciting.
10:43 I did.
10:44 I did want to point out that we are correcting a mistake that we made at PyCon, Brian.
10:50 no, no, just last week.
10:52 Somebody out in the comment in the live stream last time and Aaron, the YouTube video and
10:56 said, I'm telling y'all folks, I'm really not believe what I'm hearing.
10:58 How can they not be talking about Mojo?
11:00 Oh, so, yeah.
11:04 But what's the, what do you think?
11:06 Well, okay.
11:07 So one, it sounds very exciting.
11:08 Two things rubbed me the wrong way quite a bit from the start that it's behind a, an sort
11:14 of mailing list paywall, not paywall, but like gated wall.
11:18 Yeah.
11:18 Right.
11:19 That, that just seems, it seems off to the wrong start.
11:23 Right.
11:23 If you want to get a lot of, attraction, I think, you know, put it out there.
11:27 Maybe, maybe you've got to sign up in order to, run the compilers on, on a Jupyter notebook
11:34 in the cloud because they're not totally tested and stable or something along those lines.
11:38 That would be totally fair.
11:39 But like, it doesn't tell you if it's open source or not.
11:43 It doesn't share a GitHub repository.
11:44 It doesn't share a way in which, it expresses what this is going to be.
11:50 Is this a thousand dollar a month subscription?
11:52 Is this open source?
11:53 Is it both?
11:54 Right.
11:55 Is it like, oh gosh, what was it called?
11:57 Codon.
11:57 I believe some people were like so excited about Codon.
12:00 It's like, it's, it's under the model of if it's, if you've got to ask what the price
12:04 is, it's, it's too expensive for you.
12:05 Oh yeah.
12:06 Which like, okay, I'm not going to get super excited about investing in that, even
12:10 if it is neat and powerful.
12:11 So that, that said, everyone seems to be super excited about it.
12:15 I love the way the language looks for like a more compiled way.
12:19 I think there's a lot of possible Python integrations.
12:22 Like we already talked about, Hey, could I run Flask?
12:24 Is it so close that we could just make our stuff go faster when we need it?
12:28 If we're willing to say, decorate our, our variable declarations with a let or a var, right?
12:33 I might be willing to do that if my code could run a thousand times faster.
12:36 Yeah.
12:37 There's some, I don't know.
12:39 It's like, it's not clear to me how much sort of community there is versus product, which
12:45 I don't, I'm not saying you shouldn't have one or the other.
12:48 They're both fair, but it doesn't say in that.
12:50 And it's behind a, like a sign of wall, which makes me wonder, right?
12:55 It just makes me feel less excited about it, which is why I didn't cover it last week.
12:59 I'm like, eh, maybe, I don't know.
13:01 We'll see.
13:01 Okay.
13:02 Also the rough edges, there's a rough edges section of like roadmap and rough edges.
13:07 And some of them are really big missing things like tuples.
13:11 Yeah.
13:12 Like tuples not supported.
13:14 Class is not supported.
13:16 Well, yeah.
13:17 that's a lot of Python that you can't use without classes.
13:21 So, yeah.
13:21 Well, and maybe this is just early and they're just showing it.
13:25 And if it's coming, that is totally good.
13:28 So I just, I don't know when I first saw it though, the, like here, like sign up for our mailing list so that you can maybe look at it.
13:35 It's like, what is this thing here?
13:36 And it doesn't express, there's no GitHub repo linked.
13:39 I don't know.
13:40 So I have a lot of hope for it, but I'm just not, I'm going to just withhold my assessment of like the impact I think it will make yet because of that.
13:49 Right.
13:49 I whistled.
13:51 It could have quite an impact if, if, if we get everybody able to play with it and it's, it's, it's just going to be, I mean, it was, there's a lot of people talking about it this week, but, it seems like there's a new trend every week.
14:05 So anyway.
14:06 Yeah.
14:07 I'm a little suspect.
14:07 Is it written in rust?
14:08 I'm not sure it is.
14:09 Just kidding.
14:10 cause that's where, how can it be cool if it's not written in rust?
14:13 I know that's, that's exactly my point.
14:15 That seems where all the action is right now, which is, is cool.
14:18 But, it's also worth pointing out for people who are not putting it together that Chris Lautner is also the person behind the Swift programming language, which is a pretty interesting language that's also borrowed a lot from Python.
14:30 So it is exciting.
14:32 The other thing that is, it's sold as a make AI work fast, but like Python.
14:38 That's awesome.
14:39 And it's a, it's a cool focus, but it, it doesn't speak to, a goal of like, Hey, we could bring more and more Python until it's like a 90% case.
14:48 That's awesome.
14:49 That's awesome.
14:49 That we could do many things with if it's really focused on, you know, running Python code on, on GPUs and just like really, really focused in on the AI stuff.
14:57 So, that's the other comment that I wanted to make about like, where's this going?
15:01 So we'll see.
15:02 But yeah, a lot of people are excited.
15:04 I mean, I would say, honestly, we have not received more listener recommendations that we cover something than this.
15:11 Yeah.
15:11 I mean, maybe the only other thing was Guido retiring from, from, BDL was the only other thing that we got like that much, that much massed on Twitter email about.
15:23 So thank you all for sending that in.
15:24 these are my thoughts.
15:26 I would love to see it succeed.
15:27 but I just don't know quite, where it's going or what it's going to be yet.
15:31 Yeah.
15:31 I guess my optimism comes from the, where it's coming from.
15:35 The people involved have a history of doing things that are helpful to the community.
15:39 So yeah, it absolutely has, you know, big hitters behind it.
15:43 So it's got a way better chance than just somebody publishing something cool.
15:46 Okay.
15:47 Yeah.
15:47 All right.
15:48 Yeah.
15:48 We'll see.
15:48 I mean, certainly worth, keeping track of it.
15:51 so next up, I would like to talk about our sponsor.
15:54 No, right on influx DB.
15:56 So this episode of Python bytes is brought to you by influx data, the makers of influx DB.
16:03 Influx DB is a database purpose built for handling time series data at a massive scale for real,
16:09 real time analytics.
16:10 Developers can ingest store and analyze all types of time series data, metrics, events,
16:16 traces in a single platform.
16:18 So dear listener, let me ask you a question.
16:21 How would boundless cardinality and lightning fast SQL clear queries impact the way you develop
16:27 real time applications?
16:28 Influx DB processes, large time series data sets, data sets and provides low latency SQL
16:35 queries, making it a go-to choice for developers building real time applications and seeking
16:40 crucial insights for developer efficiency.
16:42 Influx DB helps you create IOT analytics and cloud applications using timestamped data rapidly
16:49 and at scale.
16:49 It's designed to ingest billions of data points in real time with unlimited cardinality.
16:55 Influx DB streamlines building once and deploying across various products and environments from
17:01 the edge on premise into the cloud.
17:04 Try it for free at pythonbytes.fm/influx DB.
17:07 That link is also, of course, in our show notes.
17:10 Thanks for sponsoring the show.
17:12 Yep.
17:12 Thank you, Influx DB.
17:13 Now let's talk about some Django.
17:17 Okay.
17:18 All right.
17:19 So in Django, I want to introduce something called Django prose.
17:25 Doesn't it just make you want to write, just sit down and put on your best Ernest Hemingway
17:32 impression and just start writing?
17:33 I don't know, maybe.
17:35 But this thing is a rich text editor that you plug in to, I believe, into the admin section,
17:42 the admin backend for Django.
17:44 Yeah?
17:45 Okay.
17:45 So wonderful rich text editing for your Django project.
17:48 Right?
17:49 So what you do is you install it.
17:51 You add it as one of your apps.
17:53 And then you have to run some migrations because it needs some database backend stuff to keep
17:58 track of what it's working on.
18:00 And then finally you set up a URL for it and then you're good to go.
18:03 And there's different ways in which you can work with it.
18:05 It can control basically the entire page because it's more or less HTML.
18:10 And so you can just say, show me the document.content.
18:14 Now, when you render that in your Django templates, this is HTML and Django templates, like many of
18:20 the templating languages are smart and say, yeah, no, if we just let people type in here,
18:26 they're going to type angle bracket, JavaScript, hackswords.com, dot, dot, dot, dot, dot, right?
18:31 So they're going to HTML and code that, which will show it up as like view source.
18:36 Right?
18:36 So you've got to do a pipe safe to say, nope, don't encode it.
18:41 Just drop the HTML straight in there, which in which case this should not be used by untrusted
18:46 individuals.
18:47 Right?
18:47 You can also have ORM models and the ORM model itself can have a rich text field type, which
18:56 is kind of interesting.
18:56 Right?
18:57 Yeah.
18:57 And then you can show that as part of your template.
19:01 And again, you've got to pipe safe that because if not, it won't work.
19:05 And then you can even have a separate table with a foreign key relationship to the content
19:13 for like large documents.
19:15 So there's a lot of stuff with not just dropping an editor into the admin section, but actually
19:20 integrating that into the Django ORM and models, which is where I think it gets, you know, worth
19:24 paying attention to over some of the other just JavaScript front ends for HTML editing.
19:29 Nice.
19:29 Yeah.
19:30 Yeah.
19:30 It even has a form support for rendering out editable forms and attachments, all those sorts
19:41 of things.
19:41 It also only allows a subset of tags and attributes, and it uses the bleach library, which I don't
19:48 know how familiar people are with bleach, but bleach is kind of interested.
19:52 Apparently it's deprecated.
19:54 Although you're just using it for whitelisting.
19:56 I don't know really why it would make a change, right?
20:00 Like these are the 20 tags and whatnot that are allowed and they're still going to be allowed.
20:04 But anyway, if you want to see, there's both a picture that's larger than I was hoping for.
20:09 There's a picture of basically what it looks like.
20:12 And you can imagine it's like a rich text editor or online blog thing, and it has an editing section
20:17 and a preview section, as well as a video tutorial.
20:20 So if you're doing Django and you want rich text editing that renders, that basically edits raw HTML
20:27 in a nice way, WYSIWYG, as they said back in the day, you can go and check this out and check out Django
20:33 pros.
20:33 Nice.
20:34 Hey, so have you ever heard the, you know, if you had a writing group in a penitentiary, it would be pros and cons.
20:41 Pros from cons.
20:46 I love it.
20:48 That's good.
20:48 Yeah.
20:48 We're, we're jumping ahead.
20:50 The joke comes at the end.
20:51 Okay.
20:51 Okay.
20:52 Sorry.
20:52 Don't get ahead.
20:54 Okay.
20:54 So I want to talk with, speaking of rich, I want to talk about pileizer.
20:59 Actually not rich.
21:01 Rust.
21:02 So pileizer.
21:04 So this was a suggested by Owen.
21:06 Thanks, Owen.
21:07 And this is a project that is, it reminded me of rough a little bit.
21:12 So it is pileizer is a static code on the analyzer in a language server for Python written
21:21 in rust.
21:21 Just cool.
21:22 Some of the details on it.
21:24 I'm a little, I don't quite understand, but anyway, it's a rust thing that can analyze your
21:30 code.
21:30 So what is the big deal?
21:31 Why don't we have, what is, speaking of rough, what's the difference?
21:35 Well, so rough is like pilot rough is a static code analysis, but rough is just your linter.
21:42 It doesn't do type checking in language server.
21:45 So pileizer has a little bit more.
21:47 It's a little, does more, a little more linting.
21:48 It can do things like checking for out of bounds errors and things.
21:51 So it isn't a replacement for rough.
21:53 You would run both of them if you want.
21:55 And they're so fast that why not?
21:57 So, and that's one of the things because it's written in rust, it's quick.
22:01 It's very fast, but that's not the only thing.
22:04 Cause you always want, you also want like good error messages.
22:08 So that's one of the selling points apparently is a detailed analysis.
22:12 It can check a whole bunch of stuff, but it also is readable.
22:15 So it'll, it'll do, you know, tell you what's wrong.
22:19 And, and it's supposedly, it does things like underlining where, where the problem is and
22:25 what you should do instead.
22:26 Maybe.
22:27 So this kind of looks like fun actually.
22:30 So yeah, that is a really nice error message.
22:32 It has like a tree structure under the line, under the error thing.
22:35 It says expected stir, but found int.
22:38 Yeah.
22:38 Kind of reminds me of some of the new stuff in Python to, to help you.
22:42 with exactly the three 11 error message improvements.
22:45 Yeah.
22:46 and especially if it's going to do this sort of stuff, language server, I'd like it integrated
22:51 with a, editor, right?
22:53 So this, this does have a VS Code extension that you can integrate that and use that instead
22:58 of the built in, whatever VS Code uses.
23:02 I can't.
23:02 High Lance.
23:02 High Lance.
23:03 High Lance is pretty good though.
23:05 So anyway, I'm not sure.
23:07 so how it works.
23:08 So here's the stuff that I don't quite get part is, it uses a type checker from the ERG programming language.
23:16 Erg.
23:17 Erg.
23:17 Erg.
23:18 Must be a pirate.
23:19 I've never heard of Erg.
23:20 Interesting.
23:21 I haven't heard of it either.
23:23 So I'm not quite sure.
23:24 Maybe it's faster that way, but it does that.
23:27 I don't know if there's limitations, but there's, it's a, project in the rather early stages.
23:32 I think it's got a lot of stuff going on for it, but I don't, I think it's neat that they
23:36 listed a to-do list and the things they haven't done yet.
23:39 So it doesn't check for finals and other things, but it does quite a bit.
23:42 I'm still pretty good.
23:43 So new tool.
23:45 Neat.
23:45 all right.
23:47 Are you ready for a joke or you got an extra?
23:49 I know extras today, but I'm ready for a joke.
23:52 Awesome.
23:52 Me too.
23:53 This one comes to us from Arthur Rio and says, this joke might be right up your alley.
23:57 Okay.
23:58 So what this is, is it says escape room.
24:00 So it's, it's an escape room.
24:02 Like, you know, the, like the kind of thing where you, you go and you got to find the clues
24:06 to get out.
24:07 And if you don't find the clues, you're going to be stuck in there.
24:09 So this, this person with a big smiling anticipation is walking into the escape room, finds a skeleton
24:17 sitting at a laptop, like a, a person who died is gone.
24:21 Right.
24:21 And starts to get really worried.
24:23 Like maybe this escape room is too serious for me.
24:25 Looks over the shoulder and realizes what they are doing is they're in Vim trying to get out
24:31 of it.
24:31 It's so meta.
24:33 I know.
24:34 It's so meta.
24:35 Yeah.
24:36 Go ahead.
24:36 You just have to hit escape.
24:37 I know.
24:38 And well, and look, look at the person who says there's always a way.
24:41 I'd completely beaten, smashed MacBook.
24:47 How did that happen?
24:48 I don't know.
24:49 But there's always a way.
24:51 Or something.
24:51 It does look like he got run over and then they opened it.
24:54 Yeah.
24:54 Yeah.
24:54 It's, well, it's not ideal.
24:56 But the escape room, I thought you'd appreciate that one.
24:58 Yeah.
24:58 Why is that such a big thing?
25:00 Like, I don't know.
25:01 It's one of the frustrating old joke of like, people are always going to make fun of it.
25:05 I know.
25:05 You could do the same for Emacs.
25:06 Yeah.
25:08 How do you quit Emacs?
25:08 I don't even know.
25:09 Yeah.
25:09 It's like a chord.
25:10 I forgot what it was.
25:11 Like, you know.
25:12 You have to play guitars for it?
25:14 Yeah, you do.
25:15 It's why it takes so long.
25:17 First you learn guitar, then you can save or exit.
25:20 Anyway.
25:23 So.
25:24 Awesome.
25:25 Well, I guess that's an episode.
25:27 That would be episode 335 in the bag.
25:31 Yeah.
25:32 Thanks, everybody, for listening.
25:34 Thanks, Michael.
25:35 You bet.
25:35 Fun as always.