Learn Python with Talk Python's 270 hours of courses

#214: Dive into CPython 3.8 and beyond Transcript

Recorded on Sunday, May 5, 2019.

00:00 Python 3 is coming soon. It's scheduled for release at the end of October 2019,

00:04 and you can already download test versions today.

00:06 Given that Python ships on an 18-month cycle, it's time to talk about what's coming for us Python developers in the fall.

00:12 On this episode, I meet up with Lucas Lenga and Anthony Shaw to chat about the highlights of this upcoming version of Python.

00:19 Also, a quick show note, we recorded this on location in Cleveland at PyCon 2019.

00:24 There may be a small amount of background noise, but I think you'll barely notice.

00:27 This is Talk Python to Me, episode 214, recorded May 5th, 2019.

00:32 Welcome to Talk Python to Me, a weekly podcast on Python, the language, the libraries, the ecosystem, and the personalities.

00:52 This is your host, Michael Kennedy. Follow me on Twitter where I'm @mkennedy.

00:56 Keep up with the show and listen to past episodes at talkpython.fm, and follow the show on Twitter via at Talk Python.

01:02 This episode is brought to you by Microsoft.

01:05 Be sure to check out what they're offering during their segments.

01:08 It really helps support the show.

01:09 Lucas, Anthony, welcome back to Talk Python, both of you guys.

01:13 Hello.

01:13 Hi, Michael. Good to be back.

01:15 Yeah, it's great to have you back.

01:16 We are not recording over Skype far distances, but in fact, we're right here at PyCon,

01:22 and who knows how the audio for this is going to come out, but hopefully it'll sound good enough.

01:26 But it's great to be here on site in Cleveland with both of you.

01:29 It's a unique experience to actually see you doing the recording.

01:32 Yeah, it's really good to be here in Cleveland.

01:34 The sun has finally come out today after the third day of PyCon.

01:38 The fog was pretty incredibly epic, and that was pretty special.

01:41 And yeah, Lucas, the latency on this video call is incredible, man.

01:45 It's so, it's lifelike.

01:46 Yeah, so this video call is like 3D.

01:48 It's amazing.

01:49 Yeah, it's amazing.

01:50 So thank you both for being here.

01:51 We're going to talk about Python 3.8 and maybe looking a little bit beyond that,

01:55 some of the peps that are out there and all the cool stuff there.

01:58 But, you know, let's just start with PyCon.

02:00 Like, how's your experience this year?

02:01 It felt a little different to me.

02:03 I'll say why in a minute, but you go first.

02:05 I'm Kosh Langa.

02:05 I've been co-chairing the Language Summit this year with Mariata, and this is an absolutely new experience for me.

02:12 So that was interesting, actually herding all the cats at the right time,

02:16 to the right spots, you know, pre-selecting talks, actually making sure that everybody has the opportunity to speak,

02:22 making sure that everybody is engaged.

02:24 That was new.

02:25 So I was very happy, like, you know, to have it over with, you know, after that day.

02:29 I've heard it went pretty well, so I was happy about this.

02:33 Like, the rest of PyCon was also rather intense so far for me.

02:37 I've had a talk about Black, and then, like, an extended Q&A that I just performed

02:42 during the poster session on Sunday morning.

02:44 That's really awesome.

02:45 You know, I feel like Black is one of these things that has just taken off.

02:48 Like, I often ask people, you know, what module do they recommend or package

02:52 or what is, like, special that they've seen, and it's way more than any other single answer is Black.

02:58 That's awesome.

02:59 Congratulations.

02:59 Yeah, thank you.

03:00 I'm very happy about it.

03:01 In fact, I think there was at least five talks that mentioned, you know, using Black as a good thing in them.

03:08 So it seems like, you know, we've solved an issue that people had.

03:12 We've solved a problem that people had.

03:13 Yeah, we've had these linters, and they tell us, well, you're doing wrong,

03:16 and we're just like, can't you just fix it?

03:19 Like, I don't want to be told what's wrong.

03:20 I just want it to be better.

03:21 Yeah, well, the difference between Black and other other formatters, of which we have a few in the Python community,

03:27 is that, well, Black was kind of brave, obnoxious enough to tell you, like,

03:32 that it's going to just be, you know, done in one way.

03:34 It's not really configurable.

03:35 But that kind of changes it to a workflow tool, where if you decide to use the tool,

03:40 like, now the question of auto-formatting sort of disappears.

03:43 The question of how to format your code is no longer a problem when you're developing your own projects.

03:49 Yeah, and if you're on a team, you don't have to have this debate anymore

03:53 of how we do stuff, right?

03:54 You just run Black, and that's how you do it.

03:55 Absolutely.

03:55 Awesome.

03:56 Okay, Anthony, how's your PyCon going?

03:57 Like, what do you notice this year that's special?

03:59 Yeah, this is the first PyCon I've actually given a talk.

04:03 So that was definitely a milestone for me.

04:04 Yeah, what was the talk?

04:05 It was on code complexity, and I talked about Y-Day, which is a project I've been working on,

04:10 and the principles of code complexity and why complexity is bad.

04:14 So how awesome cyclomatic complexity is?

04:16 I actually talk about how it's inevitable, the more users you have, to have more cyclomatic complexity.

04:20 People ask me how the talk went, and my response so far has been, I don't remember,

04:25 because I was so nervous that it was just a sort of adrenaline-fueled dream.

04:31 So that was, yeah, really cool.

04:32 And then yesterday, there was mentored sprints.

04:35 That's new, right?

04:36 Which is a new thing this year, and that's probably the highlight, actually,

04:40 for PyCon so far, is actually just being in there and mentoring people to contribute to different projects

04:47 and working with someone who ended up being able to send a pull request through to CPython

04:51 by the end of the day, and I think it was their first one, which is awesome.

04:55 Yeah, that's super cool.

04:56 That's got to help adoption and contributions, right?

05:00 Because even me personally, I think about, okay, well, I'd love to do something,

05:04 but I really don't even know how to get started, how to build it, what the right rules or expectations are.

05:11 Like, it's a lot of work.

05:12 And if somebody can sit down who's done that or is at least knowledgeable about that

05:15 and walks you through it, like the second time onward is much more likely to be smooth.

05:20 Yeah, and it was a proper amount of time allocated as well.

05:22 It was, I think it was just over four hours on the second day in the afternoon.

05:26 So it's good enough time to actually sit and work on a proper issue or a proper feature

05:32 and actually work through it from start to finish.

05:34 Yeah, you actually got a PR in place, not just started or whatever, right?

05:38 Yeah, exactly.

05:38 Yeah, that's awesome.

05:39 To me, it felt like when I walked into the expo hall that the booths were a little bit bigger,

05:45 there were a little bit more people.

05:46 It just seemed like a little bit, I don't know, there are a little more people,

05:50 a little more energy even than last year.

05:51 And last year was amazing.

05:52 I don't know, did you have this feeling?

05:53 Yeah, I was particularly impressed with the portrait of Guido at the Capital One booth,

05:59 which you've got to see online if you haven't seen a picture of it already.

06:02 Yeah, their booth was really artistic.

06:04 It was pretty cool.

06:05 Nice.

06:05 All right, so it's great to be here at PyCon, but let's talk about the future.

06:10 Let's start with the idea of when is Python 3.8 going to be out?

06:16 How precisely do we know that?

06:17 And Lucas, maybe just say a little bit about, like, you're mostly in control of this

06:22 at the moment, right?

06:23 Like the release schedule and management and whatnot, right?

06:25 Currently, I'm serving as the release manager of Python 3.8.

06:29 And I wrote the schedule for where things are going to go.

06:32 Traditionally, Python has been released every 18 months, which puts Python 3.8 at the end of this year.

06:39 You know, in particular, like, you know, give or take, it should be the end of October.

06:44 The reason why I'm not saying a particular date, even though it is in the pep,

06:47 is that those things tend to be a bit fluid.

06:50 Like, in the past three alphas that I released, like, we've been a day early or a day late

06:56 pretty much every time.

06:57 Yeah, would you be willing to, like, hold up a release if there's some important feature

07:01 that's two days away?

07:03 In fact, like, this time, there was a small issue, well, but small in size,

07:08 but big in significance, that I held up Alpha 4 that I had a bit of time for early in the week,

07:15 which kind of makes me late for my own schedule now.

07:18 And I have to release Alpha 4 tomorrow at the start of sprints.

07:22 But those things are more important to get right than to get on time.

07:26 And this is something.

07:28 Yeah, especially when it's 18 months.

07:29 If you were shipping monthly updates, like, whatever, just ship what you got, right?

07:32 But if it's 18 months, that couple days, that means a big, big deal, right?

07:37 This is exactly the point.

07:38 We try to make the consecutive releases, even on the Alpha level, consecutively better

07:44 and not introduce a breakage that is going to be later reverted since every release,

07:49 including alphas, is being tested by our users.

07:52 And we're happy to see, actually, Alpha releases being increasingly used

07:56 by the community to test their own libraries and applications like that used to be our problem,

08:02 that it was only after the beta releases.

08:04 And in fact, RCs very often were the first releases that users would see.

08:08 Nowadays, with like PyPI working better, where with CI options being out there,

08:15 you know, for pretty much everybody, we see more adoption of Alpha releases,

08:19 which is great.

08:20 But that is also a bigger responsibility on the Alpha releases because you are no longer free

08:24 to just make a breaking change and then later revert it.

08:27 Well, it's Alpha anyway.

08:28 Well, no, it isn't.

08:29 You see what it was?

08:30 It said Alpha.

08:30 Yes.

08:31 Come on.

08:31 Now we would need to have feature toggles that look at the Alpha version

08:35 to see whether a particular bug exists or not.

08:38 And we don't want that.

08:39 This might be a slightly political question, but have the releases of Python recently

08:45 become more stable?

08:46 Like, is it...

08:47 It feels to me that like people have almost zero trepidation or worry about

08:52 just adopting 3.7 when they had 3.6 or 3.6 when they had 3.5 these days?

08:58 And it seemed like there was more concern about what's going to break when I go to the next,

09:01 you know, semi-major version.

09:03 Has that changed or is that like perception?

09:05 For a number of years, the only version that people used was 2.7 and that was for a long time.

09:11 So it created this false perception that like Python is infallible, that every particular

09:17 update of it like never introduces issues that were not there before.

09:21 Because they were just minor fixes on a thing that wasn't changing, right?

09:24 That was good, you know, at the same time a blessing and a curse since every particular

09:30 version of Python, like including Python 2.4 to Python 2.5, Python 2.5 to Python 2.6,

09:36 did introduce internal changes that made large projects actually complex

09:43 to migrate.

09:44 The biggest example from the Python 2 world where it was when Python 2.5

09:49 was released.

09:50 Zope at the time created like such a problem for itself that it took them enough time

09:55 that they migrated to Python 2.6 directly.

09:59 So the previous version worked on Python 2.4 whereas the next one directly

10:04 on Python 2.6 they did not migrate in time for 2.5.

10:07 Right, it took so long to migrate.

10:08 They're like, let's just aim for the next one, huh?

10:09 So like this is all just like a long, long introduction to just, you know,

10:14 let you know that in Python 3 there are also changes.

10:17 Many of those changes are deliberate, right?

10:20 we are changing how the internal memory representation of objects looks like.

10:24 We are introducing and removing byte codes.

10:28 We can change how modules get initialized.

10:31 You know, there's multiple things that might break real applications but they're breaking

10:37 them in ways where it is impossible for us to guarantee eternal compatibility

10:42 with those things.

10:43 Sure, but this greater adoption of alpha versions and testing and CI probably doesn't hurt, right?

10:48 some kind of crashers, right?

10:50 Downright bugs and whatnot.

10:52 Like that I feel like we are doing a better job these days with.

10:56 Also just because Python 3 finally gets enough adoption that those versions

11:03 get vetted much better.

11:04 Right, absolutely.

11:05 When I started contributing we were just working on Python 3.2.

11:09 So for a number of years like almost none of the things I worked on were actually

11:13 very heavily used in the industry.

11:15 Like nowadays the situation is different, right?

11:18 So fortunately it's the time between a change and actually having real users

11:23 report on it is way shorter which makes the QLT just better.

11:27 Yeah, that's awesome.

11:27 Anthony, let me ask you what your perception of that's like and you work

11:31 for a pretty major company that probably has like stability in mind and stuff.

11:35 Like what's your perspective and what are you seeing at like Dimension Data

11:38 and places like that?

11:39 It's definitely become easier for people to install newer versions of Python

11:42 which is really helping.

11:43 So in terms of I guess moving towards things running as microservices on Docker

11:49 for example there's this it's not a single system running a specific version

11:54 that's got to support all these different applications.

11:56 Right, it's not cross your fingers or upgrading the server.

11:58 Yeah, we're not running on the mainframe anymore so I think that that's really helping

12:02 in terms of there's more automation for systems deployment and there's a lot more

12:07 tooling being used to automate like the building of new environments.

12:11 There's this kind of idea of immutable infrastructure now where you basically

12:16 create compute infrastructure in the cloud and you build it on a specific version.

12:20 You don't change it right, ever.

12:22 Yeah, so I think that has actually made it easier to move to newer versions

12:27 because you can just spin up new infrastructure with the new version test how it works

12:32 and you can inspect it properly whereas like 10 years ago you were talking about

12:36 we need to go and buy a million dollars of hardware to build an identical

12:40 environment to see if this new version is going to work for us.

12:43 Right, and maybe you have like downtime the whole weekend the team stays all night

12:47 and they do the testing and the rollout and you know these days when I go to websites

12:51 and I see we're down for maintenance or we have even like we have scheduled

12:55 maintenance over this like two to four hour window I'm just like what are they doing?

12:59 Like what possibly could take four hours to upgrade?

13:03 Like I understand maybe there's like a migration and you're down for a few moments

13:07 but four hours it doesn't take anyway it just seems pretty wild when you see it

13:11 but that used to be common right?

13:12 So I guess yeah so it doesn't matter as much Yeah, it still matters for some

13:16 really big applications I know some of the biggest software vendors still have four hour

13:20 maintenance windows every Saturday we definitely have to live through some

13:24 of that pain at the moment but more and more I think people are using this

13:27 sort of automated deployment and automated infrastructure which is making

13:31 it a lot easier to upgrade That's awesome What about the beta version or the alpha

13:36 version even of 3.8 you guys said late October for The main release for the main release

13:43 but we work that back like when will we see stuff that we can start playing with

13:46 can we already I know Anthony like get it and build from source a lot and play with it

13:51 and you guys do as well but you know when does the average person who just wants

13:55 to install a beta or something like that get access to it?

13:59 Any alpha release is released in both the form of sources that you can freely build

14:04 if you're cloning the repository from GitHub there's tags that tell you exactly when

14:10 a particular release was made but also for alphas, betas and later release candidates

14:16 and actual versions that we release we do have binaries right so for both

14:20 macOS and Windows we have plenty of binaries that you can use to test out

14:25 your software I would advise to do it like as early as possible like especially

14:29 3.8 was kind of like a shy release right because we had the whole governance thing

14:37 all the major changes were sort of put on hold right so now we are just four weeks

14:43 before the first beta which is the feature freeze for us right since beta 1

14:48 to the main 3.8.0 release we are just fixing bugs in some unlikely cases

14:54 maybe even reverting features that we identified are not ready for prime time

14:58 unlikely to happen like what is more likely to happen is like this is the time

15:01 where you know that breaking changes are no longer being you know new breaking

15:07 changes are no longer being accepted so it's a great time to actually you know

15:11 start using your CI to test your libraries your applications on Python 3.8

15:15 as well expect problems there's things that we have not identified even though

15:20 we have our other extensive regression suite of tests but it's great like to be

15:25 able to identify those things early so by the time the distributors come in

15:29 and package Python 3.8 its quality is good and you know we're transparent

15:33 we just can run your application with minimal churn that's pretty cool can you test it

15:38 with talks or like what's the best way to sort of test on 3.7 and 3.8 beta

15:43 or whatever there's many possible ways depending on what particular operating system

15:47 you're using for open source projects that are already using a CA system like

15:52 Travis there are ways to just utilize the latest development version of Python

15:57 and at the moment it's 3.8 so just by just saying that you would also like to run

16:03 your tests on the development version of Python you're gonna get beta version like

16:07 in a month that currently is gonna be a form of alpha so that is probably easiest

16:11 because you don't have to actually install anything locally on your computer

16:14 which tends to make things complex when you have many interpreter versions

16:19 with you homebrewing Patrick likes to default to one Python 3 version one

16:24 Python 2 version so there's PyEnv that you can use to have multiple installations

16:29 and obviously yes there's talks they actually work rather well together so you can

16:34 set up your matrix of tests that later are run online but you can also run

16:38 them locally which is what I'm doing yeah okay that seems pretty easy all right

16:42 Anthony let's kick off this PEP section and talking about the actual features

16:48 which as we all know appear as Python enhancement proposals and they go through

16:52 a life cycle and whatnot if people are wondering what peps are out there what

16:57 might make it into 3.8 and so on like where would they go to find that out

17:00 so I think on the python.org website and there's a list of peps there's also a

17:04 PEP index on the list of peps I've also made like a small web app called pep

17:09 explorer where you can go and search and filter and pull specific python

17:13 versions and get the status of the peps so I use PEP explorer because I spend time

17:19 looking at peps and reading about them and trying to understand what's coming in

17:22 future versions so yeah if you're just curious I'd say the PEP explorer is probably a

17:27 good way to go yeah the PEP explorer is pretty awesome it's just a nice little

17:30 grid it's on github pages right yeah yeah and I'll just link to that and of

17:35 course people can go to python.org but yeah it's really nice to just keep track

17:39 of that and I find that super helpful all right so let's kick it off maybe since

17:44 you're holding the mic we'll go with you first you know what's like one of the

17:48 notable things that's coming that you want to talk about what PEP or feature so I

17:52 thought I'd cover off the two ones that changed the language first so there's

17:57 assignment expressions colloquially known as the walrus operator walrus operator

18:03 yeah so this is PEP 572 yeah PEP 572 so in python if you want to assign a value

18:11 to a variable you use the equals symbol that doesn't return anything so if you just

18:16 do a equals one in the REPL then that won't return anything in the REPL an assignment

18:22 expression is basically a way of combining the assignment of a value to a variable

18:27 and returning the variable back again so the reason you would want to do that

18:31 is in some statements for example within list comprehensions within while

18:37 statements for example within if statements and the thing in the if statement

18:42 the comparison for example you can actually do assignments inside the comparison

18:46 and it just removes some additional code that you might have to do and also

18:51 there's a few other examples in list and dictionary comprehensions where you can

18:56 do some fairly smart things inside the comprehension yeah when I first saw this

18:59 I thought interesting I don't know it's really needed but it's I wasn't super against

19:04 or anything but certainly seeing it in the list comprehension space and seeing it

19:09 used in other places as well I think I'm pretty positive on this language

19:12 change it's pretty nice certainly anytime you need an expression right within

19:17 like some kind of comprehension maybe a lambda or something like that like

19:22 this often is the only way to you know do it like so if you want to create

19:28 a variable but also test it in a list comprehension and that might be the response

19:32 of a function like you can maybe have to call that twice once when you test

19:36 it and once when you put it into the list now you could assign it and then

19:40 test it right like so these things get simpler yeah they get simpler I think

19:43 looking at the syntax people's initial responses often I can't see where I

19:47 would use that but it it takes a while for these types of pieces syntax to

19:52 become common because once you know the patterns in which you would use it

19:55 and you've memorized then and then you start to use it more and more over

19:58 time this portion of talk Python to me is brought to you by Microsoft and Azure

20:05 Pipelines Azure Pipelines is a CI CD service that supports Windows Linux

20:09 and Mac it lets you run automatic builds and tests of your Python code on each

20:13 commit or pull request it is fully integrated with GitHub and it lets you

20:17 define your continuous integration and delivery pipelines with a simple YAML

20:20 file Azure Pipelines is free for individuals and small teams if you're maintaining

20:24 an open source project you'll even get unlimited build minutes and 10 concurrent

20:28 pipelines many Python projects are already using Azure Pipelines so get started for

20:33 free at talkpython.fm/Microsoft and then the second PEP I guess changes

20:40 the language slightly is positional only arguments and basically this is

20:45 PEP 570 which has also been accepted and merged into Python 3.8 it wasn't

20:52 part of alpha 3 so it'll be in the alpha 4 release I believe and basically

20:56 this one is you add a forward slash in the list of parameters in a function

21:02 definition so that it says that it's only positional arguments in this function

21:07 the reason for that is basically to protect an API to ensure that people

21:13 only use positional arguments and they don't start to use them as keyword

21:18 arguments yeah it's pretty interesting it's like the anti keyword only argument

21:23 one right which so with the keyword argument one I don't know that many people

21:28 actually know about it but it's pretty cool so if you say you know function

21:32 star comma argument argument argument those all have to be explicitly called

21:38 as keyword arguments this is like I want to make it impossible at least in this

21:43 section of the parameters to call them as keyword arguments right yeah it's

21:48 a cool feature and it's also going to help with a lot of the standard library

21:51 that's the other justification and there's a lot of the Python standard library

21:55 where the API needs to be protected so that it can be iterated on and where

21:59 this feature is basically going to help lock that down and also in 3.7 there were

22:04 some improvements to the performance of method calls that performance improvement

22:08 doesn't work with keyword arguments I see so basically you could potentially use

22:12 this as a way of enforcing that performance improvement okay that's interesting

22:16 the example that I saw I think if I remember this correctly was just like

22:20 range like even just knowing when you see stuff if you quickly read it like you could

22:25 have range and say stop and then start and then step or you could have start

22:30 and then stop or you could have step and then start and just just seeing

22:33 I mean even the words are kind of similar and it's going no I want you to always

22:37 to say start and then stop and then step or whatever right like just requiring

22:42 them to not have this sort of almost arbitrariness of the order of the parameters

22:46 seemed like an interesting idea there as well yeah an additional detail is

22:50 the fact that you know many of the functions that are implemented in C don't

22:54 implement keyword arguments so they're effectively positional only by the

22:59 sheer fact that they are just being implemented in C and this just enables

23:04 us to express those same APIs in Python faithfully so that alternative implementations

23:09 recreate the API in exactly the same way oh yeah that's interesting so you don't

23:14 want like the leaky abstraction of the C implementation to leak out and maybe

23:18 break PyPy or something like this yeah so currently like the issue is actually

23:23 the opposite where PyPy does not necessarily care that you know some argument

23:28 is positional only in CPython so they allow for keyword use of it and then

23:34 that piece of code is problematic going back to CPython so that is just

23:38 you know caring of you know making your library code your application code

23:43 sort of exchangeable between runtimes yeah interesting what about Cython

23:47 Cython it's its own kind of thing because it's a language that is being compiled

23:52 or rather transpiled to a bunch of C or C++ which is then compiled

23:57 to a C module they are kind of free to do a lot of modifications that Python

24:03 itself is not free to do because they're compile time modifications right

24:06 their transpiler can make the adjustment it needs anyway right yes the source

24:10 code that you're reading is not the source code that is being executed interesting

24:15 all right what's the next PEP that you want or feature you want to talk about

24:18 let's cover a few of them and in fact like the slew of peps is all related

24:22 to typing let me start with something old which is PEP 544 protocols so that

24:28 PEP should have been accepted a long time ago but it did not because of the

24:33 governance situation so protocol is this kind of like interface inheritance

24:39 type of thing like what's going on protocols essentially is a way to introduce

24:44 duck typing to static typing to type checkers so you can have interfaces

24:50 well or like protocols they are called protocols across the python documentation

24:54 too which is why we're using that name in the PEP too but you can have essentially

24:57 implicit interfaces that are being implemented by a class by a type and then

25:02 the type checker is able to act on them when you express a need for a given

25:07 one as an argument to a function for example if your function accepts anything

25:12 that has a read method now you can express that type before that's really

25:17 cool i'm super excited about this because if you take two things like maybe

25:21 a set and a dictionary but you want to express i'm going to have those types

25:25 and i work with them but really all i care about is i can iterate it or that's

25:28 probably not the perfect example but you know like it's hard to kind of make

25:31 make the type system express that now and this just says well if it has an

25:35 add and pop method we're good like whatever right that's is that protocols

25:39 yes so protocols is the answer like to a question that we've received a lot

25:43 early on when PEP 484 came out like the original you know formation of static

25:49 typing for Python that isn't static typing in direct opposition to what we

25:55 have been telling everybody to do for all those years which is duck typing

25:59 if it quacks like a duck and looks like a duck it is a duck we don't care

26:03 if this instance is working we just care that the calls find the right methods

26:10 with the right arguments and everything is fine so now with protocols you can

26:14 actually structurally express this all you care about is a given field or

26:19 a given method I like it I know you're a proponent of type hints and my pie

26:25 and all that kind of stuff how do you see the state of that these days well

26:28 we're definitely on the rise there at my time at Instagram and at Facebook

26:34 we've seen a lot of improvements both in terms of security team velocity

26:40 and as well just being able to comprehend the source code when types were

26:45 introduced to the biggest PHP component of Facebook.com and so since I guess

26:52 2013 I wanted to see something similar in Python so like pep484 came out

26:58 you know soon enough Python 3 started getting adopted more and more and you know

27:02 this is when annotations which are the nice way to express types have been

27:07 gaining adoption and these days like from what I've heard at the conference

27:12 now 90% of functions in the Instagram code base which is north of 2 million

27:19 lines of code at the moment is covered in types which is amazing right that is

27:24 a big achievement so definitely this trend is on the rise which I am very happy

27:29 about yeah that's awesome Anthony what are your thoughts on type hints annotations

27:34 and do you like them have they changed your code do you use them I actually

27:37 use them very rarely in 3.7 there's the the type annotations the delayed

27:43 evaluation type annotations yeah it's gotten a little nicer in that way in

27:47 3.7 which makes it a bit easier in terms of what you have to import and when

27:51 but the only reason I use them seldomly is because I mainly work on libraries

27:56 which I publish to PyPI and which are used by people who have Python 3.5

28:01 3.6 and some 2.7 as well so I really have to cover the lowest common denominator

28:07 when it comes to users because they're mainly utility libraries that I work

28:11 on not single deployment applications yeah or something like black that doesn't

28:17 really get consumed directly but is more executed right like black or py

28:22 test or something what's the next one all right so the next PEP would be

28:26 PEP 585 that I actually wrote well it's still in draft form so to kind of

28:33 set the stage for the PEP what Anthony said is like there's plenty of cases

28:37 where currently typing that was added rather carefully to the language requires

28:43 you to import names that you're later using as types there's some situations

28:48 where you are introducing names to your global scope just for type aliasing

28:53 or to introduce type variables right for example if you've got a function

28:58 and you want to say its return type is this object you now have to import

29:01 at the top if you had never actually had that part called maybe it would

29:05 have never been imported until lazily or there's changes in behavior because

29:09 of that right yeah this is often problematic right like what is even more

29:13 like just cumbersome for the user is that there's plenty of either built-in

29:18 types or abstract based classes that have their equivalents in the typing

29:23 module meaning if you want to express that some argument is a list of string

29:27 you have to import an uppercase list from the typing module and say uppercase

29:31 list of string and I always found that clumsy right I always found that it

29:37 is something new that you have to explain to new programmers that are first

29:41 interacting with typing and there's not really a great reason for that it

29:45 was just you know we wanted the actual lowercase list to be orthogonal and

29:50 not know anything about the starting typing concept which is mostly used

29:54 by an external type checker it does not have a big runtime component does

29:59 have a little right because you can inherit from generic types so you can

30:03 actually create your own data structure where you say that this is a collection

30:08 of types T so this is a possibility but for very many cases this runtime

30:14 component is just a hindrance something that you have to remember to import

30:18 the names look different because they're uppercase and lowercase they might

30:22 look exactly the same in form of set but they actually mean something else

30:26 now because the point being like so that's the first issue and the second

30:31 issue is that this is something that sits in memory right this is something

30:35 that you spend time on when you're starting up your program so I always felt

30:39 like this is something that we can maybe live without hence PEP 563 which

30:45 actually postpones evaluation of annotations that was introduced in python

30:49 37 and stemming from that you know having that foot in the door that like

30:54 now the annotations are not evaluated anymore we can regain some of the usability

31:00 that people expect just by the fact that this can be still valid python syntax

31:05 but it doesn't have to be valid at runtime so we can get away without importing

31:09 things from typing you know the type checker will know exactly what you mean

31:13 anyway right we can go come back to using a lowercase list of string instead

31:18 of uppercase list of string and a few other things you still do the bracket

31:23 of string yeah on the lowercase list type yeah so like we will never do like

31:27 you know pointy brackets for that like in Java or C++ because our LL1 parser

31:33 is like unable to deal with that case like maybe if we switch to a different

31:38 one of which there is discussion like you know maybe then that would be possible

31:42 but at that point it will still be way too late and yeah I think it's fine

31:46 the way it works it's different but it's a way of expression there's nothing

31:51 that makes the angle brackets in templates or generics necessarily the right

31:56 way yeah yes exactly it's like as long as humans understand what those things

32:00 mean the goal has been achieved so yeah the rest of the PEP 585 is just an

32:07 attempt to reform some of the pre-existing constructs in the typing module

32:13 like creating new types casting aliasing or type variables into variable

32:19 annotations so that they are also not evaluated at import time which enables

32:24 again usage of types that are not imported and some of those tricks with

32:29 syntax like lowercase list and dict and whatnot so that's while we're on this

32:35 performance and type annotations and stuff what's the story of mypyc oh this is actually

32:41 a very interesting story so like mypy has traditionally been slow like to the

32:46 point where running it over the entire Instagram code base like was taking

32:51 over five minutes right so this was a thing that you could do in continuous

32:55 integration but you could not absolutely like run it in an editor or whatnot

32:59 you know we had some hacky workarounds to at least make people in the editors

33:04 happy I wrote like a silly flake 8 mypy plugin at some point that kind of

33:08 brought us somewhere you know it was useful for a while but all of that was just

33:12 not very great so in the meantime mypy started implementing incremental typing

33:17 meaning the graph of your modules which did not change can be cached so that

33:23 with every change like most of your computation is already pre-done and that is

33:28 evolving to this point now I can with well populated cache that cuts the

33:32 time to around 40 50 seconds so it's like yeah it's like a six seven times improvement

33:37 yeah it's a big improvement so that's so that's good but still the cold type checking

33:42 was like rather slowish the meantime Facebook started developing its own

33:45 type checker for Python well more with the goal of creating static analysis

33:50 tooling that just uses types so the type checker part was only the base of the

33:57 you know static analysis that was being performed on that very code with the

34:02 important use case of doing security checks and one of the goals of that

34:08 you know new type checker was like we have to be faster than mypy right yeah

34:12 like so that created competition and competition is always good so in the

34:16 meantime like yukal like to style or like revived his original idea that

34:20 hey if we have types we can actually try to compile the Python code in a way

34:26 that runs it way faster now what is it compiled to so that's interesting

34:30 right so the mypyc compiler actually creates C extension like it actually transpiles

34:37 to C this sounds weird until you think about the C API that Python provides

34:43 and the Python C API is meant to be consumed by C so it is just natural that you

34:48 would have a generator that emits valid C for your given use case and it

34:52 turns out that with just a few constraints on how your program works you can achieve

34:58 20 to 30 times performance boosts with that so that's great and in a real

35:04 production application like mypy it's consistently four times faster this portion

35:11 of talk Python is sponsored by Microsoft and Visual Studio Code Visual Studio Code

35:16 is a free open source and lightweight code editor that runs on Mac Linux

35:20 and Windows with rich Python support download Visual Studio Code and install

35:24 the Python extension to get coding with support for tools you love like Jupyter

35:28 black formatting pilot py test and more and just announced this month you can

35:32 now work with remote Python code bases using the new Visual Studio Code remote extensions

35:37 use the full power of Visual Studio Code when coding in containers in Windows

35:42 subsystem for Linux and over SSH connections yep that's right auto completions

35:47 debugging the terminal source control your favorite extensions everything works

35:51 just right in the remote environment get started with Visual Studio Code

35:54 now at talkpython.fm/Microsoft do you see use cases for that outside

36:01 just mypy like random person doing data science that needs their Python parts

36:07 to go faster or currently mypyc tries to limit their scope since they perceive

36:13 the attempts by previous projects that meant to speed up Python those attempts

36:19 failed mostly on trying to be 100% compatible with every single feature of

36:24 Python so they're focusing on a subset but they're growing that subset like as

36:30 you know as much as they needed and the big missing piece currently is like

36:33 there is no async await support and with that support I could actually have

36:38 Black compiled which could also you know significantly speed up the formatter

36:44 which is already pretty performance already does pretty well but that would

36:48 just make it so much better for the users so in fact I think I managed to get

36:53 Soli the core developer of mypyC rather excited about the prospect of having

37:00 Black as the next production customer of mypyC so we'll see I have my fingers

37:05 crossed yeah that's exciting all right Anthony what's the next one on our list

37:09 of cool features in 3.8 so this one is still in draft it hasn't actually

37:13 been decided and potentially might be deferred to a later release if it gets

37:17 accepted but when I've talked about features at least proposed PEPs this one

37:22 gets quite a bit of attention and they're called runtime audit hooks and

37:26 basically the PEP is a way of setting a callable when certain system methods

37:33 within the Python standard library get called for example opening a network

37:37 socket or requesting a URL or opening a file or lots of different cases I guess

37:43 of low level standard library functions or you get notified that's super

37:50 cool so like if for some reason I'm in a lockdown environment I want to use

37:56 some package or write some app and it's we think it's not talking to the

38:01 network or the file system but it turns out all of a sudden it's opening

38:04 sockets or DNS stuff that might be something to inspect yeah so potentially

38:09 you could lock down a Python distribution or a Python process to not be able

38:16 to open certain URLs or open network sockets under certain circumstances

38:19 and it's cool so with the hooks do I get to say I saw what you did and okay

38:24 or I saw what you did and no you don't get it is it like a place to stop

38:28 it yeah the default is just as an FYI yeah but if you wanted to throw run

38:33 raise a runtime error or something else in line then it would actually stop

38:38 the request through to the function that's pretty awesome I think this is

38:41 pretty interesting I know there's some restricted environments and even like

38:45 app stores and stuff that maybe would be cool to package this up and use

38:48 it so yeah definitely nice Lucas what do you think about this one well I

38:52 actually think this is very important like if you ever worked for a organization

38:56 very often the audit trail of what actually happened is important not just

39:02 for security reasons very often cascading errors that end up with an entire

39:06 site being down are very hard to foresee the very easy to make mistakes are

39:13 long fixed they're all patched there's not a big red switch that if you press

39:18 the button the site goes down it's very often something that it was hard

39:23 to combine and having the trail of this happened first and another thing

39:29 happened later that is very valuable so I see this feature not only as a

39:33 security feature but as a post-mortem kind of feature as well Anthony do you

39:40 envision this might enable a different set of tooling we have visual debuggers

39:46 now could you have other types of analysis and tooling and whatnot in terms

39:52 of tooling there's a lot of things in standard library that you might want

39:55 to add hooks in and also an easy way of putting hooks into additional modules

40:00 as well and having people to catch those and deal with those separately I

40:05 can definitely think of a few examples of libraries deserialization libraries

40:09 not naming any specifically that have that have security backdoors just in

40:18 terms of the way they work so unless you explicitly specify to load it with

40:23 a safe mode then you can actually run that was a different rhyme maybe yeah

40:27 there's XML as well is another one yeah there are sort of known I guess security

40:32 backdoors in certain libraries and basically this could be a way of protecting

40:36 against those okay yeah that's great because it should not be doing these

40:40 operations while loading this file yeah if you're if you're loading a YAML

40:44 file or an XML file it shouldn't be opening network sockets yeah probably

40:49 not or issuing sub process commands or you know any of these not so lovely

40:54 things that's right all right Lucas what's next on our list I would like

40:58 to say that you know there's quite a few peps that are still in draft form

41:01 and the authors have like an entire four more weeks in which they can decide

41:05 to finish their PEP and publish it so things might change but the ones that

41:09 I'm personally interested in is always of course typing so let me just cover

41:13 two more like the first one is PEP 586 so that's literal types and second

41:19 one is 589 which is typed dict both of them are kind of an example of you

41:24 know our type system kind of starting uh conservatively and then growing

41:29 based on need right so literal types are very interesting because there are

41:33 a bunch of calls where the behavior like the return type or you know the

41:39 cascading other arguments that you're going to use in the function depend

41:42 not on the type of an argument but on the actual value that you are passing

41:49 positive integer negative integer well like so parametric types are kind

41:53 of hard but what we are doing with literal types is something like the open

41:57 built in you have a certain number of modes right and depending on whether

42:02 you're saying RB or R the resulting IO is either bytes or strings and currently

42:08 there is certain hackery both in mypy and Pyre to just work around this but

42:14 it would be good if the actual type system supported this feature so literal

42:18 is all about being able to express those types so that if you pass none here

42:25 it's going to behave differently if you pass on string here it's going to

42:29 behave differently if that string is RB or is WB or is R and so on and so

42:36 on so that's literal types there's some very interesting edge cases and deep

42:42 thought in that PEP it is surprisingly long and complex I'm not going to go

42:47 into this now the another one is the type dict originally dictionaries have been

42:52 envisioned in the static typing as there's this key value store so there's

42:59 keys of a certain type and there's values of a certain type what happens

43:04 in practice is that a lot of pre-existing Python applications do not use

43:08 name tuples do not use errors or data classes which are very new instead

43:14 they use kind of lightweight classes in the form of dictionaries that have

43:19 keys and values of various types so there can be name which is a string but

43:26 there can be a birth year which is going to be an int right and based on

43:31 the actual name of that key you're going to have different types so that

43:36 was very cumbersome to express in the previous form almost like a schema

43:41 yeah yes it's very much like schemas so now there is a way to describe a

43:47 type dictionary in the form of like a data class like type where you just

43:53 express it like class like saying this dictionary is going to have keys that

43:57 are like this and this key is going to be a string this other key is going to

44:02 be an int that solves already a lot but then the interesting part is when

44:07 those things start nesting that actually enables you to construct rather

44:12 complex schemas that can be used directly in JSON or in other forms of serialization

44:18 so that PEP alone is also very useful in practice even though you could just

44:22 say people are doing it wrong they should be using name tuples or other forms

44:26 of typing instead well you have to be pragmatic you see pre-existing valid

44:32 use cases of this you have to adhere to those yeah interesting I guess since

44:37 you're really into typing and you're on the core dev side of things what

44:42 do you think about libraries especially I'm thinking of web frameworks that

44:47 use typing for serialization and stuff so like Molten for example you can

44:53 have a class that has fields but also those fields have types and then you

44:59 say this web function takes this class but it's really a form submission

45:04 and it'll convert stuff to integers or validate against the types is that

45:09 in your mind awesome or is that an abuse of the type system so this is interesting

45:14 right because obviously as long as the type system is kind of an extension

45:18 of the type system we're using for type checking or maybe it's even exactly

45:22 the same like that is using a shared vocabulary that's great we support that

45:27 we would wish to see type hints in more places in fact in 3.7 I extended

45:34 single dispatch so that now you can just use annotations on arguments instead

45:39 of saying register off and using the annotations of the first argument it'll

45:46 behave as you expect so you can use type annotations at runtime for whatever

45:52 you want as long as the type system is the same with what we're using it

45:57 for some use cases use annotations function annotations in incompatible ways

46:03 and that creates issues because an increasing amount of tooling like Visual

46:07 Studio Code PyCharm and whatnot gets confused by seeing something that is

46:12 clearly not a type in the place where types are expected so I kind of yeah

46:17 yeah an example of that like so this example I gave you with Molten seems

46:21 like it's consistent the type checker says it takes an int it's actually

46:24 an int at runtime it is but I can't remember but some of the other frameworks

46:29 maybe rest frameworks they would say like you could say that this parameter

46:33 is a header and what it actually is the string value with that name out of

46:38 the header right it's like the value comes from the header but like at runtime

46:41 it's not a header it's not a dictionary whatever the header is it's actually

46:45 a string or an int or something it seemed like it was really cool and clever

46:49 but also incongruent with what Python intended a certain amount of those

46:54 things like our valid use cases like let's say in the case of adders adders

46:59 create valid classes for you from minimal information that you provide in

47:04 source code so this class is being fully functional at runtime however the

47:10 type checker does not know this it just sees like just some magic decorator

47:14 and just this minimal set of attributes on it and it does not know that a

47:19 certain amount of built in methods have been created and a certain amount

47:24 of functionality within it has been added so at least in the case of mypy

47:30 Empire additional functionality had to be implemented in those type checkers

47:35 to understand that those types actually behave a bit differently from regular

47:39 classes but that's just something that users want something that users need

47:44 so we're going to be extending that cool cool Anthony what do you got next

47:49 on our list here so ship it we're good yeah I think we're done now that actually

47:55 that PEP in particular the type dictionary PEP I've been thinking if anyone

47:59 seen the json schema project it's really cool it's basically a way of defining

48:04 a schema for json documents you can definitely see that if this PEP gets

48:09 accepted somebody will build tooling to integrate between the json schemas

48:13 and this new type dict type yeah I think it makes perfect sense I mean dictionaries

48:18 are so similar to json in a and they both have this sort of dynamic but mixed

48:24 types and I mean they're very sort of mappable yeah yeah so I think it's

48:27 just a matter of time until someone builds a library where you give it a

48:30 json schema and it will generate a type dict class and then you use that

48:34 class similar in the same way that you in an ORM when you would describe

48:39 a data class and then you would deploy it as a database it's basically like

48:44 a similar way of reflecting documents that's cool I can definitely see for

48:47 serialization like you say this function takes a type dict but what actually

48:52 this is a form post or JSON post or you know like a rest call or something

48:56 like that that's cool so let's see did we talk about multiprocessing is that

49:01 coming in 3.8 or is that beyond that's in 3.8 so one particular thing that

49:05 is not PEP worthy but it's still a very interesting new feature is that traditionally

49:09 multiprocessing which has been created to solve the GIL problem has solved

49:15 it you know partially what I mean by this is that yes there is a master process

49:19 that creates a bunch of children and then delegates work to it so you can

49:24 just call python functions and those python functions actually are executed

49:28 on the other side in the child process but the way this is achieved was that

49:33 function call has been pickling the arguments of the function you're calling

49:37 that ended up being on the child side that child unpickled the arguments

49:44 it did the computation it needed and then if there was a return value it

49:47 wanted it actually had to pickle that return value again and pass back to

49:51 the master process unpickled the return value again and if that's big it's

49:56 very slow for example for small things that was mostly fine but if you had

50:01 a gigantic haystack and you were looking for a needle in it just a pickling

50:07 that haystack was taking a lot of time we were going to run that on all six

50:12 cores so here's six copies of our 10 megabyte whatever that is actually annoying

50:18 because if you had a master process that gets web requests in the time that

50:25 you are spending on pickling that haystack nothing else can be actually done

50:30 in Python because the GIL is still there on that master process so you are

50:36 solving the GIL problem only partially so now multiprocessing introduces

50:40 this new fantastic feature where you can declare a shared memory between

50:46 parents and children what that does is you can actually get away with a lot

50:54 of serialization and deserialization so for certain kinds of tasks like search

51:00 like filtering this will decrease the churn just needed to pass data around

51:05 meaning it will bring us way closer to the world we want to see which is

51:10 that yes there are certain Python processes you know they still have the

51:14 guild but it does not matter because we can use as many of those processes

51:18 as we have cores and everything is fine yeah and you don't have the replication

51:21 of memory and the copying and all that that's awesome yes so I'm really excited

51:24 when I saw that come out I'm like oh this is going to be great so that's in

51:27 3.8 yes that is already in cool and what about what about the sub interpreter

51:31 5.5.4 that's beyond oh so that's interesting that is kind of related yeah

51:37 they're they're in the same category yes however the multiprocessing feature

51:41 like does have limitations right like the the shared memory segment is not

51:44 right for any arbitrary Python object there's like you know restrictions

51:49 on what types you can use that was actually a complex functionality to be

51:53 added you know within particular operating systems shared memory handling

51:56 is way different so you have to understand how those differences work and

52:00 which process is now responsible for creating that shared memory segment

52:05 and shutting it down and freeing that memory when everything is shutting

52:08 down so that is all great work by Davin Potts like multiprocessing is one

52:14 thing but sub interpreters is what if you had this multiprocessing API and

52:19 actually just had one process and just used many Python interpreters within

52:22 it each with its own GIL to achieve that many changes in the Python API

52:28 have to be added like a much clean up internally in terms of what constitutes

52:33 local and what constitutes global state have to be done Eric is working hard

52:38 on that as far as I can tell this is deferred to Python 3.9 I'm eagerly awaiting

52:43 that I think this is going to be a great improvement yeah it could definitely

52:46 change the threading story in multipress processing strong in Python async

52:52 in a way is super cool for IO bound stuff but threads have always been a

52:56 kind of well sometimes they're helpful sometimes they're not depends and

53:00 this could be awesome right you could just dedicate a sub interpreter to

53:05 each thread right and really get free of that I agree cool all right well

53:09 thank you both for sharing what's coming pretty excited about 3.8 cool that was

53:15 a pleasure yeah it's going to be great yeah and on that topic as well I guess

53:19 we've got 3.9 so some of the PEPs are being deferred to 3.9 and on the topic

53:24 of sub interpreters the unpacking of the startup sequence and also the initialization

53:29 configuration there's two proposals for that one is PEP 4.3.2 and the there's

53:34 PEP 587 which are interrelated because if you have sub interpreters you want

53:39 the interpreter startup time to be fast and also the configuration to be flexible

53:43 so I think 3.9 will definitely see some more proposals related to that which are

53:50 going to hopefully improve the startup time of Python 3 as we know it's a little

53:55 behind where Python 2 was for various reasons but that'll be a great step forward

53:59 yeah that'd be really awesome and then it also might make this sub interpreter

54:03 stuff even better if those little sub interpreters can get created faster as

54:06 well I don't know how related they are but pretty cool pretty cool all right

54:09 one we used up almost all our time so I won't keep you guys much longer but

54:13 especially Lucas let me ask you this like will there be a Python 4 and does

54:19 it matter I mean on one hand like we've got stuff that's 0.1 2 versions that have been

54:24 around for 10 years with 100 releases we've got Python 3 if we don't have like major

54:30 breaking changes is there a reason to start calling it 4 and 5 and 6 or is that just

54:35 gonna like scare people with the history or like what's your perspective here

54:39 we are at Python 3.8 now we're about to release 3.9 later you know another

54:44 18 months later historically Guido expressed his distaste with numbers after the

54:51 decimal point that have more than one digit right and so he disliked the notion of

54:57 having 2.10 2.11 same with 3.10 3.11 however we have both philosophical and technical

55:05 challenges with just releasing a Python 4 well the obvious philosophical

55:10 one is that the transition between Python 2 and Python 3 was very very challenging

55:15 right it took us a lot of effort and there's a lot of fatigue I think in the

55:19 community we just not go through that again for a while absolutely our closets

55:23 are still full of skeletons so like we are really trying hard not to make

55:29 that mistake again it's not only a problem for the users it was also unpleasant

55:34 and a problem for the core developers so we are really careful to make changes

55:39 in a very incremental manner now and communicate them well and make them gradually

55:44 so that we are disrupting our users the least which just means calling something

55:49 Python 4 well would probably be just scary on its own just on the power of that

55:55 number but just more practically speaking because of this Python 2 and 3 transition

55:59 there is a ton of code in the wild that does checks exactly for the number

56:04 3 in this version and version info and those checks would you know become invalid

56:10 if we introduced Python 4 like which is one of the reasons why you know like Linux had

56:16 problems when it suddenly became Linux 3 and why we have Windows 10 now just for that

56:22 practical reason I do expect that we're gonna see Python 3.10 first at least

56:27 before we ever decide to call the next release Python 4 yeah yeah so 3.10 is way

56:32 more likely maybe we should call it Python 6 because then it's like two times

56:36 three well I was wondering if there's a proposal to introduce calendar versioning

56:40 to Python oh yeah what do you think about calendar versioning if Python 2.7

56:44 was called 2014.1 actually yeah yeah yeah maybe people would reconsider really 2014

56:49 what's up here like we just upgraded from 2013 it would certainly remind people

56:54 how old that Python distribution is so maybe that upgrade faster that's funny

56:58 well I'm in no power to just you know like make that change I could be in power to

57:03 create a PEP about it but this is probably not a sword I'm willing to fall on

57:08 however like let me tell you this like all of my private projects do use calendar

57:12 versioning like that's the only versioning that I am familiar and comfortable with

57:16 there's obviously semantic versioning but I don't know about others but at least I

57:20 don't see myself being as strict and consistent with applying semantic versioning

57:25 like every time what does it mean to push the major version versus minor

57:29 version like yeah so obviously there's rules but like the devil is in the application

57:33 like do you apply those rules consistently and every given time like you know I

57:37 wrote an auto formatter because I was not able to apply rules of code styling you

57:42 know consistently and every time so I don't trust myself enough to do the same for

57:47 semantic versioning and if I'm not doing that then my users cannot depend on you

57:52 know what they expect from semantic versioning hence just using calendar versioning

57:55 way easier adopted by many popular projects like Ubuntu like Twisted like

58:00 others yeah I love the calendar versioning I don't know that it makes sense for like the

58:04 main Python maybe maybe it does maybe it doesn't it would be effective on

58:08 showing how old some stuff is but certainly I feel like semantic versioning

58:12 requires like on libraries it requires some expertise in that library like I

58:18 depend on library a it depends on library b I see that when I pip installed it it's

58:24 0.1.3 six months later is that out of date I have no idea like I don't even

58:30 know like roughly how old that is but if I saw the calendar version on all the

58:34 dependencies or stuff I'm not super familiar with be like oh yeah this is

58:38 actually this is pretty much new or it's old like it just it makes it easier for newcomers

58:42 I think yeah all right guys thank you for being on the show and sharing all this

58:46 and looking forward to when you actually release 3.8 I'm looking forward to

58:49 that too thank you very much I can imagine thanks Michael yeah bye this has been another

58:54 episode of talk Python to me our guests in this episode have been Lucas Lenga and Anthony

58:59 Shaw and it's been brought to you by Microsoft if you're a Python developer

59:03 Microsoft has you covered from VS Code and their modern editor plugins to

59:08 Azure pipelines for continuous integration and serverless Python functions on Azure

59:13 check them out at talkpython.fm/Microsoft want to level up your Python if

59:19 you're just getting started try my Python jumpstart by building 10 apps course or if you're

59:24 looking for something more advanced check out our new async course that digs into

59:29 all the different types of async programming you can do in Python and of course if you're

59:33 interested in more than one of these be sure to check out our everything bundle it's

59:37 like a subscription that never expires be sure to subscribe to the show open your favorite

59:41 podcatcher and search for Python we should be right at the top you can also find the

59:45 iTunes feed at /itunes the Google Play feed at /play in the direct RSS feed at

59:51 /rss on talkpython.fm this is your host Michael Kennedy thanks so much for listening I

59:57 really appreciate it now get out there and write some Python code you're welcome you're a

01:00:13 good one you're a good one you're a good one you're a good one you're a good one you're a good one

01:00:20 you're a good one you're a good one

Back to show page
Talk Python's Mastodon Michael Kennedy's Mastodon