WEBVTT

00:00:00.000 --> 00:00:02.000
You're adding type-ins to your Python code.

00:00:02.240 --> 00:00:04.560
Your editor is happy, autocomplete is working great,

00:00:05.000 --> 00:00:06.260
but then you switch tools

00:00:06.260 --> 00:00:08.540
and suddenly there are red squigglies everywhere.

00:00:09.220 --> 00:00:12.160
Who decides what a float annotation actually means

00:00:12.160 --> 00:00:15.680
or whether passing none where an int is expected

00:00:15.680 --> 00:00:16.700
should be an error?

00:00:17.180 --> 00:00:19.260
It turns out there's a five-person council

00:00:19.260 --> 00:00:21.260
dedicated to exactly these questions

00:00:21.260 --> 00:00:25.100
and two brand new Rust-based type checkers

00:00:25.100 --> 00:00:26.680
are raising the bar as well.

00:00:27.200 --> 00:00:29.620
On this episode, I sit down with three of the members

00:00:29.620 --> 00:00:31.300
of the Python Typing Council,

00:00:31.620 --> 00:00:34.380
Yela Zylstra, Rebecca Chen, and Carl Meyer

00:00:34.380 --> 00:00:37.040
to learn about how the type system is governed,

00:00:37.520 --> 00:00:40.240
where the spec and type checkers agree and disagree,

00:00:40.720 --> 00:00:42.880
and I get the council's official advice

00:00:42.880 --> 00:00:45.240
on how much typing is just enough.

00:00:45.800 --> 00:00:48.640
This is Talk Python To Me, episode 539,

00:00:49.260 --> 00:00:51.860
recorded January 27th, 2026.

00:00:53.460 --> 00:00:56.300
Talk Python To Me, yeah, we ready to roll.

00:00:56.540 --> 00:00:59.160
Upgrading the code, no fear of getting old.

00:00:59.160 --> 00:01:01.780
Async in the air, new frameworks in sight,

00:01:01.920 --> 00:01:02.960
geeky rap on deck.

00:01:03.260 --> 00:01:04.960
Quart crew, it's time to unite.

00:01:05.060 --> 00:01:07.980
We started in Pyramid, cruising old school lanes,

00:01:08.260 --> 00:01:09.760
had that stable base, yeah, sir.

00:01:09.760 --> 00:01:10.840
Welcome to Talk Python To Me,

00:01:10.940 --> 00:01:13.180
the number one Python podcast for developers

00:01:13.180 --> 00:01:14.220
and data scientists.

00:01:14.640 --> 00:01:16.080
This is your host, Michael Kennedy.

00:01:16.420 --> 00:01:20.060
I'm a PSF fellow who's been coding for over 25 years.

00:01:20.600 --> 00:01:21.740
Let's connect on social media.

00:01:22.060 --> 00:01:23.940
You'll find me and Talk Python on Mastodon,

00:01:24.040 --> 00:01:25.220
Bluesky, and X.

00:01:25.400 --> 00:01:27.380
The social links are all in your show notes.

00:01:27.380 --> 00:01:30.420
You can find over 10 years of past episodes

00:01:30.420 --> 00:01:31.620
at talkpython.fm.

00:01:31.720 --> 00:01:33.380
And if you want to be part of the show,

00:01:33.500 --> 00:01:35.140
you can join our recording live streams.

00:01:35.300 --> 00:01:37.260
That's right, we live stream the raw,

00:01:37.380 --> 00:01:39.360
uncut version of each episode on YouTube.

00:01:39.680 --> 00:01:42.400
Just visit talkpython.fm/youtube

00:01:42.400 --> 00:01:44.360
to see the schedule of upcoming events.

00:01:44.520 --> 00:01:46.160
Be sure to subscribe there and press the bell

00:01:46.160 --> 00:01:48.180
so you'll get notified anytime we're recording.

00:01:48.720 --> 00:01:50.600
This episode is brought to you by Sentry.

00:01:50.720 --> 00:01:52.240
Don't let those errors go unnoticed.

00:01:52.400 --> 00:01:53.980
Use Sentry like we do here at Talk Python.

00:01:53.980 --> 00:01:57.360
Sign up at talkpython.fm/sentry.

00:01:57.720 --> 00:01:58.880
And it's brought to you by

00:01:58.880 --> 00:02:01.920
our Agentic AI programming for Python course.

00:02:02.340 --> 00:02:05.360
Learn to work with AI that actually understands your code base

00:02:05.360 --> 00:02:06.900
and build real features.

00:02:07.400 --> 00:02:10.800
Visit talkpython.fm/agentic-ai.

00:02:11.940 --> 00:02:14.320
Della, Rebecca, and Carl,

00:02:14.780 --> 00:02:17.940
welcome to all of you type-loving Pythonistas.

00:02:18.480 --> 00:02:19.780
Awesome to have you here on the show.

00:02:20.100 --> 00:02:20.860
Thanks for being here.

00:02:20.860 --> 00:02:22.700
We're going to talk Python typing,

00:02:23.100 --> 00:02:26.920
especially from the perspective of the Python Typing Council,

00:02:27.380 --> 00:02:30.700
which honestly, I am a huge fan of Python typing.

00:02:30.840 --> 00:02:33.160
It's still something I learned about not too long ago.

00:02:33.300 --> 00:02:35.900
So I'm going to be learning along with everyone else,

00:02:35.980 --> 00:02:38.020
what it is you all do and so on.

00:02:38.100 --> 00:02:41.540
So I'm really excited to be diving into this.

00:02:41.700 --> 00:02:44.420
I think since types came to Python,

00:02:44.540 --> 00:02:46.620
I think it's made it a little bit more rigorous,

00:02:46.920 --> 00:02:48.520
you know, for all those people out there like,

00:02:48.520 --> 00:02:51.820
oh, it's not a real language without any form of static typing.

00:02:51.900 --> 00:02:52.960
We can't use it on real projects.

00:02:53.060 --> 00:02:53.920
I don't know how true that was,

00:02:54.020 --> 00:02:56.680
but certainly it's less true now.

00:02:56.880 --> 00:02:58.380
You know, you can pick per project.

00:02:58.480 --> 00:02:59.220
So it's super cool.

00:02:59.480 --> 00:03:00.700
Before we get into all that, though,

00:03:00.920 --> 00:03:03.000
let's just go around for a quick introductions.

00:03:03.880 --> 00:03:04.860
Jala, welcome to the show.

00:03:05.160 --> 00:03:05.920
Awesome to have you here.

00:03:06.180 --> 00:03:06.580
Who are you?

00:03:06.700 --> 00:03:07.200
Hi, yeah.

00:03:07.540 --> 00:03:09.260
Jala, I've been on the Python Typing Council

00:03:09.260 --> 00:03:09.980
since the beginning.

00:03:10.240 --> 00:03:12.040
I helped set it up a couple of years ago.

00:03:12.380 --> 00:03:13.860
Outside of the typing work,

00:03:13.860 --> 00:03:15.060
I currently work at OpenAI,

00:03:15.320 --> 00:03:17.120
where I work on developer productivity,

00:03:17.480 --> 00:03:19.480
which means things like running CI for people

00:03:19.480 --> 00:03:22.760
and helping, generally helping people be productive.

00:03:23.240 --> 00:03:25.440
I've been working with Python for more than a decade.

00:03:25.940 --> 00:03:28.880
Started out because my previous job was mostly in Python

00:03:28.880 --> 00:03:31.440
and then got more and more involved with the language.

00:03:32.240 --> 00:03:33.500
So let me get this right.

00:03:33.620 --> 00:03:36.440
At OpenAI, you're basically helping developers there

00:03:36.440 --> 00:03:37.700
have better developer tooling

00:03:37.700 --> 00:03:41.360
and common packages and workflows and stuff like that.

00:03:41.520 --> 00:03:42.380
Is that kind of the story?

00:03:42.380 --> 00:03:42.940
That's right.

00:03:43.380 --> 00:03:45.060
Mostly around things that happen in CI,

00:03:45.600 --> 00:03:46.940
like running tests efficiently,

00:03:47.520 --> 00:03:48.800
figuring out the right tests to run,

00:03:49.140 --> 00:03:50.540
getting the right CI workers out.

00:03:50.620 --> 00:03:51.460
That sounds very exciting.

00:03:51.720 --> 00:03:56.180
Right in the epicenter of all the big tech stuff these days.

00:03:56.260 --> 00:03:56.700
Super cool.

00:03:57.140 --> 00:03:58.080
Rebecca, hello.

00:03:58.200 --> 00:03:58.400
Welcome.

00:03:58.640 --> 00:04:00.000
Hey, thanks for having me.

00:04:00.100 --> 00:04:00.540
I'm Rebecca.

00:04:01.040 --> 00:04:05.340
I've been on the Typing Council also for about three years,

00:04:05.700 --> 00:04:07.140
I think, since the, less than three,

00:04:07.440 --> 00:04:08.120
since the beginning.

00:04:08.120 --> 00:04:13.400
But my day job, I work at Meta on Python typing,

00:04:13.760 --> 00:04:16.820
gone Pyrefly, which is a new type checker

00:04:16.820 --> 00:04:19.580
and language server written in Rust, still in beta.

00:04:20.080 --> 00:04:23.360
Prior to that, I was at Google for eight years,

00:04:23.460 --> 00:04:24.800
also on the Python team.

00:04:24.920 --> 00:04:26.280
I just, I really like Python.

00:04:26.600 --> 00:04:27.460
Yeah, super neat.

00:04:27.460 --> 00:04:29.680
I'm a big fan of both Pyrefly and ty,

00:04:30.180 --> 00:04:33.040
which will both have representatives here, I know.

00:04:33.720 --> 00:04:36.840
And I think it's just a super exciting time for Python types.

00:04:37.000 --> 00:04:38.620
And certainly that's one of the reasons.

00:04:38.940 --> 00:04:39.620
So very cool.

00:04:39.940 --> 00:04:40.700
Carl, welcome back.

00:04:40.980 --> 00:04:41.300
Thank you.

00:04:41.380 --> 00:04:41.900
Great to be here.

00:04:42.260 --> 00:04:43.800
Yeah, Carl Meyer.

00:04:43.800 --> 00:04:47.800
I currently work at Astral, where I work on ty,

00:04:48.080 --> 00:04:50.760
which is a Python type checker and language server

00:04:50.760 --> 00:04:52.780
written in Rust, also in beta.

00:04:53.320 --> 00:04:55.600
And yeah, I guess, how did I get into typing?

00:04:55.900 --> 00:04:58.680
Or I've been on the Typing Council, not since the beginning.

00:04:59.120 --> 00:05:01.100
I think it's been a year and a half.

00:05:01.720 --> 00:05:07.280
And yeah, I got into Python typing at the time in 2016, 2017.

00:05:07.280 --> 00:05:08.880
I was working at Instagram.

00:05:08.880 --> 00:05:12.520
And that was in the very early days of Python typing.

00:05:12.880 --> 00:05:17.020
The PEP44, PEP43, the early Python typing PEPs

00:05:17.020 --> 00:05:19.160
had recently come out within the last couple of years.

00:05:19.500 --> 00:05:21.440
And one of the co-authors of some of those PEPs,

00:05:21.580 --> 00:05:24.180
Lukash Lange, was actually sitting at a desk

00:05:24.180 --> 00:05:25.360
right next to me at the time.

00:05:25.860 --> 00:05:27.060
And at some point, we started to think

00:05:27.060 --> 00:05:28.840
that we should try this Python typing stuff

00:05:28.840 --> 00:05:30.960
on the Instagram server monolith.

00:05:31.400 --> 00:05:33.880
And so I took that on as a side project.

00:05:33.880 --> 00:05:35.680
And then it eventually became the main project.

00:05:35.680 --> 00:05:37.400
And then it took like three years.

00:05:37.400 --> 00:05:39.880
So a lot of Python typing experience there.

00:05:40.060 --> 00:05:40.780
There absolutely is.

00:05:40.880 --> 00:05:42.600
You know, I think a couple of things

00:05:42.600 --> 00:05:43.600
I'd like to touch on there.

00:05:43.840 --> 00:05:47.520
First of all, Instagram, is it maybe the biggest Django

00:05:47.520 --> 00:05:48.420
deployment in the world?

00:05:48.520 --> 00:05:50.020
It's certainly one of the bigger ones, right?

00:05:50.080 --> 00:05:51.640
And I think a lot of people don't necessarily

00:05:51.640 --> 00:05:55.320
know that a core chunk of Instagram is actually Python, right?

00:05:55.440 --> 00:05:57.380
I mean, I don't know if we have any way to know

00:05:57.380 --> 00:06:00.400
how big the Django deployments in the wild might be.

00:06:00.460 --> 00:06:01.480
But it's certainly a big one.

00:06:01.560 --> 00:06:02.500
Yeah, it's definitely a big one.

00:06:02.500 --> 00:06:06.680
There were some talks about dismissing the garbage collector

00:06:06.680 --> 00:06:08.500
from the Instagram folks.

00:06:08.660 --> 00:06:11.040
That wasn't you giving the talk, but at PyCon.

00:06:11.160 --> 00:06:12.120
So that was pretty interesting.

00:06:12.320 --> 00:06:15.980
But I think actually that work that you're talking about,

00:06:16.040 --> 00:06:19.480
especially with Lukash, really kind of opened

00:06:19.480 --> 00:06:22.520
a lot of people's eyes about Python typing, right?

00:06:22.560 --> 00:06:25.600
He gave a couple of PyCon talks, showed, you know,

00:06:25.640 --> 00:06:28.440
real metrics of how much of the code base is typed,

00:06:28.640 --> 00:06:31.780
how much it's changed, like error detection,

00:06:32.400 --> 00:06:33.180
that kind of stuff.

00:06:33.180 --> 00:06:36.760
So let me ask you, do you feel like it would be different?

00:06:36.860 --> 00:06:39.500
Would it have gone different now if tools like TY

00:06:39.500 --> 00:06:41.840
and Pyrefly existed back then?

00:06:42.180 --> 00:06:44.440
Is Python typing different now than it was then?

00:06:44.560 --> 00:06:45.320
Certainly, yes.

00:06:45.420 --> 00:06:47.260
I mean, there's been, the type system has gotten

00:06:47.260 --> 00:06:49.320
more complex over time.

00:06:49.320 --> 00:06:52.240
So it is both more expressive and more complex.

00:06:52.740 --> 00:06:55.880
And yeah, we have more type checkers available now.

00:06:56.460 --> 00:06:58.080
I do agree that it's more complicated,

00:06:58.080 --> 00:06:59.540
and I don't know how to feel about that.

00:06:59.540 --> 00:07:03.320
It is more expressive, but I feel like it's starting to get,

00:07:03.860 --> 00:07:06.880
I mean, we're not at C++ ATL,

00:07:06.960 --> 00:07:08.860
like templates of templates of templates,

00:07:09.060 --> 00:07:12.200
but still, it's getting more serious.

00:07:12.340 --> 00:07:14.080
But I guess one of the really nice parts

00:07:14.080 --> 00:07:16.820
is that you can just take as much as you want

00:07:16.820 --> 00:07:18.940
of the complexity, and you can just leave the rest, right?

00:07:19.220 --> 00:07:21.060
That's part of the magic of Python typing,

00:07:21.300 --> 00:07:23.460
is that it's a gradual typing system.

00:07:23.820 --> 00:07:25.780
That's a choice people get to make.

00:07:25.780 --> 00:07:28.400
It can be none, it can be quite a bit,

00:07:28.800 --> 00:07:30.220
and anywhere in between.

00:07:30.560 --> 00:07:32.780
So I guess that's probably one of the decisions.

00:07:33.220 --> 00:07:34.480
Let's talk about the typing council.

00:07:34.700 --> 00:07:37.380
So when did the typing council come along,

00:07:37.800 --> 00:07:40.640
and did the typing council exist to create

00:07:40.640 --> 00:07:42.320
all of these PEPs and make this happen,

00:07:42.400 --> 00:07:43.460
or was it afterwards?

00:07:43.720 --> 00:07:45.380
Like, what's the history of the typing council

00:07:45.380 --> 00:07:46.780
and its purpose, folks?

00:07:47.160 --> 00:07:47.460
We'll run it.

00:07:47.520 --> 00:07:49.340
Yeah, it postdates most of the PEPs.

00:07:49.480 --> 00:07:51.260
So initially, the text system was created

00:07:51.260 --> 00:07:52.740
just through the regular PEP process.

00:07:52.740 --> 00:07:54.220
It means that something gets submitted,

00:07:54.800 --> 00:07:57.440
first still to Guido as the BDFL,

00:07:57.860 --> 00:07:58.900
later to the steering council.

00:07:59.360 --> 00:08:01.520
Meant that it's very hard to make changes

00:08:01.520 --> 00:08:02.740
to, like, this specification.

00:08:03.020 --> 00:08:04.860
Like, anytime you want to make change something

00:08:04.860 --> 00:08:06.580
about how the type systems would work,

00:08:06.900 --> 00:08:08.520
we had to go through this PEP procedure,

00:08:09.040 --> 00:08:09.940
talk to the steering council,

00:08:09.940 --> 00:08:11.020
who are very busy people,

00:08:11.160 --> 00:08:12.980
who deal with a lot of other aspects

00:08:12.980 --> 00:08:14.100
of the language other than typing.

00:08:14.640 --> 00:08:17.360
So Shantanu and I came up with this idea

00:08:17.360 --> 00:08:19.000
of creating a separate council

00:08:19.000 --> 00:08:21.040
to specifically in charge of typing,

00:08:21.040 --> 00:08:22.840
that would be in a specification

00:08:22.840 --> 00:08:25.080
where we can make small changes ourselves

00:08:25.080 --> 00:08:26.000
without having to go through

00:08:26.000 --> 00:08:27.100
this whole PEP process.

00:08:27.520 --> 00:08:29.340
And this way, when all the type checkers

00:08:29.340 --> 00:08:31.360
agreed that something needs to go a certain way

00:08:31.360 --> 00:08:32.940
and it's not exactly what's in the PEPs,

00:08:33.420 --> 00:08:36.520
we can change it and have a place to record that

00:08:36.520 --> 00:08:37.680
and people can refer to it

00:08:37.680 --> 00:08:39.720
and new type checkers can also try

00:08:39.720 --> 00:08:40.740
to follow those decisions.

00:08:41.060 --> 00:08:41.480
Very interesting.

00:08:41.680 --> 00:08:43.540
I didn't realize that it was sort of,

00:08:43.540 --> 00:08:46.360
was there to allow for small changes

00:08:46.360 --> 00:08:47.920
to be made to make that much easier.

00:08:48.040 --> 00:08:49.140
But of course that makes sense

00:08:49.140 --> 00:08:50.360
because the PEP process is,

00:08:50.540 --> 00:08:52.360
it's pretty serious and drawn out.

00:08:52.420 --> 00:08:55.560
And we've seen even small language changes

00:08:55.560 --> 00:08:58.080
have quite passionate folks,

00:08:58.180 --> 00:08:59.800
I guess we should say.

00:09:00.140 --> 00:09:01.620
So yeah, yeah, very nice.

00:09:02.020 --> 00:09:04.180
Do you have any examples of the types of changes

00:09:04.180 --> 00:09:05.080
that y'all have,

00:09:05.420 --> 00:09:06.600
that have happened over the years

00:09:06.600 --> 00:09:09.020
that maybe were typing council only?

00:09:09.140 --> 00:09:09.980
One was the specification

00:09:09.980 --> 00:09:11.660
where how overloads work,

00:09:11.780 --> 00:09:13.940
which is perhaps not really a small change,

00:09:14.040 --> 00:09:16.040
but one of the most complicated features

00:09:16.040 --> 00:09:17.940
in the type system really is the overloads,

00:09:17.940 --> 00:09:19.680
where you can give multiple signatures

00:09:19.680 --> 00:09:20.540
for a function

00:09:20.540 --> 00:09:22.820
and type checkers sort of select

00:09:22.820 --> 00:09:25.080
which one to use based on the arguments

00:09:25.080 --> 00:09:26.280
when the function is called.

00:09:26.820 --> 00:09:28.080
And when it was initially created,

00:09:28.460 --> 00:09:29.400
from what I recall,

00:09:29.640 --> 00:09:31.120
there just wasn't really a specification.

00:09:31.540 --> 00:09:33.480
It's just like you use the signatures

00:09:33.480 --> 00:09:34.960
in a way that makes sense.

00:09:35.420 --> 00:09:36.200
And Eric Trout,

00:09:36.280 --> 00:09:37.400
who's currently on the council,

00:09:37.620 --> 00:09:40.080
came up with a pretty specific procedure

00:09:40.080 --> 00:09:42.000
for exactly how overload should work

00:09:42.000 --> 00:09:44.720
to make it so that type checkers have,

00:09:45.160 --> 00:09:46.620
well, sort of users can understand how it works

00:09:46.620 --> 00:09:47.820
and sort of type checkers can have something

00:09:47.820 --> 00:09:49.000
to work towards to make sure

00:09:49.000 --> 00:09:51.220
that they work infinite overloads in the same way.

00:09:51.220 --> 00:09:52.480
Maybe a smaller example

00:09:52.480 --> 00:09:54.100
that is an example of something

00:09:54.100 --> 00:09:56.140
that would have been too small for a pep

00:09:56.140 --> 00:09:57.660
and hard to accomplish

00:09:57.660 --> 00:09:59.780
before the typing council existed.

00:10:00.420 --> 00:10:01.600
And this is actually a change

00:10:01.600 --> 00:10:03.680
that I pushed through before the,

00:10:04.220 --> 00:10:05.440
before I was on the typing council,

00:10:05.560 --> 00:10:06.980
but the typing council approved it,

00:10:07.240 --> 00:10:08.780
was a clarification around

00:10:08.780 --> 00:10:11.620
the interpretation of data class fields.

00:10:11.920 --> 00:10:13.860
If a final annotation is applied

00:10:13.860 --> 00:10:15.080
to a data class field,

00:10:15.680 --> 00:10:16.500
does that mean,

00:10:16.980 --> 00:10:18.800
so if you apply a final annotation

00:10:18.800 --> 00:10:20.340
to a regular class attribute,

00:10:20.880 --> 00:10:22.120
since it can't be changed,

00:10:22.260 --> 00:10:24.260
that implies that it's a class variable.

00:10:24.620 --> 00:10:25.720
And there was a question of

00:10:25.720 --> 00:10:26.900
if that should be the interpretation

00:10:26.900 --> 00:10:28.060
with the data class or not.

00:10:28.360 --> 00:10:29.360
So we discussed that

00:10:29.360 --> 00:10:31.320
and made a clarification to the spec.

00:10:31.420 --> 00:10:32.740
I've never really thought about final

00:10:32.740 --> 00:10:35.700
being applied to a class field,

00:10:35.840 --> 00:10:36.960
but I've always used them

00:10:36.960 --> 00:10:38.220
sort of just for constants.

00:10:38.520 --> 00:10:38.840
But, you know,

00:10:38.860 --> 00:10:40.320
maybe people out there don't know,

00:10:40.320 --> 00:10:43.320
like typing dot final bracket type,

00:10:43.540 --> 00:10:43.800
right?

00:10:44.260 --> 00:10:45.360
That's kind of the way

00:10:45.360 --> 00:10:47.160
you can do constants in Python, right?

00:10:47.360 --> 00:10:48.440
Constants for the type checker.

00:10:48.860 --> 00:10:49.560
Nothing in the runtime

00:10:49.560 --> 00:10:50.660
will stop you from editing it.

00:10:51.080 --> 00:10:51.400
That's...

00:10:51.400 --> 00:10:51.980
Not there.

00:10:52.200 --> 00:10:52.820
Not there.

00:10:52.920 --> 00:10:54.460
I have some examples coming up

00:10:54.460 --> 00:10:55.660
and I'm interested

00:10:55.660 --> 00:10:56.620
to hear your thoughts on it,

00:10:56.640 --> 00:10:58.160
but for sure it's,

00:10:58.520 --> 00:10:59.860
there is this tension, right?

00:11:00.000 --> 00:11:01.340
I mean, I think that's probably

00:11:01.340 --> 00:11:02.500
worth touching on as well

00:11:02.500 --> 00:11:04.140
is this is a tension for Python

00:11:04.140 --> 00:11:05.280
in general is

00:11:05.280 --> 00:11:07.380
you can write all the types you want

00:11:07.380 --> 00:11:09.160
and then when you run your code,

00:11:09.280 --> 00:11:10.900
it just doesn't care.

00:11:11.000 --> 00:11:11.940
There's a few instances,

00:11:12.360 --> 00:11:14.020
Pydantic, FastAPI,

00:11:14.160 --> 00:11:14.600
a few others,

00:11:14.720 --> 00:11:15.740
but generally speaking,

00:11:15.960 --> 00:11:17.200
it's there for the editors

00:11:17.200 --> 00:11:18.180
and the type checkers

00:11:18.180 --> 00:11:18.760
and the linters

00:11:18.760 --> 00:11:20.460
and not for runtime, right?

00:11:20.660 --> 00:11:21.280
Yeah, that's right.

00:11:21.580 --> 00:11:23.440
There's many exceptions to that.

00:11:23.660 --> 00:11:25.160
There's a product like mypyC,

00:11:25.380 --> 00:11:26.460
which comes with mypy

00:11:26.460 --> 00:11:27.580
that's used those types

00:11:27.580 --> 00:11:28.660
to compile your code

00:11:28.660 --> 00:11:30.600
into more efficient machine codes.

00:11:30.920 --> 00:11:31.520
Maybe there's going to be

00:11:31.520 --> 00:11:32.240
more products like that

00:11:32.240 --> 00:11:32.660
in the future.

00:11:32.760 --> 00:11:33.220
I don't know.

00:11:33.540 --> 00:11:34.220
But yes, in general,

00:11:34.400 --> 00:11:35.980
it's separate from the runtime.

00:11:36.520 --> 00:11:37.060
Sort of a similar

00:11:37.060 --> 00:11:38.380
model to TypeScript

00:11:38.380 --> 00:11:39.820
where TypeScript

00:11:39.820 --> 00:11:40.940
gets compiled into JavaScript

00:11:40.940 --> 00:11:42.020
and types just go away.

00:11:42.620 --> 00:11:43.260
Here, we don't do

00:11:43.260 --> 00:11:44.060
a compilation step,

00:11:44.180 --> 00:11:45.120
but still the same idea

00:11:45.120 --> 00:11:45.720
of the types

00:11:45.720 --> 00:11:47.180
just not influencing the runtime.

00:11:47.420 --> 00:11:48.300
Although we do make them

00:11:48.300 --> 00:11:49.700
available for introspection

00:11:49.700 --> 00:11:51.500
via done annotations attributes,

00:11:51.500 --> 00:11:52.740
which is what has enabled

00:11:52.740 --> 00:11:54.420
the projects like Pydantic

00:11:54.420 --> 00:11:55.940
and other sort of

00:11:55.940 --> 00:11:56.840
runtime checkers

00:11:56.840 --> 00:11:58.660
to make use of type annotations

00:11:58.660 --> 00:11:59.400
at runtime also.

00:11:59.540 --> 00:12:00.000
Yeah, I don't know

00:12:00.000 --> 00:12:01.060
if the typing council

00:12:01.060 --> 00:12:02.020
was around for this,

00:12:02.120 --> 00:12:03.340
but there was proposed,

00:12:03.480 --> 00:12:03.780
I don't remember

00:12:03.780 --> 00:12:04.520
the exact details,

00:12:04.620 --> 00:12:05.660
but something to the effect

00:12:05.660 --> 00:12:07.420
of for type checking,

00:12:07.640 --> 00:12:08.760
not actually doing

00:12:08.760 --> 00:12:11.040
some of the full imports

00:12:11.040 --> 00:12:12.840
or something along those lines,

00:12:13.200 --> 00:12:13.420
right,

00:12:13.460 --> 00:12:15.080
where the runtime behavior

00:12:15.080 --> 00:12:15.960
would have made it hard

00:12:15.960 --> 00:12:17.420
for tools like Pydantic

00:12:17.420 --> 00:12:18.940
and others to get that.

00:12:19.300 --> 00:12:20.000
And there was

00:12:20.000 --> 00:12:21.040
some kind of compromise,

00:12:21.180 --> 00:12:21.280
right?

00:12:21.280 --> 00:12:22.600
I don't remember the details here.

00:12:22.720 --> 00:12:23.140
Anyone does?

00:12:23.260 --> 00:12:23.960
Yeah, what happened was

00:12:23.960 --> 00:12:24.540
that there was going

00:12:24.540 --> 00:12:25.180
to be a change.

00:12:25.600 --> 00:12:26.240
That's what the

00:12:26.240 --> 00:12:26.980
from future import

00:12:26.980 --> 00:12:28.040
annotations import does,

00:12:28.100 --> 00:12:29.580
that changes all annotations

00:12:29.580 --> 00:12:30.600
into raw strings.

00:12:30.600 --> 00:12:32.540
So the default behavior

00:12:32.540 --> 00:12:34.260
before recently

00:12:34.260 --> 00:12:35.400
was that annotations

00:12:35.400 --> 00:12:36.500
that are regular codes.

00:12:36.660 --> 00:12:37.760
If you write devf

00:12:37.760 --> 00:12:38.700
return to ints

00:12:38.700 --> 00:12:39.800
and you import the module,

00:12:39.900 --> 00:12:40.720
it just looks up

00:12:40.720 --> 00:12:41.400
the name ints

00:12:41.400 --> 00:12:41.920
and puts that

00:12:41.920 --> 00:12:43.000
in an annotations dictionary,

00:12:43.420 --> 00:12:44.780
which makes introspection easy,

00:12:44.940 --> 00:12:45.680
but it made

00:12:45.680 --> 00:12:47.100
a test on costs

00:12:47.100 --> 00:12:48.400
on performance

00:12:48.400 --> 00:12:49.520
because memory usage

00:12:49.520 --> 00:12:50.260
sometimes was high

00:12:50.260 --> 00:12:51.580
and also made things

00:12:51.580 --> 00:12:52.720
harder to use sometimes

00:12:52.720 --> 00:12:54.340
because if you use a name

00:12:54.340 --> 00:12:55.420
that's not defined yet

00:12:55.420 --> 00:12:56.020
at runtime,

00:12:56.540 --> 00:12:57.120
you get an error.

00:12:57.120 --> 00:12:58.160
That often comes up

00:12:58.160 --> 00:12:59.700
if you have like a class

00:12:59.700 --> 00:13:00.940
that has a reference

00:13:00.940 --> 00:13:01.760
in an adaptation

00:13:01.760 --> 00:13:02.820
to the class itself

00:13:02.820 --> 00:13:03.840
or circular

00:13:03.840 --> 00:13:05.420
dependency classes.

00:13:05.880 --> 00:13:05.980
Right.

00:13:06.080 --> 00:13:07.120
The circular imports

00:13:07.120 --> 00:13:08.640
because you want to say

00:13:08.640 --> 00:13:09.720
this class

00:13:09.720 --> 00:13:11.520
is created by that thing

00:13:11.520 --> 00:13:12.760
and it returns one,

00:13:12.840 --> 00:13:13.360
but you know,

00:13:13.420 --> 00:13:15.020
somehow you've got

00:13:15.020 --> 00:13:15.740
to import the other one

00:13:15.740 --> 00:13:17.040
and that's such a hassle.

00:13:17.420 --> 00:13:17.860
Yeah, it's,

00:13:18.220 --> 00:13:18.780
yeah, even out

00:13:18.780 --> 00:13:19.900
in the audience we have,

00:13:20.280 --> 00:13:20.740
Tom says,

00:13:20.820 --> 00:13:21.500
circular imports.

00:13:21.620 --> 00:13:22.480
Oh, yeah, for sure.

00:13:22.800 --> 00:13:24.260
What about lazy imports?

00:13:24.260 --> 00:13:25.420
Like that just recently

00:13:25.420 --> 00:13:26.040
got accepted

00:13:26.040 --> 00:13:27.000
and will be in 3.15.

00:13:27.620 --> 00:13:29.320
Which I'm super excited about

00:13:29.320 --> 00:13:29.980
because I think

00:13:29.980 --> 00:13:31.140
it'll make app startup

00:13:31.140 --> 00:13:32.100
a lot faster

00:13:32.100 --> 00:13:33.980
for many use cases.

00:13:34.400 --> 00:13:35.280
But does that have

00:13:35.280 --> 00:13:35.980
knock-on effects

00:13:35.980 --> 00:13:36.480
for typing?

00:13:36.800 --> 00:13:37.860
Not that directly

00:13:37.860 --> 00:13:39.040
because I think

00:13:39.040 --> 00:13:39.740
for a type checker

00:13:39.740 --> 00:13:40.380
lazy imports

00:13:40.380 --> 00:13:41.160
mostly just look

00:13:41.160 --> 00:13:42.320
like regular imports.

00:13:42.680 --> 00:13:43.180
I guess I should

00:13:43.180 --> 00:13:43.920
maybe leave that

00:13:43.920 --> 00:13:44.320
for the people

00:13:44.320 --> 00:13:44.740
who are actually

00:13:44.740 --> 00:13:46.040
working on type checkers

00:13:46.040 --> 00:13:47.060
and being written right now.

00:13:47.160 --> 00:13:47.660
Yeah, Rebecca,

00:13:47.880 --> 00:13:48.560
do you see this

00:13:48.560 --> 00:13:49.600
making any difference

00:13:49.600 --> 00:13:50.040
for you?

00:13:50.540 --> 00:13:51.060
Lazy imports?

00:13:51.060 --> 00:13:51.920
To be honest,

00:13:52.080 --> 00:13:53.480
it's not something

00:13:53.480 --> 00:13:54.860
we've looked at

00:13:54.860 --> 00:13:55.760
too carefully yet.

00:13:55.760 --> 00:13:56.760
3.15

00:13:56.760 --> 00:13:57.740
seems a little

00:13:57.740 --> 00:13:59.080
more in the future,

00:13:59.380 --> 00:14:01.460
but I don't think

00:14:01.460 --> 00:14:02.220
it's likely

00:14:02.220 --> 00:14:03.680
to make a huge difference.

00:14:03.960 --> 00:14:04.180
Carl?

00:14:04.340 --> 00:14:05.300
I've thought about it briefly

00:14:05.300 --> 00:14:06.260
and I think that it,

00:14:06.560 --> 00:14:07.400
I think the type checkers

00:14:07.400 --> 00:14:08.540
really won't need to care.

00:14:08.920 --> 00:14:09.520
Maybe there will be

00:14:09.520 --> 00:14:10.140
some edge cases

00:14:10.140 --> 00:14:10.660
that will come up

00:14:10.660 --> 00:14:11.420
that I haven't thought of,

00:14:11.500 --> 00:14:12.500
but it shouldn't be a big deal.

00:14:12.620 --> 00:14:13.380
Yeah, that's what I thought

00:14:13.380 --> 00:14:13.920
as well.

00:14:14.100 --> 00:14:15.660
The one variation

00:14:15.660 --> 00:14:17.080
that I can certainly see

00:14:17.080 --> 00:14:18.620
is if you have a,

00:14:19.040 --> 00:14:20.260
if you have something

00:14:20.260 --> 00:14:21.600
specified in a type,

00:14:21.920 --> 00:14:23.580
like say for a field

00:14:23.580 --> 00:14:24.260
of a class

00:14:24.260 --> 00:14:25.260
or a Pydantic model

00:14:25.260 --> 00:14:25.640
or something

00:14:25.640 --> 00:14:26.800
that would otherwise

00:14:26.800 --> 00:14:27.840
not trigger

00:14:27.840 --> 00:14:28.780
the lazy import

00:14:28.780 --> 00:14:30.100
to become imported,

00:14:30.460 --> 00:14:31.180
would potentially

00:14:31.180 --> 00:14:33.220
having types specify

00:14:33.220 --> 00:14:34.720
cause more importing

00:14:34.720 --> 00:14:36.000
to happen sooner

00:14:36.000 --> 00:14:36.640
in the runtime?

00:14:36.920 --> 00:14:37.520
Yeah, there's actually

00:14:37.520 --> 00:14:38.460
an issue related to this

00:14:38.460 --> 00:14:39.980
that I think we may need

00:14:39.980 --> 00:14:41.540
to resolve before 3.15,

00:14:41.940 --> 00:14:42.840
but I don't know how yet.

00:14:43.200 --> 00:14:44.120
If you use a type

00:14:44.120 --> 00:14:45.120
in a data class annotation

00:14:45.120 --> 00:14:46.260
that's lazy imported,

00:14:46.580 --> 00:14:47.220
actually creating

00:14:47.220 --> 00:14:47.920
a data class

00:14:47.920 --> 00:14:48.820
will delay

00:14:48.820 --> 00:14:49.520
by the import.

00:14:49.520 --> 00:14:50.660
It will try to

00:14:50.660 --> 00:14:52.760
resolve the import

00:14:52.760 --> 00:14:54.140
and actually make it

00:14:54.140 --> 00:14:54.520
not lazy.

00:14:55.000 --> 00:14:55.700
This is because

00:14:55.700 --> 00:14:56.640
data classes

00:14:56.640 --> 00:14:57.760
doesn't really need

00:14:57.760 --> 00:14:58.280
to look at all

00:14:58.280 --> 00:14:58.960
of the annotations

00:14:58.960 --> 00:14:59.620
in your class,

00:14:59.700 --> 00:15:00.300
but it looks at them

00:15:00.300 --> 00:15:01.840
enough to trigger

00:15:01.840 --> 00:15:03.860
reification of the import.

00:15:04.120 --> 00:15:04.740
I shared this

00:15:04.740 --> 00:15:05.220
with some of the people

00:15:05.220 --> 00:15:06.160
on the lazy imports team,

00:15:06.260 --> 00:15:07.460
but we haven't

00:15:07.460 --> 00:15:08.200
yet come up

00:15:08.200 --> 00:15:09.120
with a good way around it.

00:15:09.240 --> 00:15:09.980
I think this might

00:15:09.980 --> 00:15:10.980
end up being

00:15:10.980 --> 00:15:11.740
a bit of a food gun,

00:15:11.820 --> 00:15:12.260
so I feel like

00:15:12.260 --> 00:15:12.800
we should ideally

00:15:12.800 --> 00:15:13.880
find a workaround,

00:15:14.060 --> 00:15:14.720
but I don't know

00:15:14.720 --> 00:15:15.420
what it would be yet.

00:15:15.580 --> 00:15:15.920
I don't know

00:15:15.920 --> 00:15:16.680
that it's wrong

00:15:16.680 --> 00:15:17.900
that it converts it

00:15:17.900 --> 00:15:18.820
to an eager import,

00:15:18.820 --> 00:15:20.000
which it needs

00:15:20.000 --> 00:15:20.740
to know what it is

00:15:20.740 --> 00:15:21.200
potentially,

00:15:21.500 --> 00:15:21.820
right?

00:15:22.560 --> 00:15:23.660
It actually doesn't.

00:15:24.000 --> 00:15:24.420
Data classes

00:15:24.420 --> 00:15:25.240
just need to know

00:15:25.240 --> 00:15:26.080
whether it is classed

00:15:26.080 --> 00:15:26.600
for or not.

00:15:27.400 --> 00:15:27.960
I think that's

00:15:27.960 --> 00:15:28.520
pretty much all.

00:15:28.660 --> 00:15:28.960
I guess there's

00:15:28.960 --> 00:15:29.640
an init for also,

00:15:29.780 --> 00:15:30.760
but it doesn't really

00:15:30.760 --> 00:15:31.080
need to know

00:15:31.080 --> 00:15:31.800
anything else.

00:15:32.320 --> 00:15:33.220
So in theory,

00:15:33.280 --> 00:15:33.900
it should be possible

00:15:33.900 --> 00:15:34.640
to just say,

00:15:34.800 --> 00:15:35.700
hey, it is not classed

00:15:35.700 --> 00:15:37.240
for, so don't bother

00:15:37.240 --> 00:15:37.860
importing it.

00:15:38.100 --> 00:15:39.000
Okay, so that's

00:15:39.000 --> 00:15:39.660
for data classes,

00:15:39.820 --> 00:15:41.320
but say if I specify

00:15:41.320 --> 00:15:42.400
a parameter type

00:15:42.400 --> 00:15:43.180
on a function.

00:15:43.420 --> 00:15:43.880
Yeah, then it

00:15:43.880 --> 00:15:44.420
should be fine.

00:15:45.100 --> 00:15:46.280
I guess, again,

00:15:46.380 --> 00:15:47.540
unless something is,

00:15:47.960 --> 00:15:48.800
if it does annotate,

00:15:48.820 --> 00:15:49.580
so if you have

00:15:49.580 --> 00:15:49.920
something like

00:15:49.920 --> 00:15:50.480
a decorator

00:15:50.480 --> 00:15:50.960
that looks at

00:15:50.960 --> 00:15:51.880
annotations in your

00:15:51.880 --> 00:15:52.320
function,

00:15:52.660 --> 00:15:53.660
it might reify

00:15:53.660 --> 00:15:54.220
those imports.

00:15:54.540 --> 00:15:55.120
There is one other

00:15:55.120 --> 00:15:56.160
potentially interesting

00:15:56.160 --> 00:15:57.200
thing for type checkers.

00:15:57.440 --> 00:15:58.040
It's already

00:15:58.040 --> 00:15:59.880
difficult for type checkers

00:15:59.880 --> 00:16:00.620
to figure out

00:16:00.620 --> 00:16:02.480
when like a submodule

00:16:02.480 --> 00:16:03.380
should be considered

00:16:03.380 --> 00:16:04.380
to be an attribute

00:16:04.380 --> 00:16:05.340
of the parent module

00:16:05.340 --> 00:16:06.380
because the way

00:16:06.380 --> 00:16:07.260
this happens in Python

00:16:07.260 --> 00:16:08.440
is that any import

00:16:08.440 --> 00:16:09.440
of a submodule

00:16:09.440 --> 00:16:10.420
anywhere will attach

00:16:10.420 --> 00:16:11.360
that submodule

00:16:11.360 --> 00:16:12.280
as an attribute

00:16:12.280 --> 00:16:13.220
on the parent module,

00:16:13.540 --> 00:16:15.100
but that at runtime,

00:16:15.560 --> 00:16:16.560
that could literally

00:16:16.560 --> 00:16:17.220
happen anywhere.

00:16:17.220 --> 00:16:17.780
It could happen

00:16:17.780 --> 00:16:18.540
in totally unrelated

00:16:18.540 --> 00:16:19.860
code outside of the module

00:16:19.860 --> 00:16:20.680
and a type checker

00:16:20.680 --> 00:16:21.380
probably won't be able

00:16:21.380 --> 00:16:21.920
to see that.

00:16:22.220 --> 00:16:22.820
So type checkers

00:16:22.820 --> 00:16:23.740
already have sort of

00:16:23.740 --> 00:16:24.800
complex sets of rules

00:16:24.800 --> 00:16:26.080
around where they look

00:16:26.080 --> 00:16:27.020
for these submodule

00:16:27.020 --> 00:16:27.920
imports and when they

00:16:27.920 --> 00:16:28.980
consider a submodule

00:16:28.980 --> 00:16:30.600
import to be reliably

00:16:30.600 --> 00:16:31.740
happening enough

00:16:31.740 --> 00:16:32.360
that it should,

00:16:32.480 --> 00:16:33.160
that the type checker

00:16:33.160 --> 00:16:34.800
should consider

00:16:34.800 --> 00:16:35.620
this submodule

00:16:35.620 --> 00:16:36.900
to exist as an attribute.

00:16:38.080 --> 00:16:38.740
And lazy imports

00:16:38.740 --> 00:16:40.200
may make that even,

00:16:40.660 --> 00:16:41.500
we'll add one more

00:16:41.500 --> 00:16:41.820
wrinkle

00:16:41.820 --> 00:16:43.140
to those

00:16:43.140 --> 00:16:44.080
sets of heuristics

00:16:44.080 --> 00:16:44.820
in that we'll have

00:16:44.820 --> 00:16:45.300
to decide

00:16:45.300 --> 00:16:46.060
if you have

00:16:46.060 --> 00:16:46.760
a lazy import

00:16:46.760 --> 00:16:47.540
of a submodule

00:16:47.540 --> 00:16:47.940
and you're done

00:16:47.940 --> 00:16:48.720
to init.py,

00:16:48.860 --> 00:16:49.900
it's lazy.

00:16:50.420 --> 00:16:51.480
So should the type checker

00:16:51.480 --> 00:16:53.180
consider that submodule

00:16:53.180 --> 00:16:54.520
to be imported

00:16:54.520 --> 00:16:55.400
or not be imported?

00:16:55.860 --> 00:16:57.000
It'll be another case

00:16:57.000 --> 00:16:57.500
where there's no

00:16:57.500 --> 00:16:58.320
clear right answer

00:16:58.320 --> 00:16:58.920
and we'll just have

00:16:58.920 --> 00:17:00.020
to make a decision

00:17:00.020 --> 00:17:00.700
one way or the other.

00:17:02.700 --> 00:17:03.200
This portion of

00:17:03.200 --> 00:17:04.060
Talk Python is brought

00:17:04.060 --> 00:17:04.840
to you by Sentry.

00:17:05.060 --> 00:17:05.980
I've been using

00:17:05.980 --> 00:17:06.920
Sentry personally

00:17:06.920 --> 00:17:07.920
on almost every

00:17:07.920 --> 00:17:09.180
application and API

00:17:09.180 --> 00:17:10.000
that I've built

00:17:10.000 --> 00:17:10.860
for Talk Python

00:17:10.860 --> 00:17:11.420
and beyond

00:17:11.420 --> 00:17:13.040
over the last few years.

00:17:13.040 --> 00:17:13.900
They're a core

00:17:13.900 --> 00:17:14.540
building block

00:17:14.540 --> 00:17:14.980
for keeping

00:17:14.980 --> 00:17:15.720
my infrastructure

00:17:15.720 --> 00:17:16.260
solid.

00:17:16.780 --> 00:17:17.300
They should be

00:17:17.300 --> 00:17:18.140
for yours as well.

00:17:18.300 --> 00:17:18.780
Here's why.

00:17:19.420 --> 00:17:20.020
Sentry doesn't

00:17:20.020 --> 00:17:20.880
just catch errors.

00:17:21.020 --> 00:17:21.900
It catches all

00:17:21.900 --> 00:17:22.300
the stuff

00:17:22.300 --> 00:17:22.820
that makes your

00:17:22.820 --> 00:17:23.700
app feel broken.

00:17:23.940 --> 00:17:24.860
The random slowdown,

00:17:25.080 --> 00:17:25.680
the freeze you

00:17:25.680 --> 00:17:26.320
can't reproduce,

00:17:26.840 --> 00:17:27.500
that bug that

00:17:27.500 --> 00:17:28.100
only shows up

00:17:28.100 --> 00:17:29.080
once real users

00:17:29.080 --> 00:17:29.440
hit it.

00:17:29.700 --> 00:17:30.220
And when something

00:17:30.220 --> 00:17:30.700
goes wrong,

00:17:30.900 --> 00:17:31.480
Sentry gives you

00:17:31.480 --> 00:17:32.140
the whole chain

00:17:32.140 --> 00:17:32.600
of events

00:17:32.600 --> 00:17:33.260
in one place.

00:17:33.420 --> 00:17:33.740
Errors,

00:17:33.920 --> 00:17:34.200
traces,

00:17:34.460 --> 00:17:34.940
replays,

00:17:35.000 --> 00:17:35.320
logs,

00:17:35.740 --> 00:17:36.460
dots connected.

00:17:36.800 --> 00:17:37.360
You can see

00:17:37.360 --> 00:17:38.320
what's led to

00:17:38.320 --> 00:17:38.720
the issue

00:17:38.720 --> 00:17:39.320
without digging

00:17:39.320 --> 00:17:39.880
through five

00:17:39.880 --> 00:17:40.660
different dashboards.

00:17:41.400 --> 00:17:41.660
Sear,

00:17:42.000 --> 00:17:42.740
Sentry's AI

00:17:42.740 --> 00:17:43.520
debugging agents

00:17:43.520 --> 00:17:44.480
builds on this

00:17:44.480 --> 00:17:44.700
data,

00:17:44.820 --> 00:17:45.420
taking the full

00:17:45.420 --> 00:17:46.020
context,

00:17:46.640 --> 00:17:47.580
explaining why

00:17:47.580 --> 00:17:48.120
the issue

00:17:48.120 --> 00:17:48.600
happened,

00:17:49.140 --> 00:17:49.740
pointing to

00:17:49.740 --> 00:17:50.180
the code

00:17:50.180 --> 00:17:50.720
responsible,

00:17:50.940 --> 00:17:51.560
drafts a fix,

00:17:51.640 --> 00:17:52.320
and even flags

00:17:52.320 --> 00:17:52.960
if your PR

00:17:52.960 --> 00:17:53.620
is about to

00:17:53.620 --> 00:17:54.340
introduce a new

00:17:54.340 --> 00:17:54.640
problem.

00:17:55.020 --> 00:17:55.880
The workflow

00:17:55.880 --> 00:17:56.520
stays simple.

00:17:56.820 --> 00:17:57.460
Something breaks,

00:17:57.920 --> 00:17:58.680
Sentry alerts you,

00:17:58.840 --> 00:17:59.360
the dashboard

00:17:59.360 --> 00:17:59.860
shows you

00:17:59.860 --> 00:18:00.680
the full context,

00:18:01.020 --> 00:18:01.680
Sear helps you

00:18:01.680 --> 00:18:02.400
fix it and

00:18:02.400 --> 00:18:03.380
catch new issues

00:18:03.380 --> 00:18:04.100
before they ship.

00:18:04.760 --> 00:18:05.400
It's totally

00:18:05.400 --> 00:18:06.140
reasonable to go

00:18:06.140 --> 00:18:07.160
from an error

00:18:07.160 --> 00:18:07.980
occurred to

00:18:07.980 --> 00:18:08.880
fixed in production

00:18:08.880 --> 00:18:10.000
in just 10 minutes.

00:18:10.000 --> 00:18:11.360
I truly

00:18:11.360 --> 00:18:11.980
appreciate the

00:18:11.980 --> 00:18:12.460
support that

00:18:12.460 --> 00:18:12.920
Sentry has

00:18:12.920 --> 00:18:13.980
given me to

00:18:13.980 --> 00:18:14.720
help solve my

00:18:14.720 --> 00:18:15.560
bugs and issues

00:18:15.560 --> 00:18:16.340
in my apps,

00:18:16.880 --> 00:18:17.620
especially those

00:18:17.620 --> 00:18:18.460
tricky ones that

00:18:18.460 --> 00:18:19.180
only appear in

00:18:19.180 --> 00:18:19.500
production.

00:18:19.840 --> 00:18:20.420
I know you will

00:18:20.420 --> 00:18:21.020
too if you try

00:18:21.020 --> 00:18:21.360
them out.

00:18:21.640 --> 00:18:22.520
So get started

00:18:22.520 --> 00:18:23.020
today with

00:18:23.020 --> 00:18:23.280
Sentry.

00:18:23.460 --> 00:18:23.940
Just visit

00:18:23.940 --> 00:18:24.940
talkpython.fm

00:18:24.940 --> 00:18:25.860
slash Sentry

00:18:25.860 --> 00:18:27.080
and get $100

00:18:27.080 --> 00:18:28.560
in Sentry credits.

00:18:28.960 --> 00:18:29.520
Please use that

00:18:29.520 --> 00:18:29.720
link.

00:18:29.780 --> 00:18:30.100
It's in your

00:18:30.100 --> 00:18:30.640
podcast player

00:18:30.640 --> 00:18:31.080
show notes.

00:18:31.280 --> 00:18:31.500
If you're

00:18:31.500 --> 00:18:31.920
signing up

00:18:31.920 --> 00:18:32.360
some other

00:18:32.360 --> 00:18:32.620
way,

00:18:32.740 --> 00:18:33.420
you can use

00:18:33.420 --> 00:18:33.880
our code

00:18:33.880 --> 00:18:35.220
talkpython26,

00:18:35.780 --> 00:18:36.520
all one word,

00:18:36.660 --> 00:18:37.620
talkpython26,

00:18:37.620 --> 00:18:38.880
to get $100

00:18:38.880 --> 00:18:39.720
in credits.

00:18:40.380 --> 00:18:40.900
Thank you to

00:18:40.900 --> 00:18:41.460
Sentry for

00:18:41.460 --> 00:18:41.940
supporting the

00:18:41.940 --> 00:18:42.120
show.

00:18:43.160 --> 00:18:43.920
Yeah, there's

00:18:43.920 --> 00:18:44.540
some variations

00:18:44.540 --> 00:18:45.280
across type

00:18:45.280 --> 00:18:45.840
checkers, which

00:18:45.840 --> 00:18:46.540
we'll get to

00:18:46.540 --> 00:18:47.200
later.

00:18:47.600 --> 00:18:48.020
I think,

00:18:48.140 --> 00:18:48.700
though, before

00:18:48.700 --> 00:18:49.440
we move off

00:18:49.440 --> 00:18:50.420
this, there's

00:18:50.420 --> 00:18:51.960
actually off

00:18:51.960 --> 00:18:52.740
introducing the

00:18:52.740 --> 00:18:53.400
typing council.

00:18:53.560 --> 00:18:54.220
I think we

00:18:54.220 --> 00:18:54.680
should point out

00:18:54.680 --> 00:18:55.720
that there's two

00:18:55.720 --> 00:18:56.380
other folks who

00:18:56.380 --> 00:18:56.980
couldn't be here

00:18:56.980 --> 00:18:58.240
who are also on

00:18:58.240 --> 00:18:58.760
the typing

00:18:58.760 --> 00:18:59.560
council, Eric

00:18:59.560 --> 00:19:00.280
Trout and

00:19:00.280 --> 00:19:02.000
Yuka Letts,

00:19:02.380 --> 00:19:03.180
the docilo?

00:19:03.480 --> 00:19:03.940
Sorry,

00:19:04.100 --> 00:19:04.340
Yuka.

00:19:05.480 --> 00:19:06.280
But I want to

00:19:06.280 --> 00:19:06.660
make sure that

00:19:06.660 --> 00:19:07.440
we point out

00:19:07.440 --> 00:19:07.780
there's actually

00:19:07.780 --> 00:19:08.320
five people,

00:19:08.420 --> 00:19:08.880
not just the

00:19:08.880 --> 00:19:09.300
three of you,

00:19:09.320 --> 00:19:09.460
right?

00:19:09.840 --> 00:19:10.180
How do you

00:19:10.180 --> 00:19:10.860
get on the

00:19:10.860 --> 00:19:11.440
council?

00:19:11.820 --> 00:19:12.220
Is there an

00:19:12.220 --> 00:19:12.600
election?

00:19:13.020 --> 00:19:13.620
Do you just

00:19:13.620 --> 00:19:14.240
apply?

00:19:14.980 --> 00:19:15.300
I think these

00:19:15.300 --> 00:19:15.760
are filled by

00:19:15.760 --> 00:19:16.100
the members

00:19:16.100 --> 00:19:16.460
themselves.

00:19:16.740 --> 00:19:17.080
So when

00:19:17.080 --> 00:19:17.960
somebody declares

00:19:17.960 --> 00:19:18.400
the intention

00:19:18.400 --> 00:19:19.120
to leave the

00:19:19.120 --> 00:19:20.000
council, we

00:19:20.000 --> 00:19:20.880
basically ask for

00:19:20.880 --> 00:19:21.260
people who are

00:19:21.260 --> 00:19:22.080
interested and

00:19:22.080 --> 00:19:22.640
then make a

00:19:22.640 --> 00:19:23.000
selection.

00:19:23.440 --> 00:19:23.860
Generally, we

00:19:23.860 --> 00:19:24.640
try to get

00:19:24.640 --> 00:19:25.420
people who have

00:19:25.420 --> 00:19:26.120
experience in the

00:19:26.120 --> 00:19:26.680
type system.

00:19:27.140 --> 00:19:27.700
We try to get a

00:19:27.700 --> 00:19:28.120
good cross

00:19:28.120 --> 00:19:28.780
representation of

00:19:28.780 --> 00:19:29.200
people working

00:19:29.200 --> 00:19:29.720
on different

00:19:29.720 --> 00:19:30.420
type checkers.

00:19:30.700 --> 00:19:32.020
We have Carl

00:19:32.020 --> 00:19:32.620
and Rebecca

00:19:32.620 --> 00:19:33.320
here who work

00:19:33.320 --> 00:19:34.280
on two type

00:19:34.280 --> 00:19:34.620
checkers,

00:19:34.760 --> 00:19:35.160
TY and

00:19:35.160 --> 00:19:35.720
Pyrefly.

00:19:36.160 --> 00:19:36.820
Yuka works

00:19:36.820 --> 00:19:38.800
on Pyrites,

00:19:39.040 --> 00:19:39.560
which are two

00:19:39.560 --> 00:19:39.980
of the most

00:19:39.980 --> 00:19:40.420
lightly used

00:19:40.420 --> 00:19:41.060
type checkers.

00:19:41.480 --> 00:19:42.400
So we try to

00:19:42.400 --> 00:19:43.240
get representation

00:19:43.240 --> 00:19:44.340
of people working

00:19:44.340 --> 00:19:45.260
on those parts

00:19:45.260 --> 00:19:45.840
of the ecosystem.

00:19:46.100 --> 00:19:46.360
That's really

00:19:46.360 --> 00:19:47.620
cool that it's

00:19:47.620 --> 00:19:48.120
got a bias

00:19:48.120 --> 00:19:48.680
towards finding

00:19:48.680 --> 00:19:49.340
people actually

00:19:49.340 --> 00:19:50.300
doing the work.

00:19:50.700 --> 00:19:51.320
So let's talk

00:19:51.320 --> 00:19:52.020
about the

00:19:52.020 --> 00:19:53.380
specification project

00:19:53.380 --> 00:19:55.320
at typing.python.org.

00:19:55.880 --> 00:19:56.440
What is this

00:19:56.440 --> 00:19:56.720
here?

00:19:56.720 --> 00:19:57.840
I'll talk a bit

00:19:57.840 --> 00:19:58.320
about it.

00:19:58.320 --> 00:19:59.560
I guess it's

00:19:59.560 --> 00:20:00.880
a specification

00:20:00.880 --> 00:20:01.900
for how the

00:20:01.900 --> 00:20:02.680
type system

00:20:02.680 --> 00:20:03.620
used to work.

00:20:03.760 --> 00:20:04.460
The way it

00:20:04.460 --> 00:20:05.120
started was

00:20:05.120 --> 00:20:05.660
that, Yela,

00:20:05.740 --> 00:20:06.320
you basically

00:20:06.320 --> 00:20:07.220
took all the

00:20:07.220 --> 00:20:07.920
typing peps

00:20:07.920 --> 00:20:08.320
and like

00:20:08.320 --> 00:20:09.160
stapled them

00:20:09.160 --> 00:20:09.860
together,

00:20:09.860 --> 00:20:10.620
right, to

00:20:10.620 --> 00:20:11.180
make like

00:20:11.180 --> 00:20:11.920
one long

00:20:11.920 --> 00:20:12.320
doc.

00:20:12.460 --> 00:20:13.320
And since

00:20:13.320 --> 00:20:13.780
then, we've

00:20:13.780 --> 00:20:14.480
been iterating

00:20:14.480 --> 00:20:15.080
on it,

00:20:15.360 --> 00:20:15.800
filling in

00:20:15.800 --> 00:20:16.280
parts that

00:20:16.280 --> 00:20:16.800
were missing

00:20:16.800 --> 00:20:18.160
like overload

00:20:18.160 --> 00:20:19.660
evaluation and

00:20:19.660 --> 00:20:20.720
making other

00:20:20.720 --> 00:20:21.400
changes as

00:20:21.400 --> 00:20:21.560
well.

00:20:21.660 --> 00:20:22.200
Yeah, it's

00:20:22.200 --> 00:20:22.780
tricky, right?

00:20:22.860 --> 00:20:23.340
Because

00:20:23.340 --> 00:20:24.800
traditionally, the

00:20:24.800 --> 00:20:25.960
typing system

00:20:25.960 --> 00:20:26.420
is kind of

00:20:26.420 --> 00:20:27.320
defined across

00:20:27.320 --> 00:20:28.020
a series of

00:20:28.020 --> 00:20:28.360
peps.

00:20:28.780 --> 00:20:29.440
And so what

00:20:29.440 --> 00:20:30.000
is the document

00:20:30.000 --> 00:20:30.480
that tells you

00:20:30.480 --> 00:20:31.000
how it works,

00:20:31.060 --> 00:20:31.220
right?

00:20:31.340 --> 00:20:31.680
Yeah, that

00:20:31.680 --> 00:20:32.100
made it hard

00:20:32.100 --> 00:20:32.800
because often

00:20:32.800 --> 00:20:33.900
there's peps

00:20:33.900 --> 00:20:34.500
built on top

00:20:34.500 --> 00:20:35.000
of each other.

00:20:35.320 --> 00:20:36.440
So then in

00:20:36.440 --> 00:20:36.820
the extreme,

00:20:37.020 --> 00:20:37.580
you might see

00:20:37.580 --> 00:20:38.220
like one thing

00:20:38.220 --> 00:20:39.140
in one pep

00:20:39.140 --> 00:20:39.640
and then there's

00:20:39.640 --> 00:20:40.080
another pep

00:20:40.080 --> 00:20:40.480
that adds

00:20:40.480 --> 00:20:41.120
an aspect of

00:20:41.120 --> 00:20:41.480
it, another

00:20:41.480 --> 00:20:41.960
one that adds

00:20:41.960 --> 00:20:42.700
another aspect.

00:20:43.060 --> 00:20:43.400
And overall

00:20:43.400 --> 00:20:43.760
it makes it

00:20:43.760 --> 00:20:44.280
very hard to

00:20:44.280 --> 00:20:44.540
follow.

00:20:44.920 --> 00:20:45.300
One of the

00:20:45.300 --> 00:20:45.720
things I did

00:20:45.720 --> 00:20:46.260
recently was

00:20:46.260 --> 00:20:47.060
rewrite the

00:20:47.060 --> 00:20:47.740
typed dict

00:20:47.740 --> 00:20:47.740


00:20:54.800 --> 00:20:55.000
another.

00:20:55.280 --> 00:20:55.680
Ended up

00:20:55.680 --> 00:20:56.240
rewriting the

00:20:56.240 --> 00:20:56.720
whole thing

00:20:56.720 --> 00:20:57.680
to basically

00:20:57.680 --> 00:20:58.100
put all those

00:20:58.100 --> 00:20:58.700
features together

00:20:58.700 --> 00:20:59.960
in a coherent

00:20:59.960 --> 00:21:00.720
whole rather than

00:21:00.720 --> 00:21:02.240
just having them

00:21:02.240 --> 00:21:03.260
all copy-pasted

00:21:03.260 --> 00:21:04.080
one after the

00:21:04.080 --> 00:21:04.260
other.

00:21:04.400 --> 00:21:05.080
Okay, so if

00:21:05.080 --> 00:21:05.580
somebody really

00:21:05.580 --> 00:21:06.520
wants a good

00:21:06.520 --> 00:21:07.960
understanding of

00:21:07.960 --> 00:21:08.480
the Python

00:21:08.480 --> 00:21:09.240
typing system,

00:21:09.560 --> 00:21:09.960
they go to

00:21:09.960 --> 00:21:11.340
typing.python.org.

00:21:11.540 --> 00:21:12.020
You know, one

00:21:12.020 --> 00:21:12.700
thing I think

00:21:12.700 --> 00:21:13.320
maybe is worth

00:21:13.320 --> 00:21:13.840
touching on,

00:21:13.920 --> 00:21:14.500
it's just kind

00:21:14.500 --> 00:21:15.320
of out of the

00:21:15.320 --> 00:21:15.960
blue a bit,

00:21:16.060 --> 00:21:16.540
but I think

00:21:16.540 --> 00:21:17.000
it's a really

00:21:17.000 --> 00:21:17.960
interesting aspect

00:21:17.960 --> 00:21:19.400
of the Python

00:21:19.400 --> 00:21:20.240
typing system

00:21:20.240 --> 00:21:21.000
is the,

00:21:21.320 --> 00:21:21.560
what is it

00:21:21.560 --> 00:21:21.840
called, the

00:21:21.840 --> 00:21:22.720
numerical tower

00:21:22.720 --> 00:21:23.280
or the number

00:21:23.280 --> 00:21:24.340
tower, where

00:21:24.340 --> 00:21:25.280
it's like, if

00:21:25.280 --> 00:21:25.620
I have a

00:21:25.620 --> 00:21:26.400
number, I

00:21:26.400 --> 00:21:27.080
could specify

00:21:27.080 --> 00:21:27.880
it as an

00:21:27.880 --> 00:21:28.800
int, or I

00:21:28.800 --> 00:21:29.340
could specify

00:21:29.340 --> 00:21:29.920
it as a

00:21:29.920 --> 00:21:30.940
float, and

00:21:30.940 --> 00:21:31.400
those kinds

00:21:31.400 --> 00:21:32.520
of things, but

00:21:32.520 --> 00:21:33.420
do you really

00:21:33.420 --> 00:21:34.020
need to say

00:21:34.020 --> 00:21:34.580
it's an

00:21:34.580 --> 00:21:35.860
int pipe

00:21:35.860 --> 00:21:36.620
float, or a

00:21:36.620 --> 00:21:37.140
union of

00:21:37.140 --> 00:21:37.520
int and

00:21:37.520 --> 00:21:38.160
float, if it

00:21:38.160 --> 00:21:38.500
could be

00:21:38.500 --> 00:21:39.080
either, right?

00:21:39.200 --> 00:21:40.080
And the, what

00:21:40.080 --> 00:21:40.480
is it called?

00:21:40.600 --> 00:21:40.980
It's the

00:21:40.980 --> 00:21:41.680
numerical tower,

00:21:41.780 --> 00:21:42.020
right?

00:21:42.240 --> 00:21:42.560
Yeah, there

00:21:42.560 --> 00:21:42.920
are different

00:21:42.920 --> 00:21:43.560
towers too.

00:21:43.760 --> 00:21:44.540
In Python, there's

00:21:44.540 --> 00:21:45.100
also this thing

00:21:45.100 --> 00:21:45.680
called a numbers

00:21:45.680 --> 00:21:46.920
module that you

00:21:46.920 --> 00:21:48.080
have there, that's

00:21:48.080 --> 00:21:48.920
just basically

00:21:48.920 --> 00:21:49.420
ignored by the

00:21:49.420 --> 00:21:49.920
type system.

00:21:50.140 --> 00:21:50.520
It's been

00:21:50.520 --> 00:21:51.100
useful for some

00:21:51.100 --> 00:21:51.660
people, I feel

00:21:51.660 --> 00:21:52.060
like in general

00:21:52.060 --> 00:21:52.980
that module just

00:21:52.980 --> 00:21:53.780
hasn't worked out

00:21:53.780 --> 00:21:54.320
very well as

00:21:54.320 --> 00:21:54.740
being very

00:21:54.740 --> 00:21:55.060
useful.

00:21:55.260 --> 00:21:55.840
I think the

00:21:55.840 --> 00:21:56.700
interesting aspect

00:21:56.700 --> 00:21:58.080
is that you

00:21:58.080 --> 00:21:58.560
know, that you

00:21:58.560 --> 00:21:59.840
can say it's a

00:21:59.840 --> 00:22:00.580
float, and that's

00:22:00.580 --> 00:22:01.480
basically equivalent

00:22:01.480 --> 00:22:02.860
to union of

00:22:02.860 --> 00:22:03.540
integer and

00:22:03.540 --> 00:22:04.800
float, and so

00:22:04.800 --> 00:22:05.280
on, right?

00:22:05.340 --> 00:22:05.880
I think the

00:22:05.880 --> 00:22:07.520
typing numbers in

00:22:07.520 --> 00:22:08.180
Python is pretty

00:22:08.180 --> 00:22:08.540
interesting.

00:22:08.760 --> 00:22:09.300
I think every

00:22:09.300 --> 00:22:10.740
type checker has

00:22:10.740 --> 00:22:11.160
a different

00:22:11.160 --> 00:22:12.640
interpretation of

00:22:12.640 --> 00:22:13.680
what a float

00:22:13.680 --> 00:22:14.600
annotation actually

00:22:14.600 --> 00:22:14.960
means.

00:22:16.020 --> 00:22:17.100
It's an area of

00:22:17.100 --> 00:22:18.160
some lack of

00:22:18.160 --> 00:22:18.780
clarity in the

00:22:18.780 --> 00:22:19.020
spec.

00:22:19.140 --> 00:22:19.660
Yeah, a lot of

00:22:19.660 --> 00:22:20.340
contentiousness.

00:22:20.480 --> 00:22:21.740
If we could go

00:22:21.740 --> 00:22:22.960
back in time, I

00:22:22.960 --> 00:22:23.760
would, like,

00:22:23.780 --> 00:22:24.380
knowing what I

00:22:24.380 --> 00:22:24.940
know now, I

00:22:24.940 --> 00:22:25.660
probably advocate

00:22:25.660 --> 00:22:26.420
for things being

00:22:26.420 --> 00:22:27.520
done differently

00:22:27.520 --> 00:22:28.540
because, like,

00:22:28.700 --> 00:22:29.820
beginning, you

00:22:29.820 --> 00:22:30.440
know, like, there

00:22:30.440 --> 00:22:31.440
were multiple

00:22:31.440 --> 00:22:32.700
things, like, with

00:22:32.700 --> 00:22:33.460
similar flavor.

00:22:33.660 --> 00:22:34.180
Like, there was

00:22:34.180 --> 00:22:35.420
also one where

00:22:35.420 --> 00:22:36.480
you could give

00:22:36.480 --> 00:22:37.940
a parameter a

00:22:37.940 --> 00:22:38.480
non-none

00:22:38.480 --> 00:22:39.320
annotation and

00:22:39.320 --> 00:22:40.340
default it to

00:22:40.340 --> 00:22:40.800
none for

00:22:40.800 --> 00:22:41.700
convenience, and

00:22:41.700 --> 00:22:42.220
we've largely,

00:22:42.360 --> 00:22:43.420
like, moved away

00:22:43.420 --> 00:22:44.120
from stuff like

00:22:44.120 --> 00:22:44.740
that in favor of

00:22:44.740 --> 00:22:45.680
explicitness.

00:22:46.060 --> 00:22:46.540
Yeah, what the

00:22:46.540 --> 00:22:47.360
current spec says

00:22:47.360 --> 00:22:48.300
is that basically

00:22:48.300 --> 00:22:48.960
if you have a

00:22:48.960 --> 00:22:49.540
function that takes

00:22:49.540 --> 00:22:50.640
a float, you're

00:22:50.640 --> 00:22:51.320
also allowed to

00:22:51.320 --> 00:22:51.940
pass an int.

00:22:52.440 --> 00:22:53.480
That's not

00:22:53.480 --> 00:22:54.160
really enough.

00:22:54.260 --> 00:22:54.820
It doesn't tell

00:22:54.820 --> 00:22:55.620
you how these

00:22:55.620 --> 00:22:56.320
things work in

00:22:56.320 --> 00:22:57.800
all cases, and

00:22:57.800 --> 00:22:59.040
we've had some

00:22:59.040 --> 00:23:00.140
attempts to try to

00:23:00.140 --> 00:23:01.280
come up with a

00:23:01.280 --> 00:23:02.220
way to specify

00:23:02.220 --> 00:23:03.440
that special case

00:23:03.440 --> 00:23:04.160
in a way that

00:23:04.160 --> 00:23:05.360
makes more sense,

00:23:05.560 --> 00:23:06.020
at least makes

00:23:06.020 --> 00:23:06.700
more sense to me.

00:23:07.080 --> 00:23:07.740
It's been very

00:23:07.740 --> 00:23:08.260
contentious.

00:23:08.460 --> 00:23:09.040
People have very

00:23:09.040 --> 00:23:09.600
strong opinions

00:23:09.600 --> 00:23:10.220
about this.

00:23:10.400 --> 00:23:11.340
I guess non-obvious

00:23:11.340 --> 00:23:12.180
is what I'd like to

00:23:12.180 --> 00:23:12.760
say, really,

00:23:12.980 --> 00:23:13.320
honestly.

00:23:13.760 --> 00:23:15.000
So I'd like to get

00:23:15.000 --> 00:23:16.060
the official

00:23:16.060 --> 00:23:17.120
counsel's thoughts

00:23:17.120 --> 00:23:17.560
on this.

00:23:17.760 --> 00:23:18.620
When is typing

00:23:18.620 --> 00:23:19.960
too much typing?

00:23:20.440 --> 00:23:21.380
I made the joke

00:23:21.380 --> 00:23:22.300
about C++,

00:23:22.600 --> 00:23:23.700
ATL, if you've

00:23:23.700 --> 00:23:24.200
ever worked with

00:23:24.200 --> 00:23:24.820
that, it's like

00:23:24.820 --> 00:23:27.100
a template class

00:23:27.100 --> 00:23:28.020
where templated

00:23:28.020 --> 00:23:28.940
classes are part

00:23:28.940 --> 00:23:29.540
of the concrete

00:23:29.540 --> 00:23:30.220
type of the

00:23:30.220 --> 00:23:30.440
template.

00:23:30.560 --> 00:23:31.600
It's just off

00:23:31.600 --> 00:23:32.020
the hook.

00:23:32.400 --> 00:23:32.900
There's certainly

00:23:32.900 --> 00:23:33.740
places where

00:23:33.740 --> 00:23:34.880
typing can be

00:23:34.880 --> 00:23:36.180
too much, and

00:23:36.180 --> 00:23:37.220
a lot of the

00:23:37.220 --> 00:23:38.640
purity of Python

00:23:38.640 --> 00:23:40.240
or the readability

00:23:40.240 --> 00:23:41.320
of Python is the

00:23:41.320 --> 00:23:42.460
fact that it's

00:23:42.460 --> 00:23:43.320
got so few

00:23:43.320 --> 00:23:43.740
symbols.

00:23:44.260 --> 00:23:44.700
And so adding

00:23:44.700 --> 00:23:45.700
types adds

00:23:45.700 --> 00:23:46.460
context, but it

00:23:46.460 --> 00:23:47.920
also makes it

00:23:47.920 --> 00:23:48.260
a little harder

00:23:48.260 --> 00:23:48.700
to read.

00:23:49.060 --> 00:23:49.960
When is too

00:23:49.960 --> 00:23:50.520
much typing?

00:23:50.960 --> 00:23:51.460
When do you

00:23:51.460 --> 00:23:52.320
recommend typing?

00:23:53.320 --> 00:23:54.120
Rebecca, I'll

00:23:54.120 --> 00:23:54.820
let you go first,

00:23:54.940 --> 00:23:55.840
but what are your

00:23:55.840 --> 00:23:57.060
thoughts on how

00:23:57.060 --> 00:23:57.980
much typing should

00:23:57.980 --> 00:23:58.760
I use in Python?

00:23:59.040 --> 00:24:00.380
I'll give you

00:24:00.380 --> 00:24:01.420
what is my

00:24:01.420 --> 00:24:03.160
official stance,

00:24:03.260 --> 00:24:03.940
which is that if

00:24:03.940 --> 00:24:04.460
you want your

00:24:04.460 --> 00:24:05.240
type checker to

00:24:05.240 --> 00:24:06.500
work well, you

00:24:06.500 --> 00:24:07.460
should type

00:24:07.460 --> 00:24:08.160
annotate your

00:24:08.160 --> 00:24:09.320
API boundaries.

00:24:09.880 --> 00:24:10.500
So parameters

00:24:10.500 --> 00:24:11.260
and turns in

00:24:11.260 --> 00:24:12.060
public functions,

00:24:12.340 --> 00:24:12.840
public class

00:24:12.840 --> 00:24:14.000
attributes, things

00:24:14.000 --> 00:24:14.900
like that, and

00:24:14.900 --> 00:24:15.980
even things that

00:24:15.980 --> 00:24:16.440
seem true

00:24:16.460 --> 00:24:17.200
trivial, like,

00:24:17.300 --> 00:24:17.560
oh, this

00:24:17.560 --> 00:24:18.900
function returns

00:24:18.900 --> 00:24:20.160
none, better

00:24:20.160 --> 00:24:21.400
to annotate

00:24:21.400 --> 00:24:22.040
it because, you

00:24:22.040 --> 00:24:22.540
know, someone

00:24:22.540 --> 00:24:23.080
else might be

00:24:23.080 --> 00:24:24.120
depending on

00:24:24.120 --> 00:24:25.080
your library and

00:24:25.080 --> 00:24:25.700
consuming that

00:24:25.700 --> 00:24:26.080
type of

00:24:26.080 --> 00:24:26.600
information.

00:24:27.120 --> 00:24:27.780
I will say

00:24:27.780 --> 00:24:29.040
personally, what

00:24:29.040 --> 00:24:29.900
I tend to do

00:24:29.900 --> 00:24:31.760
is I annotate

00:24:31.760 --> 00:24:32.420
things that I

00:24:32.420 --> 00:24:32.900
think are

00:24:32.900 --> 00:24:33.680
non-trivial

00:24:33.680 --> 00:24:34.480
because I want

00:24:34.480 --> 00:24:35.160
to see that

00:24:35.160 --> 00:24:36.440
as documentation.

00:24:37.400 --> 00:24:38.020
And if

00:24:38.020 --> 00:24:39.080
something, you

00:24:39.080 --> 00:24:39.540
know, a

00:24:39.540 --> 00:24:39.900
function that

00:24:39.900 --> 00:24:40.560
does return

00:24:40.560 --> 00:24:41.540
none, to be

00:24:41.540 --> 00:24:42.040
honest, I will

00:24:42.040 --> 00:24:42.600
probably forget

00:24:42.600 --> 00:24:43.460
to annotate it

00:24:43.460 --> 00:24:44.340
half the time

00:24:44.340 --> 00:24:45.260
because I'll

00:24:45.260 --> 00:24:46.060
be like, I

00:24:46.060 --> 00:24:46.700
honestly don't

00:24:46.700 --> 00:24:47.220
need to see

00:24:47.220 --> 00:24:47.460
it.

00:24:47.660 --> 00:24:48.500
One of the

00:24:48.500 --> 00:24:49.940
interesting features

00:24:49.940 --> 00:24:50.760
of the

00:24:50.760 --> 00:24:52.440
Pyrefly VS

00:24:52.440 --> 00:24:53.240
Code extension,

00:24:53.380 --> 00:24:53.840
that's the only

00:24:53.840 --> 00:24:54.540
one I can speak

00:24:54.540 --> 00:24:54.920
of at the

00:24:54.920 --> 00:24:55.300
moment, and

00:24:55.300 --> 00:24:55.740
Carl, you've

00:24:55.740 --> 00:24:56.080
got to tell

00:24:56.080 --> 00:24:56.860
me if the

00:24:56.860 --> 00:24:58.000
TY one does

00:24:58.000 --> 00:24:58.600
this as well,

00:24:59.040 --> 00:24:59.580
is it will

00:24:59.580 --> 00:25:00.440
sort of overlay

00:25:00.440 --> 00:25:02.440
its belief of

00:25:02.440 --> 00:25:03.240
what types

00:25:03.240 --> 00:25:03.580
are.

00:25:03.960 --> 00:25:04.280
Like, if

00:25:04.280 --> 00:25:05.060
there's, you

00:25:05.060 --> 00:25:06.080
say x equals a

00:25:06.080 --> 00:25:06.560
function return

00:25:06.560 --> 00:25:07.180
value and it

00:25:07.180 --> 00:25:07.700
knows what the

00:25:07.700 --> 00:25:08.340
function returns,

00:25:08.440 --> 00:25:08.900
it'll have a

00:25:08.900 --> 00:25:09.520
gray, like,

00:25:09.680 --> 00:25:10.580
colon int, if

00:25:10.580 --> 00:25:11.200
it returned an

00:25:11.200 --> 00:25:11.820
int or something.

00:25:11.820 --> 00:25:12.620
So you can

00:25:12.620 --> 00:25:14.120
kind of read

00:25:14.120 --> 00:25:15.140
the code and

00:25:15.140 --> 00:25:15.600
see what the

00:25:15.600 --> 00:25:16.200
types are without

00:25:16.200 --> 00:25:17.060
actually putting

00:25:17.060 --> 00:25:18.040
it into the

00:25:18.040 --> 00:25:18.720
text of the

00:25:18.720 --> 00:25:18.980
code.

00:25:19.080 --> 00:25:19.580
It's only within

00:25:19.580 --> 00:25:20.120
the editor.

00:25:20.520 --> 00:25:21.080
Does ty do

00:25:21.080 --> 00:25:21.460
something like

00:25:21.460 --> 00:25:21.840
that, Carl?

00:25:22.040 --> 00:25:22.860
Yes, we also

00:25:22.860 --> 00:25:23.560
have inlay type

00:25:23.560 --> 00:25:23.800
ins.

00:25:23.900 --> 00:25:24.400
Yeah, inlay type

00:25:24.400 --> 00:25:24.800
ins, that's

00:25:24.800 --> 00:25:25.200
what it's called.

00:25:25.500 --> 00:25:26.060
So, yeah, I

00:25:26.060 --> 00:25:26.400
don't know, that

00:25:26.400 --> 00:25:27.420
also brings an

00:25:27.420 --> 00:25:28.300
interesting challenge,

00:25:28.400 --> 00:25:28.880
not a challenge,

00:25:28.960 --> 00:25:30.160
like a wrinkle to

00:25:30.160 --> 00:25:31.460
the recommendation

00:25:31.460 --> 00:25:33.640
of should I put

00:25:33.640 --> 00:25:34.360
types on, like,

00:25:34.400 --> 00:25:35.180
the return value

00:25:35.180 --> 00:25:35.780
because I want to

00:25:35.780 --> 00:25:36.280
know that's a

00:25:36.280 --> 00:25:36.920
list of user,

00:25:37.040 --> 00:25:37.880
not a list of

00:25:37.880 --> 00:25:38.880
user IDs or

00:25:38.880 --> 00:25:39.320
whatever, for

00:25:39.320 --> 00:25:39.940
example, like a

00:25:39.940 --> 00:25:40.780
list of UUID.

00:25:41.220 --> 00:25:41.580
But if,

00:25:41.820 --> 00:25:42.340
it's going to

00:25:42.340 --> 00:25:43.000
show up anyway

00:25:43.000 --> 00:25:43.660
in the editor,

00:25:44.160 --> 00:25:44.740
maybe I don't

00:25:44.740 --> 00:25:45.280
have to write

00:25:45.280 --> 00:25:45.780
that, right?

00:25:45.840 --> 00:25:46.220
And so that

00:25:46.220 --> 00:25:47.260
becomes sort of

00:25:47.260 --> 00:25:48.260
somewhere where

00:25:48.260 --> 00:25:49.000
you could debate

00:25:49.000 --> 00:25:49.680
again, I think.

00:25:50.120 --> 00:25:51.160
However, I do

00:25:51.160 --> 00:25:52.280
100% agree with

00:25:52.280 --> 00:25:53.040
you, Rebecca, that

00:25:53.040 --> 00:25:53.760
put it on your

00:25:53.760 --> 00:25:54.560
API boundaries.

00:25:54.740 --> 00:25:55.560
If, like, this

00:25:55.560 --> 00:25:56.600
is the place that

00:25:56.600 --> 00:25:57.500
people get into

00:25:57.500 --> 00:25:58.340
some part of your

00:25:58.340 --> 00:25:58.820
code and they

00:25:58.820 --> 00:25:59.700
don't know or

00:25:59.700 --> 00:26:00.380
want to know about

00:26:00.380 --> 00:26:01.120
the inside of it,

00:26:01.500 --> 00:26:02.460
having types there

00:26:02.460 --> 00:26:03.360
is really helpful

00:26:03.360 --> 00:26:04.440
both for editors,

00:26:04.960 --> 00:26:05.800
for type checkers,

00:26:05.840 --> 00:26:06.480
and just for

00:26:06.480 --> 00:26:07.300
reading code, and

00:26:07.300 --> 00:26:08.360
even for AI, which

00:26:08.360 --> 00:26:09.240
is a crazy world.

00:26:09.580 --> 00:26:09.680
Yeah.

00:26:09.900 --> 00:26:10.220
Carl?

00:26:10.220 --> 00:26:11.000
What are your

00:26:11.000 --> 00:26:11.400
thoughts here?

00:26:11.460 --> 00:26:12.180
How much typing is

00:26:12.180 --> 00:26:12.760
too much typing?

00:26:13.200 --> 00:26:13.780
What's the

00:26:13.780 --> 00:26:14.580
guidelines here?

00:26:14.680 --> 00:26:15.240
I think I agree

00:26:15.240 --> 00:26:15.800
with Rebecca's

00:26:15.800 --> 00:26:16.100
answer.

00:26:16.280 --> 00:26:17.120
I mean, that one

00:26:17.120 --> 00:26:17.740
place you definitely

00:26:17.740 --> 00:26:18.740
want to have

00:26:18.740 --> 00:26:19.840
explicit type

00:26:19.840 --> 00:26:21.100
annotations is that

00:26:21.100 --> 00:26:22.140
API boundaries,

00:26:22.420 --> 00:26:23.300
the public API of

00:26:23.300 --> 00:26:24.120
a library, etc.

00:26:24.120 --> 00:26:25.680
In terms of what's

00:26:25.680 --> 00:26:26.660
too much typing, I

00:26:26.660 --> 00:26:27.220
mean, there are

00:26:27.220 --> 00:26:28.320
certainly patterns

00:26:28.320 --> 00:26:28.900
that have

00:26:28.900 --> 00:26:29.740
historically been

00:26:29.740 --> 00:26:31.280
used in Python

00:26:31.280 --> 00:26:32.380
that we still

00:26:32.380 --> 00:26:34.060
can't express well

00:26:34.060 --> 00:26:34.540
in the type

00:26:34.540 --> 00:26:35.580
system, or that

00:26:35.580 --> 00:26:36.480
require extremely

00:26:36.480 --> 00:26:37.680
complex type

00:26:37.680 --> 00:26:39.240
annotations to

00:26:39.240 --> 00:26:40.020
express well, and

00:26:40.020 --> 00:26:40.640
I think there it

00:26:40.640 --> 00:26:41.720
becomes a judgment

00:26:41.720 --> 00:26:42.140
call.

00:26:43.020 --> 00:26:44.420
If it's like a

00:26:44.420 --> 00:26:45.220
core, widely

00:26:45.220 --> 00:26:46.540
used API, you

00:26:46.540 --> 00:26:47.620
may get a lot of

00:26:47.620 --> 00:26:48.940
benefit from some

00:26:48.940 --> 00:26:50.020
very complex and

00:26:50.020 --> 00:26:51.020
verbose annotations,

00:26:51.440 --> 00:26:52.100
and so then it's

00:26:52.100 --> 00:26:53.140
worth sort of going

00:26:53.140 --> 00:26:53.940
through that pain

00:26:53.940 --> 00:26:55.020
and the pain of

00:26:55.020 --> 00:26:55.660
adding them and

00:26:55.660 --> 00:26:56.960
of reading them in

00:26:56.960 --> 00:26:57.700
order to get that

00:26:57.700 --> 00:26:59.000
additional typing

00:26:59.000 --> 00:27:00.020
coverage everywhere you

00:27:00.020 --> 00:27:00.820
use that API.

00:27:01.120 --> 00:27:02.340
If it's much less

00:27:02.340 --> 00:27:03.400
frequently used code

00:27:03.400 --> 00:27:04.280
that's highly dynamic,

00:27:04.720 --> 00:27:05.520
maybe it's not worth

00:27:05.520 --> 00:27:06.280
it in that case.

00:27:06.620 --> 00:27:07.140
I think there's a lot

00:27:07.140 --> 00:27:07.780
of judgment calls

00:27:07.780 --> 00:27:07.960
here.

00:27:08.140 --> 00:27:08.960
What about like

00:27:08.960 --> 00:27:10.200
one-off scripts?

00:27:10.680 --> 00:27:11.140
You know, I'm going

00:27:11.140 --> 00:27:11.940
to write this thing to

00:27:11.940 --> 00:27:12.940
just move this data

00:27:12.940 --> 00:27:13.580
from here to there,

00:27:13.620 --> 00:27:14.220
and once it's moved,

00:27:14.280 --> 00:27:15.020
I don't need it again.

00:27:15.120 --> 00:27:16.160
It's done with that

00:27:16.160 --> 00:27:16.700
old system, we're

00:27:16.700 --> 00:27:17.260
going to the new

00:27:17.260 --> 00:27:17.460
one.

00:27:17.800 --> 00:27:18.660
Maybe less typing.

00:27:18.820 --> 00:27:19.080
Yeah, I think

00:27:19.080 --> 00:27:20.040
that's what's useful

00:27:20.040 --> 00:27:20.600
for you.

00:27:20.980 --> 00:27:21.780
Often I feel like

00:27:21.780 --> 00:27:22.420
one-off scripts are

00:27:22.420 --> 00:27:23.120
not really one-off

00:27:23.140 --> 00:27:23.880
like maybe you

00:27:23.880 --> 00:27:24.500
want to move some

00:27:24.500 --> 00:27:25.460
similar data later,

00:27:25.620 --> 00:27:26.260
and then it's useful

00:27:26.260 --> 00:27:27.160
if you can understand

00:27:27.160 --> 00:27:27.800
your code again,

00:27:27.860 --> 00:27:29.040
if you want to

00:27:29.040 --> 00:27:29.600
read what you did.

00:27:29.720 --> 00:27:30.140
You thought you

00:27:30.140 --> 00:27:30.880
didn't need it again,

00:27:30.940 --> 00:27:31.760
and all of a sudden

00:27:31.760 --> 00:27:32.500
at six months old,

00:27:32.540 --> 00:27:33.220
you don't understand

00:27:33.220 --> 00:27:34.540
it, and the types

00:27:34.540 --> 00:27:35.060
that help a lot,

00:27:35.100 --> 00:27:35.260
right?

00:27:35.560 --> 00:27:35.720
Yeah.

00:27:36.160 --> 00:27:36.780
Yellow, what's

00:27:36.780 --> 00:27:38.280
your advice?

00:27:38.540 --> 00:27:39.060
What Cara and

00:27:39.060 --> 00:27:39.480
Rebecca said

00:27:39.480 --> 00:27:40.240
makes sense to me

00:27:40.240 --> 00:27:40.440
too.

00:27:40.840 --> 00:27:41.480
I think types

00:27:41.480 --> 00:27:42.460
have advantages

00:27:42.460 --> 00:27:43.340
in terms of

00:27:43.340 --> 00:27:44.240
documenting humor

00:27:44.240 --> 00:27:45.120
readers, what

00:27:45.120 --> 00:27:46.180
is going on,

00:27:46.400 --> 00:27:47.040
and in terms of

00:27:47.040 --> 00:27:47.940
catching mistakes

00:27:47.940 --> 00:27:48.500
that otherwise

00:27:48.500 --> 00:27:49.160
would not be

00:27:49.160 --> 00:27:49.720
caught until

00:27:49.720 --> 00:27:50.740
runtime perhaps.

00:27:51.160 --> 00:27:51.680
They have costs

00:27:51.680 --> 00:27:52.340
in maybe making

00:27:52.340 --> 00:27:52.880
your code harder

00:27:52.880 --> 00:27:53.500
to read if

00:27:53.500 --> 00:27:54.020
there's too much

00:27:54.020 --> 00:27:54.580
going on.

00:27:54.940 --> 00:27:55.740
So add types

00:27:55.740 --> 00:27:56.140
as long as

00:27:56.140 --> 00:27:56.720
those benefits

00:27:56.720 --> 00:27:57.240
outweigh the

00:27:57.240 --> 00:27:57.560
costs.

00:27:57.760 --> 00:27:57.940
Yeah.

00:27:58.420 --> 00:27:59.100
I mean, do you

00:27:59.100 --> 00:27:59.780
recommend to

00:27:59.780 --> 00:28:01.060
anyone that they

00:28:01.060 --> 00:28:03.620
just 100% go full

00:28:03.620 --> 00:28:04.600
like C++,

00:28:04.840 --> 00:28:05.600
C# on it,

00:28:05.660 --> 00:28:06.620
and just type it

00:28:06.620 --> 00:28:07.740
every single thing?

00:28:08.080 --> 00:28:08.740
Is there an

00:28:08.740 --> 00:28:10.060
advantage like for

00:28:10.060 --> 00:28:11.100
static type checkers,

00:28:11.240 --> 00:28:11.540
you know, like

00:28:11.540 --> 00:28:12.400
mypy type stuff

00:28:12.400 --> 00:28:13.320
you can run across

00:28:13.320 --> 00:28:14.680
and get that?

00:28:14.780 --> 00:28:15.040
I mean, you could

00:28:15.040 --> 00:28:15.420
do that with

00:28:15.420 --> 00:28:16.160
Powerfly or TY

00:28:16.160 --> 00:28:17.260
and the CLI as

00:28:17.260 --> 00:28:18.140
well, but you know,

00:28:18.400 --> 00:28:19.340
thinking more mypy

00:28:19.340 --> 00:28:19.980
is like kind of

00:28:19.980 --> 00:28:20.640
being real strict

00:28:20.640 --> 00:28:21.200
on some of that

00:28:21.200 --> 00:28:21.500
stuff.

00:28:21.580 --> 00:28:22.140
Personally, I do

00:28:22.140 --> 00:28:23.140
tend to annotate

00:28:23.140 --> 00:28:23.880
almost all like

00:28:23.880 --> 00:28:24.700
function parameters

00:28:24.700 --> 00:28:26.240
and if class

00:28:26.240 --> 00:28:27.060
attributes, if I

00:28:27.060 --> 00:28:27.760
make a class,

00:28:28.100 --> 00:28:28.680
sometimes it's not

00:28:28.680 --> 00:28:29.560
as necessary,

00:28:29.740 --> 00:28:30.640
like you don't

00:28:30.640 --> 00:28:30.980
really need to

00:28:30.980 --> 00:28:31.400
annotate your

00:28:31.400 --> 00:28:32.060
tests perhaps,

00:28:32.220 --> 00:28:32.560
or you don't

00:28:32.560 --> 00:28:33.080
need to annotate

00:28:33.080 --> 00:28:33.800
internal functions

00:28:33.800 --> 00:28:34.840
as much, but

00:28:34.840 --> 00:28:35.680
for my own

00:28:35.680 --> 00:28:36.460
coding, I usually

00:28:36.460 --> 00:28:36.960
find it helpful

00:28:36.960 --> 00:28:37.540
to do that.

00:28:37.900 --> 00:28:39.200
But sometimes I

00:28:39.200 --> 00:28:39.540
see people

00:28:39.540 --> 00:28:40.220
annotating even

00:28:40.220 --> 00:28:41.000
local variables

00:28:41.000 --> 00:28:41.760
where it's very

00:28:41.760 --> 00:28:42.460
obvious to type

00:28:42.460 --> 00:28:43.100
check if the type

00:28:43.100 --> 00:28:44.040
is and they can

00:28:44.040 --> 00:28:44.600
just infer it

00:28:44.600 --> 00:28:46.000
reliably, and then

00:28:46.000 --> 00:28:46.860
it really just

00:28:46.860 --> 00:28:47.580
adds noise and

00:28:47.580 --> 00:28:48.140
you shouldn't do

00:28:48.140 --> 00:28:48.340
it.

00:28:48.500 --> 00:28:48.960
Yeah, exactly.

00:28:48.960 --> 00:28:49.620
If you've got a

00:28:49.620 --> 00:28:50.160
function that's

00:28:50.160 --> 00:28:50.860
annotated with a

00:28:50.860 --> 00:28:51.660
return value and

00:28:51.660 --> 00:28:53.020
you say x equals

00:28:53.020 --> 00:28:53.900
the function call,

00:28:54.320 --> 00:28:55.020
then the type

00:28:55.020 --> 00:28:55.740
checkers can infer

00:28:55.740 --> 00:28:56.560
that and you're

00:28:56.560 --> 00:28:57.560
just causing

00:28:57.560 --> 00:28:59.560
extra noise, I

00:28:59.560 --> 00:28:59.820
guess.

00:29:00.240 --> 00:29:01.400
So suppose you

00:29:01.400 --> 00:29:02.200
all want to

00:29:02.200 --> 00:29:03.640
change something.

00:29:03.960 --> 00:29:04.880
What's the process

00:29:04.880 --> 00:29:05.640
of actually going

00:29:05.640 --> 00:29:06.700
through and making

00:29:06.700 --> 00:29:07.420
some changes?

00:29:08.280 --> 00:29:09.000
Mostly sort of

00:29:09.000 --> 00:29:09.800
two levels of

00:29:09.800 --> 00:29:10.100
this.

00:29:10.400 --> 00:29:10.860
Well, maybe

00:29:10.860 --> 00:29:11.120
there's even

00:29:11.120 --> 00:29:11.660
three levels.

00:29:11.780 --> 00:29:12.320
The first one is

00:29:12.320 --> 00:29:12.780
if it's something

00:29:12.780 --> 00:29:13.580
that's so small

00:29:13.580 --> 00:29:14.500
that's just like

00:29:14.500 --> 00:29:15.100
a wording

00:29:15.100 --> 00:29:15.860
clarification or

00:29:15.860 --> 00:29:16.540
something, we

00:29:16.540 --> 00:29:17.120
just make a PR

00:29:17.120 --> 00:29:18.420
to the repo and

00:29:18.420 --> 00:29:19.220
a few of us

00:29:19.220 --> 00:29:20.040
look at it and

00:29:20.040 --> 00:29:20.740
we change it.

00:29:21.000 --> 00:29:21.640
The second level

00:29:21.640 --> 00:29:22.420
is when it's sort

00:29:22.420 --> 00:29:22.940
of a smaller

00:29:22.940 --> 00:29:24.180
change that

00:29:24.180 --> 00:29:25.200
doesn't really

00:29:25.200 --> 00:29:25.860
introduce a new

00:29:25.860 --> 00:29:26.680
feature and then

00:29:26.680 --> 00:29:28.220
we make a PR

00:29:28.220 --> 00:29:28.800
to the typing

00:29:28.800 --> 00:29:30.200
spec repo and

00:29:30.200 --> 00:29:31.140
we formally have

00:29:31.140 --> 00:29:31.900
all of us sign

00:29:31.900 --> 00:29:32.380
off on it.

00:29:32.740 --> 00:29:33.360
That's what

00:29:33.360 --> 00:29:34.040
happens like

00:29:34.040 --> 00:29:34.560
what Carl

00:29:34.560 --> 00:29:35.120
mentioned earlier

00:29:35.120 --> 00:29:35.800
of the final

00:29:35.800 --> 00:29:37.140
change in data

00:29:37.140 --> 00:29:37.680
classes.

00:29:37.860 --> 00:29:38.440
It's had to

00:29:38.440 --> 00:29:39.480
merge this one,

00:29:39.620 --> 00:29:40.300
yeah, add

00:29:40.300 --> 00:29:40.580
Carl.

00:29:41.900 --> 00:29:42.740
I love it.

00:29:42.840 --> 00:29:43.580
This repo itself

00:29:43.580 --> 00:29:44.040
doesn't have

00:29:44.040 --> 00:29:44.520
anything.

00:29:44.980 --> 00:29:45.460
It's the

00:29:45.460 --> 00:29:46.160
Python typing

00:29:46.160 --> 00:29:47.400
repo where the

00:29:47.400 --> 00:29:48.160
decisions are

00:29:48.160 --> 00:29:48.420
made.

00:29:48.840 --> 00:29:49.160
The typing

00:29:49.160 --> 00:29:49.800
council just

00:29:49.800 --> 00:29:50.800
has like some

00:29:50.800 --> 00:29:51.560
documentation.

00:29:52.420 --> 00:29:52.560
Yeah.

00:29:52.840 --> 00:29:53.240
And then the

00:29:53.240 --> 00:29:53.780
third level is

00:29:53.780 --> 00:29:54.580
peps, like really

00:29:54.580 --> 00:29:55.480
big new changes.

00:29:55.620 --> 00:29:56.000
You can still

00:29:56.000 --> 00:29:56.920
write a PEP and

00:29:56.920 --> 00:29:57.880
then we make a

00:29:57.880 --> 00:29:58.680
recommendation and

00:29:58.680 --> 00:29:59.000
the steering

00:29:59.000 --> 00:29:59.720
council makes a

00:29:59.720 --> 00:30:00.480
decision eventually.

00:30:00.740 --> 00:30:01.380
So if I wanted

00:30:01.380 --> 00:30:01.920
to suggest

00:30:01.920 --> 00:30:02.940
something, I

00:30:02.940 --> 00:30:03.500
could come up

00:30:03.500 --> 00:30:04.100
here and I

00:30:04.100 --> 00:30:05.580
could open up

00:30:05.580 --> 00:30:06.500
an issue, maybe

00:30:06.500 --> 00:30:07.380
start a conversation

00:30:07.380 --> 00:30:08.540
on typing,

00:30:09.000 --> 00:30:09.840
Python slash

00:30:09.840 --> 00:30:10.120
typing.

00:30:10.280 --> 00:30:10.760
And you can make

00:30:10.760 --> 00:30:11.360
a pull request

00:30:11.360 --> 00:30:11.960
to change the

00:30:11.960 --> 00:30:12.240
spec.

00:30:12.240 --> 00:30:12.680
Okay.

00:30:12.900 --> 00:30:13.420
And so the

00:30:13.420 --> 00:30:13.940
pull request

00:30:13.940 --> 00:30:14.480
would not be

00:30:14.480 --> 00:30:15.640
to change the

00:30:15.640 --> 00:30:16.720
code, like

00:30:16.720 --> 00:30:17.340
how Python

00:30:17.340 --> 00:30:18.920
maybe interprets

00:30:18.920 --> 00:30:19.920
code that has

00:30:19.920 --> 00:30:20.600
this new thing,

00:30:20.700 --> 00:30:21.620
but to suggest

00:30:21.620 --> 00:30:22.240
that the spec

00:30:22.240 --> 00:30:22.760
has it, which

00:30:22.760 --> 00:30:23.680
then would start

00:30:23.680 --> 00:30:24.660
a process that

00:30:24.660 --> 00:30:25.420
ultimately might

00:30:25.420 --> 00:30:26.240
make CPython

00:30:26.240 --> 00:30:26.880
understand it,

00:30:26.920 --> 00:30:27.060
right?

00:30:27.120 --> 00:30:27.600
Well, CPython

00:30:27.600 --> 00:30:28.380
itself probably

00:30:28.380 --> 00:30:29.080
doesn't do

00:30:29.080 --> 00:30:29.720
anything with it.

00:30:30.220 --> 00:30:30.800
I guess most of

00:30:30.800 --> 00:30:31.120
the things that

00:30:31.120 --> 00:30:31.880
go directly here

00:30:31.880 --> 00:30:32.800
are changes to

00:30:32.800 --> 00:30:33.420
how to interpret

00:30:33.420 --> 00:30:33.960
things that are

00:30:33.960 --> 00:30:35.380
already in CPython.

00:30:37.140 --> 00:30:38.060
This portion of

00:30:38.060 --> 00:30:38.700
Talk Python To Me

00:30:38.700 --> 00:30:39.200
is brought to you

00:30:39.200 --> 00:30:39.860
by us.

00:30:40.380 --> 00:30:41.000
I want to tell

00:30:41.000 --> 00:30:42.020
you about a

00:30:42.020 --> 00:30:42.600
course I put

00:30:42.600 --> 00:30:43.160
together that

00:30:43.160 --> 00:30:44.160
I'm really proud

00:30:44.160 --> 00:30:45.360
of, Agentic

00:30:45.360 --> 00:30:46.340
AI Programming

00:30:46.340 --> 00:30:46.980
for Python

00:30:46.980 --> 00:30:47.620
Developers.

00:30:48.280 --> 00:30:49.160
I know a lot

00:30:49.160 --> 00:30:49.540
of you have

00:30:49.540 --> 00:30:50.560
tried AI coding

00:30:50.560 --> 00:30:51.280
tools and come

00:30:51.280 --> 00:30:51.900
away thinking,

00:30:52.260 --> 00:30:52.980
well, this is

00:30:52.980 --> 00:30:53.560
more hassle

00:30:53.560 --> 00:30:54.160
than it's worth.

00:30:54.520 --> 00:30:55.120
And honestly,

00:30:55.360 --> 00:30:56.200
all the vibe

00:30:56.200 --> 00:30:57.020
coding hype

00:30:57.020 --> 00:30:57.820
isn't helping.

00:30:58.080 --> 00:30:59.080
It's a smokescreen

00:30:59.080 --> 00:30:59.800
that hides what

00:30:59.800 --> 00:31:00.480
these tools can

00:31:00.480 --> 00:31:01.280
actually do.

00:31:01.640 --> 00:31:02.560
This course is

00:31:02.560 --> 00:31:03.320
about agentic

00:31:03.320 --> 00:31:04.080
engineering,

00:31:04.660 --> 00:31:05.540
applying real

00:31:05.540 --> 00:31:06.320
software engineering

00:31:06.320 --> 00:31:07.520
practices with AI

00:31:07.520 --> 00:31:08.260
that understands

00:31:08.260 --> 00:31:09.160
your entire code

00:31:09.160 --> 00:31:10.160
database, runs

00:31:10.160 --> 00:31:11.200
your tests, and

00:31:11.200 --> 00:31:12.080
builds complete

00:31:12.080 --> 00:31:13.100
features under

00:31:13.100 --> 00:31:13.720
your direction.

00:31:14.380 --> 00:31:14.960
I've used these

00:31:14.960 --> 00:31:15.760
techniques to ship

00:31:15.760 --> 00:31:17.120
real production code

00:31:17.120 --> 00:31:18.140
across Talk Python,

00:31:18.600 --> 00:31:19.520
Python Bytes, and

00:31:19.520 --> 00:31:20.180
completely new

00:31:20.180 --> 00:31:20.580
projects.

00:31:21.000 --> 00:31:21.840
I migrated an

00:31:21.840 --> 00:31:22.960
entire CSS framework

00:31:22.960 --> 00:31:23.660
on a production

00:31:23.660 --> 00:31:24.720
site with thousands

00:31:24.720 --> 00:31:25.900
of lines of HTML

00:31:25.900 --> 00:31:27.160
in a few hours,

00:31:27.580 --> 00:31:27.900
twice.

00:31:28.240 --> 00:31:29.360
I shipped a new

00:31:29.360 --> 00:31:30.280
search feature with

00:31:30.280 --> 00:31:31.580
caching and async

00:31:31.580 --> 00:31:32.500
in under an hour.

00:31:32.500 --> 00:31:33.820
I built a complete

00:31:33.820 --> 00:31:35.200
CLI tool for

00:31:35.200 --> 00:31:36.640
Talk Python from

00:31:36.640 --> 00:31:37.700
scratch, tested,

00:31:38.020 --> 00:31:38.780
documented, and

00:31:38.780 --> 00:31:40.400
published to PyPI in

00:31:40.400 --> 00:31:41.060
an afternoon.

00:31:41.580 --> 00:31:42.780
Real projects, real

00:31:42.780 --> 00:31:43.960
production code, both

00:31:43.960 --> 00:31:45.060
Greenfield and

00:31:45.060 --> 00:31:45.540
legacy.

00:31:46.020 --> 00:31:47.360
No toy demos, no

00:31:47.360 --> 00:31:47.660
fluff.

00:31:48.220 --> 00:31:48.980
I'll show you the

00:31:48.980 --> 00:31:49.940
guardrails, the

00:31:49.940 --> 00:31:50.880
planning techniques, and

00:31:50.880 --> 00:31:51.880
the workflows that

00:31:51.880 --> 00:31:53.000
turn AI into a

00:31:53.000 --> 00:31:53.980
genuine engineering

00:31:53.980 --> 00:31:54.360
partner.

00:31:54.960 --> 00:31:55.680
Check it out at

00:31:55.680 --> 00:31:56.620
talkpython.fm

00:31:56.620 --> 00:31:57.520
slash agentic

00:31:57.520 --> 00:31:58.420
dash engineering.

00:31:58.640 --> 00:32:00.280
That's talkpython.fm

00:32:00.280 --> 00:32:01.340
slash agentic dash

00:32:01.340 --> 00:32:01.780
engineering.

00:32:01.780 --> 00:32:02.880
The link is in your

00:32:02.880 --> 00:32:03.680
podcast player's

00:32:03.680 --> 00:32:04.120
show notes.

00:32:05.320 --> 00:32:06.180
If it's adding

00:32:06.180 --> 00:32:07.240
something new, it

00:32:07.240 --> 00:32:08.200
will usually need to

00:32:08.200 --> 00:32:08.940
go through a path,

00:32:09.040 --> 00:32:09.600
except if it's

00:32:09.600 --> 00:32:10.600
something very small.

00:32:10.680 --> 00:32:11.240
Let's talk about

00:32:11.240 --> 00:32:11.900
that for a minute.

00:32:11.980 --> 00:32:13.280
We got two

00:32:13.280 --> 00:32:14.720
representatives here

00:32:14.720 --> 00:32:15.740
of the newer

00:32:15.740 --> 00:32:17.000
breed of tools.

00:32:17.700 --> 00:32:18.780
What's the story

00:32:18.780 --> 00:32:21.100
for inconsistencies

00:32:21.100 --> 00:32:22.760
across interpretations

00:32:22.760 --> 00:32:23.540
of the spec?

00:32:23.620 --> 00:32:24.340
I know that there's

00:32:24.340 --> 00:32:25.080
slight variations.

00:32:25.680 --> 00:32:26.940
I've also, you

00:32:26.940 --> 00:32:27.940
know, not putting

00:32:27.940 --> 00:32:28.640
either of you on

00:32:28.640 --> 00:32:29.440
the spotlight, but

00:32:29.440 --> 00:32:31.040
like using, say,

00:32:31.040 --> 00:32:32.320
PyCharm and

00:32:32.320 --> 00:32:33.380
like writing code.

00:32:33.500 --> 00:32:34.140
So it's type

00:32:34.140 --> 00:32:35.760
checkers happy and

00:32:35.760 --> 00:32:36.520
then using something

00:32:36.520 --> 00:32:37.780
like Pyright.

00:32:37.980 --> 00:32:39.320
And so it has a

00:32:39.320 --> 00:32:39.940
real different

00:32:39.940 --> 00:32:41.100
interpretation of

00:32:41.100 --> 00:32:42.160
what you should let

00:32:42.160 --> 00:32:42.860
slide and what you

00:32:42.860 --> 00:32:43.140
shouldn't.

00:32:43.200 --> 00:32:43.820
I feel like Pyright

00:32:43.820 --> 00:32:45.400
is more, much more

00:32:45.400 --> 00:32:47.300
focused on like

00:32:47.300 --> 00:32:48.200
enforcing the

00:32:48.200 --> 00:32:49.880
nullability and or

00:32:49.880 --> 00:32:50.660
the lack thereof.

00:32:50.700 --> 00:32:51.860
And it warns of

00:32:51.860 --> 00:32:52.960
inconsistencies there

00:32:52.960 --> 00:32:53.800
where PyCharm doesn't

00:32:53.800 --> 00:32:54.680
seem to care as much.

00:32:54.980 --> 00:32:55.500
I don't know which

00:32:55.500 --> 00:32:56.180
one I like better,

00:32:56.260 --> 00:32:56.780
but I know they're

00:32:56.780 --> 00:32:57.120
different.

00:32:57.120 --> 00:32:57.980
And if I write code

00:32:57.980 --> 00:32:58.480
in one that I

00:32:58.480 --> 00:32:59.220
open the other, I'm

00:32:59.220 --> 00:33:00.300
like, huh, why is it

00:33:00.300 --> 00:33:00.580
upset?

00:33:00.720 --> 00:33:01.480
It seemed like it

00:33:01.480 --> 00:33:01.900
was fine.

00:33:02.180 --> 00:33:02.540
How do you all

00:33:02.540 --> 00:33:03.100
navigate this?

00:33:03.260 --> 00:33:03.380
Yeah.

00:33:03.560 --> 00:33:04.580
One thing useful to

00:33:04.580 --> 00:33:05.480
say about the spec

00:33:05.480 --> 00:33:06.360
there is that the

00:33:06.360 --> 00:33:07.780
spec covers a lot of

00:33:07.780 --> 00:33:08.060
things.

00:33:08.160 --> 00:33:08.900
In particular, it

00:33:08.900 --> 00:33:09.740
tends to cover sort

00:33:09.740 --> 00:33:10.860
of the details of

00:33:10.860 --> 00:33:11.740
more advanced type

00:33:11.740 --> 00:33:12.560
system features.

00:33:12.940 --> 00:33:13.580
But there's a lot of

00:33:13.580 --> 00:33:14.980
very fundamental

00:33:14.980 --> 00:33:16.560
stuff about how a

00:33:16.560 --> 00:33:17.460
type checker works

00:33:17.460 --> 00:33:18.900
in terms of how it

00:33:18.900 --> 00:33:19.960
does inference and

00:33:19.960 --> 00:33:20.700
how it does type

00:33:20.700 --> 00:33:21.360
narrowing.

00:33:21.440 --> 00:33:22.460
And even in some

00:33:22.460 --> 00:33:23.100
cases, like you

00:33:23.100 --> 00:33:23.660
mentioned, you know,

00:33:23.660 --> 00:33:24.560
what it chooses to

00:33:24.560 --> 00:33:25.740
emit errors on that

00:33:25.740 --> 00:33:27.080
isn't really covered

00:33:27.080 --> 00:33:28.560
by the spec, partly

00:33:28.560 --> 00:33:29.760
maybe because we

00:33:29.760 --> 00:33:30.400
haven't gotten to

00:33:30.400 --> 00:33:31.260
it and also partly

00:33:31.260 --> 00:33:33.500
intentionally in that

00:33:33.500 --> 00:33:35.160
there may be room in

00:33:35.160 --> 00:33:35.880
some of those cases

00:33:35.880 --> 00:33:36.600
for different type

00:33:36.600 --> 00:33:37.400
checkers to work

00:33:37.400 --> 00:33:38.100
differently if they're

00:33:38.100 --> 00:33:38.680
serving different

00:33:38.680 --> 00:33:39.040
needs.

00:33:39.040 --> 00:33:40.440
Like if PyCharm is

00:33:40.440 --> 00:33:41.420
primarily concerned

00:33:41.420 --> 00:33:42.200
about being a

00:33:42.200 --> 00:33:44.020
useful kind of IDE

00:33:44.020 --> 00:33:45.240
and providing go-to

00:33:45.240 --> 00:33:46.100
definition and that

00:33:46.100 --> 00:33:47.340
sort of thing, maybe

00:33:47.340 --> 00:33:48.900
emitting lots of

00:33:48.900 --> 00:33:50.000
warnings or errors

00:33:50.000 --> 00:33:51.160
and all kinds of

00:33:51.160 --> 00:33:52.060
things where your

00:33:52.060 --> 00:33:52.760
code might be doing

00:33:52.760 --> 00:33:54.040
something wrong isn't

00:33:54.040 --> 00:33:54.920
as high a priority.

00:33:54.920 --> 00:33:56.200
And another type

00:33:56.200 --> 00:33:56.780
checker might have

00:33:56.780 --> 00:33:57.640
a different priority.

00:33:57.860 --> 00:33:58.760
One thing I do

00:33:58.760 --> 00:33:59.820
want to mention is

00:33:59.820 --> 00:34:01.320
that it may not

00:34:01.320 --> 00:34:02.540
seem like it, but

00:34:02.540 --> 00:34:04.080
things are already

00:34:04.080 --> 00:34:05.900
much better than

00:34:05.900 --> 00:34:06.700
they used to be.

00:34:07.120 --> 00:34:08.160
Like previously, I

00:34:08.160 --> 00:34:09.200
worked on a

00:34:09.200 --> 00:34:09.700
different type

00:34:09.700 --> 00:34:10.520
checker called

00:34:10.520 --> 00:34:11.420
PyType.

00:34:11.580 --> 00:34:12.380
And at that time,

00:34:12.420 --> 00:34:13.140
it was, you know,

00:34:13.480 --> 00:34:14.280
sort of the Wild

00:34:14.280 --> 00:34:14.640
West.

00:34:14.760 --> 00:34:15.440
Like we want to

00:34:15.440 --> 00:34:16.680
know how other

00:34:16.680 --> 00:34:17.700
type checkers like

00:34:17.700 --> 00:34:18.400
do something.

00:34:18.520 --> 00:34:18.860
Well, you know,

00:34:18.880 --> 00:34:19.500
like open up the

00:34:19.500 --> 00:34:20.260
mypy playground,

00:34:20.520 --> 00:34:21.040
open up the

00:34:21.040 --> 00:34:22.380
PyRite playground,

00:34:22.800 --> 00:34:24.660
see what tells

00:34:24.660 --> 00:34:24.880
you.

00:34:25.020 --> 00:34:25.920
Now we at least

00:34:25.920 --> 00:34:26.740
have spec and

00:34:26.740 --> 00:34:27.760
conformance tests.

00:34:28.000 --> 00:34:28.460
Yeah, that's

00:34:28.460 --> 00:34:28.880
really cool.

00:34:29.080 --> 00:34:29.640
How much would

00:34:29.640 --> 00:34:31.260
you say that

00:34:31.260 --> 00:34:32.940
your two type

00:34:32.940 --> 00:34:34.140
checkers maybe

00:34:34.140 --> 00:34:35.420
bring in mypy

00:34:35.420 --> 00:34:35.900
as well?

00:34:36.020 --> 00:34:36.460
Like how much

00:34:36.460 --> 00:34:37.200
do they agree

00:34:37.200 --> 00:34:38.060
versus disagree?

00:34:38.320 --> 00:34:38.880
You know, like

00:34:38.880 --> 00:34:40.060
you only see the

00:34:40.060 --> 00:34:40.380
differences.

00:34:40.540 --> 00:34:41.140
You don't see in

00:34:41.140 --> 00:34:41.900
which ways that

00:34:41.900 --> 00:34:42.640
they are the same

00:34:42.640 --> 00:34:43.840
as a consumer of

00:34:43.840 --> 00:34:44.380
them so much,

00:34:44.440 --> 00:34:44.580
right?

00:34:44.580 --> 00:34:45.040
You're like, why

00:34:45.040 --> 00:34:45.420
is this one

00:34:45.420 --> 00:34:46.060
squiggly when it

00:34:46.060 --> 00:34:46.680
wasn't squiggly

00:34:46.680 --> 00:34:47.120
before?

00:34:47.600 --> 00:34:48.540
But how similar

00:34:48.540 --> 00:34:49.020
or different are

00:34:49.020 --> 00:34:49.140
they?

00:34:49.240 --> 00:34:49.640
I don't know how

00:34:49.640 --> 00:34:50.260
we would quantify

00:34:50.260 --> 00:34:50.680
that.

00:34:51.000 --> 00:34:51.900
I think there's a

00:34:51.900 --> 00:34:52.640
lot that is the

00:34:52.640 --> 00:34:53.580
same just because

00:34:53.580 --> 00:34:54.760
it's based on how

00:34:54.760 --> 00:34:55.480
Python actually

00:34:55.480 --> 00:34:55.860
works.

00:34:56.200 --> 00:34:56.960
We're both trying

00:34:56.960 --> 00:34:57.420
to model the

00:34:57.420 --> 00:34:58.280
same language and

00:34:58.280 --> 00:34:58.540
then there's

00:34:58.540 --> 00:34:59.100
certainly also

00:34:59.100 --> 00:34:59.680
plenty of

00:34:59.680 --> 00:35:00.660
differences or

00:35:00.660 --> 00:35:01.120
things that we

00:35:01.120 --> 00:35:01.700
handle differently.

00:35:02.060 --> 00:35:02.960
So Rebecca, do you

00:35:02.960 --> 00:35:03.360
have a better way

00:35:03.360 --> 00:35:04.020
to quantify that?

00:35:04.400 --> 00:35:05.360
Yeah, I agree.

00:35:05.360 --> 00:35:06.840
it's hard to

00:35:06.840 --> 00:35:08.180
quantify, I suppose,

00:35:08.300 --> 00:35:08.940
talk a bit

00:35:08.940 --> 00:35:10.220
abstractly about

00:35:10.220 --> 00:35:11.040
various type

00:35:11.040 --> 00:35:12.640
checkers philosophies.

00:35:13.180 --> 00:35:14.520
With Pyrefly, we

00:35:14.520 --> 00:35:15.380
really try to do

00:35:15.380 --> 00:35:16.360
a lot of type

00:35:16.360 --> 00:35:16.960
inference.

00:35:17.220 --> 00:35:17.940
So that's a way

00:35:17.940 --> 00:35:18.840
in which we

00:35:18.840 --> 00:35:19.760
intentionally diverge

00:35:19.760 --> 00:35:21.140
a bit from mypy.

00:35:21.320 --> 00:35:22.560
But other than

00:35:22.560 --> 00:35:23.300
that deliberate

00:35:23.300 --> 00:35:24.260
decision, if we

00:35:24.260 --> 00:35:24.880
see ways in which

00:35:24.880 --> 00:35:25.940
we are accidentally

00:35:25.940 --> 00:35:27.120
different, we do

00:35:27.120 --> 00:35:28.800
try to fix that

00:35:28.800 --> 00:35:29.460
because otherwise

00:35:29.460 --> 00:35:30.540
people would have

00:35:30.540 --> 00:35:31.580
a hard time running

00:35:31.580 --> 00:35:32.160
multiple type

00:35:32.160 --> 00:35:32.760
checkers or

00:35:32.760 --> 00:35:33.220
migrating.

00:35:33.460 --> 00:35:33.960
Yeah, differences

00:35:33.960 --> 00:35:34.980
obviously cause

00:35:35.620 --> 00:35:36.560
pain for users

00:35:36.560 --> 00:35:37.220
who are using

00:35:37.220 --> 00:35:37.760
multiple type

00:35:37.760 --> 00:35:38.340
checkers or

00:35:38.340 --> 00:35:39.120
writing libraries

00:35:39.120 --> 00:35:39.580
that need to

00:35:39.580 --> 00:35:40.160
support multiple

00:35:40.160 --> 00:35:40.820
type checkers.

00:35:40.960 --> 00:35:41.960
So like Rebecca

00:35:41.960 --> 00:35:43.000
said, it's like if

00:35:43.000 --> 00:35:43.720
we are different

00:35:43.720 --> 00:35:44.440
from other type

00:35:44.440 --> 00:35:45.040
checkers, we want

00:35:45.040 --> 00:35:45.540
to be sure that

00:35:45.540 --> 00:35:45.940
there's a good

00:35:45.940 --> 00:35:46.920
reason for that

00:35:46.920 --> 00:35:47.340
difference.

00:35:47.600 --> 00:35:47.960
The difference

00:35:47.960 --> 00:35:49.040
should be because

00:35:49.040 --> 00:35:49.780
of philosophical

00:35:49.780 --> 00:35:51.580
choice, not just

00:35:51.580 --> 00:35:52.760
you happen to have

00:35:52.760 --> 00:35:53.480
chosen slightly

00:35:53.480 --> 00:35:54.140
differently, right?

00:35:54.420 --> 00:35:54.840
Yeah, and it's

00:35:54.840 --> 00:35:56.420
not just people who

00:35:56.420 --> 00:35:57.740
run different type

00:35:57.740 --> 00:35:58.240
checkers.

00:35:58.800 --> 00:35:59.600
Like you pointed

00:35:59.600 --> 00:36:00.260
out, Carl, a lot

00:36:00.260 --> 00:36:01.140
of times it is if I

00:36:01.140 --> 00:36:02.500
have a library and

00:36:02.500 --> 00:36:03.740
then different people

00:36:03.740 --> 00:36:04.420
want to consume

00:36:04.420 --> 00:36:05.360
that library, then

00:36:05.360 --> 00:36:06.600
their type checker

00:36:06.600 --> 00:36:07.300
may or may not

00:36:07.300 --> 00:36:08.200
warn them about how

00:36:08.200 --> 00:36:09.220
my library declares

00:36:09.220 --> 00:36:10.660
its types and so

00:36:10.660 --> 00:36:10.960
on.

00:36:11.700 --> 00:36:12.660
I'll give you a

00:36:12.660 --> 00:36:13.760
real quick example.

00:36:14.380 --> 00:36:16.540
I have a, I can't

00:36:16.540 --> 00:36:17.100
remember which one

00:36:17.100 --> 00:36:17.420
it was, I have

00:36:17.420 --> 00:36:17.880
three or four

00:36:17.880 --> 00:36:19.000
different open

00:36:19.000 --> 00:36:19.620
source libraries

00:36:19.620 --> 00:36:20.140
that I've created

00:36:20.140 --> 00:36:21.700
that somehow work

00:36:21.700 --> 00:36:22.960
with creating,

00:36:23.540 --> 00:36:24.440
basically passing

00:36:24.440 --> 00:36:25.600
data to templates

00:36:25.600 --> 00:36:26.980
in web apps,

00:36:27.340 --> 00:36:27.460
right?

00:36:27.500 --> 00:36:28.700
So one is like I

00:36:28.700 --> 00:36:29.260
want to use the

00:36:29.260 --> 00:36:30.020
Chameleon web

00:36:30.020 --> 00:36:30.740
template framework,

00:36:30.740 --> 00:36:31.480
but with fast

00:36:31.480 --> 00:36:32.680
API or with

00:36:32.680 --> 00:36:33.480
Flask or there's

00:36:33.480 --> 00:36:33.920
some other

00:36:33.920 --> 00:36:34.580
variations like

00:36:34.580 --> 00:36:35.360
partials and so

00:36:35.360 --> 00:36:35.500
on.

00:36:35.700 --> 00:36:36.360
I can't remember

00:36:36.360 --> 00:36:37.180
which one, but it

00:36:37.180 --> 00:36:37.500
doesn't really

00:36:37.500 --> 00:36:37.720
matter.

00:36:37.840 --> 00:36:38.280
One of them

00:36:38.280 --> 00:36:39.760
decorated a

00:36:39.760 --> 00:36:40.680
Flask.

00:36:40.820 --> 00:36:41.600
I think it was a

00:36:41.600 --> 00:36:42.420
Flask, especially

00:36:42.420 --> 00:36:43.480
makes it irrelevant.

00:36:43.900 --> 00:36:44.980
A Flask endpoint

00:36:44.980 --> 00:36:46.760
and PyRite was

00:36:46.760 --> 00:36:47.660
really upset.

00:36:47.860 --> 00:36:48.480
Like the error

00:36:48.480 --> 00:36:49.460
message filled the

00:36:49.460 --> 00:36:50.620
entire page of

00:36:50.620 --> 00:36:51.240
how it was

00:36:51.240 --> 00:36:53.000
inconsistent with

00:36:53.000 --> 00:36:54.020
what it expected

00:36:54.020 --> 00:36:54.920
for the definition

00:36:54.920 --> 00:36:55.980
of the Flask

00:36:55.980 --> 00:36:56.500
view method.

00:36:56.600 --> 00:36:57.720
I'm like, no one

00:36:57.720 --> 00:36:58.320
is going to call

00:36:58.320 --> 00:36:58.540
this.

00:36:58.540 --> 00:36:58.980
Like what does

00:36:58.980 --> 00:36:59.640
it even matter

00:36:59.640 --> 00:37:00.840
what this type

00:37:00.840 --> 00:37:01.080
is?

00:37:01.180 --> 00:37:01.960
It still runs

00:37:01.960 --> 00:37:02.260
fine.

00:37:02.320 --> 00:37:02.920
The runtime is

00:37:02.920 --> 00:37:03.260
fine.

00:37:03.540 --> 00:37:04.780
You know, it's no

00:37:04.780 --> 00:37:05.480
problem with this

00:37:05.480 --> 00:37:05.860
decorator.

00:37:05.980 --> 00:37:07.260
It worked fine, but

00:37:07.260 --> 00:37:08.800
something about the

00:37:08.800 --> 00:37:10.040
way that the Flask

00:37:10.040 --> 00:37:11.980
at get returned

00:37:11.980 --> 00:37:12.820
the type versus

00:37:12.820 --> 00:37:13.560
what my thing

00:37:13.560 --> 00:37:14.500
returned varied in

00:37:14.500 --> 00:37:15.060
like a really

00:37:15.060 --> 00:37:16.320
slight way.

00:37:16.460 --> 00:37:17.600
I didn't care, but

00:37:17.600 --> 00:37:18.600
somebody was using

00:37:18.600 --> 00:37:19.780
some editor that

00:37:19.780 --> 00:37:20.700
used PyRite and

00:37:20.700 --> 00:37:21.140
they're like, you

00:37:21.140 --> 00:37:22.380
have to help fix

00:37:22.380 --> 00:37:22.560
this.

00:37:22.640 --> 00:37:23.300
I can't take all

00:37:23.300 --> 00:37:23.760
these warnings.

00:37:23.880 --> 00:37:24.500
They're huge and

00:37:24.500 --> 00:37:25.080
they're everywhere.

00:37:25.420 --> 00:37:26.780
Like, okay, I'll

00:37:26.780 --> 00:37:27.360
go fix it.

00:37:27.360 --> 00:37:27.720
Right.

00:37:27.720 --> 00:37:29.060
And I went and I

00:37:29.060 --> 00:37:30.740
put way more effort

00:37:30.740 --> 00:37:31.440
than was justified

00:37:31.440 --> 00:37:32.840
into a function type

00:37:32.840 --> 00:37:33.340
that no one ever

00:37:33.340 --> 00:37:34.580
calls just to make

00:37:34.580 --> 00:37:36.080
the errors on some

00:37:36.080 --> 00:37:37.140
type checker I

00:37:37.140 --> 00:37:38.420
didn't use go

00:37:38.420 --> 00:37:38.800
away.

00:37:38.920 --> 00:37:39.220
Right.

00:37:39.260 --> 00:37:39.800
And that's the

00:37:39.800 --> 00:37:40.540
kind of thing where

00:37:40.540 --> 00:37:41.300
it becomes just a

00:37:41.300 --> 00:37:41.580
headache.

00:37:41.760 --> 00:37:42.260
I don't know.

00:37:42.280 --> 00:37:42.820
I wish I remember.

00:37:42.880 --> 00:37:43.540
I probably got that

00:37:43.540 --> 00:37:44.800
written down in an

00:37:44.800 --> 00:37:45.900
issue somebody filed,

00:37:46.000 --> 00:37:46.840
but it was, it was

00:37:46.840 --> 00:37:47.520
a gnarly error.

00:37:47.660 --> 00:37:48.520
And, or if you're

00:37:48.520 --> 00:37:49.120
working on an open

00:37:49.120 --> 00:37:50.240
source project, you

00:37:50.240 --> 00:37:50.900
know, you can't make

00:37:50.900 --> 00:37:51.700
everybody use the

00:37:51.700 --> 00:37:53.100
same editor that

00:37:53.100 --> 00:37:53.940
wants to contribute

00:37:53.940 --> 00:37:54.800
on a big project.

00:37:55.160 --> 00:37:55.980
And so you might run

00:37:55.980 --> 00:37:56.880
into this variation as

00:37:56.880 --> 00:37:57.020
well.

00:37:57.020 --> 00:37:57.580
So there's a lot

00:37:57.580 --> 00:37:58.000
of cases.

00:37:58.240 --> 00:37:58.320
Yeah.

00:37:58.340 --> 00:37:58.940
It can be really

00:37:58.940 --> 00:38:00.220
difficult to make

00:38:00.220 --> 00:38:01.240
these decisions about

00:38:01.240 --> 00:38:03.020
what kind of, what

00:38:03.020 --> 00:38:04.460
sorts of errors people

00:38:04.460 --> 00:38:06.220
want their type checker

00:38:06.220 --> 00:38:07.560
to catch or what's

00:38:07.560 --> 00:38:08.120
too pedantic.

00:38:08.460 --> 00:38:09.440
You want your type

00:38:09.440 --> 00:38:10.200
checker to catch

00:38:10.200 --> 00:38:11.700
non-obvious errors,

00:38:11.700 --> 00:38:12.740
not just the obvious

00:38:12.740 --> 00:38:13.440
ones that you probably

00:38:13.440 --> 00:38:14.020
would have seen by

00:38:14.020 --> 00:38:14.660
looking at the code

00:38:14.660 --> 00:38:15.040
yourself.

00:38:15.300 --> 00:38:16.020
But then there'll be

00:38:16.020 --> 00:38:17.440
cases where somebody

00:38:17.440 --> 00:38:18.040
says, well, I don't

00:38:18.040 --> 00:38:18.240
care.

00:38:18.300 --> 00:38:18.940
That's too pedantic.

00:38:19.160 --> 00:38:20.220
And it is difficult to

00:38:20.220 --> 00:38:20.960
make everyone happy.

00:38:21.640 --> 00:38:22.560
Who decides what the

00:38:22.560 --> 00:38:24.360
right signature of a

00:38:24.360 --> 00:38:25.860
flask view and point

00:38:25.860 --> 00:38:26.940
should be like if you

00:38:27.020 --> 00:38:27.900
the framework can call

00:38:27.900 --> 00:38:28.080
it.

00:38:28.080 --> 00:38:29.080
It should be okay.

00:38:29.080 --> 00:38:30.080
There's not.

00:38:30.200 --> 00:38:30.800
Just because it had a

00:38:30.800 --> 00:38:31.600
decorator before, that

00:38:31.600 --> 00:38:32.300
doesn't mean that's the

00:38:32.300 --> 00:38:33.360
official structure.

00:38:33.480 --> 00:38:34.700
But anyway, I do think

00:38:34.700 --> 00:38:35.440
one of the bigger

00:38:35.440 --> 00:38:37.000
philosophical differences

00:38:37.000 --> 00:38:39.120
has to do around this

00:38:39.120 --> 00:38:41.100
concept of nullability.

00:38:41.340 --> 00:38:42.080
Do you guys call it

00:38:42.080 --> 00:38:43.360
nullability or none

00:38:43.360 --> 00:38:43.920
ability?

00:38:44.280 --> 00:38:45.600
Like nullability comes

00:38:45.600 --> 00:38:46.040
from the other

00:38:46.040 --> 00:38:46.420
languages.

00:38:46.620 --> 00:38:48.080
And by that, I mean, I

00:38:48.080 --> 00:38:49.220
can specify that I have

00:38:49.220 --> 00:38:49.760
an integer.

00:38:49.760 --> 00:38:51.100
And in the Python type

00:38:51.100 --> 00:38:53.180
system, it cannot be set

00:38:53.180 --> 00:38:54.220
to none, even though in

00:38:54.220 --> 00:38:54.940
the runtime it can.

00:38:55.440 --> 00:38:56.740
It has to be a concrete

00:38:56.740 --> 00:38:58.820
int type unless you make

00:38:58.820 --> 00:39:00.940
it a optional int or an

00:39:00.940 --> 00:39:02.460
int pipe none or one of

00:39:02.460 --> 00:39:03.480
those type things, right?

00:39:03.580 --> 00:39:05.340
And how strong that gets

00:39:05.340 --> 00:39:06.480
enforced seems to be one

00:39:06.480 --> 00:39:07.980
of the biggest difference

00:39:07.980 --> 00:39:09.460
of opinions that I've

00:39:09.460 --> 00:39:10.040
seen around.

00:39:10.240 --> 00:39:10.860
Like, how do you all

00:39:10.860 --> 00:39:11.460
think about that?

00:39:11.600 --> 00:39:12.580
That's interesting to me

00:39:12.580 --> 00:39:13.540
that that's your

00:39:13.540 --> 00:39:15.100
experience because my

00:39:15.100 --> 00:39:16.000
experience has been that

00:39:16.000 --> 00:39:16.860
that's actually an area

00:39:16.860 --> 00:39:18.220
where everyone seems to

00:39:18.220 --> 00:39:19.120
agree as far as I can

00:39:19.120 --> 00:39:21.300
tell that these are is

00:39:21.300 --> 00:39:22.100
an important source of

00:39:22.100 --> 00:39:22.980
bugs and it's better to

00:39:22.980 --> 00:39:23.400
catch them.

00:39:23.480 --> 00:39:24.120
So I think all of the

00:39:24.120 --> 00:39:25.700
type checkers, maybe you

00:39:25.700 --> 00:39:26.720
said PyCharm doesn't.

00:39:26.900 --> 00:39:27.720
I don't think PyCharm

00:39:27.720 --> 00:39:28.220
does that.

00:39:28.340 --> 00:39:29.680
I'm pretty sure it

00:39:29.680 --> 00:39:31.440
doesn't because I agree

00:39:31.440 --> 00:39:32.200
that it's an important

00:39:32.200 --> 00:39:34.020
thing to check, but it's

00:39:34.020 --> 00:39:35.920
also a point of a lot of

00:39:35.920 --> 00:39:36.480
friction.

00:39:37.100 --> 00:39:37.920
And by that, I mean,

00:39:38.180 --> 00:39:39.480
let's suppose I'm going

00:39:39.480 --> 00:39:41.700
to have a class that I

00:39:41.700 --> 00:39:42.340
need to create an

00:39:42.340 --> 00:39:43.920
instance of and then put

00:39:43.920 --> 00:39:44.900
values into.

00:39:45.320 --> 00:39:46.580
And I know once I put

00:39:46.580 --> 00:39:47.680
the values into it, let's

00:39:47.680 --> 00:39:49.480
say it has a user ID, I

00:39:49.480 --> 00:39:50.960
know for certain that

00:39:50.960 --> 00:39:51.960
that's going to be an

00:39:51.960 --> 00:39:53.020
integer, right?

00:39:53.060 --> 00:39:54.260
So I'd like to say user

00:39:54.260 --> 00:39:55.520
ID colon int because

00:39:55.520 --> 00:39:57.000
everywhere I use that

00:39:57.000 --> 00:39:58.840
object later, if it's a

00:39:58.840 --> 00:39:59.820
function that takes an

00:39:59.820 --> 00:40:01.540
int and I specify it as

00:40:01.540 --> 00:40:03.000
optional int, I will get

00:40:03.000 --> 00:40:03.840
a type check warning

00:40:03.840 --> 00:40:05.400
every single call site

00:40:05.400 --> 00:40:06.960
when I try to pass that.

00:40:07.240 --> 00:40:08.100
But I know from the

00:40:08.100 --> 00:40:09.000
semantics of the

00:40:09.000 --> 00:40:10.780
behavior that it's going

00:40:10.780 --> 00:40:12.480
to always be an int

00:40:12.480 --> 00:40:13.440
unless it's not

00:40:13.440 --> 00:40:14.820
initialized, right?

00:40:14.820 --> 00:40:16.080
And like in this short

00:40:16.080 --> 00:40:17.060
period where I want to

00:40:17.060 --> 00:40:17.480
create it.

00:40:17.560 --> 00:40:18.700
So I can't set the type

00:40:18.700 --> 00:40:19.060
to int.

00:40:19.120 --> 00:40:19.660
I have to set the

00:40:19.660 --> 00:40:20.760
optional int until I've

00:40:20.760 --> 00:40:21.300
loaded it.

00:40:21.920 --> 00:40:22.680
And, but there's like

00:40:22.680 --> 00:40:23.660
this, I don't know,

00:40:23.720 --> 00:40:24.380
that's, that's the part

00:40:24.380 --> 00:40:25.480
where I see a lot of it

00:40:25.480 --> 00:40:27.720
show up is inconsistencies

00:40:27.720 --> 00:40:29.400
and then warnings all

00:40:29.400 --> 00:40:29.980
over the place.

00:40:29.980 --> 00:40:31.140
So I'm like, well, but

00:40:31.140 --> 00:40:32.300
that function is actually

00:40:32.300 --> 00:40:33.240
checking if it's none

00:40:33.240 --> 00:40:34.880
and it'll return null,

00:40:35.080 --> 00:40:35.900
you know, none or

00:40:35.900 --> 00:40:36.500
something like that.

00:40:36.500 --> 00:40:38.200
So I totally agree with

00:40:38.200 --> 00:40:38.380
you.

00:40:38.520 --> 00:40:39.420
It's just somewhere I've

00:40:39.420 --> 00:40:40.320
seen the most

00:40:40.320 --> 00:40:41.860
inconsistencies across

00:40:41.860 --> 00:40:43.660
maybe PyCharm versus

00:40:43.660 --> 00:40:44.280
others.

00:40:44.480 --> 00:40:45.580
mypy also has a legacy

00:40:45.580 --> 00:40:46.900
mode for not checking

00:40:46.900 --> 00:40:48.340
none things called

00:40:48.340 --> 00:40:49.760
non-strict optional.

00:40:50.200 --> 00:40:51.240
We're trying to get

00:40:51.240 --> 00:40:52.300
rid of that from mypy

00:40:52.300 --> 00:40:53.480
because yeah, strict

00:40:53.480 --> 00:40:54.360
optional, like being

00:40:54.360 --> 00:40:55.200
strict about it is the

00:40:55.200 --> 00:40:55.940
more sensible thing to

00:40:55.940 --> 00:40:56.160
do.

00:40:56.480 --> 00:40:57.580
But it's possible that

00:40:57.580 --> 00:40:58.540
you've seen that too.

00:40:59.020 --> 00:40:59.460
Yeah, I agree.

00:40:59.720 --> 00:41:00.320
So what you mentioned

00:41:00.320 --> 00:41:01.720
is maybe sort of a

00:41:01.720 --> 00:41:02.540
special case of the

00:41:02.540 --> 00:41:03.540
case where you pass

00:41:03.540 --> 00:41:04.360
something to a class

00:41:04.360 --> 00:41:05.380
and there's initialization

00:41:05.380 --> 00:41:06.440
that changes the types.

00:41:06.820 --> 00:41:07.660
Doesn't necessarily have

00:41:07.660 --> 00:41:08.220
to deal with none.

00:41:08.300 --> 00:41:08.960
It could also just be

00:41:08.960 --> 00:41:09.780
like the attribute doesn't

00:41:09.780 --> 00:41:10.740
exist at all beforehand

00:41:10.740 --> 00:41:11.240
or something.

00:41:11.240 --> 00:41:12.940
Yeah, we don't have a

00:41:12.940 --> 00:41:13.780
good solution for that.

00:41:13.900 --> 00:41:14.840
Maybe there's room for

00:41:14.840 --> 00:41:16.120
something to support that

00:41:16.120 --> 00:41:16.720
use case better.

00:41:17.020 --> 00:41:17.660
I don't know what it

00:41:17.660 --> 00:41:18.120
would look like.

00:41:18.260 --> 00:41:19.180
In some cases, there's

00:41:19.180 --> 00:41:20.720
ways you can, these

00:41:20.720 --> 00:41:21.900
things can sometimes

00:41:21.900 --> 00:41:22.760
nudge you towards a

00:41:22.760 --> 00:41:23.760
different design that is

00:41:23.760 --> 00:41:24.920
actually safer and will

00:41:24.920 --> 00:41:26.020
avoid errors.

00:41:26.020 --> 00:41:27.040
Like in the kind of

00:41:27.040 --> 00:41:27.640
case you're talking

00:41:27.640 --> 00:41:29.000
about, you know, is

00:41:29.000 --> 00:41:30.580
it actually necessary

00:41:30.580 --> 00:41:31.820
that an uninitialized

00:41:31.820 --> 00:41:32.600
object and an

00:41:32.600 --> 00:41:33.360
initialized one are

00:41:33.360 --> 00:41:34.120
represented by the

00:41:34.120 --> 00:41:34.580
same type?

00:41:34.780 --> 00:41:35.840
Or is there a way to

00:41:35.840 --> 00:41:37.260
adjust the API so that

00:41:37.260 --> 00:41:37.840
those are actually

00:41:37.840 --> 00:41:38.960
different types than you

00:41:38.960 --> 00:41:40.080
solve the problem and

00:41:40.080 --> 00:41:41.220
your code is safer

00:41:41.220 --> 00:41:41.580
or so?

00:41:41.580 --> 00:41:42.500
I'm thinking like you

00:41:42.500 --> 00:41:44.500
submit a web form and

00:41:44.500 --> 00:41:45.680
before you parse it, you've

00:41:45.680 --> 00:41:46.440
got to create the instance

00:41:46.440 --> 00:41:47.360
to set the values.

00:41:47.940 --> 00:41:48.300
And I don't know.

00:41:48.420 --> 00:41:49.320
It's not worth diving into,

00:41:49.380 --> 00:41:50.340
but I do find this

00:41:50.340 --> 00:41:52.260
differentiation between like

00:41:52.260 --> 00:41:53.880
the strict enforcement of

00:41:53.880 --> 00:41:55.200
none versus not none.

00:41:55.340 --> 00:41:56.500
I think it's powerful and I

00:41:56.500 --> 00:41:57.440
do think you all are right

00:41:57.440 --> 00:41:58.600
that it does catch a lot of

00:41:58.600 --> 00:41:58.840
errors.

00:41:58.940 --> 00:42:00.000
It's just, it's just a

00:42:00.000 --> 00:42:00.880
difference and it's just an

00:42:00.880 --> 00:42:02.280
interesting, interesting

00:42:02.280 --> 00:42:02.560
choice.

00:42:02.680 --> 00:42:03.620
But I didn't get a

00:42:03.620 --> 00:42:05.280
concrete answer from the

00:42:05.280 --> 00:42:06.140
official counsel.

00:42:06.720 --> 00:42:07.640
Nullable or

00:42:07.640 --> 00:42:08.200
noneable?

00:42:08.640 --> 00:42:09.140
What is it?

00:42:09.140 --> 00:42:09.700
I feel like you just

00:42:09.700 --> 00:42:10.600
don't really even talk

00:42:10.600 --> 00:42:11.700
about it as a term mostly.

00:42:12.340 --> 00:42:13.900
It's, yeah, none is

00:42:13.900 --> 00:42:15.420
special in the type system

00:42:15.420 --> 00:42:16.720
in like how you represent

00:42:16.720 --> 00:42:17.820
it, but it's not really

00:42:17.820 --> 00:42:19.660
special in other ways.

00:42:19.920 --> 00:42:20.940
You don't have a term for

00:42:20.940 --> 00:42:21.860
int pipe none?

00:42:22.140 --> 00:42:22.620
Int or none.

00:42:22.860 --> 00:42:23.780
Historically, the term was

00:42:23.780 --> 00:42:24.820
optional, although I think

00:42:24.820 --> 00:42:26.560
that term has problems and

00:42:26.560 --> 00:42:28.220
we're sort of moving away

00:42:28.220 --> 00:42:29.080
from it because

00:42:29.080 --> 00:42:31.680
specifically one problem is

00:42:31.680 --> 00:42:33.360
that optional can mean

00:42:33.360 --> 00:42:34.920
you don't have to pass it

00:42:34.920 --> 00:42:36.200
in, like I say, as a

00:42:36.200 --> 00:42:36.900
function parameter.

00:42:37.080 --> 00:42:38.200
Let's talk a little bit

00:42:38.200 --> 00:42:39.600
about TypeShed.

00:42:40.060 --> 00:42:41.440
I think TypeShed is pretty

00:42:41.440 --> 00:42:41.800
interesting.

00:42:41.940 --> 00:42:42.860
Maybe people don't know

00:42:42.860 --> 00:42:44.160
too much about it.

00:42:44.640 --> 00:42:45.840
So I'm sure you all are

00:42:45.840 --> 00:42:47.000
familiar with this project

00:42:47.000 --> 00:42:48.500
that you can basically add

00:42:48.500 --> 00:42:50.220
type information that the

00:42:50.220 --> 00:42:51.880
libraries didn't bother to

00:42:51.880 --> 00:42:52.740
include for you, right?

00:42:53.160 --> 00:42:54.460
What are thoughts on TypeShed?

00:42:54.620 --> 00:42:55.640
How much do you all lean on

00:42:55.640 --> 00:42:57.060
this to sort of round out

00:42:57.060 --> 00:42:58.020
missing types?

00:42:58.240 --> 00:42:59.160
There are two parts to

00:42:59.160 --> 00:43:00.040
TypeShed, right?

00:43:00.040 --> 00:43:02.440
There's the standard library

00:43:02.440 --> 00:43:04.480
type stubs, which I think

00:43:04.480 --> 00:43:05.600
are invaluable.

00:43:06.000 --> 00:43:07.260
Like all the type checkers

00:43:07.260 --> 00:43:07.980
use those.

00:43:08.480 --> 00:43:09.620
And I mean, will the standard

00:43:09.620 --> 00:43:10.660
library itself ever have

00:43:10.660 --> 00:43:11.880
inline types?

00:43:12.060 --> 00:43:12.640
Who knows?

00:43:12.700 --> 00:43:13.900
This might be around forever.

00:43:14.520 --> 00:43:15.900
And then there are also

00:43:15.900 --> 00:43:18.640
the third party stubs.

00:43:18.960 --> 00:43:20.320
And I think that's what you're

00:43:20.320 --> 00:43:20.780
describing.

00:43:20.940 --> 00:43:21.980
They're libraries that for

00:43:21.980 --> 00:43:23.160
whatever reason don't ship

00:43:23.160 --> 00:43:24.540
with stubs themselves.

00:43:24.920 --> 00:43:26.640
Those are in TypeShed.

00:43:26.640 --> 00:43:29.080
And I think it's been like

00:43:29.080 --> 00:43:31.040
for a while, there's sort of

00:43:31.040 --> 00:43:31.940
been a question of like what

00:43:31.940 --> 00:43:33.560
we want to do with like

00:43:33.560 --> 00:43:35.440
TypeShed's third party stubs,

00:43:35.540 --> 00:43:35.740
right?

00:43:35.860 --> 00:43:37.420
Because like ideally like

00:43:37.420 --> 00:43:38.480
libraries would ship with

00:43:38.480 --> 00:43:39.780
their own types, but there

00:43:39.780 --> 00:43:41.220
are various obstacles to that.

00:43:41.360 --> 00:43:43.120
The obstacles that I know of

00:43:43.120 --> 00:43:45.000
used to be like, we want this

00:43:45.000 --> 00:43:47.080
to run on Python 2 and Python 3.

00:43:47.520 --> 00:43:48.920
Or we want it to run on

00:43:48.920 --> 00:43:50.480
Python 3.3 still.

00:43:50.740 --> 00:43:52.480
But it's been a long time

00:43:52.480 --> 00:43:55.160
since any non-type supporting

00:43:55.160 --> 00:43:57.700
version of Python was a real,

00:43:57.840 --> 00:43:58.880
you know, a supported type

00:43:58.880 --> 00:43:59.500
of thing, right?

00:43:59.740 --> 00:44:01.300
I mean, even 3.9 became

00:44:01.300 --> 00:44:02.080
deprecated.

00:44:02.560 --> 00:44:04.440
So on one hand, I feel like

00:44:04.440 --> 00:44:05.880
they could be merged in,

00:44:05.920 --> 00:44:07.100
but there's also a lot of

00:44:07.100 --> 00:44:09.700
other areas that are maybe

00:44:09.700 --> 00:44:11.720
we don't, they're not common,

00:44:12.120 --> 00:44:12.300
right?

00:44:12.360 --> 00:44:13.900
Like other libraries, like

00:44:13.900 --> 00:44:15.960
pick some, let's say Pyramid.

00:44:16.120 --> 00:44:17.400
I don't think the Pyramid web

00:44:17.400 --> 00:44:19.220
framework really ever got

00:44:19.220 --> 00:44:20.280
types added to it.

00:44:20.280 --> 00:44:21.620
Somebody could go and create

00:44:21.620 --> 00:44:24.800
a typeshed stub or a types

00:44:24.800 --> 00:44:26.160
underscore pyramid you could

00:44:26.160 --> 00:44:27.180
pip install and then we'll

00:44:27.180 --> 00:44:28.040
add the types, right?

00:44:28.420 --> 00:44:29.680
I certainly see it being

00:44:29.680 --> 00:44:30.780
really valuable for third

00:44:30.780 --> 00:44:31.680
party things that are just

00:44:31.680 --> 00:44:33.000
not going to get the type

00:44:33.000 --> 00:44:33.840
attention they need.

00:44:33.960 --> 00:44:34.780
Yeah, I think typeshed is

00:44:34.780 --> 00:44:35.040
great.

00:44:35.180 --> 00:44:36.880
I've spent a lot of time on

00:44:36.880 --> 00:44:37.600
improving it.

00:44:37.800 --> 00:44:39.020
As Rebecca said, especially

00:44:39.020 --> 00:44:39.880
with a standard library,

00:44:39.980 --> 00:44:41.080
it's irreplaceable.

00:44:41.440 --> 00:44:42.520
For third party libraries,

00:44:42.780 --> 00:44:44.360
I think it's become less

00:44:44.360 --> 00:44:45.200
needed over time.

00:44:45.980 --> 00:44:47.480
It used to be that very few

00:44:47.480 --> 00:44:49.060
third party libraries had

00:44:49.060 --> 00:44:49.760
any types.

00:44:49.760 --> 00:44:51.480
Now that's obviously changed.

00:44:51.600 --> 00:44:53.080
A lot of libraries ship

00:44:53.080 --> 00:44:54.700
their own types, but still

00:44:54.700 --> 00:44:56.180
there are quite a few types

00:44:56.180 --> 00:44:57.680
of libraries left where

00:44:57.680 --> 00:44:59.460
there aren't inline types

00:44:59.460 --> 00:45:00.580
and typeshed can provide

00:45:00.580 --> 00:45:01.300
useful types.

00:45:01.800 --> 00:45:02.660
I think typeshed also

00:45:02.660 --> 00:45:03.620
provides a service because

00:45:03.620 --> 00:45:04.880
it has a really great

00:45:04.880 --> 00:45:05.980
framework for testing

00:45:05.980 --> 00:45:06.660
these types.

00:45:06.940 --> 00:45:07.820
We have tools like step

00:45:07.820 --> 00:45:09.260
tests and various type

00:45:09.260 --> 00:45:11.260
checkers that help to

00:45:11.260 --> 00:45:12.480
make sure these types are

00:45:12.480 --> 00:45:14.280
good and meet a high

00:45:14.280 --> 00:45:14.620
standard.

00:45:15.200 --> 00:45:16.100
So yeah, I think they're

00:45:16.100 --> 00:45:17.000
still useful for many

00:45:17.000 --> 00:45:17.460
libraries.

00:45:17.800 --> 00:45:18.640
Yeah, I was just looking at

00:45:18.640 --> 00:45:21.640
the types dash flask and

00:45:21.640 --> 00:45:23.320
I guess it must be, must

00:45:23.320 --> 00:45:24.440
be gone because now type

00:45:24.440 --> 00:45:25.520
flask must have it

00:45:25.520 --> 00:45:25.940
internally.

00:45:26.260 --> 00:45:27.720
So it's kind of an interim

00:45:27.720 --> 00:45:28.520
sort of thing.

00:45:28.580 --> 00:45:29.080
That's pretty cool.

00:45:29.240 --> 00:45:29.940
In general, typeshed has

00:45:29.940 --> 00:45:31.320
the policy that we remove

00:45:31.320 --> 00:45:32.460
the snaps from typeshed if

00:45:32.460 --> 00:45:34.120
they are in the library

00:45:34.120 --> 00:45:34.520
itself.

00:45:34.600 --> 00:45:35.340
I find these super

00:45:35.340 --> 00:45:37.160
valuable because if there's

00:45:37.160 --> 00:45:38.120
a library I want to work

00:45:38.120 --> 00:45:39.440
with and it just doesn't

00:45:39.440 --> 00:45:40.240
have types for whatever

00:45:40.240 --> 00:45:41.760
reason, you can install

00:45:41.760 --> 00:45:43.000
stuff from here and all

00:45:43.000 --> 00:45:43.920
of a sudden your editor's

00:45:43.920 --> 00:45:44.740
way happier.

00:45:44.740 --> 00:45:47.120
I mean, I know we, you

00:45:47.120 --> 00:45:48.340
all agreed on like the

00:45:48.340 --> 00:45:49.960
API boundaries and I did

00:45:49.960 --> 00:45:50.400
as well.

00:45:50.480 --> 00:45:51.040
It's like that's one of

00:45:51.040 --> 00:45:51.880
the really cool things.

00:45:51.980 --> 00:45:52.780
The other thing that

00:45:52.780 --> 00:45:53.620
really makes me excited

00:45:53.620 --> 00:45:54.960
about types is if I hit

00:45:54.960 --> 00:45:57.080
dot in my editor, I get

00:45:57.080 --> 00:45:58.960
a meaningful list of real

00:45:58.960 --> 00:46:00.420
information about what I'm

00:46:00.420 --> 00:46:00.900
working on.

00:46:00.960 --> 00:46:02.040
And so adding, adding

00:46:02.040 --> 00:46:03.320
these types of things are

00:46:03.320 --> 00:46:04.000
pretty interesting.

00:46:04.260 --> 00:46:05.440
I want to ask you all

00:46:05.440 --> 00:46:07.560
about sort of these rogue,

00:46:07.760 --> 00:46:10.300
rogue tools that do stuff

00:46:10.300 --> 00:46:11.460
with Python typing that

00:46:11.460 --> 00:46:12.900
maybe y'all didn't intend.

00:46:12.900 --> 00:46:14.060
Like we all mentioned

00:46:14.060 --> 00:46:15.840
Pydantic, we've got

00:46:15.840 --> 00:46:18.240
Typer and FastAPI, but

00:46:18.240 --> 00:46:19.640
even a little farther out

00:46:19.640 --> 00:46:20.960
there is a bear type.

00:46:21.020 --> 00:46:21.620
Are you familiar with

00:46:21.620 --> 00:46:22.160
bear type?

00:46:22.600 --> 00:46:22.740
Yeah.

00:46:22.800 --> 00:46:23.640
Bear type's interesting.

00:46:24.280 --> 00:46:26.840
You can import, they have

00:46:26.840 --> 00:46:27.180
fun.

00:46:27.840 --> 00:46:29.080
They have fun with their,

00:46:29.180 --> 00:46:30.920
their import names and

00:46:30.920 --> 00:46:31.240
stuff.

00:46:31.480 --> 00:46:33.120
But basically you can put

00:46:33.120 --> 00:46:35.080
a, either a decorator onto

00:46:35.080 --> 00:46:36.940
some sort of call site or

00:46:36.940 --> 00:46:37.860
something, or you can just

00:46:37.860 --> 00:46:40.480
do it to an entire package

00:46:40.480 --> 00:46:41.700
or entire modules rather.

00:46:41.700 --> 00:46:43.740
So just run bear type

00:46:43.740 --> 00:46:45.200
dot claw import bear type

00:46:45.200 --> 00:46:45.440
this.

00:46:45.540 --> 00:46:47.380
And then it actually turns

00:46:47.380 --> 00:46:49.020
into runtime type checks.

00:46:49.640 --> 00:46:51.240
Good idea, bad idea.

00:46:51.440 --> 00:46:51.800
Interesting.

00:46:52.380 --> 00:46:53.060
What do you all think?

00:46:53.340 --> 00:46:54.860
So un-Pythonic, you won't

00:46:54.860 --> 00:46:55.920
even open the webpage.

00:46:56.060 --> 00:46:57.320
People should feel free to

00:46:57.320 --> 00:46:58.800
write whatever code helps

00:46:58.800 --> 00:47:00.220
them make like better

00:47:00.220 --> 00:47:00.600
software.

00:47:01.080 --> 00:47:01.940
I haven't really used

00:47:01.940 --> 00:47:02.840
bear type much myself,

00:47:03.040 --> 00:47:04.240
but it's clearly useful for

00:47:04.240 --> 00:47:04.700
some people.

00:47:05.020 --> 00:47:06.200
And I think generally in

00:47:06.200 --> 00:47:07.300
designing a type system,

00:47:07.400 --> 00:47:08.180
we should try to

00:47:08.180 --> 00:47:09.580
accommodate all users who

00:47:09.580 --> 00:47:10.460
do useful things to the

00:47:10.460 --> 00:47:10.980
type system.

00:47:10.980 --> 00:47:12.000
And that includes things

00:47:12.000 --> 00:47:13.020
like Pydentic or bear

00:47:13.020 --> 00:47:13.280
type.

00:47:13.400 --> 00:47:14.240
It's pretty fast.

00:47:14.360 --> 00:47:15.900
It's not as big of a hit

00:47:15.900 --> 00:47:17.540
as you would, you would

00:47:17.540 --> 00:47:17.920
imagine.

00:47:18.580 --> 00:47:19.360
They, let me see, what

00:47:19.360 --> 00:47:20.560
are they, somewhere they

00:47:20.560 --> 00:47:21.960
had a really fun, fun

00:47:21.960 --> 00:47:23.240
saying in here, but here

00:47:23.240 --> 00:47:23.560
we go.

00:47:24.100 --> 00:47:25.640
Bear type brings Rust C++

00:47:25.640 --> 00:47:26.780
inspired zero cost

00:47:26.780 --> 00:47:27.860
abstractions into the

00:47:27.860 --> 00:47:29.400
lawless world of dynamically

00:47:29.400 --> 00:47:31.020
typed Python by enforcing

00:47:31.020 --> 00:47:32.360
type safety at the granular

00:47:32.360 --> 00:47:33.660
level of functions and

00:47:33.660 --> 00:47:35.540
methods against type hints

00:47:35.540 --> 00:47:36.800
standardized by the Python

00:47:36.800 --> 00:47:37.260
community.

00:47:37.260 --> 00:47:39.260
order one, non-amortized

00:47:39.260 --> 00:47:40.200
worst case time with

00:47:40.200 --> 00:47:41.420
negligible constant factors.

00:47:41.520 --> 00:47:42.240
Like, how about that?

00:47:43.180 --> 00:47:43.940
No, it's a pretty neat

00:47:43.940 --> 00:47:44.820
library and it's pretty

00:47:44.820 --> 00:47:45.120
fast.

00:47:45.240 --> 00:47:46.660
I honestly, I've never used

00:47:46.660 --> 00:47:47.200
it in production.

00:47:47.720 --> 00:47:49.680
Having type hints and

00:47:49.680 --> 00:47:50.840
squigglies in the editors

00:47:50.840 --> 00:47:53.540
or in the linters has always

00:47:53.540 --> 00:47:54.880
been enough for me, but I

00:47:54.880 --> 00:47:56.120
can see using this if it's

00:47:56.120 --> 00:47:57.520
really critical and you're

00:47:57.520 --> 00:47:58.460
having issues, maybe you

00:47:58.460 --> 00:47:59.600
want to catch some runtime

00:47:59.600 --> 00:48:00.000
errors.

00:48:00.340 --> 00:48:00.720
I don't know.

00:48:00.960 --> 00:48:02.000
It's not quite an endorsement,

00:48:02.120 --> 00:48:03.300
but it sure is like a, huh,

00:48:03.400 --> 00:48:04.340
that's different.

00:48:04.340 --> 00:48:06.120
I definitely think that the

00:48:06.120 --> 00:48:08.240
extent to which type

00:48:08.240 --> 00:48:10.820
checkers may have a

00:48:10.820 --> 00:48:11.760
different understanding of

00:48:11.760 --> 00:48:12.780
your code from what happens

00:48:12.780 --> 00:48:14.040
at runtime and there isn't

00:48:14.040 --> 00:48:15.660
anything built in to catch

00:48:15.660 --> 00:48:17.420
that is sometimes a pain

00:48:17.420 --> 00:48:17.740
point.

00:48:18.160 --> 00:48:19.300
And so the desire to have

00:48:19.300 --> 00:48:20.860
your type annotations, to

00:48:20.860 --> 00:48:22.360
find out at runtime if your

00:48:22.360 --> 00:48:23.420
type annotations are telling

00:48:23.420 --> 00:48:24.880
you a lie, it makes a lot of

00:48:24.880 --> 00:48:26.560
sense why people would like

00:48:26.560 --> 00:48:26.860
that.

00:48:27.140 --> 00:48:27.500
I mean, it's something

00:48:27.500 --> 00:48:28.980
used to from other languages

00:48:28.980 --> 00:48:30.080
where the type checker is built

00:48:30.080 --> 00:48:30.760
into the compiler.

00:48:30.920 --> 00:48:31.100
Right.

00:48:31.160 --> 00:48:32.480
You get like a runtime type

00:48:32.480 --> 00:48:33.400
cast, like cannot.

00:48:33.400 --> 00:48:35.280
We kind of get that if you

00:48:35.280 --> 00:48:37.480
try to parse a thing, you

00:48:37.480 --> 00:48:38.860
know, like put the int

00:48:38.860 --> 00:48:40.280
param around a string and

00:48:40.280 --> 00:48:41.840
it's not really a parsable

00:48:41.840 --> 00:48:42.280
as an int.

00:48:42.460 --> 00:48:43.740
But for like real type

00:48:43.740 --> 00:48:44.720
information, I think

00:48:44.720 --> 00:48:45.860
personally I would use this

00:48:45.860 --> 00:48:48.280
as like I might apply types,

00:48:48.700 --> 00:48:50.480
type checking to a module

00:48:50.480 --> 00:48:52.780
for debugging and development

00:48:52.780 --> 00:48:53.700
for a minute and just see

00:48:53.700 --> 00:48:54.500
what happens and then turn

00:48:54.500 --> 00:48:55.000
it back off.

00:48:55.280 --> 00:48:55.880
You know, I don't know that

00:48:55.880 --> 00:48:57.420
I'd just ship production code

00:48:57.420 --> 00:48:57.820
that way.

00:48:58.140 --> 00:48:59.760
But anyway, I got a couple

00:48:59.760 --> 00:49:00.760
more questions.

00:49:00.880 --> 00:49:01.680
We're getting shorter on

00:49:01.680 --> 00:49:02.280
time here.

00:49:02.620 --> 00:49:03.520
What was one of the

00:49:03.520 --> 00:49:05.400
harder questions that you

00:49:05.400 --> 00:49:07.240
all, harder decisions you

00:49:07.240 --> 00:49:09.420
all had to address on the

00:49:09.420 --> 00:49:09.700
council?

00:49:09.700 --> 00:49:10.440
I think the most

00:49:10.440 --> 00:49:11.620
contentious one was

00:49:11.620 --> 00:49:14.680
PEP 724, if I remember

00:49:14.680 --> 00:49:15.520
the number correctly.

00:49:15.940 --> 00:49:17.460
It was around a feature

00:49:17.460 --> 00:49:19.020
called type guards, which

00:49:19.020 --> 00:49:20.660
is around user-defined type

00:49:20.660 --> 00:49:21.540
narrowing functions.

00:49:22.040 --> 00:49:23.100
Initially, they find that in

00:49:23.100 --> 00:49:24.740
a way that later was found

00:49:24.740 --> 00:49:25.820
to be somewhat problematic

00:49:25.820 --> 00:49:27.600
and we basically came up

00:49:27.600 --> 00:49:28.420
with a better set of

00:49:28.420 --> 00:49:30.000
proposed semantics that

00:49:30.000 --> 00:49:30.900
maybe we should have done

00:49:30.900 --> 00:49:32.980
the first time around.

00:49:33.520 --> 00:49:35.060
And what this PEP proposed,

00:49:35.300 --> 00:49:36.080
and as you can see, I

00:49:36.080 --> 00:49:37.840
sponsored it, is that we

00:49:37.840 --> 00:49:38.660
basically changed the

00:49:38.660 --> 00:49:39.420
meaning of the existing

00:49:39.420 --> 00:49:40.940
type guards under certain

00:49:40.940 --> 00:49:41.500
conditions.

00:49:41.800 --> 00:49:42.620
What is a type guard?

00:49:42.820 --> 00:49:43.780
A type guard is a function,

00:49:43.940 --> 00:49:44.840
like there's a good example

00:49:44.840 --> 00:49:45.780
there, the isiterable.

00:49:46.220 --> 00:49:47.980
It's a function that tells

00:49:47.980 --> 00:49:49.680
you how to narrow something.

00:49:50.240 --> 00:49:52.040
So in this example, there's

00:49:52.040 --> 00:49:53.320
an isiterable type guard,

00:49:53.480 --> 00:49:55.240
which narrows an object to

00:49:55.240 --> 00:49:56.280
an iterable of anything.

00:49:56.680 --> 00:49:58.400
And then inside the func

00:49:58.400 --> 00:49:59.840
there, you can see if

00:49:59.840 --> 00:50:01.860
isiterable file, it knows

00:50:01.860 --> 00:50:03.740
that it's an iterable.

00:50:04.320 --> 00:50:06.200
And in this case, yeah, I

00:50:06.200 --> 00:50:07.000
guess it just narrows

00:50:07.000 --> 00:50:08.200
exactly to iterable any.

00:50:08.600 --> 00:50:09.520
That's one of the ways that

00:50:09.520 --> 00:50:10.500
type guards works.

00:50:10.760 --> 00:50:10.940
I see.

00:50:11.040 --> 00:50:12.320
And the type that returns

00:50:12.320 --> 00:50:14.020
kind of communicates to the

00:50:14.020 --> 00:50:15.680
type system, like that this

00:50:15.680 --> 00:50:18.280
function ensures that this,

00:50:18.560 --> 00:50:19.760
the thing that came in as an

00:50:19.760 --> 00:50:21.160
arbitrary object, in fact,

00:50:21.220 --> 00:50:22.040
is one of these.

00:50:22.380 --> 00:50:22.660
Okay.

00:50:22.800 --> 00:50:23.180
Interesting.

00:50:23.600 --> 00:50:23.740
Yeah.

00:50:23.840 --> 00:50:25.200
So that was a tricky one,

00:50:25.260 --> 00:50:25.400
huh?

00:50:25.740 --> 00:50:27.400
Any other standout, Rebecca or

00:50:27.400 --> 00:50:27.620
Carl?

00:50:27.620 --> 00:50:28.740
Well, the current discussion

00:50:28.740 --> 00:50:29.800
around what is the meaning

00:50:29.800 --> 00:50:32.020
of a float annotation, still

00:50:32.020 --> 00:50:33.960
unresolved, contentious topic.

00:50:34.360 --> 00:50:34.760
Okay.

00:50:34.920 --> 00:50:35.180
Gotcha.

00:50:35.420 --> 00:50:38.720
I mean, this on PEP724 is

00:50:38.720 --> 00:50:41.180
also what came to my mind

00:50:41.180 --> 00:50:42.900
immediately as well, because

00:50:42.900 --> 00:50:44.280
this was challenging

00:50:44.280 --> 00:50:45.560
discussion because, you

00:50:45.560 --> 00:50:47.140
know, like there were very

00:50:47.140 --> 00:50:48.840
conflicting considerations at

00:50:48.840 --> 00:50:49.140
play.

00:50:49.300 --> 00:50:50.660
It's like, what semantics

00:50:50.660 --> 00:50:52.000
did we want in the long

00:50:52.000 --> 00:50:52.420
term?

00:50:52.620 --> 00:50:53.580
And what did we want the

00:50:53.580 --> 00:50:55.220
type system to look like,

00:50:55.280 --> 00:50:56.280
you know, say like 10 years

00:50:56.280 --> 00:50:57.620
from now versus backwards

00:50:57.620 --> 00:50:59.680
compatibility and what the

00:50:59.680 --> 00:51:00.780
migration story would look

00:51:00.780 --> 00:51:01.060
like?

00:51:01.060 --> 00:51:02.120
It was quite tricky.

00:51:02.300 --> 00:51:03.340
I guess that's something you

00:51:03.340 --> 00:51:04.880
will always have to be

00:51:04.880 --> 00:51:07.160
cognizant of is like every

00:51:07.160 --> 00:51:08.400
change, even if it's an

00:51:08.400 --> 00:51:10.400
improvement, has to justify

00:51:10.400 --> 00:51:12.600
the fact that now you have

00:51:12.600 --> 00:51:14.480
challenges with the version

00:51:14.480 --> 00:51:16.440
history over time.

00:51:16.440 --> 00:51:19.880
I'm thinking like dict of string

00:51:19.880 --> 00:51:21.800
comma int with a capital or

00:51:21.800 --> 00:51:22.540
lowercase d.

00:51:22.920 --> 00:51:24.640
I've got people, I did a

00:51:24.640 --> 00:51:25.500
YouTube video showing

00:51:25.500 --> 00:51:26.640
something with the lowercase

00:51:26.640 --> 00:51:27.840
version because I was using

00:51:27.840 --> 00:51:29.280
something super modern like

00:51:29.280 --> 00:51:30.260
Python 3.11.

00:51:30.680 --> 00:51:32.260
And I got a message like,

00:51:32.340 --> 00:51:33.600
hey, Michael, you don't know

00:51:33.600 --> 00:51:34.400
how to write Python.

00:51:34.520 --> 00:51:35.400
Your code is broken.

00:51:35.860 --> 00:51:37.220
This code that you wrote just

00:51:37.220 --> 00:51:38.160
doesn't even run.

00:51:38.240 --> 00:51:39.140
I don't know how this is.

00:51:39.280 --> 00:51:40.180
I'm like, what version of

00:51:40.180 --> 00:51:40.740
Python is in?

00:51:40.860 --> 00:51:41.340
3.8.

00:51:41.580 --> 00:51:41.820
Nope.

00:51:41.880 --> 00:51:42.940
You can't use 3.8 for that.

00:51:43.000 --> 00:51:43.620
You're going to need to get a

00:51:43.620 --> 00:51:44.040
newer one.

00:51:44.140 --> 00:51:44.580
You know what I mean?

00:51:44.880 --> 00:51:47.240
But like those are complexities

00:51:47.240 --> 00:51:48.540
that get added to Python

00:51:48.540 --> 00:51:49.820
because of that.

00:51:49.900 --> 00:51:51.000
Now you've got two ways to

00:51:51.000 --> 00:51:52.680
specify what a dict is.

00:51:52.840 --> 00:51:54.000
There's a preferred new way,

00:51:54.080 --> 00:51:55.080
but there's still the old way

00:51:55.080 --> 00:51:57.440
and it just, it sort of piles

00:51:57.440 --> 00:51:57.780
up.

00:51:58.000 --> 00:51:58.880
And it's very hard to ever

00:51:58.880 --> 00:51:59.840
actually get rid of the old

00:51:59.840 --> 00:52:00.940
way, even if there's no good

00:52:00.940 --> 00:52:01.820
reason to use it anymore.

00:52:01.960 --> 00:52:02.280
Exactly.

00:52:02.440 --> 00:52:04.020
Once it's there, it's written

00:52:04.020 --> 00:52:05.540
in ink pretty much, right?

00:52:05.580 --> 00:52:06.880
Like we have five or six

00:52:06.880 --> 00:52:07.680
different ways to format

00:52:07.680 --> 00:52:08.120
strings.

00:52:08.220 --> 00:52:09.920
Maybe with t-strings at six

00:52:09.920 --> 00:52:10.200
now.

00:52:10.560 --> 00:52:11.380
They're all going to still be

00:52:11.380 --> 00:52:12.160
there, right?

00:52:12.160 --> 00:52:13.520
So every change, every

00:52:13.520 --> 00:52:14.560
decision you make is not

00:52:14.560 --> 00:52:16.420
just a matter of, is it the

00:52:16.420 --> 00:52:17.420
right decision, right?

00:52:17.660 --> 00:52:19.580
It's the, is it worth it?

00:52:19.720 --> 00:52:20.140
I'm sure.

00:52:20.620 --> 00:52:20.840
Yeah.

00:52:21.200 --> 00:52:21.460
I don't know.

00:52:21.460 --> 00:52:22.300
How do you all balance that?

00:52:22.400 --> 00:52:23.660
Like that's tricky.

00:52:23.820 --> 00:52:24.540
With things like the dict

00:52:24.540 --> 00:52:25.860
chains, at least we sort of

00:52:25.860 --> 00:52:27.060
know we're moving towards

00:52:27.060 --> 00:52:29.720
better states and there's two

00:52:29.720 --> 00:52:30.860
things, but they mean exactly

00:52:30.860 --> 00:52:31.580
the same thing.

00:52:31.720 --> 00:52:33.700
So the confusion is not as

00:52:33.700 --> 00:52:34.040
bad.

00:52:34.460 --> 00:52:35.600
The problem with type cards

00:52:35.600 --> 00:52:36.700
is that we're going to change

00:52:36.700 --> 00:52:38.200
how some existing thing

00:52:38.200 --> 00:52:39.720
works, like what it meant.

00:52:39.720 --> 00:52:41.360
And I think there are good

00:52:41.360 --> 00:52:42.260
reasons that maybe that's the

00:52:42.260 --> 00:52:43.640
right thing to do, but the,

00:52:44.120 --> 00:52:45.340
it would also have been pretty

00:52:45.340 --> 00:52:46.400
confusing for people if their

00:52:46.400 --> 00:52:47.820
existing types suddenly started

00:52:47.820 --> 00:52:48.640
meaning something completely

00:52:48.640 --> 00:52:48.980
different.

00:52:49.320 --> 00:52:49.680
Absolutely.

00:52:50.180 --> 00:52:50.760
Hence float.

00:52:51.120 --> 00:52:51.460
Okay.

00:52:51.940 --> 00:52:53.000
What's coming next?

00:52:53.120 --> 00:52:55.920
Like 3.15, 3.16, do you all

00:52:55.920 --> 00:52:57.800
have things that are in the works

00:52:57.800 --> 00:52:58.880
that you think are going to come

00:52:58.880 --> 00:53:00.980
or debates that are brewing?

00:53:01.180 --> 00:53:03.320
For 3.15, the, there's a type

00:53:03.320 --> 00:53:04.940
dict feature coming, extra

00:53:04.940 --> 00:53:05.400
items.

00:53:05.400 --> 00:53:07.040
you can already use it in

00:53:07.040 --> 00:53:08.740
tapping extensions if you want

00:53:08.740 --> 00:53:10.560
to use it, but it will be in

00:53:10.560 --> 00:53:11.940
CPath as of 2.15.

00:53:12.100 --> 00:53:13.720
It's likely we'll have a small

00:53:13.720 --> 00:53:14.980
thing I added called disjoint

00:53:14.980 --> 00:53:16.900
basis, which is very technical,

00:53:17.140 --> 00:53:18.620
but helps type narrowing in some

00:53:18.620 --> 00:53:19.040
cases.

00:53:19.440 --> 00:53:19.540
Yeah.

00:53:19.540 --> 00:53:20.240
I think those are the things

00:53:20.240 --> 00:53:21.960
that are likely to make it.

00:53:22.440 --> 00:53:23.800
There's, we can only speculate

00:53:23.800 --> 00:53:24.900
about what else people can

00:53:24.900 --> 00:53:25.280
propose.

00:53:25.380 --> 00:53:26.380
We're sort of bound by what

00:53:26.380 --> 00:53:27.440
people actually write up as

00:53:27.440 --> 00:53:27.760
peps.

00:53:28.060 --> 00:53:28.860
We have to wait for Google to

00:53:28.860 --> 00:53:29.760
write the peps before we can

00:53:29.760 --> 00:53:30.200
approve them.

00:53:30.200 --> 00:53:32.240
I think there's PEP 747 for

00:53:32.240 --> 00:53:34.100
type form, which I think is

00:53:34.100 --> 00:53:35.820
not, I think we recommended

00:53:35.820 --> 00:53:37.260
its acceptance, but I don't

00:53:37.260 --> 00:53:38.140
think the steering council

00:53:38.140 --> 00:53:39.340
accepted it yet or it hasn't

00:53:39.340 --> 00:53:40.240
been accepted formally.

00:53:40.400 --> 00:53:41.040
I think that's on their

00:53:41.040 --> 00:53:41.500
plate.

00:53:41.660 --> 00:53:41.820
Yeah.

00:53:42.180 --> 00:53:42.380
Yeah.

00:53:42.400 --> 00:53:43.740
So that's also pretty likely

00:53:43.740 --> 00:53:45.180
to make it into 3.15.

00:53:45.320 --> 00:53:46.720
This is one example of a

00:53:46.720 --> 00:53:47.780
case that will be pretty

00:53:47.780 --> 00:53:49.180
useful to people working

00:53:49.180 --> 00:53:50.880
with type annotations at

00:53:50.880 --> 00:53:52.300
runtime because it'll allow

00:53:52.300 --> 00:53:53.940
you to, it's sort of a meta

00:53:53.940 --> 00:53:55.960
thing where you can annotate,

00:53:56.760 --> 00:53:57.900
have a type annotation that

00:53:57.900 --> 00:53:58.960
describes another type

00:53:58.960 --> 00:53:59.400
annotation.

00:53:59.940 --> 00:54:00.940
So that's useful if you're,

00:54:01.000 --> 00:54:02.040
if you're writing code that

00:54:02.040 --> 00:54:03.240
works with type annotations.

00:54:03.240 --> 00:54:04.620
Make the peidantics of the

00:54:04.620 --> 00:54:05.400
world very happy.

00:54:05.540 --> 00:54:07.620
I am actually pretty excited

00:54:07.620 --> 00:54:09.780
about type form because,

00:54:10.060 --> 00:54:10.760
you know, I feel like there's

00:54:10.760 --> 00:54:12.100
a gap and we can express in

00:54:12.100 --> 00:54:13.460
the type system and we're

00:54:13.460 --> 00:54:14.380
good.

00:54:14.680 --> 00:54:15.760
And there are cases in the

00:54:15.760 --> 00:54:17.780
existing type system, like

00:54:17.780 --> 00:54:18.740
for instance, the cast

00:54:18.740 --> 00:54:20.360
function and some other

00:54:20.360 --> 00:54:22.320
cases where something takes

00:54:22.320 --> 00:54:24.120
any type expression as an

00:54:24.120 --> 00:54:24.400
argument.

00:54:24.520 --> 00:54:25.220
We actually don't have a good

00:54:25.220 --> 00:54:27.000
way to annotate that today

00:54:27.000 --> 00:54:28.040
and this will provide a nice

00:54:28.040 --> 00:54:28.880
way to express that.

00:54:28.960 --> 00:54:30.000
Let me pull up one thing

00:54:30.000 --> 00:54:30.680
really quick.

00:54:31.020 --> 00:54:31.840
Quick shout out to Will

00:54:31.840 --> 00:54:32.500
McGuggan here.

00:54:32.500 --> 00:54:33.800
He just released his

00:54:33.800 --> 00:54:35.760
Toad project, which is the

00:54:35.760 --> 00:54:38.400
new, takes textual and rich

00:54:38.400 --> 00:54:39.580
and all that kind of stuff

00:54:39.580 --> 00:54:40.980
and applies it to like, what

00:54:40.980 --> 00:54:42.300
if we had a better cloud code

00:54:42.300 --> 00:54:43.460
type of experience, which is

00:54:43.460 --> 00:54:43.980
pretty interesting.

00:54:44.560 --> 00:54:45.440
So the reason I'm bringing

00:54:45.440 --> 00:54:47.200
this up is, you know, final

00:54:47.200 --> 00:54:47.620
question.

00:54:47.840 --> 00:54:49.560
What about, do you all even

00:54:49.560 --> 00:54:52.680
worry about the role of like

00:54:52.680 --> 00:54:54.480
how types interact with AI

00:54:54.480 --> 00:54:56.120
and agentic coding tools?

00:54:56.120 --> 00:54:58.980
I know that if you have some

00:54:58.980 --> 00:55:00.660
code that has types on it

00:55:00.660 --> 00:55:02.300
and you give it to an AI, it's

00:55:02.300 --> 00:55:03.340
got a better chance of

00:55:03.340 --> 00:55:04.280
understanding what's happening

00:55:04.280 --> 00:55:05.880
than if you give it purely

00:55:05.880 --> 00:55:07.560
untyped code and say, tell me

00:55:07.560 --> 00:55:08.300
about this, right?

00:55:08.340 --> 00:55:09.540
It doesn't even know necessarily

00:55:09.540 --> 00:55:10.580
what's being passed to it.

00:55:10.720 --> 00:55:12.160
But is that anything you'll

00:55:12.160 --> 00:55:13.320
think about or what are your

00:55:13.320 --> 00:55:14.500
thoughts on this?

00:55:14.760 --> 00:55:15.660
Certainly think about it some.

00:55:15.860 --> 00:55:17.460
I mean, I think overall my

00:55:17.460 --> 00:55:19.500
feeling is that these coding

00:55:19.500 --> 00:55:21.200
agents seem to do better than

00:55:21.200 --> 00:55:23.700
more kind of the tighter

00:55:23.700 --> 00:55:25.120
feedback loops you can give them

00:55:25.120 --> 00:55:25.760
to work with.

00:55:26.020 --> 00:55:27.080
And so typing is another

00:55:27.080 --> 00:55:28.400
useful source of feedback

00:55:28.400 --> 00:55:29.840
where you can say, add type

00:55:29.840 --> 00:55:30.880
annotations and make sure the

00:55:30.880 --> 00:55:32.920
type checker passes and seems

00:55:32.920 --> 00:55:34.600
so it still seems pretty useful

00:55:34.600 --> 00:55:35.140
in that world.

00:55:35.240 --> 00:55:36.340
Yeah, you can easily write

00:55:36.340 --> 00:55:38.120
rules that say when you are

00:55:38.120 --> 00:55:39.540
done on anything I've asked

00:55:39.540 --> 00:55:42.340
you to do, always run ty or

00:55:42.340 --> 00:55:43.760
always run Pyrefly and make

00:55:43.760 --> 00:55:45.180
sure that there's no more, no

00:55:45.180 --> 00:55:46.720
new errors or at least or

00:55:46.720 --> 00:55:48.240
ideally zero errors, right?

00:55:48.320 --> 00:55:49.340
But nothing has been

00:55:49.340 --> 00:55:49.840
introduced.

00:55:50.220 --> 00:55:50.800
Yeah, pretty interesting.

00:55:51.360 --> 00:55:52.820
You other folks, Rebecca,

00:55:53.260 --> 00:55:53.440
Yela?

00:55:53.700 --> 00:55:54.560
Yeah, I guess in general, I

00:55:54.560 --> 00:55:55.460
think typing will remain

00:55:55.460 --> 00:55:57.040
useful for AI.

00:55:57.400 --> 00:55:58.180
We are probably rapidly

00:55:58.180 --> 00:55:59.780
moving to a world where a

00:55:59.780 --> 00:56:00.960
large proportion of all code

00:56:00.960 --> 00:56:01.940
is written by AI.

00:56:02.120 --> 00:56:03.020
Not everybody likes that

00:56:03.020 --> 00:56:03.620
opinion, Yael.

00:56:03.640 --> 00:56:04.440
Not everybody likes that.

00:56:04.660 --> 00:56:06.760
I guess I, maybe my current

00:56:06.760 --> 00:56:07.780
line of work makes me think

00:56:07.780 --> 00:56:08.820
that's more likely to happen.

00:56:08.940 --> 00:56:09.900
You don't have to like the

00:56:09.900 --> 00:56:10.800
fact it's going to be night

00:56:10.800 --> 00:56:11.840
soon, but it's going to be

00:56:11.840 --> 00:56:11.980
night.

00:56:12.040 --> 00:56:12.380
You know what I mean?

00:56:12.420 --> 00:56:14.080
Like there's the, I just

00:56:14.080 --> 00:56:14.900
think there's so much

00:56:14.900 --> 00:56:16.220
momentum on this, at least in

00:56:16.220 --> 00:56:17.460
the next five years or

00:56:17.460 --> 00:56:18.260
something, that it's going to

00:56:18.260 --> 00:56:19.400
be really, it's, it's a

00:56:19.400 --> 00:56:21.320
truth of how many people are

00:56:21.320 --> 00:56:22.360
writing code regardless of

00:56:22.360 --> 00:56:23.920
whether individuals want to

00:56:23.920 --> 00:56:24.640
write code that way.

00:56:24.840 --> 00:56:25.180
You know what I mean?

00:56:25.200 --> 00:56:25.780
So I think it's a

00:56:25.780 --> 00:56:26.200
consideration.

00:56:26.380 --> 00:56:26.460
Yeah.

00:56:26.460 --> 00:56:26.640
Yeah.

00:56:26.700 --> 00:56:27.740
I forgot that you worked

00:56:27.740 --> 00:56:28.160
at OpenAI.

00:56:28.300 --> 00:56:30.920
So of course, I should pull

00:56:30.920 --> 00:56:32.060
up a codex example or

00:56:32.060 --> 00:56:32.840
something, shouldn't I?

00:56:32.960 --> 00:56:33.100
Yeah.

00:56:33.180 --> 00:56:33.820
Codex is great.

00:56:33.900 --> 00:56:34.220
Use it.

00:56:34.360 --> 00:56:35.160
No, but I mean, do you

00:56:35.160 --> 00:56:36.780
have any further insight into

00:56:36.780 --> 00:56:38.840
like the role of types

00:56:38.840 --> 00:56:39.660
and coding agents?

00:56:40.040 --> 00:56:40.900
I know that's not exactly

00:56:40.900 --> 00:56:41.700
what you work on, right?

00:56:41.740 --> 00:56:42.600
You're more at the lower.

00:56:42.740 --> 00:56:43.900
As Carl said, types can

00:56:43.900 --> 00:56:45.720
also be helpful for AI to

00:56:45.720 --> 00:56:47.060
understand code better and to

00:56:47.060 --> 00:56:48.020
get a better feedback loop.

00:56:48.320 --> 00:56:49.700
I feel like the very big AI,

00:56:49.700 --> 00:56:50.740
the board is like humans.

00:56:51.060 --> 00:56:53.140
And if AI makes, sorry, if

00:56:53.140 --> 00:56:54.800
typing makes humans better

00:56:54.800 --> 00:56:55.940
at writing understanding

00:56:55.940 --> 00:56:56.780
this code, they're probably

00:56:56.780 --> 00:56:58.560
also big AI better at it.

00:56:58.620 --> 00:56:59.540
It's the locality of

00:56:59.540 --> 00:56:59.940
information.

00:57:00.080 --> 00:57:01.120
You can read the function

00:57:01.120 --> 00:57:03.100
and know everything you need

00:57:03.100 --> 00:57:03.900
to know about what's going

00:57:03.900 --> 00:57:05.660
into it without bouncing

00:57:05.660 --> 00:57:06.720
around and trying to

00:57:06.720 --> 00:57:07.780
understand blocks of code

00:57:07.780 --> 00:57:08.660
and like what might've been

00:57:08.660 --> 00:57:09.320
created that's getting

00:57:09.320 --> 00:57:09.580
impacted.

00:57:09.740 --> 00:57:10.980
It's good for humans and

00:57:10.980 --> 00:57:11.980
also good for AI.

00:57:12.160 --> 00:57:12.300
Right.

00:57:12.600 --> 00:57:12.880
Rebecca.

00:57:12.980 --> 00:57:13.700
Because I don't have much

00:57:14.240 --> 00:57:15.920
need to, and I'll say I am

00:57:15.920 --> 00:57:18.320
maybe a little more skeptical

00:57:18.320 --> 00:57:20.680
than most of my coworkers

00:57:20.680 --> 00:57:22.040
about the quality of AI

00:57:22.040 --> 00:57:23.360
generated code.

00:57:23.500 --> 00:57:25.500
But that means I think I am

00:57:25.500 --> 00:57:27.700
particularly gung-ho about,

00:57:27.800 --> 00:57:29.860
you know, like get AI to use

00:57:29.860 --> 00:57:32.200
types, type checkers, keep

00:57:32.200 --> 00:57:33.400
the guardrails there.

00:57:33.600 --> 00:57:34.300
I think that'll be very

00:57:34.300 --> 00:57:34.540
important.

00:57:34.540 --> 00:57:35.160
Yeah, if it's going to make

00:57:35.160 --> 00:57:36.440
a mistake, don't let it at

00:57:36.440 --> 00:57:38.180
least like make the type

00:57:38.180 --> 00:57:39.720
system become disconnected

00:57:39.720 --> 00:57:40.820
and not working.

00:57:40.980 --> 00:57:42.600
Like it has to keep the types

00:57:42.600 --> 00:57:43.560
hanging together as a

00:57:43.560 --> 00:57:44.360
minimum bar, right?

00:57:44.360 --> 00:57:45.760
And you can easily set that

00:57:45.760 --> 00:57:46.500
up as an automation.

00:57:46.980 --> 00:57:47.140
Yeah.

00:57:47.220 --> 00:57:48.220
Interesting to think of it as

00:57:48.220 --> 00:57:49.740
guardrails rather than an

00:57:49.740 --> 00:57:50.280
accelerant.

00:57:50.520 --> 00:57:51.860
But yeah, 100% it is.

00:57:52.140 --> 00:57:52.760
All right, folks.

00:57:52.900 --> 00:57:54.120
I think that's it for all

00:57:54.120 --> 00:57:55.240
the time that we have.

00:57:55.640 --> 00:57:55.960
Thank you.

00:57:56.000 --> 00:57:56.800
Thank you for being here.

00:57:57.240 --> 00:57:59.040
Final thoughts before we go.

00:57:59.340 --> 00:58:00.280
Carl, I'll let you go first.

00:58:00.600 --> 00:58:01.260
Final thoughts for people

00:58:01.260 --> 00:58:02.020
out there interested in

00:58:02.020 --> 00:58:02.520
Python typing.

00:58:02.740 --> 00:58:02.900
Yeah.

00:58:02.960 --> 00:58:03.740
Well, first of all, thanks

00:58:03.740 --> 00:58:05.540
for having us on the podcast.

00:58:05.640 --> 00:58:06.520
Really appreciate it.

00:58:06.860 --> 00:58:07.840
And thoughts for people

00:58:07.840 --> 00:58:08.340
out there.

00:58:08.680 --> 00:58:10.660
I guess if you have ideas

00:58:10.660 --> 00:58:12.400
of how Python typing could

00:58:12.400 --> 00:58:14.340
be improved, discuss.python.

00:58:14.360 --> 00:58:15.300
Python.org is a good

00:58:15.300 --> 00:58:16.760
place to bring up ideas

00:58:16.760 --> 00:58:18.180
and discuss them with the

00:58:18.180 --> 00:58:19.900
typing community and see

00:58:19.900 --> 00:58:21.160
what positive changes we

00:58:21.160 --> 00:58:21.420
can make.

00:58:22.080 --> 00:58:22.400
Rebecca.

00:58:22.580 --> 00:58:24.040
First, thank you, Michael.

00:58:24.120 --> 00:58:25.760
This is a lot of fun.

00:58:26.760 --> 00:58:27.680
Last thoughts?

00:58:28.240 --> 00:58:30.180
Hey, so, you know, like

00:58:30.180 --> 00:58:31.260
we'll look at the typing

00:58:31.260 --> 00:58:32.500
council and sometimes think,

00:58:32.780 --> 00:58:33.480
oh, you know, like the

00:58:33.480 --> 00:58:34.280
PEP has like governance

00:58:34.280 --> 00:58:35.640
in its name, but I

00:58:35.640 --> 00:58:37.200
wouldn't say we're really

00:58:37.200 --> 00:58:39.300
a governing body or

00:58:39.300 --> 00:58:39.720
anything.

00:58:39.720 --> 00:58:42.120
It's like people who are

00:58:42.120 --> 00:58:43.300
using the type system,

00:58:43.480 --> 00:58:44.780
like users, they're the

00:58:44.780 --> 00:58:45.520
ones who come up with,

00:58:45.580 --> 00:58:46.140
you know, like all the

00:58:46.140 --> 00:58:47.840
best ideas, propose them,

00:58:47.940 --> 00:58:48.640
discuss them.

00:58:48.640 --> 00:58:50.500
And we're just here to

00:58:50.500 --> 00:58:52.940
sort of be like, hey,

00:58:53.040 --> 00:58:53.840
you know, like we have

00:58:53.840 --> 00:58:55.140
some background and like

00:58:55.140 --> 00:58:56.560
how type checkers work and

00:58:56.560 --> 00:58:57.420
maybe some of the history

00:58:57.420 --> 00:58:58.940
and we can provide input.

00:58:58.940 --> 00:59:00.040
But I just encourage

00:59:00.040 --> 00:59:00.740
people, if there's a

00:59:00.740 --> 00:59:02.120
change you want to see in

00:59:02.120 --> 00:59:03.740
the type system, you know,

00:59:03.740 --> 00:59:05.400
like propose it yourself.

00:59:05.400 --> 00:59:06.980
It's very friendly and

00:59:06.980 --> 00:59:07.680
open community.

00:59:07.880 --> 00:59:07.940
Yeah.

00:59:08.020 --> 00:59:09.080
Now people who have

00:59:09.080 --> 00:59:10.560
listened know a little bit

00:59:10.560 --> 00:59:11.460
more about how to do so.

00:59:11.680 --> 00:59:11.920
Awesome.

00:59:12.100 --> 00:59:12.320
Thanks.

00:59:12.640 --> 00:59:13.440
Jale, final word.

00:59:13.620 --> 00:59:13.760
Yeah.

00:59:13.840 --> 00:59:14.920
Also, again, thank you for

00:59:14.920 --> 00:59:15.600
having me here.

00:59:16.000 --> 00:59:17.040
It's been great talking to

00:59:17.040 --> 00:59:17.480
all of you.

00:59:17.700 --> 00:59:18.360
I guess what I want to say

00:59:18.360 --> 00:59:18.940
is similar to what

00:59:18.940 --> 00:59:19.920
Karin Rebecca just said.

00:59:20.300 --> 00:59:21.220
If you want to have

00:59:21.220 --> 00:59:22.220
something changed to the

00:59:22.220 --> 00:59:23.140
type system, I'd really

00:59:23.140 --> 00:59:24.540
encourage you to sign up

00:59:24.540 --> 00:59:25.680
for discuss.python.org,

00:59:25.800 --> 00:59:26.920
make a proposal, go

00:59:26.920 --> 00:59:27.680
through the process.

00:59:27.920 --> 00:59:28.620
It can be somewhat

00:59:28.620 --> 00:59:29.500
daunting, perhaps,

00:59:29.620 --> 00:59:30.700
especially if you have to

00:59:30.700 --> 00:59:32.160
create a PEP, but it is

00:59:32.160 --> 00:59:32.500
doable.

00:59:32.960 --> 00:59:34.060
There are several recent

00:59:34.060 --> 00:59:34.980
typing PEPs have just

00:59:34.980 --> 00:59:36.280
been community members

00:59:36.280 --> 00:59:37.880
who saw something they

00:59:37.880 --> 00:59:38.580
wanted to improve,

00:59:38.720 --> 00:59:40.200
proposed a PEP, and saw

00:59:40.200 --> 00:59:40.800
it to completion.

00:59:41.180 --> 00:59:41.900
If there's something you

00:59:41.900 --> 00:59:42.480
want to see in the type

00:59:42.480 --> 00:59:44.240
system, then you can do

00:59:44.240 --> 00:59:44.480
it too.

00:59:44.580 --> 00:59:46.180
Thank you all for keeping

00:59:46.180 --> 00:59:47.120
Python typing going

00:59:47.120 --> 00:59:47.600
strong.

00:59:48.040 --> 00:59:48.880
Really appreciate your

00:59:48.880 --> 00:59:49.560
time on the show.

00:59:49.980 --> 00:59:50.540
See you all later.

00:59:50.640 --> 00:59:50.940
Bye.

00:59:51.080 --> 00:59:51.260
Bye.

00:59:51.260 --> 00:59:54.180
This has been another episode

00:59:54.180 --> 00:59:55.140
of Talk Python To Me.

00:59:55.280 --> 00:59:56.260
Thank you to our sponsors.

00:59:56.440 --> 00:59:57.280
Be sure to check out what

00:59:57.280 --> 00:59:57.720
they're offering.

00:59:57.920 --> 00:59:59.100
It really helps support the

00:59:59.100 --> 00:59:59.280
show.

00:59:59.980 --> 01:00:01.000
Take some stress out of

01:00:01.000 --> 01:00:01.420
your life.

01:00:01.760 --> 01:00:02.920
Get notified immediately

01:00:02.920 --> 01:00:04.600
about errors and performance

01:00:04.600 --> 01:00:06.140
issues in your web or mobile

01:00:06.140 --> 01:00:07.200
applications with Sentry.

01:00:07.680 --> 01:00:09.680
Just visit talkpython.fm

01:00:09.680 --> 01:00:11.420
slash Sentry and get

01:00:11.420 --> 01:00:12.180
started for free.

01:00:12.660 --> 01:00:13.900
Be sure to use our code

01:00:13.900 --> 01:00:15.140
talkpython26.

01:00:15.740 --> 01:00:17.360
That's talkpython, the

01:00:17.360 --> 01:00:19.220
numbers two, six, all one

01:00:19.220 --> 01:00:19.440
word.

01:00:19.820 --> 01:00:20.960
And it's brought to you by

01:00:20.960 --> 01:00:22.900
our Agentic AI programming

01:00:22.900 --> 01:00:24.000
for Python course.

01:00:24.420 --> 01:00:25.600
Learn to work with AI that

01:00:25.600 --> 01:00:26.920
actually understands your

01:00:26.920 --> 01:00:28.500
code base and build real

01:00:28.500 --> 01:00:28.980
features.

01:00:29.480 --> 01:00:30.940
Visit talkpython.fm

01:00:30.940 --> 01:00:33.000
slash agentic dash AI.

01:00:33.560 --> 01:00:35.220
If you or your team needs

01:00:35.220 --> 01:00:36.240
to learn Python, we have

01:00:36.240 --> 01:00:38.220
over 270 hours of beginner

01:00:38.220 --> 01:00:39.740
and advanced courses on

01:00:39.740 --> 01:00:40.820
topics ranging from

01:00:40.820 --> 01:00:42.280
complete beginners to

01:00:42.280 --> 01:00:44.020
async code, Flask, Django,

01:00:44.220 --> 01:00:46.020
HTMX, and even LLMs.

01:00:46.260 --> 01:00:47.340
Best of all, there's no

01:00:47.340 --> 01:00:48.680
subscription in sight.

01:00:48.680 --> 01:00:49.920
Browse the catalog at

01:00:49.920 --> 01:00:50.880
talkpython.fm.

01:00:51.520 --> 01:00:52.360
And if you're not already

01:00:52.360 --> 01:00:53.820
subscribed to the show on

01:00:53.820 --> 01:00:54.660
your favorite podcast

01:00:54.660 --> 01:00:55.800
player, what are you

01:00:55.800 --> 01:00:56.200
waiting for?

01:00:56.660 --> 01:00:57.960
Just search for Python in

01:00:57.960 --> 01:00:58.680
your podcast player.

01:00:58.780 --> 01:00:59.420
We should be right at the

01:00:59.420 --> 01:00:59.660
top.

01:00:59.980 --> 01:01:01.080
If you enjoy that geeky

01:01:01.080 --> 01:01:01.960
rap song, you can

01:01:01.960 --> 01:01:02.960
download the full track.

01:01:03.060 --> 01:01:03.860
The link is actually in

01:01:03.860 --> 01:01:04.760
your podcast blur show

01:01:04.760 --> 01:01:04.980
notes.

01:01:05.540 --> 01:01:06.800
This is your host, Michael

01:01:06.800 --> 01:01:07.100
Kennedy.

01:01:07.300 --> 01:01:08.320
Thank you so much for

01:01:08.320 --> 01:01:08.600
listening.

01:01:08.780 --> 01:01:09.560
I really appreciate it.

01:01:09.960 --> 01:01:10.720
I'll see you next time.

01:01:18.680 --> 01:01:19.680
Voyager.

01:01:19.920 --> 01:01:21.980
Voyager.

01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:21.980


01:01:21.980 --> 01:01:24.760
And we ready to roll

01:01:24.760 --> 01:01:27.540
Upgrading the code

01:01:27.540 --> 01:01:29.960
No fear of getting whole

01:01:29.960 --> 01:01:33.560
We tapped into that modern vibe

01:01:33.560 --> 01:01:34.940
Overcame each storm

01:01:34.940 --> 01:01:36.940
Talk Python To Me

01:01:36.940 --> 01:01:38.400
IceSync is the norm