You're adding type-ins to your Python code.
Your editor is happy, autocomplete is working great,
but then you switch tools
and suddenly there are red squigglies everywhere.
Who decides what a float annotation actually means
or whether passing none where an int is expected
should be an error?
It turns out there's a five-person council
dedicated to exactly these questions
and two brand new Rust-based type checkers
are raising the bar as well.
On this episode, I sit down with three of the members
of the Python Typing Council,
Yela Zylstra, Rebecca Chen, and Carl Meyer
to learn about how the type system is governed,
where the spec and type checkers agree and disagree,
and I get the council's official advice
on how much typing is just enough.
This is Talk Python To Me, episode 539,
recorded January 27th, 2026.
Talk Python To Me, yeah, we ready to roll.
Upgrading the code, no fear of getting old.
Async in the air, new frameworks in sight,
geeky rap on deck.
Quart crew, it's time to unite.
We started in Pyramid, cruising old school lanes,
had that stable base, yeah, sir.
Welcome to Talk Python To Me,
the number one Python podcast for developers
and data scientists.
This is your host, Michael Kennedy.
I'm a PSF fellow who's been coding for over 25 years.
Let's connect on social media.
You'll find me and Talk Python on Mastodon,
Bluesky, and X.
The social links are all in your show notes.
You can find over 10 years of past episodes
at talkpython.fm.
And if you want to be part of the show,
you can join our recording live streams.
That's right, we live stream the raw,
uncut version of each episode on YouTube.
Just visit talkpython.fm/youtube
to see the schedule of upcoming events.
Be sure to subscribe there and press the bell
so you'll get notified anytime we're recording.
This episode is brought to you by Sentry.
Don't let those errors go unnoticed.
Use Sentry like we do here at Talk Python.
Sign up at talkpython.fm/sentry.
And it's brought to you by
our Agentic AI programming for Python course.
Learn to work with AI that actually understands your code base
and build real features.
Visit talkpython.fm/agentic-ai.
Della, Rebecca, and Carl,
welcome to all of you type-loving Pythonistas.
Awesome to have you here on the show.
Thanks for being here.
We're going to talk Python typing,
especially from the perspective of the Python Typing Council,
which honestly, I am a huge fan of Python typing.
It's still something I learned about not too long ago.
So I'm going to be learning along with everyone else,
what it is you all do and so on.
So I'm really excited to be diving into this.
I think since types came to Python,
I think it's made it a little bit more rigorous,
you know, for all those people out there like,
oh, it's not a real language without any form of static typing.
We can't use it on real projects.
I don't know how true that was,
but certainly it's less true now.
You know, you can pick per project.
So it's super cool.
Before we get into all that, though,
let's just go around for a quick introductions.
Jala, welcome to the show.
Awesome to have you here.
Who are you?
Hi, yeah.
Jala, I've been on the Python Typing Council
since the beginning.
I helped set it up a couple of years ago.
Outside of the typing work,
I currently work at OpenAI,
where I work on developer productivity,
which means things like running CI for people
and helping, generally helping people be productive.
I've been working with Python for more than a decade.
Started out because my previous job was mostly in Python
and then got more and more involved with the language.
So let me get this right.
At OpenAI, you're basically helping developers there
have better developer tooling
and common packages and workflows and stuff like that.
Is that kind of the story?
That's right.
Mostly around things that happen in CI,
like running tests efficiently,
figuring out the right tests to run,
getting the right CI workers out.
That sounds very exciting.
Right in the epicenter of all the big tech stuff these days.
Super cool.
Rebecca, hello.
Welcome.
Hey, thanks for having me.
I'm Rebecca.
I've been on the Typing Council also for about three years,
I think, since the, less than three,
since the beginning.
But my day job, I work at Meta on Python typing,
gone Pyrefly, which is a new type checker
and language server written in Rust, still in beta.
Prior to that, I was at Google for eight years,
also on the Python team.
I just, I really like Python.
Yeah, super neat.
I'm a big fan of both Pyrefly and ty,
which will both have representatives here, I know.
And I think it's just a super exciting time for Python types.
And certainly that's one of the reasons.
So very cool.
Carl, welcome back.
Thank you.
Great to be here.
Yeah, Carl Meyer.
I currently work at Astral, where I work on ty,
which is a Python type checker and language server
written in Rust, also in beta.
And yeah, I guess, how did I get into typing?
Or I've been on the Typing Council, not since the beginning.
I think it's been a year and a half.
And yeah, I got into Python typing at the time in 2016, 2017.
I was working at Instagram.
And that was in the very early days of Python typing.
The PEP44, PEP43, the early Python typing PEPs
had recently come out within the last couple of years.
And one of the co-authors of some of those PEPs,
Lukash Lange, was actually sitting at a desk
right next to me at the time.
And at some point, we started to think
that we should try this Python typing stuff
on the Instagram server monolith.
And so I took that on as a side project.
And then it eventually became the main project.
And then it took like three years.
So a lot of Python typing experience there.
There absolutely is.
You know, I think a couple of things
I'd like to touch on there.
First of all, Instagram, is it maybe the biggest Django
deployment in the world?
It's certainly one of the bigger ones, right?
And I think a lot of people don't necessarily
know that a core chunk of Instagram is actually Python, right?
I mean, I don't know if we have any way to know
how big the Django deployments in the wild might be.
But it's certainly a big one.
Yeah, it's definitely a big one.
There were some talks about dismissing the garbage collector
from the Instagram folks.
That wasn't you giving the talk, but at PyCon.
So that was pretty interesting.
But I think actually that work that you're talking about,
especially with Lukash, really kind of opened
a lot of people's eyes about Python typing, right?
He gave a couple of PyCon talks, showed, you know,
real metrics of how much of the code base is typed,
how much it's changed, like error detection,
that kind of stuff.
So let me ask you, do you feel like it would be different?
Would it have gone different now if tools like TY
and Pyrefly existed back then?
Is Python typing different now than it was then?
Certainly, yes.
I mean, there's been, the type system has gotten
more complex over time.
So it is both more expressive and more complex.
And yeah, we have more type checkers available now.
I do agree that it's more complicated,
and I don't know how to feel about that.
It is more expressive, but I feel like it's starting to get,
I mean, we're not at C++ ATL,
like templates of templates of templates,
but still, it's getting more serious.
But I guess one of the really nice parts
is that you can just take as much as you want
of the complexity, and you can just leave the rest, right?
That's part of the magic of Python typing,
is that it's a gradual typing system.
That's a choice people get to make.
It can be none, it can be quite a bit,
and anywhere in between.
So I guess that's probably one of the decisions.
Let's talk about the typing council.
So when did the typing council come along,
and did the typing council exist to create
all of these PEPs and make this happen,
or was it afterwards?
Like, what's the history of the typing council
and its purpose, folks?
We'll run it.
Yeah, it postdates most of the PEPs.
So initially, the text system was created
just through the regular PEP process.
It means that something gets submitted,
first still to Guido as the BDFL,
later to the steering council.
Meant that it's very hard to make changes
to, like, this specification.
Like, anytime you want to make change something
about how the type systems would work,
we had to go through this PEP procedure,
talk to the steering council,
who are very busy people,
who deal with a lot of other aspects
of the language other than typing.
So Shantanu and I came up with this idea
of creating a separate council
to specifically in charge of typing,
that would be in a specification
where we can make small changes ourselves
without having to go through
this whole PEP process.
And this way, when all the type checkers
agreed that something needs to go a certain way
and it's not exactly what's in the PEPs,
we can change it and have a place to record that
and people can refer to it
and new type checkers can also try
to follow those decisions.
Very interesting.
I didn't realize that it was sort of,
was there to allow for small changes
to be made to make that much easier.
But of course that makes sense
because the PEP process is,
it's pretty serious and drawn out.
And we've seen even small language changes
have quite passionate folks,
I guess we should say.
So yeah, yeah, very nice.
Do you have any examples of the types of changes
that y'all have,
that have happened over the years
that maybe were typing council only?
One was the specification
where how overloads work,
which is perhaps not really a small change,
but one of the most complicated features
in the type system really is the overloads,
where you can give multiple signatures
for a function
and type checkers sort of select
which one to use based on the arguments
when the function is called.
And when it was initially created,
from what I recall,
there just wasn't really a specification.
It's just like you use the signatures
in a way that makes sense.
And Eric Trout,
who's currently on the council,
came up with a pretty specific procedure
for exactly how overload should work
to make it so that type checkers have,
well, sort of users can understand how it works
and sort of type checkers can have something
to work towards to make sure
that they work infinite overloads in the same way.
Maybe a smaller example
that is an example of something
that would have been too small for a pep
and hard to accomplish
before the typing council existed.
And this is actually a change
that I pushed through before the,
before I was on the typing council,
but the typing council approved it,
was a clarification around
the interpretation of data class fields.
If a final annotation is applied
to a data class field,
does that mean,
so if you apply a final annotation
to a regular class attribute,
since it can't be changed,
that implies that it's a class variable.
And there was a question of
if that should be the interpretation
with the data class or not.
So we discussed that
and made a clarification to the spec.
I've never really thought about final
being applied to a class field,
but I've always used them
sort of just for constants.
But, you know,
maybe people out there don't know,
like typing dot final bracket type,
right?
That's kind of the way
you can do constants in Python, right?
Constants for the type checker.
Nothing in the runtime
will stop you from editing it.
That's...
Not there.
I have some examples coming up
and I'm interested
to hear your thoughts on it,
but for sure it's,
there is this tension, right?
I mean, I think that's probably
worth touching on as well
is this is a tension for Python
in general is
you can write all the types you want
and then when you run your code,
it just doesn't care.
There's a few instances,
Pydantic, FastAPI,
a few others,
but generally speaking,
it's there for the editors
and the type checkers
and the linters
and not for runtime, right?
Yeah, that's right.
There's many exceptions to that.
There's a product like mypyC,
which comes with mypy
that's used those types
to compile your code
into more efficient machine codes.
Maybe there's going to be
more products like that
in the future.
I don't know.
But yes, in general,
it's separate from the runtime.
Sort of a similar
model to TypeScript
where TypeScript
gets compiled into JavaScript
and types just go away.
Here, we don't do
a compilation step,
but still the same idea
of the types
just not influencing the runtime.
Although we do make them
available for introspection
via done annotations attributes,
which is what has enabled
the projects like Pydantic
and other sort of
runtime checkers
to make use of type annotations
at runtime also.
Yeah, I don't know
if the typing council
was around for this,
but there was proposed,
I don't remember
the exact details,
but something to the effect
of for type checking,
not actually doing
some of the full imports
or something along those lines,
right,
where the runtime behavior
would have made it hard
for tools like Pydantic
and others to get that.
And there was
some kind of compromise,
right?
I don't remember the details here.
Anyone does?
Yeah, what happened was
that there was going
to be a change.
That's what the
from future import
annotations import does,
that changes all annotations
into raw strings.
So the default behavior
before recently
was that annotations
that are regular codes.
If you write devf
return to ints
and you import the module,
it just looks up
the name ints
and puts that
in an annotations dictionary,
which makes introspection easy,
but it made
a test on costs
on performance
because memory usage
sometimes was high
and also made things
harder to use sometimes
because if you use a name
that's not defined yet
at runtime,
you get an error.
That often comes up
if you have like a class
that has a reference
in an adaptation
to the class itself
or circular
dependency classes.
Right.
The circular imports
because you want to say
this class
is created by that thing
and it returns one,
but you know,
somehow you've got
to import the other one
and that's such a hassle.
Yeah, it's,
yeah, even out
in the audience we have,
Tom says,
circular imports.
Oh, yeah, for sure.
What about lazy imports?
Like that just recently
got accepted
and will be in 3.15.
Which I'm super excited about
because I think
it'll make app startup
a lot faster
for many use cases.
But does that have
knock-on effects
for typing?
Not that directly
because I think
for a type checker
lazy imports
mostly just look
like regular imports.
I guess I should
maybe leave that
for the people
who are actually
working on type checkers
and being written right now.
Yeah, Rebecca,
do you see this
making any difference
for you?
Lazy imports?
To be honest,
it's not something
we've looked at
too carefully yet.
3.15
seems a little
more in the future,
but I don't think
it's likely
to make a huge difference.
Carl?
I've thought about it briefly
and I think that it,
I think the type checkers
really won't need to care.
Maybe there will be
some edge cases
that will come up
that I haven't thought of,
but it shouldn't be a big deal.
Yeah, that's what I thought
as well.
The one variation
that I can certainly see
is if you have a,
if you have something
specified in a type,
like say for a field
of a class
or a Pydantic model
or something
that would otherwise
not trigger
the lazy import
to become imported,
would potentially
having types specify
cause more importing
to happen sooner
in the runtime?
Yeah, there's actually
an issue related to this
that I think we may need
to resolve before 3.15,
but I don't know how yet.
If you use a type
in a data class annotation
that's lazy imported,
actually creating
a data class
will delay
by the import.
It will try to
resolve the import
and actually make it
not lazy.
This is because
data classes
doesn't really need
to look at all
of the annotations
in your class,
but it looks at them
enough to trigger
reification of the import.
I shared this
with some of the people
on the lazy imports team,
but we haven't
yet come up
with a good way around it.
I think this might
end up being
a bit of a food gun,
so I feel like
we should ideally
find a workaround,
but I don't know
what it would be yet.
I don't know
that it's wrong
that it converts it
to an eager import,
which it needs
to know what it is
potentially,
right?
It actually doesn't.
Data classes
just need to know
whether it is classed
for or not.
I think that's
pretty much all.
I guess there's
an init for also,
but it doesn't really
need to know
anything else.
So in theory,
it should be possible
to just say,
hey, it is not classed
for, so don't bother
importing it.
Okay, so that's
for data classes,
but say if I specify
a parameter type
on a function.
Yeah, then it
should be fine.
I guess, again,
unless something is,
if it does annotate,
so if you have
something like
a decorator
that looks at
annotations in your
function,
it might reify
those imports.
There is one other
potentially interesting
thing for type checkers.
It's already
difficult for type checkers
to figure out
when like a submodule
should be considered
to be an attribute
of the parent module
because the way
this happens in Python
is that any import
of a submodule
anywhere will attach
that submodule
as an attribute
on the parent module,
but that at runtime,
that could literally
happen anywhere.
It could happen
in totally unrelated
code outside of the module
and a type checker
probably won't be able
to see that.
So type checkers
already have sort of
complex sets of rules
around where they look
for these submodule
imports and when they
consider a submodule
import to be reliably
happening enough
that it should,
that the type checker
should consider
this submodule
to exist as an attribute.
And lazy imports
may make that even,
we'll add one more
wrinkle
to those
sets of heuristics
in that we'll have
to decide
if you have
a lazy import
of a submodule
and you're done
to init.py,
it's lazy.
So should the type checker
consider that submodule
to be imported
or not be imported?
It'll be another case
where there's no
clear right answer
and we'll just have
to make a decision
one way or the other.
This portion of
Talk Python is brought
to you by Sentry.
I've been using
Sentry personally
on almost every
application and API
that I've built
for Talk Python
and beyond
over the last few years.
They're a core
building block
for keeping
my infrastructure
solid.
They should be
for yours as well.
Here's why.
Sentry doesn't
just catch errors.
It catches all
the stuff
that makes your
app feel broken.
The random slowdown,
the freeze you
can't reproduce,
that bug that
only shows up
once real users
hit it.
And when something
goes wrong,
Sentry gives you
the whole chain
of events
in one place.
Errors,
traces,
replays,
logs,
dots connected.
You can see
what's led to
the issue
without digging
through five
different dashboards.
Sear,
Sentry's AI
debugging agents
builds on this
data,
taking the full
context,
explaining why
the issue
happened,
pointing to
the code
responsible,
drafts a fix,
and even flags
if your PR
is about to
introduce a new
problem.
The workflow
stays simple.
Something breaks,
Sentry alerts you,
the dashboard
shows you
the full context,
Sear helps you
fix it and
catch new issues
before they ship.
It's totally
reasonable to go
from an error
occurred to
fixed in production
in just 10 minutes.
I truly
appreciate the
support that
Sentry has
given me to
help solve my
bugs and issues
in my apps,
especially those
tricky ones that
only appear in
production.
I know you will
too if you try
them out.
So get started
today with
Sentry.
Just visit
talkpython.fm
slash Sentry
and get $100
in Sentry credits.
Please use that
link.
It's in your
podcast player
show notes.
If you're
signing up
some other
way,
you can use
our code
talkpython26,
all one word,
talkpython26,
to get $100
in credits.
Thank you to
Sentry for
supporting the
show.
Yeah, there's
some variations
across type
checkers, which
we'll get to
later.
I think,
though, before
we move off
this, there's
actually off
introducing the
typing council.
I think we
should point out
that there's two
other folks who
couldn't be here
who are also on
the typing
council, Eric
Trout and
Yuka Letts,
the docilo?
Sorry,
Yuka.
But I want to
make sure that
we point out
there's actually
five people,
not just the
three of you,
right?
How do you
get on the
council?
Is there an
election?
Do you just
apply?
I think these
are filled by
the members
themselves.
So when
somebody declares
the intention
to leave the
council, we
basically ask for
people who are
interested and
then make a
selection.
Generally, we
try to get
people who have
experience in the
type system.
We try to get a
good cross
representation of
people working
on different
type checkers.
We have Carl
and Rebecca
here who work
on two type
checkers,
TY and
Pyrefly.
Yuka works
on Pyrites,
which are two
of the most
lightly used
type checkers.
So we try to
get representation
of people working
on those parts
of the ecosystem.
That's really
cool that it's
got a bias
towards finding
people actually
doing the work.
So let's talk
about the
specification project
at typing.python.org.
What is this
here?
I'll talk a bit
about it.
I guess it's
a specification
for how the
type system
used to work.
The way it
started was
that, Yela,
you basically
took all the
typing peps
and like
stapled them
together,
right, to
make like
one long
doc.
And since
then, we've
been iterating
on it,
filling in
parts that
were missing
like overload
evaluation and
making other
changes as
well.
Yeah, it's
tricky, right?
Because
traditionally, the
typing system
is kind of
defined across
a series of
peps.
And so what
is the document
that tells you
how it works,
right?
Yeah, that
made it hard
because often
there's peps
built on top
of each other.
So then in
the extreme,
you might see
like one thing
in one pep
and then there's
another pep
that adds
an aspect of
it, another
one that adds
another aspect.
And overall
it makes it
very hard to
follow.
One of the
things I did
recently was
rewrite the
typed dict
another.
Ended up
rewriting the
whole thing
to basically
put all those
features together
in a coherent
whole rather than
just having them
all copy-pasted
one after the
other.
Okay, so if
somebody really
wants a good
understanding of
the Python
typing system,
they go to
typing.python.org.
You know, one
thing I think
maybe is worth
touching on,
it's just kind
of out of the
blue a bit,
but I think
it's a really
interesting aspect
of the Python
typing system
is the,
what is it
called, the
numerical tower
or the number
tower, where
it's like, if
I have a
number, I
could specify
it as an
int, or I
could specify
it as a
float, and
those kinds
of things, but
do you really
need to say
it's an
int pipe
float, or a
union of
int and
float, if it
could be
either, right?
And the, what
is it called?
It's the
numerical tower,
right?
Yeah, there
are different
towers too.
In Python, there's
also this thing
called a numbers
module that you
have there, that's
just basically
ignored by the
type system.
It's been
useful for some
people, I feel
like in general
that module just
hasn't worked out
very well as
being very
useful.
I think the
interesting aspect
is that you
know, that you
can say it's a
float, and that's
basically equivalent
to union of
integer and
float, and so
on, right?
I think the
typing numbers in
Python is pretty
interesting.
I think every
type checker has
a different
interpretation of
what a float
annotation actually
means.
It's an area of
some lack of
clarity in the
spec.
Yeah, a lot of
contentiousness.
If we could go
back in time, I
would, like,
knowing what I
know now, I
probably advocate
for things being
done differently
because, like,
beginning, you
know, like, there
were multiple
things, like, with
similar flavor.
Like, there was
also one where
you could give
a parameter a
non-none
annotation and
default it to
none for
convenience, and
we've largely,
like, moved away
from stuff like
that in favor of
explicitness.
Yeah, what the
current spec says
is that basically
if you have a
function that takes
a float, you're
also allowed to
pass an int.
That's not
really enough.
It doesn't tell
you how these
things work in
all cases, and
we've had some
attempts to try to
come up with a
way to specify
that special case
in a way that
makes more sense,
at least makes
more sense to me.
It's been very
contentious.
People have very
strong opinions
about this.
I guess non-obvious
is what I'd like to
say, really,
honestly.
So I'd like to get
the official
counsel's thoughts
on this.
When is typing
too much typing?
I made the joke
about C++,
ATL, if you've
ever worked with
that, it's like
a template class
where templated
classes are part
of the concrete
type of the
template.
It's just off
the hook.
There's certainly
places where
typing can be
too much, and
a lot of the
purity of Python
or the readability
of Python is the
fact that it's
got so few
symbols.
And so adding
types adds
context, but it
also makes it
a little harder
to read.
When is too
much typing?
When do you
recommend typing?
Rebecca, I'll
let you go first,
but what are your
thoughts on how
much typing should
I use in Python?
I'll give you
what is my
official stance,
which is that if
you want your
type checker to
work well, you
should type
annotate your
API boundaries.
So parameters
and turns in
public functions,
public class
attributes, things
like that, and
even things that
seem true
trivial, like,
oh, this
function returns
none, better
to annotate
it because, you
know, someone
else might be
depending on
your library and
consuming that
type of
information.
I will say
personally, what
I tend to do
is I annotate
things that I
think are
non-trivial
because I want
to see that
as documentation.
And if
something, you
know, a
function that
does return
none, to be
honest, I will
probably forget
to annotate it
half the time
because I'll
be like, I
honestly don't
need to see
it.
One of the
interesting features
of the
Pyrefly VS
Code extension,
that's the only
one I can speak
of at the
moment, and
Carl, you've
got to tell
me if the
TY one does
this as well,
is it will
sort of overlay
its belief of
what types
are.
Like, if
there's, you
say x equals a
function return
value and it
knows what the
function returns,
it'll have a
gray, like,
colon int, if
it returned an
int or something.
So you can
kind of read
the code and
see what the
types are without
actually putting
it into the
text of the
code.
It's only within
the editor.
Does ty do
something like
that, Carl?
Yes, we also
have inlay type
ins.
Yeah, inlay type
ins, that's
what it's called.
So, yeah, I
don't know, that
also brings an
interesting challenge,
not a challenge,
like a wrinkle to
the recommendation
of should I put
types on, like,
the return value
because I want to
know that's a
list of user,
not a list of
user IDs or
whatever, for
example, like a
list of UUID.
But if,
it's going to
show up anyway
in the editor,
maybe I don't
have to write
that, right?
And so that
becomes sort of
somewhere where
you could debate
again, I think.
However, I do
100% agree with
you, Rebecca, that
put it on your
API boundaries.
If, like, this
is the place that
people get into
some part of your
code and they
don't know or
want to know about
the inside of it,
having types there
is really helpful
both for editors,
for type checkers,
and just for
reading code, and
even for AI, which
is a crazy world.
Yeah.
Carl?
What are your
thoughts here?
How much typing is
too much typing?
What's the
guidelines here?
I think I agree
with Rebecca's
answer.
I mean, that one
place you definitely
want to have
explicit type
annotations is that
API boundaries,
the public API of
a library, etc.
In terms of what's
too much typing, I
mean, there are
certainly patterns
that have
historically been
used in Python
that we still
can't express well
in the type
system, or that
require extremely
complex type
annotations to
express well, and
I think there it
becomes a judgment
call.
If it's like a
core, widely
used API, you
may get a lot of
benefit from some
very complex and
verbose annotations,
and so then it's
worth sort of going
through that pain
and the pain of
adding them and
of reading them in
order to get that
additional typing
coverage everywhere you
use that API.
If it's much less
frequently used code
that's highly dynamic,
maybe it's not worth
it in that case.
I think there's a lot
of judgment calls
here.
What about like
one-off scripts?
You know, I'm going
to write this thing to
just move this data
from here to there,
and once it's moved,
I don't need it again.
It's done with that
old system, we're
going to the new
one.
Maybe less typing.
Yeah, I think
that's what's useful
for you.
Often I feel like
one-off scripts are
not really one-off
like maybe you
want to move some
similar data later,
and then it's useful
if you can understand
your code again,
if you want to
read what you did.
You thought you
didn't need it again,
and all of a sudden
at six months old,
you don't understand
it, and the types
that help a lot,
right?
Yeah.
Yellow, what's
your advice?
What Cara and
Rebecca said
makes sense to me
too.
I think types
have advantages
in terms of
documenting humor
readers, what
is going on,
and in terms of
catching mistakes
that otherwise
would not be
caught until
runtime perhaps.
They have costs
in maybe making
your code harder
to read if
there's too much
going on.
So add types
as long as
those benefits
outweigh the
costs.
Yeah.
I mean, do you
recommend to
anyone that they
just 100% go full
like C++,
C# on it,
and just type it
every single thing?
Is there an
advantage like for
static type checkers,
you know, like
mypy type stuff
you can run across
and get that?
I mean, you could
do that with
Powerfly or TY
and the CLI as
well, but you know,
thinking more mypy
is like kind of
being real strict
on some of that
stuff.
Personally, I do
tend to annotate
almost all like
function parameters
and if class
attributes, if I
make a class,
sometimes it's not
as necessary,
like you don't
really need to
annotate your
tests perhaps,
or you don't
need to annotate
internal functions
as much, but
for my own
coding, I usually
find it helpful
to do that.
But sometimes I
see people
annotating even
local variables
where it's very
obvious to type
check if the type
is and they can
just infer it
reliably, and then
it really just
adds noise and
you shouldn't do
it.
Yeah, exactly.
If you've got a
function that's
annotated with a
return value and
you say x equals
the function call,
then the type
checkers can infer
that and you're
just causing
extra noise, I
guess.
So suppose you
all want to
change something.
What's the process
of actually going
through and making
some changes?
Mostly sort of
two levels of
this.
Well, maybe
there's even
three levels.
The first one is
if it's something
that's so small
that's just like
a wording
clarification or
something, we
just make a PR
to the repo and
a few of us
look at it and
we change it.
The second level
is when it's sort
of a smaller
change that
doesn't really
introduce a new
feature and then
we make a PR
to the typing
spec repo and
we formally have
all of us sign
off on it.
That's what
happens like
what Carl
mentioned earlier
of the final
change in data
classes.
It's had to
merge this one,
yeah, add
Carl.
I love it.
This repo itself
doesn't have
anything.
It's the
Python typing
repo where the
decisions are
made.
The typing
council just
has like some
documentation.
Yeah.
And then the
third level is
peps, like really
big new changes.
You can still
write a PEP and
then we make a
recommendation and
the steering
council makes a
decision eventually.
So if I wanted
to suggest
something, I
could come up
here and I
could open up
an issue, maybe
start a conversation
on typing,
Python slash
typing.
And you can make
a pull request
to change the
spec.
Okay.
And so the
pull request
would not be
to change the
code, like
how Python
maybe interprets
code that has
this new thing,
but to suggest
that the spec
has it, which
then would start
a process that
ultimately might
make CPython
understand it,
right?
Well, CPython
itself probably
doesn't do
anything with it.
I guess most of
the things that
go directly here
are changes to
how to interpret
things that are
already in CPython.
This portion of
Talk Python To Me
is brought to you
by us.
I want to tell
you about a
course I put
together that
I'm really proud
of, Agentic
AI Programming
for Python
Developers.
I know a lot
of you have
tried AI coding
tools and come
away thinking,
well, this is
more hassle
than it's worth.
And honestly,
all the vibe
coding hype
isn't helping.
It's a smokescreen
that hides what
these tools can
actually do.
This course is
about agentic
engineering,
applying real
software engineering
practices with AI
that understands
your entire code
database, runs
your tests, and
builds complete
features under
your direction.
I've used these
techniques to ship
real production code
across Talk Python,
Python Bytes, and
completely new
projects.
I migrated an
entire CSS framework
on a production
site with thousands
of lines of HTML
in a few hours,
twice.
I shipped a new
search feature with
caching and async
in under an hour.
I built a complete
CLI tool for
Talk Python from
scratch, tested,
documented, and
published to PyPI in
an afternoon.
Real projects, real
production code, both
Greenfield and
legacy.
No toy demos, no
fluff.
I'll show you the
guardrails, the
planning techniques, and
the workflows that
turn AI into a
genuine engineering
partner.
Check it out at
talkpython.fm
slash agentic
dash engineering.
That's talkpython.fm
slash agentic dash
engineering.
The link is in your
podcast player's
show notes.
If it's adding
something new, it
will usually need to
go through a path,
except if it's
something very small.
Let's talk about
that for a minute.
We got two
representatives here
of the newer
breed of tools.
What's the story
for inconsistencies
across interpretations
of the spec?
I know that there's
slight variations.
I've also, you
know, not putting
either of you on
the spotlight, but
like using, say,
PyCharm and
like writing code.
So it's type
checkers happy and
then using something
like Pyright.
And so it has a
real different
interpretation of
what you should let
slide and what you
shouldn't.
I feel like Pyright
is more, much more
focused on like
enforcing the
nullability and or
the lack thereof.
And it warns of
inconsistencies there
where PyCharm doesn't
seem to care as much.
I don't know which
one I like better,
but I know they're
different.
And if I write code
in one that I
open the other, I'm
like, huh, why is it
upset?
It seemed like it
was fine.
How do you all
navigate this?
Yeah.
One thing useful to
say about the spec
there is that the
spec covers a lot of
things.
In particular, it
tends to cover sort
of the details of
more advanced type
system features.
But there's a lot of
very fundamental
stuff about how a
type checker works
in terms of how it
does inference and
how it does type
narrowing.
And even in some
cases, like you
mentioned, you know,
what it chooses to
emit errors on that
isn't really covered
by the spec, partly
maybe because we
haven't gotten to
it and also partly
intentionally in that
there may be room in
some of those cases
for different type
checkers to work
differently if they're
serving different
needs.
Like if PyCharm is
primarily concerned
about being a
useful kind of IDE
and providing go-to
definition and that
sort of thing, maybe
emitting lots of
warnings or errors
and all kinds of
things where your
code might be doing
something wrong isn't
as high a priority.
And another type
checker might have
a different priority.
One thing I do
want to mention is
that it may not
seem like it, but
things are already
much better than
they used to be.
Like previously, I
worked on a
different type
checker called
PyType.
And at that time,
it was, you know,
sort of the Wild
West.
Like we want to
know how other
type checkers like
do something.
Well, you know,
like open up the
mypy playground,
open up the
PyRite playground,
see what tells
you.
Now we at least
have spec and
conformance tests.
Yeah, that's
really cool.
How much would
you say that
your two type
checkers maybe
bring in mypy
as well?
Like how much
do they agree
versus disagree?
You know, like
you only see the
differences.
You don't see in
which ways that
they are the same
as a consumer of
them so much,
right?
You're like, why
is this one
squiggly when it
wasn't squiggly
before?
But how similar
or different are
they?
I don't know how
we would quantify
that.
I think there's a
lot that is the
same just because
it's based on how
Python actually
works.
We're both trying
to model the
same language and
then there's
certainly also
plenty of
differences or
things that we
handle differently.
So Rebecca, do you
have a better way
to quantify that?
Yeah, I agree.
it's hard to
quantify, I suppose,
talk a bit
abstractly about
various type
checkers philosophies.
With Pyrefly, we
really try to do
a lot of type
inference.
So that's a way
in which we
intentionally diverge
a bit from mypy.
But other than
that deliberate
decision, if we
see ways in which
we are accidentally
different, we do
try to fix that
because otherwise
people would have
a hard time running
multiple type
checkers or
migrating.
Yeah, differences
obviously cause
pain for users
who are using
multiple type
checkers or
writing libraries
that need to
support multiple
type checkers.
So like Rebecca
said, it's like if
we are different
from other type
checkers, we want
to be sure that
there's a good
reason for that
difference.
The difference
should be because
of philosophical
choice, not just
you happen to have
chosen slightly
differently, right?
Yeah, and it's
not just people who
run different type
checkers.
Like you pointed
out, Carl, a lot
of times it is if I
have a library and
then different people
want to consume
that library, then
their type checker
may or may not
warn them about how
my library declares
its types and so
on.
I'll give you a
real quick example.
I have a, I can't
remember which one
it was, I have
three or four
different open
source libraries
that I've created
that somehow work
with creating,
basically passing
data to templates
in web apps,
right?
So one is like I
want to use the
Chameleon web
template framework,
but with fast
API or with
Flask or there's
some other
variations like
partials and so
on.
I can't remember
which one, but it
doesn't really
matter.
One of them
decorated a
Flask.
I think it was a
Flask, especially
makes it irrelevant.
A Flask endpoint
and PyRite was
really upset.
Like the error
message filled the
entire page of
how it was
inconsistent with
what it expected
for the definition
of the Flask
view method.
I'm like, no one
is going to call
this.
Like what does
it even matter
what this type
is?
It still runs
fine.
The runtime is
fine.
You know, it's no
problem with this
decorator.
It worked fine, but
something about the
way that the Flask
at get returned
the type versus
what my thing
returned varied in
like a really
slight way.
I didn't care, but
somebody was using
some editor that
used PyRite and
they're like, you
have to help fix
this.
I can't take all
these warnings.
They're huge and
they're everywhere.
Like, okay, I'll
go fix it.
Right.
And I went and I
put way more effort
than was justified
into a function type
that no one ever
calls just to make
the errors on some
type checker I
didn't use go
away.
Right.
And that's the
kind of thing where
it becomes just a
headache.
I don't know.
I wish I remember.
I probably got that
written down in an
issue somebody filed,
but it was, it was
a gnarly error.
And, or if you're
working on an open
source project, you
know, you can't make
everybody use the
same editor that
wants to contribute
on a big project.
And so you might run
into this variation as
well.
So there's a lot
of cases.
Yeah.
It can be really
difficult to make
these decisions about
what kind of, what
sorts of errors people
want their type checker
to catch or what's
too pedantic.
You want your type
checker to catch
non-obvious errors,
not just the obvious
ones that you probably
would have seen by
looking at the code
yourself.
But then there'll be
cases where somebody
says, well, I don't
care.
That's too pedantic.
And it is difficult to
make everyone happy.
Who decides what the
right signature of a
flask view and point
should be like if you
the framework can call
it.
It should be okay.
There's not.
Just because it had a
decorator before, that
doesn't mean that's the
official structure.
But anyway, I do think
one of the bigger
philosophical differences
has to do around this
concept of nullability.
Do you guys call it
nullability or none
ability?
Like nullability comes
from the other
languages.
And by that, I mean, I
can specify that I have
an integer.
And in the Python type
system, it cannot be set
to none, even though in
the runtime it can.
It has to be a concrete
int type unless you make
it a optional int or an
int pipe none or one of
those type things, right?
And how strong that gets
enforced seems to be one
of the biggest difference
of opinions that I've
seen around.
Like, how do you all
think about that?
That's interesting to me
that that's your
experience because my
experience has been that
that's actually an area
where everyone seems to
agree as far as I can
tell that these are is
an important source of
bugs and it's better to
catch them.
So I think all of the
type checkers, maybe you
said PyCharm doesn't.
I don't think PyCharm
does that.
I'm pretty sure it
doesn't because I agree
that it's an important
thing to check, but it's
also a point of a lot of
friction.
And by that, I mean,
let's suppose I'm going
to have a class that I
need to create an
instance of and then put
values into.
And I know once I put
the values into it, let's
say it has a user ID, I
know for certain that
that's going to be an
integer, right?
So I'd like to say user
ID colon int because
everywhere I use that
object later, if it's a
function that takes an
int and I specify it as
optional int, I will get
a type check warning
every single call site
when I try to pass that.
But I know from the
semantics of the
behavior that it's going
to always be an int
unless it's not
initialized, right?
And like in this short
period where I want to
create it.
So I can't set the type
to int.
I have to set the
optional int until I've
loaded it.
And, but there's like
this, I don't know,
that's, that's the part
where I see a lot of it
show up is inconsistencies
and then warnings all
over the place.
So I'm like, well, but
that function is actually
checking if it's none
and it'll return null,
you know, none or
something like that.
So I totally agree with
you.
It's just somewhere I've
seen the most
inconsistencies across
maybe PyCharm versus
others.
mypy also has a legacy
mode for not checking
none things called
non-strict optional.
We're trying to get
rid of that from mypy
because yeah, strict
optional, like being
strict about it is the
more sensible thing to
do.
But it's possible that
you've seen that too.
Yeah, I agree.
So what you mentioned
is maybe sort of a
special case of the
case where you pass
something to a class
and there's initialization
that changes the types.
Doesn't necessarily have
to deal with none.
It could also just be
like the attribute doesn't
exist at all beforehand
or something.
Yeah, we don't have a
good solution for that.
Maybe there's room for
something to support that
use case better.
I don't know what it
would look like.
In some cases, there's
ways you can, these
things can sometimes
nudge you towards a
different design that is
actually safer and will
avoid errors.
Like in the kind of
case you're talking
about, you know, is
it actually necessary
that an uninitialized
object and an
initialized one are
represented by the
same type?
Or is there a way to
adjust the API so that
those are actually
different types than you
solve the problem and
your code is safer
or so?
I'm thinking like you
submit a web form and
before you parse it, you've
got to create the instance
to set the values.
And I don't know.
It's not worth diving into,
but I do find this
differentiation between like
the strict enforcement of
none versus not none.
I think it's powerful and I
do think you all are right
that it does catch a lot of
errors.
It's just, it's just a
difference and it's just an
interesting, interesting
choice.
But I didn't get a
concrete answer from the
official counsel.
Nullable or
noneable?
What is it?
I feel like you just
don't really even talk
about it as a term mostly.
It's, yeah, none is
special in the type system
in like how you represent
it, but it's not really
special in other ways.
You don't have a term for
int pipe none?
Int or none.
Historically, the term was
optional, although I think
that term has problems and
we're sort of moving away
from it because
specifically one problem is
that optional can mean
you don't have to pass it
in, like I say, as a
function parameter.
Let's talk a little bit
about TypeShed.
I think TypeShed is pretty
interesting.
Maybe people don't know
too much about it.
So I'm sure you all are
familiar with this project
that you can basically add
type information that the
libraries didn't bother to
include for you, right?
What are thoughts on TypeShed?
How much do you all lean on
this to sort of round out
missing types?
There are two parts to
TypeShed, right?
There's the standard library
type stubs, which I think
are invaluable.
Like all the type checkers
use those.
And I mean, will the standard
library itself ever have
inline types?
Who knows?
This might be around forever.
And then there are also
the third party stubs.
And I think that's what you're
describing.
They're libraries that for
whatever reason don't ship
with stubs themselves.
Those are in TypeShed.
And I think it's been like
for a while, there's sort of
been a question of like what
we want to do with like
TypeShed's third party stubs,
right?
Because like ideally like
libraries would ship with
their own types, but there
are various obstacles to that.
The obstacles that I know of
used to be like, we want this
to run on Python 2 and Python 3.
Or we want it to run on
Python 3.3 still.
But it's been a long time
since any non-type supporting
version of Python was a real,
you know, a supported type
of thing, right?
I mean, even 3.9 became
deprecated.
So on one hand, I feel like
they could be merged in,
but there's also a lot of
other areas that are maybe
we don't, they're not common,
right?
Like other libraries, like
pick some, let's say Pyramid.
I don't think the Pyramid web
framework really ever got
types added to it.
Somebody could go and create
a typeshed stub or a types
underscore pyramid you could
pip install and then we'll
add the types, right?
I certainly see it being
really valuable for third
party things that are just
not going to get the type
attention they need.
Yeah, I think typeshed is
great.
I've spent a lot of time on
improving it.
As Rebecca said, especially
with a standard library,
it's irreplaceable.
For third party libraries,
I think it's become less
needed over time.
It used to be that very few
third party libraries had
any types.
Now that's obviously changed.
A lot of libraries ship
their own types, but still
there are quite a few types
of libraries left where
there aren't inline types
and typeshed can provide
useful types.
I think typeshed also
provides a service because
it has a really great
framework for testing
these types.
We have tools like step
tests and various type
checkers that help to
make sure these types are
good and meet a high
standard.
So yeah, I think they're
still useful for many
libraries.
Yeah, I was just looking at
the types dash flask and
I guess it must be, must
be gone because now type
flask must have it
internally.
So it's kind of an interim
sort of thing.
That's pretty cool.
In general, typeshed has
the policy that we remove
the snaps from typeshed if
they are in the library
itself.
I find these super
valuable because if there's
a library I want to work
with and it just doesn't
have types for whatever
reason, you can install
stuff from here and all
of a sudden your editor's
way happier.
I mean, I know we, you
all agreed on like the
API boundaries and I did
as well.
It's like that's one of
the really cool things.
The other thing that
really makes me excited
about types is if I hit
dot in my editor, I get
a meaningful list of real
information about what I'm
working on.
And so adding, adding
these types of things are
pretty interesting.
I want to ask you all
about sort of these rogue,
rogue tools that do stuff
with Python typing that
maybe y'all didn't intend.
Like we all mentioned
Pydantic, we've got
Typer and FastAPI, but
even a little farther out
there is a bear type.
Are you familiar with
bear type?
Yeah.
Bear type's interesting.
You can import, they have
fun.
They have fun with their,
their import names and
stuff.
But basically you can put
a, either a decorator onto
some sort of call site or
something, or you can just
do it to an entire package
or entire modules rather.
So just run bear type
dot claw import bear type
this.
And then it actually turns
into runtime type checks.
Good idea, bad idea.
Interesting.
What do you all think?
So un-Pythonic, you won't
even open the webpage.
People should feel free to
write whatever code helps
them make like better
software.
I haven't really used
bear type much myself,
but it's clearly useful for
some people.
And I think generally in
designing a type system,
we should try to
accommodate all users who
do useful things to the
type system.
And that includes things
like Pydentic or bear
type.
It's pretty fast.
It's not as big of a hit
as you would, you would
imagine.
They, let me see, what
are they, somewhere they
had a really fun, fun
saying in here, but here
we go.
Bear type brings Rust C++
inspired zero cost
abstractions into the
lawless world of dynamically
typed Python by enforcing
type safety at the granular
level of functions and
methods against type hints
standardized by the Python
community.
order one, non-amortized
worst case time with
negligible constant factors.
Like, how about that?
No, it's a pretty neat
library and it's pretty
fast.
I honestly, I've never used
it in production.
Having type hints and
squigglies in the editors
or in the linters has always
been enough for me, but I
can see using this if it's
really critical and you're
having issues, maybe you
want to catch some runtime
errors.
I don't know.
It's not quite an endorsement,
but it sure is like a, huh,
that's different.
I definitely think that the
extent to which type
checkers may have a
different understanding of
your code from what happens
at runtime and there isn't
anything built in to catch
that is sometimes a pain
point.
And so the desire to have
your type annotations, to
find out at runtime if your
type annotations are telling
you a lie, it makes a lot of
sense why people would like
that.
I mean, it's something
used to from other languages
where the type checker is built
into the compiler.
Right.
You get like a runtime type
cast, like cannot.
We kind of get that if you
try to parse a thing, you
know, like put the int
param around a string and
it's not really a parsable
as an int.
But for like real type
information, I think
personally I would use this
as like I might apply types,
type checking to a module
for debugging and development
for a minute and just see
what happens and then turn
it back off.
You know, I don't know that
I'd just ship production code
that way.
But anyway, I got a couple
more questions.
We're getting shorter on
time here.
What was one of the
harder questions that you
all, harder decisions you
all had to address on the
council?
I think the most
contentious one was
PEP 724, if I remember
the number correctly.
It was around a feature
called type guards, which
is around user-defined type
narrowing functions.
Initially, they find that in
a way that later was found
to be somewhat problematic
and we basically came up
with a better set of
proposed semantics that
maybe we should have done
the first time around.
And what this PEP proposed,
and as you can see, I
sponsored it, is that we
basically changed the
meaning of the existing
type guards under certain
conditions.
What is a type guard?
A type guard is a function,
like there's a good example
there, the isiterable.
It's a function that tells
you how to narrow something.
So in this example, there's
an isiterable type guard,
which narrows an object to
an iterable of anything.
And then inside the func
there, you can see if
isiterable file, it knows
that it's an iterable.
And in this case, yeah, I
guess it just narrows
exactly to iterable any.
That's one of the ways that
type guards works.
I see.
And the type that returns
kind of communicates to the
type system, like that this
function ensures that this,
the thing that came in as an
arbitrary object, in fact,
is one of these.
Okay.
Interesting.
Yeah.
So that was a tricky one,
huh?
Any other standout, Rebecca or
Carl?
Well, the current discussion
around what is the meaning
of a float annotation, still
unresolved, contentious topic.
Okay.
Gotcha.
I mean, this on PEP724 is
also what came to my mind
immediately as well, because
this was challenging
discussion because, you
know, like there were very
conflicting considerations at
play.
It's like, what semantics
did we want in the long
term?
And what did we want the
type system to look like,
you know, say like 10 years
from now versus backwards
compatibility and what the
migration story would look
like?
It was quite tricky.
I guess that's something you
will always have to be
cognizant of is like every
change, even if it's an
improvement, has to justify
the fact that now you have
challenges with the version
history over time.
I'm thinking like dict of string
comma int with a capital or
lowercase d.
I've got people, I did a
YouTube video showing
something with the lowercase
version because I was using
something super modern like
Python 3.11.
And I got a message like,
hey, Michael, you don't know
how to write Python.
Your code is broken.
This code that you wrote just
doesn't even run.
I don't know how this is.
I'm like, what version of
Python is in?
3.8.
Nope.
You can't use 3.8 for that.
You're going to need to get a
newer one.
You know what I mean?
But like those are complexities
that get added to Python
because of that.
Now you've got two ways to
specify what a dict is.
There's a preferred new way,
but there's still the old way
and it just, it sort of piles
up.
And it's very hard to ever
actually get rid of the old
way, even if there's no good
reason to use it anymore.
Exactly.
Once it's there, it's written
in ink pretty much, right?
Like we have five or six
different ways to format
strings.
Maybe with t-strings at six
now.
They're all going to still be
there, right?
So every change, every
decision you make is not
just a matter of, is it the
right decision, right?
It's the, is it worth it?
I'm sure.
Yeah.
I don't know.
How do you all balance that?
Like that's tricky.
With things like the dict
chains, at least we sort of
know we're moving towards
better states and there's two
things, but they mean exactly
the same thing.
So the confusion is not as
bad.
The problem with type cards
is that we're going to change
how some existing thing
works, like what it meant.
And I think there are good
reasons that maybe that's the
right thing to do, but the,
it would also have been pretty
confusing for people if their
existing types suddenly started
meaning something completely
different.
Absolutely.
Hence float.
Okay.
What's coming next?
Like 3.15, 3.16, do you all
have things that are in the works
that you think are going to come
or debates that are brewing?
For 3.15, the, there's a type
dict feature coming, extra
items.
you can already use it in
tapping extensions if you want
to use it, but it will be in
CPath as of 2.15.
It's likely we'll have a small
thing I added called disjoint
basis, which is very technical,
but helps type narrowing in some
cases.
Yeah.
I think those are the things
that are likely to make it.
There's, we can only speculate
about what else people can
propose.
We're sort of bound by what
people actually write up as
peps.
We have to wait for Google to
write the peps before we can
approve them.
I think there's PEP 747 for
type form, which I think is
not, I think we recommended
its acceptance, but I don't
think the steering council
accepted it yet or it hasn't
been accepted formally.
I think that's on their
plate.
Yeah.
So that's also pretty likely
to make it into 3.15.
This is one example of a
case that will be pretty
useful to people working
with type annotations at
runtime because it'll allow
you to, it's sort of a meta
thing where you can annotate,
have a type annotation that
describes another type
annotation.
So that's useful if you're,
if you're writing code that
works with type annotations.
Make the peidantics of the
world very happy.
I am actually pretty excited
about type form because,
you know, I feel like there's
a gap and we can express in
the type system and we're
good.
And there are cases in the
existing type system, like
for instance, the cast
function and some other
cases where something takes
any type expression as an
argument.
We actually don't have a good
way to annotate that today
and this will provide a nice
way to express that.
Let me pull up one thing
really quick.
Quick shout out to Will
McGuggan here.
He just released his
Toad project, which is the
new, takes textual and rich
and all that kind of stuff
and applies it to like, what
if we had a better cloud code
type of experience, which is
pretty interesting.
So the reason I'm bringing
this up is, you know, final
question.
What about, do you all even
worry about the role of like
how types interact with AI
and agentic coding tools?
I know that if you have some
code that has types on it
and you give it to an AI, it's
got a better chance of
understanding what's happening
than if you give it purely
untyped code and say, tell me
about this, right?
It doesn't even know necessarily
what's being passed to it.
But is that anything you'll
think about or what are your
thoughts on this?
Certainly think about it some.
I mean, I think overall my
feeling is that these coding
agents seem to do better than
more kind of the tighter
feedback loops you can give them
to work with.
And so typing is another
useful source of feedback
where you can say, add type
annotations and make sure the
type checker passes and seems
so it still seems pretty useful
in that world.
Yeah, you can easily write
rules that say when you are
done on anything I've asked
you to do, always run ty or
always run Pyrefly and make
sure that there's no more, no
new errors or at least or
ideally zero errors, right?
But nothing has been
introduced.
Yeah, pretty interesting.
You other folks, Rebecca,
Yela?
Yeah, I guess in general, I
think typing will remain
useful for AI.
We are probably rapidly
moving to a world where a
large proportion of all code
is written by AI.
Not everybody likes that
opinion, Yael.
Not everybody likes that.
I guess I, maybe my current
line of work makes me think
that's more likely to happen.
You don't have to like the
fact it's going to be night
soon, but it's going to be
night.
You know what I mean?
Like there's the, I just
think there's so much
momentum on this, at least in
the next five years or
something, that it's going to
be really, it's, it's a
truth of how many people are
writing code regardless of
whether individuals want to
write code that way.
You know what I mean?
So I think it's a
consideration.
Yeah.
I forgot that you worked
at OpenAI.
So of course, I should pull
up a codex example or
something, shouldn't I?
Yeah.
Codex is great.
Use it.
No, but I mean, do you
have any further insight into
like the role of types
and coding agents?
I know that's not exactly
what you work on, right?
You're more at the lower.
As Carl said, types can
also be helpful for AI to
understand code better and to
get a better feedback loop.
I feel like the very big AI,
the board is like humans.
And if AI makes, sorry, if
typing makes humans better
at writing understanding
this code, they're probably
also big AI better at it.
It's the locality of
information.
You can read the function
and know everything you need
to know about what's going
into it without bouncing
around and trying to
understand blocks of code
and like what might've been
created that's getting
impacted.
It's good for humans and
also good for AI.
Right.
Rebecca.
Because I don't have much
need to, and I'll say I am
maybe a little more skeptical
than most of my coworkers
about the quality of AI
generated code.
But that means I think I am
particularly gung-ho about,
you know, like get AI to use
types, type checkers, keep
the guardrails there.
I think that'll be very
important.
Yeah, if it's going to make
a mistake, don't let it at
least like make the type
system become disconnected
and not working.
Like it has to keep the types
hanging together as a
minimum bar, right?
And you can easily set that
up as an automation.
Yeah.
Interesting to think of it as
guardrails rather than an
accelerant.
But yeah, 100% it is.
All right, folks.
I think that's it for all
the time that we have.
Thank you.
Thank you for being here.
Final thoughts before we go.
Carl, I'll let you go first.
Final thoughts for people
out there interested in
Python typing.
Yeah.
Well, first of all, thanks
for having us on the podcast.
Really appreciate it.
And thoughts for people
out there.
I guess if you have ideas
of how Python typing could
be improved, discuss.python.
Python.org is a good
place to bring up ideas
and discuss them with the
typing community and see
what positive changes we
can make.
Rebecca.
First, thank you, Michael.
This is a lot of fun.
Last thoughts?
Hey, so, you know, like
we'll look at the typing
council and sometimes think,
oh, you know, like the
PEP has like governance
in its name, but I
wouldn't say we're really
a governing body or
anything.
It's like people who are
using the type system,
like users, they're the
ones who come up with,
you know, like all the
best ideas, propose them,
discuss them.
And we're just here to
sort of be like, hey,
you know, like we have
some background and like
how type checkers work and
maybe some of the history
and we can provide input.
But I just encourage
people, if there's a
change you want to see in
the type system, you know,
like propose it yourself.
It's very friendly and
open community.
Yeah.
Now people who have
listened know a little bit
more about how to do so.
Awesome.
Thanks.
Jale, final word.
Yeah.
Also, again, thank you for
having me here.
It's been great talking to
all of you.
I guess what I want to say
is similar to what
Karin Rebecca just said.
If you want to have
something changed to the
type system, I'd really
encourage you to sign up
for discuss.python.org,
make a proposal, go
through the process.
It can be somewhat
daunting, perhaps,
especially if you have to
create a PEP, but it is
doable.
There are several recent
typing PEPs have just
been community members
who saw something they
wanted to improve,
proposed a PEP, and saw
it to completion.
If there's something you
want to see in the type
system, then you can do
it too.
Thank you all for keeping
Python typing going
strong.
Really appreciate your
time on the show.
See you all later.
Bye.
This has been another episode
of Talk Python To Me.
Thank you to our sponsors.
Be sure to check out what
they're offering.
It really helps support the
show.
Take some stress out of
your life.
Get notified immediately
about errors and performance
issues in your web or mobile
applications with Sentry.
Just visit talkpython.fm
slash Sentry and get
started for free.
Be sure to use our code
talkpython26.
That's talkpython, the
numbers two, six, all one
word.
And it's brought to you by
our Agentic AI programming
for Python course.
Learn to work with AI that
actually understands your
code base and build real
features.
Visit talkpython.fm
slash agentic dash AI.
If you or your team needs
to learn Python, we have
over 270 hours of beginner
and advanced courses on
topics ranging from
complete beginners to
async code, Flask, Django,
HTMX, and even LLMs.
Best of all, there's no
subscription in sight.
Browse the catalog at
talkpython.fm.
And if you're not already
subscribed to the show on
your favorite podcast
player, what are you
waiting for?
Just search for Python in
your podcast player.
We should be right at the
top.
If you enjoy that geeky
rap song, you can
download the full track.
The link is actually in
your podcast blur show
notes.
This is your host, Michael
Kennedy.
Thank you so much for
listening.
I really appreciate it.
I'll see you next time.
Voyager.
And we ready to roll
Upgrading the code
No fear of getting whole
We tapped into that modern vibe
Overcame each storm
Talk Python To Me
IceSync is the norm