#479: Talking About Types
About the show
Sponsored by us! Support our work through:
Connect with the hosts
- Michael: @mkennedy@fosstodon.org / @mkennedy.codes (bsky)
- Brian: @brianokken@fosstodon.org / @brianokken.bsky.social
- Show: @pythonbytes@fosstodon.org / @pythonbytes.fm (bsky)
Join us on YouTube at pythonbytes.fm/live to be part of the audience. Usually Monday at 11am PT. Older video versions available there too.
Finally, if you want an artisanal, hand-crafted digest of every week of the show notes in email form? Add your name and email to our friends of the show list, we'll never share it.
Michael #1: httpxyz one month in
- First version of httpxyz contained just the fixes to get zstd working, and the fixes to get the test suite running on python 3.14, some ‘housekeeping’ changes related to the renaming
- End of March: a compatibility shim that allows you to use httpxyz even with third-party packages that import httpx themselves, as long as you import httpxyz first.
- Importing
httpxyzautomatically registers it under thehttpxname insys.modules, see https://httpxyz.org/httpx-compatibility/
- Importing
- Fixed a WHOLE bunch of performance related issues by forking httpcore
Brian #2: Learn concurrency - a deep dive into multithreading with Python
- Nikos Vaggalis
- “Whenever you are trying to speed up code using multiple cores, always ask yourself: “Do these threads need to talk to each other right now?” If the answer is yes, it will be slow. The best parallel code splits a big job into completely isolated chunks, processes them separately, and merges the results at the finish line.”
- Good overview of thread concurrency with Python and how that’s been improved dramatically with free-threaded Python
- Defines lots of terms you come across, including “embarrassingly parallel multithreading”
- There’s a counter example that’s nice
- Start with a shared resource, a counter, and multiple threads updating it
- Attempt to fix with
threading.Lock(), which fixes it, but slows things down - Good explanation of why
- Proper fix with
concurrent.futuresand separating the work of different threads so that they can be independent and their results can be combined when they’re all finished.
Michael #3: pip 26.1 - lockfiles and dependency cooldowns
- Python 3.9 is no longer supported
- Experimental: installing from pylock files
- Dependency cooldowns (see my post about this)
- Lifting several 2020 resolver limitations
Brian #4: Python 3.15 sentinal values from PEP 661
MISSING = sentinel("MISSING")
def next_value(default: int | MISSING = MISSING):
...
if default is MISSING:
...
- Take a name str as a constructor parameter
- Intended to be compared with
isoperator, similar toNone - Sentinal objects can be used as a type, also similar to
None- and can be combined with other types with
|.
- and can be combined with other types with
- Unlike
None, sentinal values are truthy. (Elipses...are also truthy)- This seems like a strange choice. but I guess it must have made sense to someone.
- It does force you to use
isinstead of depending on False-ness, so I guess it’ll make code using sentinels more readable.
- Interesting that the PEP was started in 2021, and we’re finally getting it this year.
Extras
Brian:
- Before GitHub - Armin Ronacher
- tenacity - cross-platform multi-track audio editor/recorder
- learned about it from Armin’s article
Joke:
- Joke option Make it myself
- Seems similar to what people think about software now
Links
- httpxyz one month in
- httpxyz.org/httpx-compatibility
- Learn concurrency - a deep dive into multithreading with Python
- pip 26.1 - lockfiles and dependency cooldowns
- my post about this
- Python 3.15
sentinalvalues from PEP 661 - Before GitHub
- tenacity
- Make it myself
Episode Transcript
Collapse transcript
00:00 Hello and welcome to Python Bytes, where we deliver Python news and headlines directly to earbuds.
00:05 This is episode 479, recorded May 11th, 2026.
00:10 And I'm Brian Aachen.
00:11 And I'm Michael Kennedy.
00:12 This episode is sponsored by all of our stuff, like the pytest book and pytest courses and Talk Python training and so much else.
00:22 And also Patreon supporters.
00:23 Thank you, Patreon supporters.
00:24 If you'd like to get a topic, if you've got a topic that you think we ought to talk about or just are interested in, don't worry about whether or not we've heard it or not.
00:34 Just send it on over anyway.
00:36 You can reach us on Mastodon and Bluesky.
00:39 And there's a contact form right on the show notes, but right there on pythonbytes.fm as well.
00:47 So you can check that out.
00:48 Thanks to everybody that watches us live on YouTube.
00:51 If you'd like to be a part of the audience and submit comments and stuff, you can head on over to pythonbytes.fm/live and be part of that.
00:59 And you don't need to take notes because you can just get our newsletter.
01:03 So go to the pythonbytes.fm also and subscribe to the newsletter and we'll send you.
01:09 We don't send much other than just the links and all the information.
01:14 Well, there's a lot of content in the weekly email that we send out.
01:17 So it's not just the links to everything we talked about, but it's also some background information.
01:23 And you'll especially want this time because we got some cool stuff.
01:27 So speaking of cool stuff, Michael, want to kick us off?
01:32 Yeah, let's kick it.
01:33 Let's kick it off.
01:34 Let's talk about HTTPX YZ.
01:37 So recall, this is Mikhail had created a fork and we covered why I forked HTTPX and it was part of the larger churn around in code, I believe, and so on and all of that.
01:52 So this is the one month check-in and it's pretty interesting.
01:56 I think it's got some ideas worth paying attention to here.
01:59 So basically a couple of things worth talking about is they got the first version out.
02:05 It contains some fixes to get ZSTD working, get the test running, housekeeping, and so on.
02:11 But then more importantly, end of March, some fixes came out.
02:15 Compatibility shim that allows you to use HTTPX.
02:18 This is, okay, this is the thing that really made me want to cover this because they released a compatibility shim that allows you to use HTTPX YZ even when third-party packages use HTTPX themselves.
02:31 So this is my dilemma.
02:32 I look at my project and I see that I'm using HTTPX and I'm like, huh, it'd be really cool to switch to HTTPX YZ.
02:38 Seems like the right thing to do.
02:39 And then I go look at my pip compiled output and it says HTTPX because these seven packages are using HTTPX.
02:47 I'm like, huh, well, that's kind of useless.
02:49 Like why would I use one when I have to effectively use these others all the time when I interact with those libraries, right?
02:55 I'm still in the same boat and I don't see a life raft or any way to get out of that boat.
02:59 But here's that thing.
03:01 And it's pretty interesting.
03:02 If all you got to do is if you import at the startup of your app HTTPX YZ, it also tells it the world that it is HTTPX.
03:13 Okay.
03:13 So for example, you can assert that HTTPX is in system modules of HTTPX YZ, right?
03:20 That kind of thing.
03:20 So if you import HTTPX somewhere along the way, some other app does, other part of your app does, it will still, it'll still return basically a compatible layer, even at a type instance.
03:32 So if you ask, is this thing that I got from HTTPX YZ.response of some type of, is that actually an HTTPX.response?
03:40 Yes.
03:41 So really interesting compatibility.
03:43 And honestly, I don't know how it does that.
03:44 That's pretty interesting.
03:45 Yeah.
03:46 How do you say you are, I derive from this class in another library without having the other library present?
03:53 You know what I mean?
03:54 Well, as long as the endpoints are there, you're going to fulfill it.
03:58 But it is a...
03:59 Yeah, but it's not duck typing.
04:01 This is strong typing.
04:01 It's asking is instance, right?
04:03 That's what I think is interesting.
04:04 Yeah.
04:04 Well, yeah.
04:05 Interesting.
04:06 I don't know.
04:06 I feel like I'm going to go on a typing rant this episode.
04:10 So prepare yourself, people.
04:12 Prepare yourself.
04:12 So this is not uncommon, like Pillow has done this, OpenCV has done this, YAML, PyYAML have done this, and so on.
04:18 Well, but done this being, they've got a different name that you use, you import from the library.
04:26 But the hijacking some other project's name, that's, I don't know what I feel about that.
04:33 I don't know a way around it other than this.
04:36 No, in this case, I think it's a good thing.
04:39 It seems like this could be abused.
04:42 Yes.
04:43 Agreed.
04:43 Agreed.
04:44 Okay.
04:44 Well, welcome to Python imports, I guess, huh?
04:47 Yeah.
04:47 So I think this is actually pretty interesting.
04:50 And also, this is kind of the flow of this project.
04:53 It's like, oh, we noticed that HTTP core is actually the root of many of the problems, which is also a similar project.
04:59 So we have to create HTTP core XYZ, and fix a whole bunch of issues, some serious, and so on.
05:06 So there you go.
05:07 Got some nice quotes here.
05:08 And then finally, it's on Codeberg, which I think is not the right choice.
05:14 I understand the desire, but in practice, I don't think it's the right.
05:20 I think it should be on GitHub, even with all the GitHub issues.
05:23 Because, you know, you look at it, it's got 39 stars.
05:26 Like, HTTPX has 15,000.
05:29 Right.
05:29 So on GitHub.
05:31 I don't know.
05:31 I think that that's, you know, Mikhail says, look, I'd love to make GitHub a little bit less dominant.
05:36 Yes, I agree.
05:38 But, you know, I don't necessarily know that I would try to fight two battles in one.
05:42 You're already trying to make HTTPX not less dominant.
05:44 I see it.
05:45 I have sympathy.
05:48 You can get rid of a lot of junk if you're not on GitHub.
05:52 Yeah.
05:53 I know.
05:53 It's like, what are you optimizing for?
05:55 Are you optimizing for the developers, the project's benefit?
05:58 Or are you optimizing for exposure?
05:59 I don't think so.
06:00 I think it's whether or not you want contributors.
06:03 Because the exposure's through, like, PyPI, not really GitHub.
06:08 And maybe podcasts, people talk about it.
06:10 Yeah.
06:11 Anyway, I think it's a cool project.
06:12 I'm going to look into maybe use it more now that that shim thing exists.
06:17 Yeah.
06:17 Cool.
06:18 And while I'm doing that, Brian, maybe you want to talk to us about concurrency?
06:22 I'll get back to you on what I've learned.
06:23 I do.
06:25 Yeah.
06:25 While I'm doing that.
06:27 Yeah.
06:28 So concurrency.
06:30 So I ran across this article.
06:33 It's on GeekUni.
06:34 I don't know what that is.
06:35 But it looks like there's some interesting stuff way back to 2013.
06:39 But anyway, Lean Concurrency, a deep dive into multithreading with Python.
06:45 And this is the author, Nikos.
06:48 And I actually really like this article.
06:51 So I do.
06:53 I'm familiar with multithreading in multiple languages.
06:56 And I don't use it a lot in Python.
06:59 And I do have a lot of projects or at least a couple of projects coming up that I want to use some concurrency.
07:05 And so a refresher is a good idea.
07:08 And the world has changed a little bit recently.
07:12 I mean, the big recently in Python because we've got Gilders Python.
07:18 We have free-threaded.
07:19 And it changes the dynamics a little bit.
07:22 So it's a good time to have a refresher on concurrency with Python.
07:25 And this is...
07:26 So we are going to talk about multithreading in this article.
07:31 But one of the great things that I like about this is it doesn't assume anything.
07:36 So it's talking about like in data science or cryptography or data processing, some of the places where you might want concurrency.
07:44 But there is really lots of places where you want it.
07:47 And then filling in some of the terms that you may not be familiar with, like concurrency versus sequential.
07:54 We probably should know that.
07:55 But things like global interpreter lock.
07:59 And, you know, I guess we already know those things.
08:02 But there's a...
08:03 One of the terms is like embarrassingly concurrent.
08:07 And I kind of forgot what that meant.
08:09 So it's good there.
08:11 And that just means...
08:12 Well, it means that you can separate the work into things that can work without any interactions.
08:20 Those are embarrassingly concurrent.
08:23 Anyway.
08:23 Yeah.
08:23 One super, super common example of that is like video game graphics.
08:27 Each pixel is computed independent of each other pixel.
08:31 So if you've got a million pixels, like as much parallelism as you can just compute each pixel at the same time, they're not going to interfere with each other, right?
08:39 Yeah.
08:39 It is funny that it's embarrassingly.
08:41 It's not really embarrassingly.
08:43 It's just ideal.
08:45 Exactly.
08:46 What a glass half empty perspective that is.
08:49 So I just encourage people to look through this.
08:53 There's some great walkthroughs about different things.
08:57 And also, it talks about free-threaded concurrency as well.
09:02 If you want to catch up with the GIL and getting rid of the GIL and stuff.
09:08 And it even talks about how to install the free-threaded Python, which is nice.
09:13 Which, of course, you're going to just use uv.
09:15 But even with uv, you have to do the 3.14T.
09:20 You have to add the T to the end to get it to work.
09:22 One of the cool things, I think, is that it's not a magic bullet.
09:27 You can't just use free-threaded Python with threads and have it be magically fast.
09:32 And that's one of the cool...
09:34 Like, Fibonacci is a hard one because you're sort of...
09:37 To really do it faster, you depend on previous ones.
09:41 So it's slightly interesting with a Fibonacci.
09:45 But how many times do you really calculate Fibonacci?
09:48 So the better examples below that.
09:51 And it's a very simple example of just having a bunch of threads update a counter.
09:56 But it's...
09:57 And you won't do this.
09:58 But it'll be...
09:59 It's a cool example because it's an obvious one where you've got shared data.
10:04 There are a bunch of threads all accessing the counter.
10:07 So it's a very simple toy example.
10:09 But you could see how that relates to a lot of other work.
10:11 The cool thing...
10:13 One of the interesting things about this is it talks about some of the problems with concurrency, how to get around it, problems with concurrency and shared data.
10:23 And one of the first things I reached for because I came from C and C++ is locks when I want to have shared data.
10:32 And within this example, locks turns out to be the wrong solution because it actually slows everything down.
10:40 And I'm familiar with that with other languages as well.
10:44 But the cool thing that I've never really understood before that I'm grateful for this article to talk about is the thread pool executor.
10:54 Or executor?
10:55 Thread pool?
10:55 I don't know.
10:56 Thread pool executor.
10:57 Of how to launch a bunch of threads, have them come up with their own answer without talking to each other at all, no shared data, and then collect the return values.
11:08 And that's the really good way.
11:10 So with concurrency, not surprising.
11:14 Best way to do it is to re-architect your algorithms so that they can take advantage of it.
11:19 And what I'm excited about is that now we don't have to rely on async.io.
11:26 You can still.
11:27 But for a lot of parallel processing, we can just use threads now, finally, in Python.
11:32 Threads are okay.
11:33 So anyway, good article.
11:35 It's very exciting.
11:36 Good introduction.
11:37 Yeah, cool.
11:37 And it's very exciting.
11:38 I think it's going to give us a chance to talk about all sorts of fun things.
11:42 You know, we in Python land have not obsessed about all these design patterns, race conditions, making sure you lock all of your activity.
11:51 Yeah.
11:52 But we're going to have to start.
11:53 Have to start.
11:53 And I'm not sure that we necessarily should not have.
11:56 The guild does not protect you against corrupt multi-step race conditions.
12:01 Well, we've, I mean, we've kind of benefited that threads don't really run at the same time up until now.
12:07 So.
12:07 Yeah, yeah, I know.
12:08 But like, that's totally fine for one operation.
12:11 But let's suppose that I like, you know, the classic bank example.
12:15 I take, I debit somebody out of this account.
12:16 I do 10 lines of work.
12:18 And then I credit the other account.
12:20 Yeah.
12:20 Nothing, nothing says that the guild will not stop halfway through.
12:24 It's just, it's not very likely.
12:26 So the, you know, those problems are there in the code, which I think is going to be a double whammy.
12:30 But it also lets us start to think about the fun things like double checked locking, which is such a cool idea.
12:35 You know, like, there's, there's, I think it's going to be really fun.
12:39 I think it's going to be fun.
12:39 So for example.
12:40 Checked locking.
12:41 Yeah.
12:41 So check this out.
12:42 So I, I'll put this in the show notes.
12:44 It's just off of, or put it, look it up on Wikipedia.
12:46 So what you can do is you can say, if you have a single threaded thing, you can check, like, if this, this object is null.
12:52 Let's say it's a singleton.
12:53 If this object is null, create a new one.
12:54 So you only create it once and then return it.
12:56 But it's like a lazy crate.
12:57 But if like the default multi-threaded version would be every time you call this function, take a lock, check if it's null.
13:05 If it is created, return it.
13:07 But you can do things like check outside the lock if it's null and then take a lock and then check again if it's null.
13:13 Because maybe two things hit, one of them locked, one of them created it.
13:16 You still want the same one.
13:17 But you can like skip the locking ever, except for like during the once, one and only creation.
13:24 Like there's really fun patterns like that.
13:25 So I'm kind of actually looking forward to it, you know?
13:28 I'm not looking forward to the race conditions.
13:30 Yeah, yeah, yeah, yeah.
13:32 Speaking of locks, let's lock files instead of memory and execution.
13:36 So it turns out that pip 26.1 is out.
13:40 And it comes with features that I've been very excited about.
13:43 Most importantly, dependency cooldowns.
13:47 Don't remember, I don't remember when I wrote about this.
13:49 It was December last year.
13:51 I wrote about Python supply chains made easy.
13:54 And I wrote a follow-up one for like doing that production.
13:57 One of the really most important significant bits of this was, you know, instead of you finding out, let's let others find out that something's bad.
14:05 And the way you do that is you simply just go over and you just say uv pip, whatever, install, compile, whatever.
14:12 Or exclude newer one week.
14:14 And this was a thing that uv had that pip did not have, right?
14:18 So chalk one more thing for uv over pip.
14:22 But now pip itself actually has the same concept.
14:25 They have different CLI flags, which I don't know.
14:28 I feel like they should have just said, well, what are people using now?
14:31 Let's use that same CLI flag.
14:32 But so it is.
14:33 So it has this.
14:35 Let's go down to the cooldowns.
14:38 Here we go.
14:38 So you can say --uploaded prior to.
14:43 And you can put some kind of time in there, a duration.
14:48 So PND, where N is the number of days, kind of.
14:53 Okay.
14:53 Anyway, so you say P3D is like prior to three days is the value.
14:57 And then you can install something.
14:58 And that says it will only install the older, you know, stuff older than three days.
15:02 And this is super valuable.
15:04 It sounds like, oh, Michael, this is like security through obscurity.
15:07 And it's not going to make a difference.
15:08 Like almost all of these major takeovers are like three hours later, it was found.
15:11 Five hours later, it was found.
15:13 Yeah.
15:13 Rarely do these things sit around for a week unless they're extremely rare.
15:17 But the major projects take over like the, oh my gosh.
15:21 You remember which, that LLM library that you use for like a facade over all the different LLMs.
15:26 That one was taken down two hours after it was gotten in there.
15:30 You know what I mean?
15:30 So these, I think these are meaningful differences.
15:33 Why the actual difference in CLI?
15:36 I don't know.
15:37 Maybe there's a good reason, but I don't know.
15:38 Anyway, I'm really glad to see pip having this.
15:41 Also, Python 3.9 is not supported.
15:43 It's end of life over six, seven months ago.
15:48 So it seems fine that it shouldn't be here anymore.
15:51 I mean, I don't even remember 3.9.
15:52 Yeah, I don't.
15:53 What was 3.9?
15:54 We don't even know.
15:54 So honestly, I don't know why you would have any support for any older version.
16:00 You might say, well, Michael, somebody might be on Python 3.9 and they got to install stuff.
16:04 Like just pin pip to 25, right?
16:06 Like pip 25 is what they were using when they had Python 3.9 anyway.
16:10 Just install a different version of Pip.
16:12 I think that's like a no-brainer and should just be like a default.
16:15 New features.
16:16 This is interesting.
16:18 Like, first of all, I am very positive about this.
16:19 I think this is a great move and I'm really happy to see it.
16:22 Even if I have some criticisms like PND, which is just weird.
16:27 And there's already existing ones.
16:28 So this is also a little like that.
16:30 So Brett Cannon.
16:31 Go ahead.
16:32 No, what are PND files?
16:34 I don't know.
16:34 No, no.
16:34 That's how you specify the three days ago.
16:38 You say uploaded prior to equals P3D instead of just three days.
16:42 Who's going to remember that?
16:43 Okay.
16:44 Yeah.
16:44 Like the uv one you just put in quotes, one week, seven days.
16:48 Well, I mean, it's easier.
16:49 Yeah, whatever.
16:49 The parsing is probably easier or something.
16:51 I don't know.
16:51 I know, but it's used by millions of people, written by ones.
16:54 You could ask AI, help me parse this.
16:56 Anyway.
16:57 Yeah, I got it.
16:58 So there's this PEP 751, which was created 2024.
17:03 And it was, I believe it was accepted 14 months ago.
17:07 I'm not entirely sure.
17:08 It's not super obvious, but the resolution is March 2025.
17:12 So it's been around for a long time, about a year plus.
17:15 Okay.
17:15 And this is the file format to record Python dependencies for installation reproducibility by Brett Cannon.
17:21 He's been working on this forever.
17:22 And the idea is this is basically the pylock.toml.
17:26 And that's, if you go over here, it's actually in the Python packaging user guide on how to do it.
17:31 This is great.
17:32 So why am I talking about this?
17:33 Because the deal is pip now supports installing these.
17:37 Oh.
17:38 Oh.
17:38 Somewhat as an experimental feature.
17:40 So a year after its acceptance, which standardized pylock.toml, pip 26.1 gains experimental support for such files, for reading and installing from them.
17:50 Okay.
17:50 So this is great.
17:51 I think it's just, you know, pip is the most common way to install stuff in Python still, even if it's not the most hyped or most Rust implemented way to do it.
18:01 It's still the most common way.
18:02 Right.
18:03 And so having this support is kind of like table stakes.
18:05 Right.
18:05 So I think this is really cool.
18:06 There's a bunch of caveats and limitations and so on and so on.
18:09 But the criticism is like, if this is officially accepted by the core developers and Python and the steering council, why did it take a year for pip to support it?
18:20 You know, that seems pretty out of sync.
18:22 That's a long time from, yeah, we have this official feature and our official installer can't use it.
18:27 Yeah.
18:27 But I'm glad that it has it.
18:28 So that's good.
18:29 Maybe there's more to it than I know again, but who knows.
18:32 Some stuff about the older, like newer and older resolvers.
18:35 The new resolver now does many of the things that the older resolvers were being kept around for.
18:40 So I believe there's now a plan to remove the older legacy resolvers.
18:45 Like if you've got this version less than or equal to, and you've got that other version and so on, like how do you resolve that?
18:50 Then a few security fixes, not necessarily going to go into it too much, but there you go.
18:55 A brand new pip 26.1.
18:56 I feel like this is a big release, which is why I brought it up.
18:59 It's got the dependencies cooldowns, which I think is critical these days.
19:03 And it's got lock file support.
19:05 Yeah.
19:05 Yeah, no, it's really cool.
19:06 And it's definitely moving in the right direction.
19:09 Yeah.
19:10 Also, shout out.
19:10 This is, yeah, go ahead.
19:12 With wacky CLI names, but okay.
19:15 Yeah, yeah.
19:15 Also just shout out.
19:16 This is by Richard C.
19:17 So thanks, Richard.
19:18 Cool.
19:19 I actually am excited about another PEP as well.
19:22 So, we're going to stick with the PEP thing for a little bit.
19:25 this time Sentinel Values and also a blast from the past because, my search still up.
19:32 Anyway, this, Sentinel Values is PEP 661 and it was created in 2021 and it's five years later.
19:41 so it's taken a while.
19:43 However, it is, resolved as of, and, and final as of, for, for five, on 315.
19:49 So we'll get, we'll get Sentinels finally.
19:52 there's a, there's, the, the, PEP 661 has a bunch of information, but it's also, it says important.
20:01 This is a historical document, even though it's just finally here, but it's been working, being worked on for five years.
20:07 The, the actual information then is in, in, the Sentinel information now in the documentation.
20:14 So we can, we can click over and look at, I already had it up, look at Sentinel Values and they're kind of neat.
20:21 So I, I'm excited about this.
20:23 I don't, I don't quite understand some of the information, the decisions, but that's okay.
20:28 So, we often use like none for Sentinel value or some, or Nan, if you're doing, like floating point stuff.
20:36 but this, you just, Sentinel is a built-in that you just have to, you don't have to import anything.
20:42 You just say Sentinel and then give it a quote, a name, like in the example, in the docs, it's missing.
20:48 So Sentinel parentheses, and then the quote missing, you can name it, whatever.
20:52 But the object, one of the interesting things is it acts kind of like none you use is like if, if you want to check a variable or, an element, if it is the Sentinel, you can say is, is missing.
21:05 and, and then in the types, the type is handled interestingly.
21:09 The, the object is both the value and the type.
21:12 So you can say like a default, like some variable is, is of a, of type int or the pipe operator or missing.
21:22 So you can, you can have that together and it isn't missing altogether.
21:26 Missing isn't the magical, magical Sentinel value.
21:30 You can have anything like, not available or whatever you want to call it.
21:34 so about, I guess, you know, I think that it's, very much about time that we have a, Sentinel value built into the language.
21:43 interesting that the, okay.
21:45 So everything so far is, sounds great.
21:48 The part that I don't quite get is the, is that it's, it's not truthy or it is truthy.
21:53 That's it.
21:54 so if you're going through a list, like an array, and, and you want to check to see if it's Sentinel, you have to say is your Sentinel, you know, if you use the is operator
22:05 to make sure it's there, you can't like none, you could just say if like, you know, if the value in, if that's true, that means it's not none because none is evaluates to false.
22:16 All the Sentinels evaluate to true.
22:19 so you have to treat it differently.
22:21 All right.
22:22 I'm already feeling a PEP to enhance the Sentinel coming on.
22:25 to, to make it, to flip the values.
22:27 but what do you mean?
22:29 You know what?
22:29 I love the idea of a Sentinel.
22:31 I love it because it lets you check, you know, it's like if you're doing a, you know, find me the index of this thing, this item in a string and it's negative one, which is also an integer, but like, that's the, that's means it's not there.
22:44 Right.
22:44 Like it's all those kinds of checks are just odd.
22:47 And I love having the idea of a Sentinel, a thing where you say, I can check this and it's the same type, but if it's, but if it is this, that means actually we weren't able to process it.
22:56 Right.
22:56 Cause yeah.
22:58 Something weird came back.
22:59 What I mean is, so the way you create the Sentinel value, like the, the, it's a singleton or one off type of thing.
23:06 Like that's why you use is right.
23:07 And so you say Sentinel and you give it a string, which I guess is the, what it prints when you try to like string or rep the value.
23:16 Right.
23:17 Yeah.
23:17 And that's cool.
23:18 Why not give it a default?
23:21 I'm even in true, I guess, for compatibility at this point you would have to do, but why not give it a second variable?
23:26 You could pass like a falseness, like, is it true or false?
23:29 Like comma false.
23:31 And then boom.
23:31 Okay.
23:31 If this Sentinel comes up and I say, if value, no, this is not a value because it indicates the absence of a value.
23:38 You know what I mean?
23:38 Yeah.
23:39 Can I continue to rant?
23:41 Yeah.
23:41 I like that.
23:42 It wouldn't break the current, current implementation, but you could make it more usable.
23:47 I think so.
23:48 Yeah, exactly.
23:48 Just default the value to true on that, yeah.
23:51 Second parameter.
23:52 So you don't have to set it.
23:54 It doesn't break anything, but allow you to pass false.
23:56 So if you, if it or anything like where it's truthness, truthiness has to be checked.
24:01 Then it can be what it says it is because you might have a Sentinel for two different outcomes, right?
24:06 That's plausible, I guess.
24:07 Although it's not usually the way it's used.
24:10 Yeah.
24:10 But like a lot of, I mean, for Sentinels for, to mean I've like, I've got a big vector of stuff.
24:17 I want to know if there's, if it's not filled out.
24:20 yeah, I think the default should be false.
24:24 Primarily Sentinels are used in the case where something didn't work out right.
24:28 Normally you get a value, but sometimes you get a special value.
24:30 That means you couldn't get a value.
24:32 That should be false.
24:33 I agree.
24:34 Yeah.
24:34 The, I guess the one part where I say, you know, maybe it's, maybe it's, it's going to be more readable because it's going to force you to say is missing or is, you know, not there or whatever your value is.
24:46 But, I don't know.
24:49 I do like that.
24:50 You don't have to do that with none.
24:52 You can just say that it's just values false.
24:54 I do like the, I like the idea.
24:56 I think that maybe you should get on that whole PEP thing for, for extending that Michael won't you?
25:00 Yeah.
25:00 Before you scroll that screen, let me work on my second version of the pep.
25:05 I somewhat dislike the truthiness, although I get it.
25:08 And like, I'll just give a shout out to, the quirky out in the audience that I guess even the Sentinel is an object, which kind of makes it hard to be false, but like you can implement dunderbool, right?
25:18 So then you could do it.
25:19 Empty strings are objects and they evaluate the false.
25:23 Yeah, yeah, yeah, exactly.
25:24 Like you can, there's a magic method to say false.
25:27 They just return the value of the parameter that goes in when you created it, right?
25:30 I think it's, it's like a five minute implementation and 47 hour, like documentation and negotiation afterwards.
25:38 But here's the other one.
25:39 I think this is more subtle.
25:40 There's an example saying like, how do I express in the type system that something might be of the value expect or the value that is the Sentinel.
25:50 And this was much, I think this is a much more significant, probably not going to use this after all sort of thing in my mind.
25:57 Let me set the stage.
25:58 If I have a function that returns none or integer, and I say X plus Y where X came from that function, my type checker will say, oh, you cannot plus that with another integer because none does
26:12 not allow addition with integer.
26:14 So you can say, if is not none, X plus Y will work without the type checker failing.
26:19 But if you just say X plus Y types fall apart, it gets all upset.
26:23 I'm pretty sure that's what's going to happen here with Sentinels.
26:26 Your type has to be, I return an int or missing or an int or the Sentinel.
26:32 The Sentinel does not have type information based on an integer.
26:36 And so any int operation on it will fail.
26:39 And the type checker is going to warn.
26:40 So you're going to have to add all of these, like, I know it said it was an int or a Sentinel, but it's not any longer.
26:47 Now it's just an int.
26:48 And I feel like there's a lot of clumsiness that's going to go, go along with like trying to work with things that express themselves as int or Sentinel.
26:57 So can we just add another, another type, another parameter to the creation?
27:02 Like it's a Sentinel of int.
27:04 It's a Sentinel of...
27:05 Yeah, but we're not going to get it for 3.15, but maybe we can get it later.
27:09 No, no.
27:09 I'm just saying like, wouldn't it be nice if you could have it also be the type so you don't have to express in the type system that it is something else?
27:19 You know, I don't know.
27:20 To me, I think that's going to be, I think it's going to be rugged.
27:22 I think it's going to be rugged.
27:24 So.
27:25 Yeah.
27:25 I think we're, I think we're getting into like old man yells at cloud territory.
27:29 So, we may have to move on.
27:33 Cut me off, Ryan.
27:34 I'm telling you.
27:34 Yeah.
27:34 I told you I was going to be on like a type, a type, run this time, but no, I'm glad you covered it.
27:40 Cause this is interesting.
27:41 I love the idea of Sentinels.
27:42 I've used them.
27:43 I haven't used them very much in Python, but I used them back in my C++ and C# days and I really liked them.
27:48 I think they provide a really interesting goal.
27:51 Yeah.
27:52 Yep.
27:52 do you have any extras?
27:54 Of course.
27:54 Yeah.
27:55 You know what?
27:55 I got some stuff to talk about.
27:57 Let me swap it over.
27:58 I didn't have any extras written down, but then I decided I have extras.
28:02 So I haven't talked about this yet, but, if I go over at Talk Python training, I've done some cool stuff.
28:09 So no, there's so many, you, you warned me of this, pop out thing, Brian.
28:15 I'm now starting to feel it.
28:16 So over at, Talk Python training, we now have German subtitles for every single course for all 280 hours of courses.
28:24 So like I'll, I pull up, Vincent Wormerdam's, LLM building blocks course.
28:31 And now if I click on the CC, I get English, German, and this one even has Spanish.
28:36 How about that?
28:37 Nice.
28:38 Yeah.
28:38 So I could turn on like German transcripts and, you know, they're on the screen.
28:42 Maybe those are too big.
28:43 So I can make them a little smaller, put them up at the top.
28:45 So they're not in the way.
28:46 So I've done a ton of work on the transcripts over here.
28:49 And now guess what Vincent's speaking German now, right?
28:55 Let's go.
28:56 So anyway, if, if you were a German speaker, check out the courses, and turn on the subtitles for German, if you like.
29:03 I'm wondering how, like when we're going to have AI tools that can not just do different translations for subtitles, but can we get like dubbing in the original speaker's voice?
29:16 That'd be cool.
29:17 Hold that thought.
29:17 All right.
29:18 That's my extra.
29:19 We have a German subtitles for all the courses that talk Python, all 280 hours.
29:24 And I would just like to point, I said this in the blog post, but just to listen to 280 hours of audio is seven weeks, almost two months of work, not the translating, not the double
29:34 checking just to listen to is seven weeks worth of work, 40 hours, you know, eight hours a day, five days a week sort of thing.
29:42 so that is a mega, mega project I've been working on.
29:46 And you got a lot of courses up.
29:48 I know it's crazy.
29:49 So I'm working through the Spanish ones.
29:51 Now I've got maybe four courses converted over Spanish, but Spanish is going to be the next language.
29:56 So don't feel left out Spanish speaking folks.
29:58 It's coming soon.
30:01 Yeah.
30:01 That's my extra.
30:02 All right.
30:03 Well, I'm going to roll back to, we were talking about, what was it?
30:08 It's not, the place, the non GitHub place that we had somebody at, anyway.
30:14 Kudberg.
30:14 Kudberg.
30:15 Yeah.
30:15 So, on that topic, Armin Ronecker, wrote an article about GitHub.
30:21 So before, before GitHub, basically the, like it's talking about this, like we're at, we're at an inflection point, not sure where we're going to go forward.
30:30 But before GitHub, it was a weird place.
30:33 We had basically, source controls roll your own or do something wacky or, it was, it was a very different experience.
30:41 So we're, and I have to agree.
30:44 I am even at the state of GitHub right now, I'm still using it a lot and other things, but I also understand some of the gripes people have, there's political stuff and with AI and everything.
30:57 But aside from that and whether or not they should have been able to just steal everybody's content, or intellectual property, because open source does not mean please just, you know, train your AIs on it.
31:10 But anyway, regardless of that, the, there's a, there's another, there's another aspect of it that the GitHub is really built around community building and collab getting as many collaborators as possible.
31:23 And it doesn't often work that way.
31:26 I mean, we often get a lot of people submitting issues and griping about things, but not a lot of people contributing actual good code contribute contributions.
31:35 And it's even different.
31:36 It's even worse now with a lot of people just submitting AI slop, as, as stuff.
31:42 So I totally get projects getting, moving away.
31:46 So there's a interesting discussion about like, you know, GitHub is slow.
31:50 GitHub is slowly dying.
31:51 I don't think it's going to die.
31:53 I think it'll stick around for a long time.
31:54 And I think, for many years, it'll be still the dominant one, but there is some interesting shifts.
32:00 at first there were like just a few people moving over or not a few, a lot of people moving over to Codeberg, but it was a smaller projects.
32:09 But now there's some bigger ones.
32:10 And, and one of the things that I'm grateful for is he brought up tenacity and I'm like, what's tenacity?
32:16 I don't know what that is.
32:17 And it's a, it's a total tangent for the topic, but it's a, cross platform, multi-track audio editor and recorder that I'd never heard of.
32:26 And it looks pretty cool.
32:28 So I might check that out.
32:29 It's an open source thing.
32:30 Anyway.
32:31 Oh, that's very cool.
32:32 I've used audacity and I bet it is a, a riff on audacity, right?
32:37 But yeah, yeah, yeah.
32:38 Now I'm definitely checking this out.
32:39 This is cool.
32:40 Yeah.
32:40 So I definitely want to check that out, even though I, I, I'm happy with my audio situation right now.
32:46 But anyway, the interesting thing around this that I, I, it's a, it's an interesting topic and it's not a really long article.
32:56 One of the things he talks about really is when, if we go to Codeberg or other roll your own stuff and have source code, like all over the place, we do lose some things because even, even though you can clone, you can do things that conversations are less, we have less
33:09 conversations around, around issues around the direction of some projects.
33:14 And if it goes away, if somebody deletes their repo, we lose all of that.
33:18 so there's some archive possibly needed some history that would be helpful.
33:23 anyway, interesting discussion around, around that here.
33:27 So thanks, Armin.
33:28 Yeah.
33:29 Very nice article, Armin.
33:30 And I've really appreciated his, his thought pieces and his writing over the last year or two.
33:35 So good job.
33:36 Yeah.
33:36 Yeah.
33:36 Also Hugo out in the audience said, Hey, don't forget Python 314.5 is now out with the new, which is actually the old GC and 315 beta one, the feature freezes out.
33:50 So yes.
33:51 Thank you so much for that.
33:51 Like most notably the garbage collector GC has changed back to the full pausing one, not the incremental one.
33:59 Everything old is new again.
34:00 Yeah, exactly.
34:01 Here we go.
34:02 Back around.
34:03 All right.
34:04 tell us a joke.
34:05 Ready for a joke.
34:06 So, I've been thinking about like everybody's saying, Oh, like now that with AI and everything, I can write my own software.
34:13 I don't need software engineers.
34:14 So it reminded me of this XKCD.
34:17 So I'm bringing this up.
34:18 So it's a make it yourself, make it, make it, make it myself, XKCD.
34:23 And there's two people looking at a couple boxes and I'll just read it out to you.
34:28 It's mostly text.
34:29 They want $80 for this.
34:30 I could make one myself for $10 in parts, an hour of work, a trip to the hardware store, another $30 for parts, another few hours of work, two more trips to the store for $20 more in parts, another hour to redo the first hour of work because I messed
34:45 it up and $80 to buy this when the one I made breaks.
34:49 So that is so true.
34:52 It's a hundred percent true.
34:54 Yeah.
34:55 Yeah, exactly.
34:56 And I don't, that's why I think this whole vibe coding thing, you know, there was the SaaS apocalypse.
35:01 And I think that's going to be a very focused and very narrow impact because it's like, yeah, you can make it and you got to back it up and maintain it and run it and operationally and secure it.
35:11 And you know what?
35:12 Let's just let them run it for 10 bucks.
35:13 Yeah.
35:14 I think I'm, I'm hoping that it will drive.
35:16 I mean, not the, I think it'll change the dynamics of how people make money about software, but I do think that I'm hoping we get more good SaaS out there and some of
35:28 the, the, even if it's helped being made by AI, but the good ones will stick around even if they get, have to get really recoded.
35:37 So yeah, indeed.
35:38 All right.
35:38 Well, thanks a lot for a great episode.
35:40 Thanks everybody for listening.
35:42 Yeah.
35:42 Thanks.
35:42 Bye.
35:43 Bye.



