Brought to you by Michael and Brian - take a Talk Python course or get Brian's pytest book

#271: CPython: Async Task Groups in Python 3.11

Published Wed, Feb 16, 2022, recorded Wed, Feb 16, 2022

Watch the live stream:

Watch this episode on YouTube
Play on YouTube
Watch the live stream replay

About the show

Sponsored by us:

Special guest: Steve Dower

Michael #1: fastapi-events

  • Asynchronous event dispatching/handling library for FastAPI and Starlette
  • Features:
    • straightforward API to emit events anywhere in your code
    • events are handled after responses are returned (doesn't affect response time)
    • support event piping to remote queues
    • powerful built-in handlers to handle events locally and remotely
    • coroutine functions (async def) are the first-class citizen
    • write your handlers, never be limited to just what fastapi_events provides

Brian #2: Ways I Use Testing as a Data Scientist

  • Peter Baumgartner
  • “In my work, writing tests serves three purposes: making sure things work, documenting my understanding, preventing future errors.”
  • Test
    • The results of some analysis process (using assert)
    • Code that operates on data (using hypothesis)
    • Aspects of the data (using pandera or Great Expectations)
    • Code for others (using pytest)
  • Use asserts liberally even within the code
    • use on as many intermediate calculations and processes as you can
    • embed expressions in f-strings as the last argument to assert to help debug failures
    • check calculations and arithmetic
    • check the obvious
  • Notebooks: “One practice I’ve started is that whenever I visually investigate some aspect of my data by writing some disposable code in a notebook, I convert that validation into an assert statement.”
  • utilize numpy and pandas checks, especially for arrays and floating point values
  • hypothesis can help you think of edge cases that should work, but don’t, like empty Series, and NaN values.
  • Write tests on the data itself
    • pandera useful for lightweight cases, checking schema on datasets.
    • Great Expectations if we’re epecting to repeatedly read new data with the same structure.
  • Use pytest, especially for code you are sharking with other people, like libraries.
  • TDD works great for API development
  • Arrange-Act-Assert is a great structure.
  • “Even if we’re not sure what to assert, writing a test that executes the code is still valuable. “
    • At least you’ll catch when you’ve forgotten to implement something.

Steve #3: PEP 654 Exception groups and except

  • A necessary building block for more advanced asyncio helpers
  • Mainly for use by scheduler libraries to handle raising multiple errors “simultaneously”
  • except: “a single exception group can cause several except clauses to execute, but each such clause executes at most once (for all matching exceptions from the group)”
  • Necessary for complex scheduling, such as task groups

Michael #4: py-overload

  • A Runtime method override decorator.
  • Python lacks method overriding (do_it(7) vs. do_it(``"``7``"``))
  • Probably due to lack of typing in the early days

Go from this:

def _func_str(a: str):
    ...

def _func_int(a: int):
    ...

def func(a: Union[str, int]):
    if isinstance(a, str):
        _func_str(a)
    else:
        _func_int(a)

To this:

@overload
def func(a: str):
    ...

@overload
def func(a: int):
    ...

Brian #5: Next-generation seaborn interface

  • Love the background and goals section
    • “This work grew out of long-running efforts to refactor the seaborn internals so that its functions could rely on common code-paths. At a certain point, I decided that I was developing an API that would also be interesting for external users too.”
    • “seaborn was originally conceived as a toolbox of domain-specific statistical graphics to be used alongside matplotlib.”
      • I’ve always wondered about this
    • Some people now reach for, or learn, seaborn first.
    • As seaborn has grown, reproducing with raw matplotlib to change something seaborn doesn’t expose is sometimes painful
    • goal : “expose seaborn’s core features — integration with pandas, automatic mapping between data and graphics, statistical transformations — within an interface that is more compositional, extensible, and comprehensive.”
  • I also like interface discussions that have phrases like “This is a clean namespace, and I’m leaning towards recommending from seaborn.objects import * for interactive usecases. But let’s not go so far just yet.”
    • I like clean namespaces, and use some of my own libs like this, but import * always is a red flag for me.
  • The new interface exists as a set of classes that can be acessed through a single namespace import: import seaborn.objects as so
  • Start with so.Plot, add layers, like so.Scatter(), even multiple layers.
  • layers have a Mark object, which defines how to draw the plot, like so.Line or so.Dot
  • There’s a lot more detail in there.
  • The discussion is great. Also a neat understanding that established libraries can change their mind on APIs. This is a good way to discuss it, in the open.
  • Note included at the top:
    • “This is very much a work in progress. It is almost certain that code patterns demonstrated here will change before an official release.
    • I do plan to issue a series of alpha/beta releases so that people can play around with it and give feedback, but it’s not at that point yet.”

Steve #6: Compile CPython to Web Assembly

  • Allows fully in-browser use of CPython (demo at https://repl.ethanhs.me/)
  • Currently uses Emscriptem as its runtime environment, to fill in gaps that browsers don’t normally offer (like an in-memory file system), or WASI to more carefully add system functionality
  • Still the CPython runtime, and a lot of work to do before you’ll see it as part of client-side web apps, but the possibility is now there.

Extras

Michael:

Steve:

  • Python 3.11’s latest alpha now has Windows ARM64 installers. These aren’t the dominant devices yet, but they’re out there, and if you’ve got one the CPython team would love to hear about your experience.
  • Steve just released a new version of Deck, which started as a way to help people who misspelled collections.deque, but has grown into a useful building block for traditional 52-card games (or 54 including jokers).

Joke: Help is coming

Episode Transcript

Collapse transcript

00:00 Hey there, thanks for listening. Before we jump into this episode, I just want to remind you

00:03 that this episode is brought to you by us over at Talk Python Training and Brian through his pytest

00:09 book. So if you want to get hands-on and learn something with Python, be sure to consider our

00:14 courses over at Talk Python Training. Visit them via pythonbytes.fm/courses. And if you're

00:21 looking to do testing and get better with pytest, check out Brian's book at pythonbytes.fm slash

00:27 pytest. Enjoy the episode. Hello and welcome to Python Bytes, where we deliver Python news and

00:32 headlines directly to your earbuds. This is episode 271. Really? Wow. Recorded February 16th,

00:39 2022. I'm Brian Okken. Hi, I'm Michael Kennedy. And I'm Steve Dower. Welcome, Steve. So who's

00:46 Steve Dower? Who's Steve Dower? Yeah. Number of things. Probably most interesting to this audience

00:52 is I'm a core developer on CPython, one of our Windows experts. So I spend a lot of my time

00:57 focusing on making Python run better on Windows. I also work at Microsoft, where I also spend a lot

01:04 of my time making Python run better on Windows. So I'm kind of a bit of a one-trick pony, I guess.

01:09 But I feel like it's good work and it helps a lot of people. So if I have a problem with Python on

01:15 Windows, it's your fault. If there's solutions for Python on Windows, then it's my fault. I'll let

01:22 other people own the problems. So if I go to the Windows store, I can now install Python from there.

01:30 And you were part of that, right? Oh, I should have had that up on screen, shouldn't I?

01:34 Yeah, that was actually... The request came from people within Microsoft were like,

01:41 hey, why can't we get Python up on the store? And my response to all of these is like, well,

01:47 if the community is willing to do it, which is half me and is half the people who would have to take over

01:52 if I stopped doing it, then yeah, we'll go ahead and do it. And so I got actual work time for that.

01:58 That was a contribution from Microsoft for that one. But yeah, the community was on board and

02:03 it's going really well. That's also the one that we tied into the default Python.exe that's on every

02:10 Windows machine now. So if you go to a brand new machine and just type in Python, you'll get straight

02:14 to the PSF's Python. Microsoft is not doing it anymore. We just contributed the change. And now I

02:22 switch hat and do it with the other hat on. So it's real Python, right? It's exactly the same as what you

02:27 get from python.org. It's just delivered, you know, easily fast install automatic updates.

02:32 And a couple of edge issues that we're working on bringing down. So yeah, fantastic.

02:40 Automatic update. I know this wasn't one of the topics, but now I think I might have to rethink

02:45 how I'm installing Python on my desktop at work. So that's a cool idea.

02:50 I have only had store installs on my own machines since 3.8. I think I haven't,

02:57 apart from testing, I haven't actually used the regular installer on my own.

03:01 But I mean, you, of course that makes sense, but.

03:03 I mean, you know, it's always testing, right? Every time I'm using Python, I'm testing.

03:08 So.

03:08 Chris May out there says, thank you so much for making my work life in Windows easier.

03:13 Anytime.

03:14 Yeah. Well, Michael, why don't you kick us off with a story or topic?

03:18 I have got a good one. So I'm a big fan of FastAPI and FastAPI being built on Starlet.

03:25 So by the transitive property, I'm also a fan of Starlet. And there's this thing I want to cover

03:30 called FastAPI events. So when a request comes in to a particular API endpoint, or if you convert it

03:38 over to a web app, to a web page sort of request or something, you might want to dispatch that out to

03:44 say like WebSocket listeners or something along those lines. So there's this cool project called FastAPI

03:49 events. It's pretty small and new. So I'm going to try to give it some visibility. It's only got 36 stars.

03:54 It's pretty new, but the idea is that you can go through and basically create this middleware

03:59 handler that will let you say when a request comes in, here's the way when an event is raised,

04:05 here's the thing that's going to handle it. And then in some API endpoint, you can say dispatch,

04:09 give the event a name and some dictionary data to be passed along. I suppose it doesn't have to be

04:15 a dictionary. It could be whatever. And then in other parts of your code and say, I want to just hear

04:19 about this event that happens no matter what API endpoint received it, no matter where in like how

04:26 deep down in the code it was received and so on. So then way down here, you just put a role handler

04:33 decorator on there. You say, I want to capture all the events that start with some substring like cat

04:38 star for like category, whatever, or this one is actually literally about cats. And then you can just go

04:45 through and write these functions that will then handle that. And you can also pass them off to

04:50 queues like you can use the SQS, the simple queuing service from AWS, I believe that is, as the endpoint

04:57 instead of it just being your app. So if you've got like lots of scale out and stuff like that.

05:01 Wow. Of course. So just like a neat way to do logging or even distributed logging, I guess,

05:06 if you've got forwarding handlers in there, you can just...

05:08 Yeah. Yeah. It seems like it, right? Like, or if you want to sort of build up, like, here's the

05:14 request transaction and here we're at this stage, or like you could maybe do like visibility into

05:18 long running workflows with this kind of thing or something along those lines, I would think.

05:21 So yeah, there's also an echo handler for debugging. I kind of like that. Like if I just need to see what

05:27 is happening, it'll just print whatever's happening. It'll just start printing out all the behaviors that

05:31 you're logging. So...

05:32 And then when you want to stop doing that, you just take away the handler and you don't have to

05:36 search the entire code base for print and find everywhere that you added it in for debugging.

05:41 Exactly. Alvaro out there says this looks similar to Django events. Yeah, I suspect. I suspect it is

05:50 similar. Yeah. Anyway, pretty short and simple, but if you're looking for a way to sort of

05:55 put notifications in a structured way into a FastAPI app, well, here you go.

06:01 Oh, I'm thinking of a whole bunch of more abusive ways to use this.

06:04 Yeah, you can write some really impressive spaghetti code with this.

06:11 Yeah, I'm sure that you can. Get the cloud involved in everything.

06:14 Yeah. So let's switch gears a little bit and talk about testing. Imagine that. I've got a testing topic.

06:23 So this is... I'm pretty excited. This is... I've been asked a lot about testing pipelines,

06:30 testing data science stuff, and I'm not... That's not something I do day to day. So I'm really glad

06:35 to find people talking about it. So this... We've got an article from Peter Baumgartner.

06:42 Ways to use testing... Ways I use testing as a data scientist. And I actually just really love this

06:48 article. It's great. To start with, he starts off with what he uses testing for. As a data scientist,

06:56 he uses testing to make sure things work, to document his understanding, and to prevent future

07:03 errors. Well, that seems straightforward. But the reason why he wrote this up is apparently because

07:10 there's a lot of software... There's a lot of testing stuff out on the web, but it's not... It's like geared

07:15 towards test engineers or software developers. And he's like, I'm not a software developer. I'm a...

07:21 And, you know, I'm doing something else. I'm doing analysis. I'm not a software person, even though... Yeah,

07:27 you are. But to write this up in a context where data people might understand it better. For instance,

07:36 he doesn't even start off with writing... Having written tests. His analysis is like, if you're doing

07:43 notebooks or other code, just use a cert a lot. So he's using a cert all over the place, including... He says,

07:52 "Where do you have? Use it for as many intermediate calculations and processes as you can, as it makes

07:59 sense." Because... And doing things like checking obvious stuff. Like he's got an example of a table

08:07 count where he's counting up all the yeses. Well, you can do a little bit of math just to make sure

08:11 the math works. So like all the yeses and nos and missings should all add up to the same count. Go

08:17 ahead and throw an assert in there because sometimes it doesn't. And in this example, he said that he

08:22 actually caught an error because he was looking at two different data frames. So they really weren't,

08:29 they didn't add up to the same. So you can catch things like that. So just double checking yourself on

08:35 things as you go wrong away, go as you're developing. One of the cool quotes he has in here is like,

08:43 as he has a habit of when he's using notebooks to whenever he's visually inspecting the output,

08:50 if you're visually looking at the data that comes out, maybe write an assert statement to do that

08:56 analysis so that it's always checked. And this is a cool use of putting asserts in notebooks. I like this

09:04 idea. The article goes on, it's pretty extensive, talking about checking the data, using hypothesis

09:12 to, well, not the data, not the data at this part, but your assumptions around the data. So using hypothesis

09:20 to check your assumptions and hypothesis will think, show you things that maybe you didn't consider like

09:26 NANDs, are you handling those correctly? Empty series or empty data structures that are going into your

09:32 into your code? Are you handling those? If I mean, hypothesis does have take some handholding,

09:39 but it does make you think about really what is the shape of the data going in? And do you, can you,

09:46 do you need to limit it? What hypothesis is looking at, or do you need to change your code to handle more things?

09:51 Hypothesis is great. I've used that for a couple of, you know, parsing projects or combining projects.

09:58 I spent way too long adding all the strategies to be able to test a URL parser that I was calling into.

10:04 But it's fantastic for finding kind of things that you would not have thought of.

10:11 Yeah. I mean, it's finding things, but it's also, and it does make, yeah, that aspect of it seems like

10:16 the point of it. But the real value I get on a hypothesis is thinking, making sure I really

10:22 understand the data that's going to come in and thinking through those. It goes on to talk about

10:28 actually testing your data using things like Pandera, which I wasn't familiar with, and another

10:33 package called great expectations to look at like putting schemas around the data coming in and making

10:39 sure that the data always matches a schema. Going on to talk about a range act assert and using

10:45 pytest. pytest comes in with, he's only really writing formal tests when he's writing libraries

10:51 for other people. But all these other packages to be able to test with data science, I think this is a

10:57 great addition to the data science community.

10:59 Yeah. Alvaro talks about how this is often referred to as defensive programming. And then,

11:05 you know, I feel for him a little bit, says that work, we use this with our Fortran code. So there's that.

11:11 But I do think this is a really interesting way of thinking about defensive code. You know, I just,

11:16 I think of writing defensive code as like, oh, I'm gonna have a bunch of is statements to verify this

11:20 thing's not none or verify that this is the right type and that it has like a reasonable value and raise

11:25 exceptions. I haven't really thought so much of it for like notebooks. So that's pretty interesting.

11:31 And one of the neat things about like, if you're actually putting a search in your code, you can actually, you can write

11:36 tests against your code that don't even have any certs in them. And because the search will happen

11:43 within your code and the test will still fail and catch it. So it's kind of cool.

11:47 Yeah. Yeah. Very cool. Good stuff.

11:49 Yeah.

11:49 Steve, I am super excited to hear about what you're, you got coming up because this is brand new being a core developer. I feel it is appropriate that you

11:58 break this.

11:58 I mean, I'm not going to lie when it came to, you know, what am I going to talk about? Okay.

12:03 What's the most recently accepted PEP that was somewhat controversial? And I think just as you

12:09 kind of look down to the section on rejected ideas, which is considerably longer than the accepted ideas,

12:16 you can probably get a bit of a sense for just what went on with, with exception groups. And I know,

12:24 Michael, you've just had a conversation, you've learned all about them. So you can, you can take

12:28 over when I run out here, but I'll share my thoughts with it, but yeah, go ahead. I'd love

12:33 to hear about it. This is sort of inspired by trio, right?

12:36 The, the end goal kind of is, so this is an interesting PEP and we've got a few of these on

12:40 the go at the moment. It's kind of like a stepping stone towards a better programming model or a stepping

12:46 stone towards better libraries. So it's, it's something that I think in, in my opinion, very few kind of

12:53 application developers, kind of the last developer in the chain is like, I'm often not

12:59 going to use them and they're not going to need them. But as you go further in towards the lower

13:04 levels of libraries, especially people writing async schedulers are going to find incredible value out

13:09 of them. Essentially what the idea is, is that when you're running multiple tasks in parallel,

13:15 if some of them fail, we don't currently have a, have a neat way to capture the exceptions from all

13:21 of the ones that failed. There, there's some approaches that would be like, wait for all of

13:25 them to complete and wrap it in a list. And then you get some exception that contains a list of exceptions,

13:30 but that's lost a whole lot of context. you can get just whichever exception happens first,

13:36 but then you lose all the other exceptions and there's just been no real way to handle it. So an

13:40 exception group essentially does bundle up all the exceptions, internally in some way. But the

13:46 really interesting thing is the except star syntax, which I'm going to have to scroll a long way down

13:51 to find where that comes up. but, but this is really clever because if you're in that situation where

13:59 say you're running 10 parallel processes, so here's kind of the first example of it, then

14:04 exceptions are no longer control flow at this level. Cause if you're, if you've run 10 things and you're

14:11 waiting for 10 things to complete, you're not actually doing control flow with the exceptions anymore.

14:15 What you're doing is handling the exception, but then the control flow is going to go back to where it

14:20 was anyway, because you, because you, you're going to, you know, be doing something different. So for

14:25 example, if a file doesn't open, then you, you would want to, you know, do something different,

14:30 right? You're going to stop going on and trying to read from the file. but if you've tried to open

14:36 10 files and three of them failed, you at the outside level. So at the end, at the inner level

14:41 for each file that may have failed, you'll do something different at the outer level.

14:45 All you're really going to do is say, Hey, this task failed because a file couldn't be opened.

14:50 And maybe you do something else, but it's at the outside level. So except star takes that exception

14:54 group and it's going to give you a chance to handle each exception, essentially on its own.

14:59 It will group them together. So in this example, if you know, five tasks report spam error,

15:04 then you'll get into this except spam error block with all five of them at once. which is just

15:11 what is that a list of spam exception, spam error exceptions, something like, or a tuple, something

15:16 like that. I think it's a tuple. I think with the stars in time, I believe, something

15:22 iterable basically. Yeah. Yeah. so something you can iterate over to see the exceptions, but

15:27 it's really just, you know, this happened at some point and you process it. And if the group actually

15:34 contains multiple types of exceptions, then each handler that matches is going to be called for all the

15:39 exceptions that match that. So you could have this tri block raise an exception group that has some spam

15:45 errors. It has some full errors. It has some bar errors and all three except, except star blocks are

15:51 going to get called with the exceptions that match those, which is a bit, it's, it's definitely going

15:56 to confuse a lot of people. It confuses me, which is, you know, why I was keen to actually spend

16:01 a bit more time digging into it, and trying to figure out what's really valuable about this.

16:07 and I do think the most valuable one is really where the error is canceled error, because if for

16:12 whatever reason, five of your tasks have been canceled, then you need to capture that and do

16:17 something with that outside of it. But it doesn't necessarily mean you want to throw away the five

16:22 successful results. And so you do kind of want to, to keep a bit of everything going on. it's,

16:30 and like I say, it's a building block on its own. This isn't enough to do anything new and useful.

16:36 The next thing that comes along is task groups and that's, you know, being worked on by,

16:41 you know, I expect a lot of the same people who worked on exception groups because with task

16:45 groups, now you can actually start, there we go. Guido has just merged task groups. Excellent.

16:50 then now you can actually, like run the task group. And if the group raises any errors,

16:58 then you'll catch them through an exception group. And so that enables a whole lot of, new uses

17:04 and new ways to use asyncio or just async generally, no matter the library, as you say,

17:10 trios already had something like this for a while. and from their nursery thing.

17:15 Yeah. And so that is now being standardized. So libraries can kind of share their implementations

17:21 and work together on it. So one of the reasons you need this is if I start two web requests and

17:28 three database queries, and then I go to wait on them, you know, then the, if, if several of them

17:33 fail, the error state captured in totality is a, a tree of errors that represent, well, this,

17:40 this, this, this task started this other task, which then had this error, this other one.

17:45 Right. So you need some way to deal with a, a group of errors that could happen

17:48 kind of all at once. Right. And one of these task groups that gets kicked off.

17:52 Yeah.

17:52 Yeah. So the new task group thing is super cool. So you say async with task group as TG,

17:58 and there's two things that are neat about it. One is right now, if you fire off a bunch of tasks

18:03 and async and await style, they're basically unrelated. Like if one fails, that means nothing

18:08 for the other, right? They're just like, well, here's a bunch of stuff that happened. And this

18:11 creates a relationship between them. Right. So that if one fails, I think it might not schedule new ones,

18:16 something to that. Like it's brand new. I'm just seeing the tweets. So I think that that's the

18:20 story. I believe that was the story of Rio. The other thing that's interesting here that in this

18:25 example, which I all linked to from Yuri that he posted, he tweeted about the news was notice that

18:33 the first one says task group, create task for some task, and then it awaits something that creates

18:38 another task. There's nowhere where you say, store all those values into like some lists of tasks,

18:44 then go to the task and iterate them and wait for them or gather them or whatever the heck it was

18:48 you had to do before. This now makes tasks fire and forget. I can say, run this, run this. And within

18:54 that, I could do more of those types of things. And then you just block at the with context manager

19:00 level to wait for all the tasks to finish, which I think is a real big improvement. Because right now

19:05 you've got to like constantly juggle, well, I've got to return a task from this so I can go wait on it

19:08 later and all those sort of oddities. And this cleans up a lot of that.

19:12 Right. And of course, being Python, I don't know exactly how the syntax works, but being Python,

19:17 that TG object, the task group doesn't actually disappear at the end of the with block. So if

19:21 that's got results stored into it, then you still have access to those and all of the information

19:27 about the task group, even after you've waited for it to complete running.

19:30 Oh yeah, that's cool. Yeah. So I think this is a nice addition to async I/O and Python. This is cool. And apparently 3.11 is coming.

19:37 Yeah, coming in 3.11.

19:38 Yeah.

19:39 I do see a question from Sam Morley in the chat there. Is there a way to short circuit

19:43 so that you don't re-catch certain exceptions? My understanding, and Michael, if you've got a

19:48 better one, correct me, is that the exception, the accept blocks work in the same way as regular ones.

19:55 The first one that matches a particular exception will handle it, and the later ones don't, even if they

20:00 would also match. So if you have, so if the spam error is a subclass of foo error, but there's another

20:07 subclass of foo error, then spam errors will get handled by the spam error handler. The foo

20:13 and foo error handler will handle all the other ones apart from the spam error subclass.

20:18 Nice. Yeah. I don't know much about the accept star other than it was basically a requirement for the

20:23 task group stuff to be implemented properly. So once one came in, then the other could come in. Yeah.

20:28 It's the only feasible way to actually do something as a result of an exception group. Otherwise,

20:34 you do end up with a very generic exception, and then you write a for loop over all the exceptions that

20:42 are handled and try and figure it out yourself. So you'd end up rewriting the code, and it was just

20:47 not going to be feasible. It needed to be syntax. And so it is. Yeah. Right on. Very, very exciting and

20:53 very timely. Thanks, Steve. I'm kind of glad that I put off learning how to do async code until 3.11.

20:58 This looks easier. It's a good band and a good time for async.io. Well, cool. All right. I guess I'm

21:05 up with the next one, huh, Brian? Yeah. Let's see what you got. I have got some other interesting things.

21:10 I'm here about showing off the underappreciated projects or the new projects. Just a couple of stars here.

21:16 And we talked about overloading before, but I thought this was a clean way to do it that people

21:21 can think about. And Steve, I would definitely love to hear your thoughts on this. So Felix the cat

21:25 created this library called pyoverload. And the idea is basically once you have type information,

21:32 then you can have method or function overloading. The idea of being like, okay, I have a function called

21:37 foo or whatever. And you can say, if it takes an integer, I want this implementation to run. If it takes a

21:42 string, I want some other implementation to run. Right. That's sort of the traditional C++,

21:47 C# definition of it. Right. But in Python, we don't have that really because the language started

21:53 without type. So how are you going to figure out the type to overload it? You know, right. That just

21:56 like, doesn't make any sense. So with this one, you could sort of use like traditionally, you could use

22:01 this instance. We're going to do one thing or another. Is it a single thing? Or is it a list of those

22:05 things? What are we going to do? But with this one, you can put just at overload and then whatever the

22:10 signature is, if you can say it has no functions or has no parameters, or it has like two integers,

22:15 or it has three integers, or it has like a list of them, whatever. And there's even a way to sort of

22:21 say somewhere down here, there's a way to say like, if none of them match call this particular one.

22:26 So basically it's, it's just straight function overloading in Python. If that's the thing you want,

22:31 Steve, does this make you cringe or do you like it? Well, you know, I'm, I'm, I'm not going to lie.

22:38 I'm not the most into static typing in my Python code as a lot of other people. And, and there's a

22:46 lot of, you know, there's a lot of complicated reasons, but I think for a situation like this,

22:49 I mean, if I know if I was writing a function that took a string or an int, the very first line would be

22:55 converted to whichever type I actually want. And then the rest of the function is going to look identical.

22:59 Yeah. And that's sure. And that, in that case where like, there might be a, an unparse type of thing,

23:05 for sure. I think you wouldn't really do an overload. That would be insane.

23:08 And my, my kind of gut feel, and you know, I'm always open to, to examples proving me wrong.

23:14 in which case I, you know, I would write the is instance code that's in those examples.

23:19 You know, my, my kind of gut feeling is that if you're doing two drastically different things in

23:23 the function based on the type, you need two functions. and once you've got two separate

23:27 functions, you know, if the people calling don't know what they're passing you, then that's, you know,

23:32 they've got a problem and it's not, you know, so much my responsibility to fix it with overloading.

23:37 That said, overloading is really cool. and you know, I am the exact opposite person when it comes

23:43 to like C and C++. I will do all the craziest possible stuff with overloading in those languages,

23:48 because I think it fits the language and it's a lot of fun. and, and there's definitely occasions

23:53 and value for having it in Python. we do have the single dispatch decorator has been part of Python

23:58 for a while, which will do this on the very first parameter. this, you know, very trivially extending

24:05 it to the whole function signature is, is really cool. So, you know, it's, if, if I needed to do this,

24:12 I would probably want to use this, a library like this. would I, would I, you know,

24:17 I'd probably, I would probably reconsider my API design choices up to that point.

24:22 but, but I can understand the attraction of, of getting to, you know, to, to reuse,

24:28 reuse the name and not make the person calling it think too hard about how, you know, what's actually

24:33 going to run. Yeah. The place where this sort of seems interesting to me is, you know, there's some,

24:39 a lot of like tricks and juggling people do with like star, star, star, star, KWRs where like,

24:43 okay, depending on how you pass it stuff, we'll do a bunch of things. Yeah. And I'm always looking

24:48 for a way to like, not do that. Yeah. How, how can I not, how can I remove that? Like,

24:54 it's completely opaque. I have to do a Google search and read the docs to figure out what is

24:58 at all possible here. Well, one of these days I I'm going, probably going to take all of the kind

25:03 of patents for that kind of thing that I've collected and turn it into a book, but writing

25:07 book just feels like way too much work. So anytime soon. Sorry. my, my colleagues at work can

25:13 ping me at any time and I'll, I'll give them a patent for what they're trying to do. But that's,

25:17 I do have quite a set of, oh, you, you're trying to make stuff weirdly work in this way.

25:24 Here's, here's a nice way that you can enable that without having to resort to, you know, type checks and

25:29 everything. Yeah. Yeah. I've been using, I mean, I've been using Python for a long time and I do

25:34 remember one of the first things that I noticed is I couldn't do overloading. And at the time,

25:39 so this was, you know, many years ago, I was using a lot of overloading in my C and C++ code.

25:44 and, and I was like, oh, I can't do overloading. But one of the things I've noticed

25:49 is actually the, instead of keeping wishing that I had overloading in Python, I've noticed that I

25:55 don't really use it in C and C++ anymore. I've, it's gone the other way.

26:00 Yeah. I really, I'd rather be more explicit about the, and just have a function that two functions

26:06 that, that are some, maybe they're similarly named, but they have an appendix that's,

26:12 that's different so that if you have different data, you pass it. And I'm with you, Michael,

26:16 I'd rather have people go, well, which one do I need? I'll look it up. Then just, passing the

26:21 wrong data type and having me, so because, you know, sometimes if they've, if they haven't

26:26 converted the data, like the string string versus number is a scary one for me because I'm often

26:32 getting, getting my numbers from an API or something and they come in as a string. If you forgot to

26:38 convert it and you passed it to the wrong thing and you're really doing something completely different,

26:42 that's, that's not a good thing, but I got bit by that one just yesterday,

26:47 updating one of my, one of my CI builds to use Python 3.1, I mean, 3.10. but you know,

26:54 is it, is it a string or is it a number? Interesting. Yes. But yeah, certainly that conversion would be,

27:03 you know, would be worrying. The other one is, is it a string or is it a list of strings? And that's

27:07 the one that bites us in Python all the time. And I don't even know how you resolve an overloaded function

27:13 based on, is it a string or can I iterate it? Well, like in that case, actually, I would rather

27:19 just have that part be part of the function at the, at the top of it, if it can handle both to,

27:24 to check the type and, and iterate or not, but you know. Yeah. Well, all right, let me close this out

27:30 with two quick thoughts. first, I think this is interesting because it's one of the things that's

27:36 possible with modern Python. Like once we've added typing, now you could consider this as a thing,

27:41 whereas previously it really was highly impractical, I think as a way to do, do it. So I think that's

27:48 kind of cool. And then two, I think it might be an, an entryway for people who are not where Brian

27:53 and I'll put myself in there as well yet of going like, actually these things I thought I need,

27:58 I don't need those, right? There's a lot of stuff I thought I needed and I haven't used it for three

28:02 years. So maybe I actually don't need it, but that's not how you maybe first approach,

28:06 approach solving your first problem in Python that you're coming from C++ or whatever,

28:10 C#, whatever. This might be a gateway. So anyway, those are my two thoughts.

28:15 One more thought from Dean after Python 3.11, do we get Python 95?

28:19 I, there, there was, you know, there was a windows 3.12. So I think Python gets to do a 3.12 as well.

28:29 I think it was only available in China. Interesting. And I believe I like to follow

28:34 on with that Dean. Very funny. I believe that Windows 10 was named, you let me know if you

28:41 know different, Steve. Windows 10 was named Windows 10 because there used to be the check Windows 9 as

28:46 the starting string for 95 and 98. So you can't be nine because then you're going to be 95. So we got a

28:52 kick on past it. There was some embarrassingly big, language run times out there still doing that

29:00 check. that, that really struggled with Windows 9. and, and showed up in enough places that,

29:07 yeah, I think it just made sense for everyone to just skip it.

29:12 Not skipping 13. We're skipping nine. It's too unlucky. All right. Awesome. Brian, what you got for us?

29:18 Oh, what do I have next? I have, the next generation, Seaborn interface. So Seaborn is a really awesome,

29:27 plotting library built on matplotlib. and I, you know, actually I don't use it that much, but I've always been

29:34 intrigued by it and what kind of watching what plotting libraries do and stuff. And one of the things I was curious about,

29:41 which I'm really grateful for this article, is some of the history behind it. So the,

29:46 the article starts off a next generation Seaborn interface talks about the background and goals.

29:51 but, some of the, some of the great things in here, let me grab, grab some notes.

29:58 this work grew out of a long running effort to refactor Seaborn internals. so that, functions,

30:04 you know, anyway, where I wanted to get at was he was developing a refactor of the internals.

30:10 And he's like, wait, wait a second. If I want to refactor it, maybe I should expose more stuff.

30:14 And some of the background was originally Seaborn was originally conceived of as a toolbox to do,

30:21 of domain specific statistical graphics to be used alongside matplotlib. So the intent was people

30:28 would use both Seaborn and matplotlib together. However, things that people have doing, are doing

30:33 things differently. A lot of people just grab Seaborn by itself. Some people even just learn Seaborn before they

30:39 even learn matplotlib, which is an interesting thing. And that's how I thought you were supposed

30:44 to be doing this, but the concept was, and, and then at over time, there's a whole bunch of features

30:49 that have been added to Seaborn to where it's like really slick looking, but to do the same thing by

30:54 hand in matplotlib is a lot of work. So there's some things that like, if you, if you Seaborn's almost

31:01 there, but you need to tweak it a little bit and you have to do things manually. Well, then you have to

31:05 just do everything by yourself and it's a lot of work. So the idea around this, this, a rewrite

31:10 of the API is let's rework some of the internals so that a lot of the little sub components that go

31:17 inside of a plot are exposed. that way people can get access to it to do a more fine tune

31:24 configuration, within the, so they don't really have to just do everything by hand. It's either all

31:30 or nothing Seaborn or matplotlib, you can kind of do both more easily, which is a kind of a cool idea.

31:35 there's a whole bunch of great details in here that talk about some of the API changes,

31:39 basically exposing the internal. If you create a plot, there's nothing there and it won't show up.

31:45 You have to create layers on the plot. And then within the layers, you've got marks and,

31:50 and different components that go into it. I kind of like this idea of building things up,

31:55 what I really like is the public aspect of this. So you've got a, you've got a library that's out

32:00 in the open. it's being used by a lot of people already. And somebody saying, maybe we should tweak

32:06 the API and do something different and just go ahead and doing that in the open saying, Hey, we're going

32:11 to do this. There's a note at the top, or I'm thinking about doing this note at the top saying

32:15 it's a work in progress. Don't depend on these examples because things might change,

32:20 but this is the direction we're trying to go. trying to get feedback from people. And,

32:25 I think this is a lot of thing, things that a lot of people struggle with when they're maintaining

32:29 packages that have been around for a long time is, I want to do things a little different,

32:34 but am I going to break everybody? and talking through it. So anyway, this is a great read,

32:39 especially if you're a data plotting kind of person.

32:43 Yeah. Very nice. I always want to do more with visualization and I'm sure that I have some good

32:47 data I could pull up. Yeah. I ended up basically just writing APIs and websites these days,

32:52 but, but I really should be pulling this up and doing some of these graphs and I'm really happy

32:56 these are, these are around. Steve, how about you?

32:58 See, Seaborn's great. It's always, like back when I first discovered it, one of its major

33:04 selling points was simply importing Seaborn would magically make your default map plot.lib charts look

33:10 nicer. which, which map.lib is.

33:13 I love it. It's like the bootstrap of map plot.lib.

33:15 It really was. It's like they, they just apply their style by default and every map plot.lib chart

33:21 suddenly looked nicer, which, you know, map plot.lib's done their own styling work now. So it's

33:26 less valuable for that. I do like this API. It looks good. And, and as Dean's pointing out in

33:32 chat, it's like map plot.lib has an object oriented plotting API similar to this, possibly identical,

33:37 just like everyone else. I've never learned the object oriented API. but, but it is there.

33:43 And it's, it's, you know, it's, that's the modern one. It's like, I know a lot of people say map

33:48 plot.lib is impenetrable, and kind of hard to build things up, but it does have a really nice API

33:53 there. It's just not the pipe plot one that kind of imitates mat labs old API. and, and so,

34:01 you know, having it there is, is really nice. And Seaborn, you know, having their own is also great.

34:06 another, nice, thing that to read about in this is, he's does a hat tip to a

34:14 ggplot or ggplot two or whatever it's called. saying that, yes, it's going to look, a lot of

34:21 this is similar to ggplot, but, it isn't that I'm trying to copy it or maybe that's, that's definitely

34:28 influence, but, it is, that Seaborn is, is important because we think about things

34:35 differently in Python than we do in R and, and, and just having, it would be, but also a hat tip to

34:42 another library that is a, a wrapper around ggplot. If you just want that, you can do that in Python too.

34:48 That's available. So, I, it is interesting to, these are, we think of these as competing libraries,

34:54 but they're really not competing with each other. They're working together to push the, push

34:58 plotting forward. So, yeah. Nice. Dean out there points out you can do plot.style.useSeaborn or ggplot,

35:06 which is another one. Let me throw out. Oh yeah, go ahead, Steve.

35:10 ggplot's certainly the one to copy from. I mean, that's the, there's a reason that one is, you know,

35:15 as universally popular as, you know, any plotting library can possibly be. it's probably even,

35:22 you know, it's probably competing with Excel for popularity of plotting data. Realistically, it's,

35:27 it's, it's a really nice API and it looks good and everyone's familiar with it. And so, you know,

35:32 there's nothing wrong with copying from ggplot. Nice. I got one more shout out to throw,

35:37 into this conversation, the XKCD plotting style for, matplotlib. So you've got, I mean, this is

35:46 fantastic. It looks like the, it really does look like XKCD would, you know, the comic would do

35:54 for, for these. So, this is fantastic. I love it. What I love is I actually see this. I see this

35:59 in papers and stuff like that. People just go ahead and use the XKCD style and for serious stuff. And it

36:05 just is, it's awesome. I love it. I think there's actually some value to having like cartoony looking

36:10 graphics, like UI sketches and graphs to say like, look, this is speculative. This is just like,

36:15 don't read too much into it. I'm trying to give you an idea rather than an exact thing. And I think

36:20 sort of a UI like cartoony looking sketches. And this also plays into that. Yeah. Right. Steve,

36:26 you got the last one. I got the last one. Yeah. So this is another kind of recent, delivery from,

36:31 from the CPython core team. we can now compile CPython to WebAssembly. so, and to a lot of

36:39 people that probably means very little, but I guess the brief, brief summary is,

36:43 is WebAssembly is, kind of what the JavaScript in your browser compiles to before it runs.

36:50 So it's skipped that initial step of being JavaScript and it's now ready to run in the browser.

36:56 so it's, it's a lower level, there are tool chains out there that can compile all sorts of languages

37:01 directly to WebAssembly. and so in this case we've taken, I believe we use one of the,

37:08 I don't know the exact tool chain that's used and it may not matter, but it basically takes the C code

37:13 and compiles that to WebAssembly gives you a package that can be brought into an electron app

37:19 or a node JS app or a web browser, modern web browser and be run in the browser. there is,

37:25 so this page is a little bit dated. there's been a bit more work since then, but I found this is the

37:30 best overview of where things are kind of at long list of C extensions that don't work. Probably unsurprising,

37:35 like the browser doesn't have a lot of this stuff in it. Yeah. You don't have,

37:40 what no TK, all the different APIs, the win 32 API underneath or whatever it was delegating to you.

37:45 Yeah. Don't no Tkinter. What? No. Yeah. No, no Tkinter, no sub process, C types. Apparently

37:53 you can do, I've, I've heard there is a lib FFI port to, to the M script and kind of platform.

38:00 so how, how, how this kind of works is kind of when you take WebAssembly in, into a browser,

38:07 it has access to nothing. Like it starts off in a really enclosed kind of box of things that it can

38:12 do. and, and that doesn't actually work for Python at all because the very early thing that

38:17 tries to do is search the file system for what files it should be loading. so, so you, we actually

38:23 build it as part of another platform. And script is one platform that kind of poly fills a whole lot of

38:31 native looking APIs so that code that's compiled on top of them script and is able to use it. And that

38:37 this little demo, which I just hit start REPL, this is running on that. So this is a build of

38:43 Python 3 11 alpha four built with clang running on em script. And I can, I believe I can do this

38:51 and be like OS Lister. And, and it thinks there's a file system there. Now that's not my file system.

38:56 That's in memory. it can be changed to browser storage. but this is entirely in the

39:01 browser. Like there's nothing downloaded. There's nothing running on my machine here.

39:04 There's nothing running in the cloud. it's literally in the browser. I can probably freeze

39:08 my browser with this. Like I can do an infinite loop and do it, do it. Let's see if this cuts me off.

39:13 I'll just let that run. What happens if you hit clear?

39:18 Started again. We're going to start again. No, no, no, no. It's done. I'll just refresh. And yeah.

39:26 so yeah. And, and the, there's a second one that the actual builders, it was committed supports,

39:32 which is WASI W-A-S-I. that's a slightly different approach to adding all the functionality

39:38 around a WebAssembly module. it's, so it's a little bit more flexible, a little bit more controlled.

39:44 And scripted is really like, give me POSIX system inside my browser, all in memory. and so, and so

39:51 we have two options, and these are available in the, in the main branch. I don't, at the moment,

39:58 we're not shipping prebuilt modules for WebAssembly. That might be a possibility. if that's something

40:03 that you'd like to see, then I guess go to discuss.python.org and post about it. It's probably

40:08 a post there. I should have looked for a post there. but we're not currently doing prebuilt releases,

40:14 but, but I think we could, I think this is one of these options where the WebAssembly build is

40:20 totally portable. And so if we build it, we can distribute it. And then, you know, websites that

40:25 want to do something like this could just download it from our servers and, and run it. So I think

40:30 there's, there's a lot of potential here. what I'm, you know, and, and, and it's at the potential

40:36 stage, right? This is another stepping stone to bigger and better things. our kind of responsibility

40:42 as the core team is to enable it. And now we really want people to come in and pick this up and do

40:46 awesome things with it. Firstly, so we can figure out what gaps still need to be filled. but also just,

40:51 just to, just to expand, you know, the growth and the reach of Python, to bring it into places

40:55 that currently doesn't exist or can't work, and you know, give it new life and new places,

41:01 open it up to new people. This is fantastic. Congratulations. and so the work for this

41:07 primarily done by Katie Bell, Christian Himes, and Ethan Smith. So I think Christian got to do all the

41:14 merge commits, but it's definitely been number of people working on this for a while. those are the,

41:19 the primary three. I'm really excited for the possibility for this. I think one of the

41:25 things that could be amazing, obviously running it in the front end is a thing that could be done.

41:30 I saw the documentation said it was about 10 megs to download it. I'm sure you can put that on like a

41:36 CDN. So you kind of hit it once somewhere for a particular version of Python. That's pretty good.

41:41 You know, it's, we all have pretty fast things these days. Yeah. It's still bigger than doing it.

41:46 Yeah. What gets me really excited though, is, putting that into an Electron JS app.

41:52 Yeah, absolutely. Right. Because Electron JS is a really interesting way to bring web technologies

41:58 cross platform as much as I like, oh, I said an Electron app. Still it's, it's really opened up the

42:04 possibility for a lot of things, but it really has meant, okay, you're doing TypeScript, you're doing

42:08 JavaScript and you just have to go full on in that world. So here you could still do like your front

42:13 end and whatever, but having the core logic of that desktop app being in Python running in this,

42:19 that's exciting. If that's, that can be put together.

42:21 I should also add two things. Pyodide is a project that people have probably heard of before,

42:27 which has been working on this for considerably longer than the core team has. And so I think a

42:31 lot of the patches that needed to happen have come from them and they now get to spend more time focusing

42:37 on the data science stack, which, cause they've got ports of NumPy and pandas and other libraries,

42:43 to actually do data science in the browser. and the other interesting thing that I saw was

42:49 someone from, from CondorForge suggesting that they could elevate was wasn't builds to

42:54 their kind of automated level. And so all of CondorForge may suddenly become available to use

43:00 in the browser on top of a build of Python like this.

43:03 Wow. So that, that would unlock so much. That would be incredible.

43:07 Yeah. Interesting.

43:08 I imagine initially it would unlock a lot of bug reports, but, but we need to work through those first.

43:14 Yeah. I was just thinking of, you know, take the top 1000 most popular packages,

43:19 you know, could you get 90% of those compiled to like other WebAssembly things that then could be

43:24 included and then imported here somehow.

43:26 Exactly. And the top 1000 with native code, cause it's only the native code, right? The Python code

43:32 still compiles in the browser, just like it would in the CPython interpreter.

43:37 it's only the native code that has to be ported and built. And so once that's done, then,

43:42 you know, grow up and running. So the top 1000 is probably more than you need.

43:46 Yeah, absolutely. All right. Awesome. I'm looking forward to seeing where this goes.

43:50 So many neat options. There's, there's just cool ways to say, like ship the Python runtime

43:56 to places where maybe it would have been hard to get. Now you drop this WASM file plus something that

44:01 can run WASM. And then now you've got a deployable shipable. Yeah.

44:05 See Python runtime without Tkinter and a few things, but still you might not miss it.

44:09 It depends what you're doing. I mean, most apps are not Tkinter apps is all I'm saying.

44:14 I'm not trying to bang on it.

44:16 No, no, but I just haven't. Every time it comes up that it's still there. I'm like,

44:20 really? We still have that. Okay.

44:22 Don't ask me what I've been spending my week working on, Brian. It's not going to make you happy.

44:28 Are you, are you creating a Tkinter base killer for against textual?

44:33 No, no, unfortunately not.

44:37 Awesome. All right. Well, Brian, are we at extras?

44:43 We are at extras. Do you want to kick us off?

44:46 I will kick us off. So I've got a couple of things that I think are interesting. Let's

44:51 start with this one. So we've talked about, oh, oh, my Z shell, right? Yeah.

44:57 A lot. Love it. I just came across, realizing that actually this is a Portland company that puts

45:03 together the sort of core maintainers of, that. So I just thought it was funny to give a quick

45:09 shout out to, planet Argonne. They're not really in the Python space, but they're in Portland,

45:14 which I thought was kind of fun. and then what is this? This, next one comes to us, I think

45:20 via PyCoders. That's where I got this. Django just reformatted all of Django with black. And I know

45:28 I know I was just having a discussion with somebody like, oh, your code doesn't have,

45:31 doesn't follow PEP 8. Oh, like, oh, I don't want it to follow PEP 8. Yeah. But if people are

45:35 going to use your code, you know, like literally you got to import it, then it probably should follow,

45:39 like it should not come up with all sorts of warnings. And so I thought it was interesting that

45:43 Django just said everything, make it black. Steve, what do you think about that?

45:47 I'm totally on board with, with just using black on everything. I don't agree a hundred percent with

45:53 the style, but I agree a hundred percent with not arguing about it. So yeah, it's close enough.

46:00 Yeah. Plus, there's enough tweaks like that make it good. Like I really, I'm really grateful

46:06 that that has, you can tweak the line length for instance. Yes. Because I mean, here's example.

46:12 What if I want it really short? So, for no, for seriously, for formatting the code for the,

46:18 the pie test book, I wanted them all quite a bit shorter so that they fit better in a book format.

46:24 And I could use black to cover with that and convert everything with, with black to make them like that.

46:31 So it was great. Nice. Awesome. All right. And the final one is I have been doing some stuff with,

46:37 more fun things on YouTube, trying to put these little short videos together. So here's

46:41 a, how long are the six minutes, 44 second video on using time Delta to get like,

46:47 how many weeks are in some time span that, you know, the cool tricks you can do there.

46:51 So people should check that out. That's my latest Python short thing. And yeah, that's,

46:55 that's it for my extras. okay. So I've got a quick one. Just, I've got, I don't have a graph, something to throw up, but I just, I was looking at looking at the get history of,

47:06 of, a repo and trying to figure out whether I included one of my coworkers,

47:11 branches in it, if I merged it yet or not, things like that. And I was on the command line

47:16 and I just learned, I'm like, can I just do this with the command line? Apparently I didn't know this

47:21 exists. So apparently a get log --graph just shows you the get graph that your branch

47:28 history or the branch graph on the command line. And I didn't know it was there until today.

47:34 I started using it, tweeted about it. And then a whole bunch of people said,

47:38 Oh, you should use these flags too. That makes it even nicer. So, so it's fun to,

47:43 to learn something old as a new thing. And then somebody else told me, how about get K? So,

47:51 get K is a, is a graphical browser of your repository that just comes with most

47:58 get installs that I didn't know was there. I'm like, do I need to install it? I'll just type it and see what

48:03 happens. And it popped up this graphical interface. I'm like, this is great. This is exactly what I

48:08 wanted. So get K is pretty cool. I didn't know about that one. I I've seen the command. I've never

48:13 actually run it to see what happens. So I was not feeling quite brave enough.

48:18 Did it mean get kill or was it something else?

48:22 I was just most get commands scare me until I've run them the first hundred times or so.

48:29 How about you? Yeah, I got, I got a couple of extras. Okay. Can I get my screen back up there?

48:32 there's, I was feeling a little bad about, you know, being a bit self-serving here,

48:36 but then Michael just promoted his video series. So I don't feel too bad anymore.

48:40 Get it. Get it on, man.

48:41 This is the Python 3.11 alpha five download page. And we have a new addition this time around,

48:46 which is this windows installer for arm 64. So arm 64 is not a massive, massive platform for windows yet,

48:53 but it's growing and, we want to have Python support on it. So the builds have been running in

48:59 the background for a while, but we've never actually released it. We're hoping to get it out with 3.11.

49:03 That is going to depend largely on, do people use it? Do they love it? Do they hate it?

49:09 My experience so far with it has been that it is noticeably faster, on at least on the arm 64

49:16 devices I've had access to compared to the Intel devices, which is really, really cool. and

49:22 there's, there's like the test suite is, kind of 30 to 50% faster, which is huge, huge really. So,

49:30 so I think there's a lot of potential here. I may just have had awesome hardware. I'm not sure it was

49:34 a virtual machine, so it's kind of hard to tell. Yeah. but this is fantastic. This is new.

49:39 if you have an arm 64 device, like a surface pro X, or there's a couple out there from other

49:44 manufacturers, I'm running windows 11 arm on my MacBook pro and through parallels.

49:50 I then use please in download and install it and let, let me know how it goes. If you get it

49:56 through the windows store, which is currently still not public, you need to get the link from basically

50:01 from one of my tweets, to the windows store, you'll automatically get the arm 64 version on arm 64

50:06 as well. So this installer is the traditional one. otherwise you get it through the store.

50:12 The other thing, which I wasn't going to do, and then I spent a bit of time working on this,

50:16 a couple, couple of years back at the, at the core dev sprints, I forget who I was chatting

50:22 with. I was chatting with one of the other core devs about everyone typing from collections, import deck,

50:28 and misspelling it. And it's like, you tell, you know, so a deck D Q U E is double ended Q,

50:34 very useful data type for certain purposes, but people would type it deck, like deck as in D E C K.

50:39 Because it's phonetically what it sounds like.

50:41 Exactly. And so as, as a bit of a joke, I made a package that when you, when you installed it,

50:47 it would give you from collections, import deck. and obviously the thing that that collection

50:52 should be is a, a deck, a double ended Q of 52 cards representing the cards in a normal deck.

50:58 and over time for various reasons, it's just kind of grown. And, and I recently, you know,

51:03 added support for calculating poker hands to it. And so now you could build a game with this.

51:08 it does, it uses enums. It's got shuffling, dealing, jokers are optional. and you can

51:16 calculate a poker hand and yeah, my, my little compare them poker hand one greater than poker hand two.

51:22 I spent a lot of time. most of my work on this over the last week was writing the tests

51:27 that proved how incorrect that function was until I wrote the tests for it. but now at this point,

51:33 yeah, it's, yeah, you can look at the values it gives back. It's actually a tuple with an enumeration

51:38 saying what the hand is and then a selection of the card values in a way that makes the tuples

51:43 comparable. So you can actually look and see, you know, it's a pair of, of aces that will have the

51:49 number 14 there for the ace. And the next highest card was a 10. So if someone else has a pair of aces

51:55 and their next highest card was a nine, then you're still going to compare higher. So I'm pretty proud

51:59 of that function. Yeah, that's clever. But, but yeah, this is, and, and,

52:03 and it's code style black. Nice. Oh, very nice. So yeah, it's, it's one short file. and it does

52:10 still override deck in the collections module for you. So I love it. It doesn't over. So, so that deck

52:18 isn't there, right? It's like DQ is, is untouched, but if you try and import DCK from collections,

52:24 then you'll get it. Nice. Hey, one of the quick things to shout out, we're hiring contractors

52:30 to help develop features for pypi.org. It says at the top of pypi.org. That's, do you know anything

52:35 about this? I guess if people want to work on pypi.org, that's pretty neat. Yeah, no, they, they have

52:40 funding and, there, there is a post that describes the surveys. I believe this is the organizational

52:46 accounts project they're looking at. Yeah. Organization accounts. So, if, if like me,

52:54 you are kind of the, one of the primary Python people at your company, then you'll spend a lot

52:59 of time helping people publish packages to pypi. If that's the business you're in certainly is for,

53:04 for us, there's a lot of packages from Microsoft up on pypi. and the kind of corporate

53:10 account for that is, but it does exist. We have a user account with 483 projects. This is all manually

53:17 curated right now. cause pypi just doesn't have the functionality to kind of hand out permissions

53:23 to it safely. The teams and all that kind of stuff. Yeah. Yeah. So, so I believe the idea of this

53:30 is to add that functionality to pypi. So I would love it if someone comes along and does this. I believe

53:36 we've contributed some of the funding towards this. So, you know, yeah, it looks like it.

53:40 Okay. Oh, so Steve, I've got a 3.11 question for you. So, 3.11 is an alpha. So what does,

53:47 what does that mean really? does that mean I can like start using 3.11 or should I wait?

53:52 it, it means you can, it means we still may change stuff that will break you and we won't

53:58 apologize. Okay. But if my code runs, can I trust it or? Yeah. If, if you're, if all of your tests pass,

54:07 then you should be, you should be out of trust it fairly well, certainly existing code.

54:11 there will be new features available in the alpha that have not been as thoroughly tested yet or may

54:17 change again. But again, if you're running existing code, you won't be using those. So, so that won't

54:22 matter, but yeah, it's totally viable to use. You can specify 3.11 dev on GitHub actions. I believe it

54:28 compiles from source when you do that. Now, they don't have a build there. They should for beta.

54:34 beta is when we really want people to start doing stuff at this point. alpha is so that

54:40 people can test the new features kind of targeted testing on anything new that we've put in beta is

54:45 when we really want people to start, porting libraries, especially kind of the core libraries to

54:51 be able to work with it. and, and just test it because if existing code doesn't work on the beta,

54:57 we want to hear about that so we can fix it in the runtime and not force you to fix it in your code.

55:02 Okay. But if I'm like a package maintainer, I can start, if it's got GitHub actions for it,

55:06 I can start testing, having my CI test against 3.11 then two.

55:09 Absolutely. Okay. You will likely want to market as it's okay if it fails.

55:14 Okay. Yeah. Awesome. Okay. Thanks. should we do a joke?

55:19 Let's do a joke. Let's, let's do a joke. All right. So this one coming from the programming humor

55:25 one and it's a, like you talked about the visualization stuff, right? And this one,

55:30 it says there's a search that says how to get labels on MATLAB bar charts to be horizontal.

55:36 Well, look what the results came back from Google was says you're not alone. Help is available. If

55:42 you're experiencing difficult thoughts, please call one one six dash one two three, or if you,

55:47 this is an emergency called nine nine nine. And the underlying bit here is it isn't that drastic

55:54 Google, but thanks. And I believe it might also work on being, I'm not sure.

55:59 There's a few scrolling on. I think there's a being equivalent down here. Yeah. Not just Google

56:05 being thinks you're an emergency as well. yeah, that's awesome. Yeah. So it's not that,

56:13 that, that much of an emergency. I'll go to stack over for it.

56:16 Nice to know that the big search engines are looking out for our mental health.

56:20 That's right. People become very upset after failing to get those bar charts.

56:27 This is not the emergency, but it's coming next when you realize what the answer is.

56:30 It's something that I don't know.

56:32 Nice. All right.

56:34 Anyway, that's the joke I found for us guys.

56:35 Well, thanks everybody. Thanks, Steve for coming and thanks Michael again.

56:40 Yeah. Thanks for having me.

56:41 Thanks all. Bye. Bye.

56:42 Bye.

56:42 Bye, everyone.

56:43 Thanks for listening to Python bytes.

56:45 Follow the show on Twitter via at Python bytes.

56:48 That's Python bytes as in B Y T E S.

56:51 Get the full show notes over at Python bytes.fm.

56:54 If you have a news item we should cover, just visit Python bytes.fm and click submit in the nav bar.

56:59 We're always on the lookout for sharing something cool.

57:01 If you want to join us for the live recording, just visit the website and click live stream to

57:06 get notified of when our next episode goes live. That's usually happening at noon Pacific on Wednesdays

57:12 over at YouTube on behalf of myself and Brian Okken. This is Michael Kennedy.

57:16 Thank you for listening and sharing this podcast with your friends and colleagues.


Want to go deeper? Check our projects