Catching up with the Python Typing Council
Panelists
Episode Deep Dive
Guests Introduction and Background
This episode features three of the five members of the Python Typing Council, the body that governs the evolution of Python's type system.
Jelle Zijlstra is a founding member of the Python Typing Council who helped create the council alongside Shantanu Jain. He currently works at OpenAI on developer productivity, focusing on CI infrastructure, test selection, and helping developers be more productive. He has been working with Python for over a decade and has invested significant time improving TypeShed, the community repository of type stubs for the standard library and third-party packages.
Rebecca Chen has been on the Typing Council since near its inception (approximately three years). She works at Meta on Pyrefly, a new type checker and language server written in Rust that is currently in beta. Before Meta, she spent eight years at Google on the Python team, where she also worked on a type checker called PyType. Rebecca brings a practical perspective on type inference and the importance of balancing strictness with usability.
Carl Meyer joined the Typing Council about a year and a half ago. He currently works at Astral (the company behind uv and Ruff) on ty, another new Python type checker and language server written in Rust, also in beta. Carl got his start with Python typing at Instagram around 2016-2017, working alongside Lukasz Langa (a co-author of early typing PEPs) on adding type checking to Instagram's massive Django monolith -- a project that eventually became his main focus for three years.
Two additional Typing Council members -- Eric Traut (creator of Pyright) and Jukka Lehtosalo (who works on mypy) -- were unable to join the episode but were acknowledged.
What to Know If You're New to Python
If you are new to Python or new to Python's type system, here is some background that will help you get more out of this episode:
- Python type hints (introduced in PEP 484 for Python 3.5) let you annotate your code with type information (e.g.,
def greet(name: str) -> str:). These annotations are not enforced at runtime by default -- they exist for editors, type checkers, and human readers. See the typing module docs for an overview. - A type checker (such as mypy, Pyright, ty, or Pyrefly) is a tool that reads your code and its annotations to find potential bugs before you ever run the program. Think of it as a spell-checker, but for types.
- Gradual typing means you do not have to type-annotate everything at once. You can add types incrementally to the parts of your codebase where they add the most value -- there is no all-or-nothing requirement.
- PEPs (Python Enhancement Proposals) are the formal design documents that propose changes to the Python language. Many typing features began as PEPs, and the Typing Council now helps govern which proposals get accepted.
Key Points and Takeaways
1. The Python Typing Council exists to streamline the evolution of the type system
The Typing Council was formally established by PEP 729 to govern Python's type system independently from the Steering Council. Before the Typing Council existed, every change to how Python types worked -- even small clarifications -- had to go through the full PEP process and be reviewed by the Steering Council, who had many other language concerns on their plate. Jelle Zijlstra and Shantanu Jain proposed creating a dedicated body specifically for typing decisions. The council now handles three levels of changes: trivial wording fixes via direct PRs, smaller behavioral clarifications that all five members sign off on, and full PEPs for major new features that go through the Steering Council. This structure lets the typing ecosystem iterate faster on the many nuanced questions that arise from specifying a type system for a dynamic language.
- peps.python.org/pep-0729 - PEP 729: Typing Governance Process
- github.com/python/typing-council - Typing Council governance repository
- github.com/python/typing - Python typing repository (where spec changes are proposed)
- discuss.python.org - Python community discussion forum (recommended place to bring up ideas)
2. A new wave of Rust-based type checkers is reshaping the ecosystem
Two brand-new type checkers written in Rust are now in beta and generating significant excitement. Pyrefly, built at Meta, focuses heavily on type inference so developers can detect errors even without explicit annotations. ty, built at Astral (the makers of Ruff and uv), promises 10x-100x performance gains over mypy and Pyright. Both tools also function as language servers, providing editor features like code navigation, completions, and inlay type hints. Together with the established tools mypy and Pyright, the Python typing ecosystem now has four major type checkers, each with slightly different philosophies. The Typing Council's composition intentionally represents these different tools to ensure the specification works well across the board.
- github.com/facebook/pyrefly - Pyrefly: Meta's Python type checker and language server (Rust)
- github.com/astral-sh/ty - ty: Astral's Python type checker and language server (Rust)
- mypy-lang.org - mypy: the established optional static type checker for Python
- github.com/microsoft/pyright - Pyright: Microsoft's static type checker
3. Type your API boundaries -- that is the universal advice from the council
When asked "how much typing is too much?", all three council members converged on the same answer: at minimum, annotate your API boundaries. This means function parameters, return types, and public class attributes -- the places where other code (or other people) interact with your code. Rebecca noted that even seemingly trivial return types like None are worth annotating because downstream consumers depend on that information. Carl added that for widely used, core APIs, the benefit of even complex annotations may justify the added verbosity, while less-used internal code can be left lighter. Jelle pointed out that annotating local variables whose types are already obvious to the type checker just adds noise and should generally be avoided.
4. The typing specification at typing.python.org unifies scattered PEPs into one source of truth
Before the specification project, the Python type system was defined across dozens of individual PEPs that built on top of each other in ways that were difficult to follow. Jelle led the effort to consolidate these into a single, coherent specification hosted at typing.python.org. Rebecca described the initial effort as basically "stapling all the PEPs together" and then iterating to fill in gaps and restructure the content. Jelle recently rewrote the entire TypedDict section of the spec because that feature had been extended across so many separate PEPs that piecing them together was unreasonable. The specification is now the canonical reference for how the Python type system should work, and the Typing Council can update it directly for clarifications without needing a full PEP.
- typing.python.org - The official Python typing specification and documentation
5. Type checker inconsistencies are a real pain point, but things are improving
Different type checkers can produce different results for the same code -- a source of frustration especially for library authors whose users may run any type checker. Michael shared a story about spending significant effort fixing a type mismatch in one of his open-source Flask libraries, solely because a user's type checker (Pyright) flagged a verbose error that another tool (PyCharm) ignored entirely. Rebecca acknowledged this problem but noted it is "already much better than it used to be" -- she recalled working on PyType where figuring out how other type checkers handled something meant literally opening up the mypy and Pyright playgrounds and testing. Now there is a spec and conformance tests. Both Carl and Rebecca emphasized that when their tools differ from others, they want it to be for good, intentional reasons -- not accidental divergence.
6. TypeShed provides type information the standard library and third-party packages lack
TypeShed is a community-maintained repository of type stub files that all major type checkers rely on. It has two parts: standard library stubs (which Rebecca called "invaluable" and possibly "around forever" since the standard library itself may never have inline types) and third-party package stubs for libraries that don't ship their own type annotations. Jelle noted that the third-party side has become less critical over time as more libraries ship inline types -- TypeShed even has a policy of removing stubs once a library adds its own types (e.g., Flask stubs were removed after Flask added inline types). The project also provides a robust framework for testing type stubs via tools like stubtest, which helps maintain a high standard of quality.
- github.com/python/typeshed - TypeShed: type stubs for the Python standard library and third-party packages
7. Lazy imports in Python 3.15 mostly won't affect type checkers -- with one catch
Python 3.15 will introduce lazy imports (accepted via PEP), a feature Michael expressed excitement about for improving app startup times. All three council members agreed that type checkers generally won't need to care, since lazy imports look like regular imports to static analysis. However, Jelle flagged one notable issue: dataclasses examine their annotations at class creation time, which triggers reification of lazy imports -- essentially making them eager again. This defeats the purpose of lazy imports in that context. Jelle said he has flagged this to the lazy imports team but no workaround exists yet. Carl also noted a subtler wrinkle around submodule imports in __init__.py files, where type checkers will need to decide whether a lazy import "counts" as making that submodule available.
8. The "from __future__ import annotations" saga illustrates the tension between runtime and static typing
The episode touched on the long history of PEPs 563, 649, and 749, which dealt with whether annotations should be eagerly evaluated at runtime or stored as strings. The default behavior (eager evaluation) makes introspection easy for tools like Pydantic but has costs: memory overhead and forward-reference errors when a class references itself or creates circular imports. The from __future__ import annotations import converts all annotations to raw strings, solving the forward-reference problem but making runtime introspection harder. This tension between the needs of static type checkers and runtime frameworks like Pydantic has been one of the most consequential ongoing debates in Python typing.
- peps.python.org/pep-0563 - PEP 563: Postponed Evaluation of Annotations
- peps.python.org/pep-0649 - PEP 649: Deferred Evaluation of Annotations
- peps.python.org/pep-0749 - PEP 749: Deferred Evaluation of Annotations (follow-up)
9. The meaning of "float" is still one of the most contentious unsettled questions
Carl revealed that every type checker currently has a different interpretation of what a float annotation actually means -- whether passing an int where a float is expected should be allowed, and exactly how that special case works in all scenarios. The current spec says a function taking a float should also accept an int, but Jelle noted that rule alone is insufficient to describe all edge cases. Rebecca said if she could go back in time, she would advocate for more explicitness from the start. The related "numeric tower" (Python's numbers module) is essentially ignored by the type system. This remains an open, actively debated topic with strong opinions on all sides.
10. Runtime type checking tools like BearType push typing into new territory
Michael introduced BearType, a library that turns Python's type annotations into actual runtime checks. You can apply it via a decorator to individual functions or globally to entire modules with an import hook. The library claims O(1) non-amortized performance. While none of the council members reported using BearType personally, they expressed an open-minded stance. Jelle said "people should feel free to write whatever code helps them make better software" and that the type system should try to accommodate all users doing useful things with types. Carl noted that the gap between what a type checker believes about your code and what actually happens at runtime is a real pain point, making the desire for runtime validation understandable. Michael suggested BearType could be particularly useful as a temporary debugging tool rather than a permanent production fixture.
- beartype.readthedocs.io - BearType: runtime type checking for Python
11. PEP 724 and TypeGuard changes were among the hardest council decisions
When asked about the most contentious decisions, both Jelle and Rebecca immediately pointed to PEP 724, which proposed changing the semantics of TypeGuard (user-defined type narrowing functions). The original TypeGuard behavior was found to be problematic, and the PEP proposed changing what the existing annotation meant under certain conditions. This created a difficult tradeoff: the long-term semantics the council wanted versus backwards compatibility and migration burden. The PEP was ultimately withdrawn because the Typing Council could not reach consensus. It illustrates a fundamental challenge the council faces: every change to the type system accumulates permanently, so new features must justify not just their correctness but the added complexity they bring.
- peps.python.org/pep-0724 - PEP 724: Stricter Type Guards (withdrawn)
- peps.python.org/pep-0647 - PEP 647: User-Defined Type Guards
12. PEP 747 (TypeForm) and other features are on the horizon for Python 3.15
Several new typing features are expected in Python 3.15. PEP 747 introduces TypeForm, a way to annotate functions that accept type expressions as arguments -- a "meta" feature that lets you have a type annotation describing another type annotation. Rebecca said she is "pretty excited" about it because it fills a gap in what the type system can express, and Carl noted it will finally allow proper annotation of existing constructs like the cast() function. Other expected additions include TypedDict "extra items" (already available via typing_extensions) and "disjoint bases" (a technical feature Jelle added to improve type narrowing). All three council members emphasized that the typing ecosystem is driven by community proposals -- anyone can propose a PEP.
- peps.python.org/pep-0747 - PEP 747: TypeForm -- Type Syntax for Type Expressions
- github.com/python/typing_extensions - typing_extensions: backports of new typing features
13. Type annotations serve as guardrails for AI-generated code
The episode closed with a discussion about how Python typing interacts with AI coding agents. Carl observed that coding agents perform better with tighter feedback loops, and type checking provides exactly that -- you can instruct an AI agent to always run a type checker and ensure no new errors are introduced. Jelle noted that as AI writes a growing proportion of code, typing will remain useful because "if typing makes humans better at writing and understanding code, it'll probably also make AI better at it." Rebecca offered a slightly different angle: as someone "maybe a little more skeptical than most of my coworkers about the quality of AI-generated code," she is especially enthusiastic about using type checkers as guardrails to keep AI-generated code honest.
14. Inlay type hints in editors reduce the need to annotate everything
Both Pyrefly and ty (and other modern tools) support "inlay type hints" -- a feature where the editor overlays its inferred type information in gray text next to variables, even when the developer hasn't explicitly annotated them. Michael pointed out that this creates an interesting dynamic: if the editor is already showing you the types, you may not need to write them all out explicitly. This aligns with the council's advice to let type inference handle local variables and focus your annotations on API boundaries and non-obvious types.
Interesting Quotes and Stories
"I think types have advantages in terms of documenting for human 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." -- Jelle Zijlstra
"If you want your type checker to work well, you should type annotate your API boundaries. So like parameters and returns in public functions, public class attributes, things like that." -- Rebecca Chen
"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, get AI to use types, type checkers, keep the guardrails there." -- Rebecca Chen
"We are probably rapidly moving to a world where a large proportion of all code is written by AI... I feel like the better we make AI, the more it is like humans. And if typing makes humans better at writing and understanding this code, it'll probably also make AI better at it." -- Jelle Zijlstra
"If we could go back in time, I would... knowing what I know now, I'd probably advocate for things being done differently." -- Rebecca Chen, on how the numeric tower and implicit type promotions were originally designed
"People should feel free to write whatever code helps them make better software." -- Jelle Zijlstra, on runtime type checking tools like BearType
"One-off scripts are not really one-off. Maybe you want to move some similar data later, and then it's useful if you can understand your code again." -- Jelle Zijlstra, on whether to add types to throwaway scripts
"Look at the typing council and sometimes think, oh, the PEP has 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 all the best ideas, propose them, discuss them." -- Rebecca Chen
Key Definitions and Terms
- Gradual typing: A type system design where adding type annotations is optional and incremental. You can mix typed and untyped code in the same project, adding types where they provide the most value.
- Type narrowing: The process by which a type checker refines a variable's type based on control flow (e.g., after an
if isinstance(x, int)check, the checker knowsxis anintinside that block). - TypeGuard: A special return type annotation for functions that perform user-defined type narrowing. When such a function returns
True, the type checker narrows the input variable's type accordingly. - TypeForm (PEP 747): A proposed special form that allows type annotations to describe other type annotations -- useful for functions that accept type expressions as arguments (e.g.,
cast()). - TypeShed: A community-maintained repository of type stub (
.pyi) files that provide type information for the Python standard library and third-party packages that don't include their own types. - Type stubs (.pyi files): Files that contain only type annotations for a Python module, without any implementation code. They let type checkers understand libraries that don't ship inline types.
- Inlay type hints: A modern editor feature where inferred types are displayed as subtle overlay text in your code, showing you what the type checker believes each variable's type is without requiring explicit annotations.
- Strict optional / nullability: The enforcement that a variable annotated as
intcannot holdNone-- you must explicitly annotate it asint | None(orOptional[int]) ifNoneis a valid value. - Reification: In the context of lazy imports, the process of actually executing a deferred import, converting it from a lazy placeholder into a real module reference.
- Numeric tower: A hierarchy of numeric types (from Python's
numbersmodule) that is largely ignored by the type system today. The related question of whetherintshould be accepted wherefloatis expected remains contentious. - Overload: A typing feature that lets you declare multiple signatures for a single function, allowing the type checker to select the appropriate return type based on the arguments at each call site.
Learning Resources
Here are some resources to learn more about Python typing and go deeper on the topics discussed in this episode.
Rock Solid Python with Python Typing: A hands-on course that teaches the ins and outs of Python typing, explores popular frameworks that use types (Pydantic, FastAPI, and more), and provides guidance for using types effectively in your applications and libraries. This is the most directly relevant course for this episode's content.
Python for Absolute Beginners: If you are just getting started with Python and want to build a solid foundation before diving into type annotations, this course takes you from the very beginning through building real applications.
Modern APIs with FastAPI and Python: FastAPI is one of the most prominent frameworks that leverages Python type hints at runtime for validation, serialization, and documentation. This course teaches you how to build APIs that put typing to practical use.
Overall Takeaway
Python typing has matured from an experimental add-on into a thriving ecosystem with dedicated governance, a formal specification, and an expanding set of powerful tools. The creation of the Typing Council via PEP 729 was a pivotal moment -- it gave the community a faster, more focused way to evolve the type system without bottlenecking on the broader Python governance process. With two new Rust-based type checkers (Pyrefly and ty) joining established tools like mypy and Pyright, developers have more choices than ever, and healthy competition is driving rapid innovation. The council's consistent advice -- type your API boundaries, let inference handle the rest, and use as much typing as genuinely helps you -- reflects a pragmatic philosophy that honors Python's dynamic roots while embracing the safety and clarity that types provide. Whether you are a library author, an application developer, or someone using AI to write code, Python typing is increasingly relevant to how you work. And if you see something in the type system you want to improve, the council's message is clear: the community is open, the process is accessible, and the best ideas come from the people using the tools every day.
Links from the show
Carl Meyer: github.com
Jelle Zijlstra: jellezijlstra.github.io
Rebecca Chen: github.com
Typing Council: github.com
typing.python.org: typing.python.org
details here: github.com
ty: docs.astral.sh
pyrefly: pyrefly.org
conformance test suite project: github.com
typeshed: github.com
Stub files: mypy.readthedocs.io
Pydantic: pydantic.dev
Beartype: github.com
TOAD AI: github.com
PEP 747 – Annotating Type Forms: peps.python.org
PEP 724 – Stricter Type Guards: peps.python.org
Python Typing Repo (PRs and Issues): github.com
Watch this episode on YouTube: youtube.com
Episode #539 deep-dive: talkpython.fm/539
Episode transcripts: talkpython.fm
Theme Song: Developer Rap
🥁 Served in a Flask 🎸: talkpython.fm/flasksong
---== Don't be a stranger ==---
YouTube: youtube.com/@talkpython
Bluesky: @talkpython.fm
Mastodon: @talkpython@fosstodon.org
X.com: @talkpython
Michael on Bluesky: @mkennedy.codes
Michael on Mastodon: @mkennedy@fosstodon.org
Michael on X.com: @mkennedy
Episode Transcript
Collapse transcript
00:00 You're adding type-ins to your Python code.
00:02 Your editor is happy, autocomplete is working great, but then you switch tools
00:06 and suddenly there are red squigglies everywhere.
00:09 Who decides what a float annotation actually means or whether passing none where an int is expected
00:15 should be an error?
00:17 It turns out there's a five-person council dedicated to exactly these questions
00:21 and two brand new Rust-based type checkers are raising the bar as well.
00:27 On this episode, I sit down with three of the members of the Python Typing Council,
00:31 Yela Zylstra, Rebecca Chen, and Carl Meyer to learn about how the type system is governed,
00:37 where the spec and type checkers agree and disagree, and I get the council's official advice
00:42 on how much typing is just enough.
00:45 This is Talk Python To Me, episode 539, recorded January 27th, 2026.
00:53 Talk Python To Me, yeah, we ready to roll.
00:56 Upgrading the code, no fear of getting old.
00:59 Async in the air, new frameworks in sight, geeky rap on deck.
01:03 Quart crew, it's time to unite.
01:05 We started in Pyramid, cruising old school lanes, had that stable base, yeah, sir.
01:09 Welcome to Talk Python To Me, the number one Python podcast for developers
01:13 and data scientists.
01:14 This is your host, Michael Kennedy.
01:16 I'm a PSF fellow who's been coding for over 25 years.
01:20 Let's connect on social media.
01:22 You'll find me and Talk Python on Mastodon, Bluesky, and X.
01:25 The social links are all in your show notes.
01:27 You can find over 10 years of past episodes at talkpython.fm.
01:31 And if you want to be part of the show, you can join our recording live streams.
01:35 That's right, we live stream the raw, uncut version of each episode on YouTube.
01:39 Just visit talkpython.fm/youtube to see the schedule of upcoming events.
01:44 Be sure to subscribe there and press the bell so you'll get notified anytime we're recording.
01:48 This episode is brought to you by Sentry.
01:50 Don't let those errors go unnoticed.
01:52 Use Sentry like we do here at Talk Python.
01:53 Sign up at talkpython.fm/sentry.
01:57 And it's brought to you by our Agentic AI programming for Python course.
02:02 Learn to work with AI that actually understands your code base and build real features.
02:07 Visit talkpython.fm/agentic-ai.
02:11 Della, Rebecca, and Carl, welcome to all of you type-loving Pythonistas.
02:18 Awesome to have you here on the show.
02:20 Thanks for being here.
02:20 We're going to talk Python typing, especially from the perspective of the Python Typing Council,
02:27 which honestly, I am a huge fan of Python typing.
02:30 It's still something I learned about not too long ago.
02:33 So I'm going to be learning along with everyone else, what it is you all do and so on.
02:38 So I'm really excited to be diving into this.
02:41 I think since types came to Python, I think it's made it a little bit more rigorous,
02:46 you know, for all those people out there like, oh, it's not a real language without any form of static typing.
02:51 We can't use it on real projects.
02:53 I don't know how true that was, but certainly it's less true now.
02:56 You know, you can pick per project.
02:58 So it's super cool.
02:59 Before we get into all that, though, let's just go around for a quick introductions.
03:03 Jala, welcome to the show.
03:05 Awesome to have you here.
03:06 Who are you?
03:06 Hi, yeah.
03:07 Jala, I've been on the Python Typing Council since the beginning.
03:10 I helped set it up a couple of years ago.
03:12 Outside of the typing work, I currently work at OpenAI, where I work on developer productivity,
03:17 which means things like running CI for people and helping, generally helping people be productive.
03:23 I've been working with Python for more than a decade.
03:25 Started out because my previous job was mostly in Python and then got more and more involved with the language.
03:32 So let me get this right.
03:33 At OpenAI, you're basically helping developers there have better developer tooling
03:37 and common packages and workflows and stuff like that.
03:41 Is that kind of the story?
03:42 That's right.
03:43 Mostly around things that happen in CI, like running tests efficiently, figuring out the right tests to run,
03:49 getting the right CI workers out.
03:50 That sounds very exciting.
03:51 Right in the epicenter of all the big tech stuff these days.
03:56 Super cool.
03:57 Rebecca, hello.
03:58 Welcome.
03:58 Hey, thanks for having me.
04:00 I'm Rebecca.
04:01 I've been on the Typing Council also for about three years, I think, since the, less than three,
04:07 since the beginning.
04:08 But my day job, I work at Meta on Python typing, gone Pyrefly, which is a new type checker
04:16 and language server written in Rust, still in beta.
04:20 Prior to that, I was at Google for eight years, also on the Python team.
04:24 I just, I really like Python.
04:26 Yeah, super neat.
04:27 I'm a big fan of both Pyrefly and ty, which will both have representatives here, I know.
04:33 And I think it's just a super exciting time for Python types.
04:37 And certainly that's one of the reasons.
04:38 So very cool.
04:39 Carl, welcome back.
04:40 Thank you.
04:41 Great to be here.
04:42 Yeah, Carl Meyer.
04:43 I currently work at Astral, where I work on ty, which is a Python type checker and language server
04:50 written in Rust, also in beta.
04:53 And yeah, I guess, how did I get into typing?
04:55 Or I've been on the Typing Council, not since the beginning.
04:59 I think it's been a year and a half.
05:01 And yeah, I got into Python typing at the time in 2016, 2017.
05:07 I was working at Instagram.
05:08 And that was in the very early days of Python typing.
05:12 The PEP44, PEP43, the early Python typing PEPs had recently come out within the last couple of years.
05:19 And one of the co-authors of some of those PEPs, Lukash Lange, was actually sitting at a desk
05:24 right next to me at the time.
05:25 And at some point, we started to think that we should try this Python typing stuff
05:28 on the Instagram server monolith.
05:31 And so I took that on as a side project.
05:33 And then it eventually became the main project.
05:35 And then it took like three years.
05:37 So a lot of Python typing experience there.
05:40 There absolutely is.
05:40 You know, I think a couple of things I'd like to touch on there.
05:43 First of all, Instagram, is it maybe the biggest Django deployment in the world?
05:48 It's certainly one of the bigger ones, right?
05:50 And I think a lot of people don't necessarily know that a core chunk of Instagram is actually Python, right?
05:55 I mean, I don't know if we have any way to know how big the Django deployments in the wild might be.
06:00 But it's certainly a big one.
06:01 Yeah, it's definitely a big one.
06:02 There were some talks about dismissing the garbage collector from the Instagram folks.
06:08 That wasn't you giving the talk, but at PyCon.
06:11 So that was pretty interesting.
06:12 But I think actually that work that you're talking about, especially with Lukash, really kind of opened
06:19 a lot of people's eyes about Python typing, right?
06:22 He gave a couple of PyCon talks, showed, you know, real metrics of how much of the code base is typed,
06:28 how much it's changed, like error detection, that kind of stuff.
06:33 So let me ask you, do you feel like it would be different?
06:36 Would it have gone different now if tools like TY and Pyrefly existed back then?
06:42 Is Python typing different now than it was then?
06:44 Certainly, yes.
06:45 I mean, there's been, the type system has gotten more complex over time.
06:49 So it is both more expressive and more complex.
06:52 And yeah, we have more type checkers available now.
06:56 I do agree that it's more complicated, and I don't know how to feel about that.
06:59 It is more expressive, but I feel like it's starting to get, I mean, we're not at C++ ATL,
07:06 like templates of templates of templates, but still, it's getting more serious.
07:12 But I guess one of the really nice parts is that you can just take as much as you want
07:16 of the complexity, and you can just leave the rest, right?
07:19 That's part of the magic of Python typing, is that it's a gradual typing system.
07:23 That's a choice people get to make.
07:25 It can be none, it can be quite a bit, and anywhere in between.
07:30 So I guess that's probably one of the decisions.
07:33 Let's talk about the typing council.
07:34 So when did the typing council come along, and did the typing council exist to create
07:40 all of these PEPs and make this happen, or was it afterwards?
07:43 Like, what's the history of the typing council and its purpose, folks?
07:47 We'll run it.
07:47 Yeah, it postdates most of the PEPs.
07:49 So initially, the text system was created just through the regular PEP process.
07:52 It means that something gets submitted, first still to Guido as the BDFL,
07:57 later to the steering council.
07:59 Meant that it's very hard to make changes to, like, this specification.
08:03 Like, anytime you want to make change something about how the type systems would work,
08:06 we had to go through this PEP procedure, talk to the steering council, who are very busy people,
08:11 who deal with a lot of other aspects of the language other than typing.
08:14 So Shantanu and I came up with this idea of creating a separate council to specifically in charge of typing,
08:21 that would be in a specification where we can make small changes ourselves
08:25 without having to go through this whole PEP process.
08:27 And this way, when all the type checkers agreed that something needs to go a certain way
08:31 and it's not exactly what's in the PEPs, we can change it and have a place to record that
08:36 and people can refer to it and new type checkers can also try to follow those decisions.
08:41 Very interesting.
08:41 I didn't realize that it was sort of, was there to allow for small changes
08:46 to be made to make that much easier.
08:48 But of course that makes sense because the PEP process is, it's pretty serious and drawn out.
08:52 And we've seen even small language changes have quite passionate folks, I guess we should say.
09:00 So yeah, yeah, very nice.
09:02 Do you have any examples of the types of changes that y'all have, that have happened over the years
09:06 that maybe were typing council only?
09:09 One was the specification where how overloads work, which is perhaps not really a small change,
09:14 but one of the most complicated features in the type system really is the overloads,
09:17 where you can give multiple signatures for a function and type checkers sort of select
09:22 which one to use based on the arguments when the function is called.
09:26 And when it was initially created, from what I recall, there just wasn't really a specification.
09:31 It's just like you use the signatures in a way that makes sense.
09:35 And Eric Trout, who's currently on the council, came up with a pretty specific procedure
09:40 for exactly how overload should work to make it so that type checkers have,
09:45 well, sort of users can understand how it works and sort of type checkers can have something
09:47 to work towards to make sure that they work infinite overloads in the same way.
09:51 Maybe a smaller example that is an example of something that would have been too small for a pep
09:56 and hard to accomplish before the typing council existed.
10:00 And this is actually a change that I pushed through before the, before I was on the typing council,
10:05 but the typing council approved it, was a clarification around the interpretation of data class fields.
10:11 If a final annotation is applied to a data class field, does that mean, so if you apply a final annotation
10:18 to a regular class attribute, since it can't be changed, that implies that it's a class variable.
10:24 And there was a question of if that should be the interpretation with the data class or not.
10:28 So we discussed that and made a clarification to the spec.
10:31 I've never really thought about final being applied to a class field, but I've always used them
10:36 sort of just for constants.
10:38 But, you know, maybe people out there don't know, like typing dot final bracket type,
10:43 right?
10:44 That's kind of the way you can do constants in Python, right?
10:47 Constants for the type checker.
10:48 Nothing in the runtime will stop you from editing it.
10:51 That's...
10:51 Not there.
10:52 Not there.
10:52 I have some examples coming up and I'm interested to hear your thoughts on it,
10:56 but for sure it's, there is this tension, right?
11:00 I mean, I think that's probably worth touching on as well is this is a tension for Python
11:04 in general is you can write all the types you want and then when you run your code,
11:09 it just doesn't care.
11:11 There's a few instances, Pydantic, FastAPI, a few others, but generally speaking,
11:15 it's there for the editors and the type checkers and the linters and not for runtime, right?
11:20 Yeah, that's right.
11:21 There's many exceptions to that.
11:23 There's a product like mypyC, which comes with mypy that's used those types
11:27 to compile your code into more efficient machine codes.
11:30 Maybe there's going to be more products like that in the future.
11:32 I don't know.
11:33 But yes, in general, it's separate from the runtime.
11:36 Sort of a similar model to TypeScript where TypeScript gets compiled into JavaScript
11:40 and types just go away.
11:42 Here, we don't do a compilation step, but still the same idea of the types
11:45 just not influencing the runtime.
11:47 Although we do make them available for introspection via done annotations attributes,
11:51 which is what has enabled the projects like Pydantic and other sort of runtime checkers
11:56 to make use of type annotations at runtime also.
11:59 Yeah, I don't know if the typing council was around for this, but there was proposed,
12:03 I don't remember the exact details, but something to the effect of for type checking,
12:07 not actually doing some of the full imports or something along those lines,
12:13 right, where the runtime behavior would have made it hard for tools like Pydantic
12:17 and others to get that.
12:19 And there was some kind of compromise, right?
12:21 I don't remember the details here.
12:22 Anyone does?
12:23 Yeah, what happened was that there was going to be a change.
12:25 That's what the from future import annotations import does, that changes all annotations
12:29 into raw strings.
12:30 So the default behavior before recently was that annotations that are regular codes.
12:36 If you write devf return to ints and you import the module, it just looks up
12:40 the name ints and puts that in an annotations dictionary, which makes introspection easy,
12:44 but it made a test on costs on performance because memory usage sometimes was high
12:50 and also made things harder to use sometimes because if you use a name that's not defined yet
12:55 at runtime, you get an error.
12:57 That often comes up if you have like a class that has a reference in an adaptation
13:01 to the class itself or circular dependency classes.
13:05 Right.
13:06 The circular imports because you want to say this class is created by that thing
13:11 and it returns one, but you know, somehow you've got to import the other one
13:15 and that's such a hassle.
13:17 Yeah, it's, yeah, even out in the audience we have, Tom says, circular imports.
13:21 Oh, yeah, for sure.
13:22 What about lazy imports?
13:24 Like that just recently got accepted and will be in 3.15.
13:27 Which I'm super excited about because I think it'll make app startup a lot faster
13:32 for many use cases.
13:34 But does that have knock-on effects for typing?
13:36 Not that directly because I think for a type checker lazy imports mostly just look
13:41 like regular imports.
13:42 I guess I should maybe leave that for the people who are actually working on type checkers
13:46 and being written right now.
13:47 Yeah, Rebecca, do you see this making any difference for you?
13:50 Lazy imports?
13:51 To be honest, it's not something we've looked at too carefully yet.
13:55 3.15 seems a little more in the future, but I don't think it's likely to make a huge difference.
14:03 Carl?
14:04 I've thought about it briefly and I think that it, I think the type checkers
14:07 really won't need to care.
14:08 Maybe there will be some edge cases that will come up that I haven't thought of,
14:11 but it shouldn't be a big deal.
14:12 Yeah, that's what I thought as well.
14:14 The one variation that I can certainly see is if you have a, if you have something
14:20 specified in a type, like say for a field of a class or a Pydantic model
14:25 or something that would otherwise not trigger the lazy import to become imported,
14:30 would potentially having types specify cause more importing to happen sooner
14:36 in the runtime?
14:36 Yeah, there's actually an issue related to this that I think we may need
14:39 to resolve before 3.15, but I don't know how yet.
14:43 If you use a type in a data class annotation that's lazy imported, actually creating
14:47 a data class will delay by the import.
14:49 It will try to resolve the import and actually make it not lazy.
14:55 This is because data classes doesn't really need to look at all of the annotations
14:58 in your class, but it looks at them enough to trigger reification of the import.
15:04 I shared this with some of the people on the lazy imports team, but we haven't
15:07 yet come up with a good way around it.
15:09 I think this might end up being a bit of a food gun, so I feel like we should ideally
15:12 find a workaround, but I don't know what it would be yet.
15:15 I don't know that it's wrong that it converts it to an eager import, which it needs
15:20 to know what it is potentially, right?
15:22 It actually doesn't.
15:24 Data classes just need to know whether it is classed for or not.
15:27 I think that's pretty much all.
15:28 I guess there's an init for also, but it doesn't really need to know anything else.
15:32 So in theory, it should be possible to just say, hey, it is not classed for, so don't bother
15:37 importing it.
15:38 Okay, so that's for data classes, but say if I specify a parameter type on a function.
15:43 Yeah, then it should be fine.
15:45 I guess, again, unless something is, if it does annotate, so if you have
15:49 something like a decorator that looks at annotations in your function, it might reify
15:53 those imports.
15:54 There is one other potentially interesting thing for type checkers.
15:57 It's already difficult for type checkers to figure out when like a submodule
16:02 should be considered to be an attribute of the parent module because the way
16:06 this happens in Python is that any import of a submodule anywhere will attach
16:10 that submodule as an attribute on the parent module, but that at runtime,
16:15 that could literally happen anywhere.
16:17 It could happen in totally unrelated code outside of the module and a type checker
16:20 probably won't be able to see that.
16:22 So type checkers already have sort of complex sets of rules around where they look
16:26 for these submodule imports and when they consider a submodule import to be reliably
16:30 happening enough that it should, that the type checker should consider this submodule
16:35 to exist as an attribute.
16:38 And lazy imports may make that even, we'll add one more wrinkle to those
16:43 sets of heuristics in that we'll have to decide if you have a lazy import
16:46 of a submodule and you're done to init.py, it's lazy.
16:50 So should the type checker consider that submodule to be imported or not be imported?
16:55 It'll be another case where there's no clear right answer and we'll just have
16:58 to make a decision one way or the other.
17:02 This portion of Talk Python is brought to you by Sentry.
17:05 I've been using Sentry personally on almost every application and API that I've built
17:10 for Talk Python and beyond over the last few years.
17:13 They're a core building block for keeping my infrastructure solid.
17:16 They should be for yours as well.
17:18 Here's why.
17:19 Sentry doesn't just catch errors.
17:21 It catches all the stuff that makes your app feel broken.
17:23 The random slowdown, the freeze you can't reproduce, that bug that only shows up
17:28 once real users hit it.
17:29 And when something goes wrong, Sentry gives you the whole chain of events
17:32 in one place.
17:33 Errors, traces, replays, logs, dots connected.
17:36 You can see what's led to the issue without digging through five different dashboards.
17:41 Sear, Sentry's AI debugging agents builds on this data, taking the full context,
17:46 explaining why the issue happened, pointing to the code responsible, drafts a fix,
17:51 and even flags if your PR is about to introduce a new problem.
17:55 The workflow stays simple.
17:56 Something breaks, Sentry alerts you, the dashboard shows you the full context,
18:01 Sear helps you fix it and catch new issues before they ship.
18:04 It's totally reasonable to go from an error occurred to fixed in production
18:08 in just 10 minutes.
18:10 I truly appreciate the support that Sentry has given me to help solve my
18:14 bugs and issues in my apps, especially those tricky ones that only appear in
18:19 production.
18:19 I know you will too if you try them out.
18:21 So get started today with Sentry.
18:23 Just visit talkpython.fm slash Sentry and get $100 in Sentry credits.
18:28 Please use that link.
18:29 It's in your podcast player show notes.
18:31 If you're signing up some other way, you can use our code talkpython26, all one word,
18:36 talkpython26, to get $100 in credits.
18:40 Thank you to Sentry for supporting the show.
18:43 Yeah, there's some variations across type checkers, which we'll get to later.
18:47 I think, though, before we move off this, there's actually off introducing the
18:52 typing council.
18:53 I think we should point out that there's two other folks who couldn't be here
18:56 who are also on the typing council, Eric Trout and Yuka Letts, the docilo?
19:03 Sorry, Yuka.
19:05 But I want to make sure that we point out there's actually five people, not just the
19:08 three of you, right?
19:09 How do you get on the council?
19:11 Is there an election?
19:13 Do you just apply?
19:14 I think these are filled by the members themselves.
19:16 So when somebody declares the intention to leave the council, we basically ask for
19:20 people who are interested and then make a selection.
19:23 Generally, we try to get people who have experience in the type system.
19:27 We try to get a good cross representation of people working on different
19:29 type checkers.
19:30 We have Carl and Rebecca here who work on two type checkers, ty and Pyrefly.
19:36 Yuka works on Pyrites, which are two of the most lightly used type checkers.
19:41 So we try to get representation of people working on those parts of the ecosystem.
19:46 That's really cool that it's got a bias towards finding people actually doing the work.
19:50 So let's talk about the specification project at typing.python.org.
19:55 What is this here?
19:56 I'll talk a bit about it.
19:58 I guess it's a specification for how the type system used to work.
20:03 The way it started was that, Yela, you basically took all the typing peps
20:07 and like stapled them together, right, to make like one long doc.
20:12 And since then, we've been iterating on it, filling in parts that were missing
20:16 like overload evaluation and making other changes as well.
20:21 Yeah, it's tricky, right?
20:22 Because traditionally, the typing system is kind of defined across a series of
20:28 peps.
20:28 And so what is the document that tells you how it works, right?
20:31 Yeah, that made it hard because often there's peps built on top of each other.
20:35 So then in the extreme, you might see like one thing in one pep and then there's
20:39 another pep that adds an aspect of it, another one that adds another aspect.
20:43 And overall it makes it very hard to follow.
20:44 One of the things I did recently was rewrite the typed dict another.
20:55 Ended up rewriting the whole thing to basically put all those features together
20:58 in a coherent whole rather than just having them all copy-pasted one after the
21:04 other.
21:04 Okay, so if somebody really wants a good understanding of the Python typing system,
21:09 they go to typing.python.org.
21:11 You know, one thing I think maybe is worth touching on, it's just kind of out of the
21:15 blue a bit, but I think it's a really interesting aspect of the Python typing system
21:20 is the, what is it called, the numerical tower or the number tower, where
21:24 it's like, if I have a number, I could specify it as an int, or I could specify
21:29 it as a float, and those kinds of things, but do you really need to say it's an
21:34 int pipe float, or a union of int and float, if it could be either, right?
21:39 And the, what is it called?
21:40 It's the numerical tower, right?
21:42 Yeah, there are different towers too.
21:43 In Python, there's also this thing called a numbers module that you have there, that's
21:48 just basically ignored by the type system.
21:50 It's been useful for some people, I feel like in general that module just
21:52 hasn't worked out very well as being very useful.
21:55 I think the interesting aspect is that you know, that you can say it's a
21:59 float, and that's basically equivalent to union of integer and float, and so
22:04 on, right?
22:05 I think the typing numbers in Python is pretty interesting.
22:08 I think every type checker has a different interpretation of what a float
22:13 annotation actually means.
22:16 It's an area of some lack of clarity in the spec.
22:19 Yeah, a lot of contentiousness.
22:20 If we could go back in time, I would, like, knowing what I know now, I probably advocate
22:25 for things being done differently because, like, beginning, you know, like, there
22:30 were multiple things, like, with similar flavor.
22:33 Like, there was also one where you could give a parameter a non-none annotation and
22:39 default it to none for convenience, and we've largely, like, moved away from stuff like
22:44 that in favor of explicitness.
22:46 Yeah, what the current spec says is that basically if you have a function that takes
22:49 a float, you're also allowed to pass an int.
22:52 That's not really enough.
22:54 It doesn't tell you how these things work in all cases, and we've had some
22:59 attempts to try to come up with a way to specify that special case in a way that
23:04 makes more sense, at least makes more sense to me.
23:07 It's been very contentious.
23:08 People have very strong opinions about this.
23:10 I guess non-obvious is what I'd like to say, really, honestly.
23:13 So I'd like to get the official counsel's thoughts on this.
23:17 When is typing too much typing?
23:20 I made the joke about C++, ATL, if you've ever worked with that, it's like
23:24 a template class where templated classes are part of the concrete type of the
23:30 template.
23:30 It's just off the hook.
23:32 There's certainly places where typing can be too much, and a lot of the purity of Python
23:38 or the readability of Python is the fact that it's got so few symbols.
23:44 And so adding types adds context, but it also makes it a little harder to read.
23:49 When is too much typing?
23:50 When do you recommend typing?
23:53 Rebecca, I'll let you go first, but what are your thoughts on how much typing should
23:57 I use in Python?
23:59 I'll give you what is my official stance, which is that if you want your
24:04 type checker to work well, you should type annotate your API boundaries.
24:09 So parameters and turns in public functions, public class attributes, things
24:14 like that, and even things that seem true trivial, like, oh, this function returns
24:18 none, better to annotate it because, you know, someone else might be depending on
24:24 your library and consuming that type of information.
24:27 I will say personally, what I tend to do is I annotate things that I think are
24:32 non-trivial because I want to see that as documentation.
24:37 And if something, you know, a function that does return none, to be honest, I will
24:42 probably forget to annotate it half the time because I'll be like, I honestly don't
24:46 need to see it.
24:47 One of the interesting features of the Pyrefly VS Code extension, that's the only
24:53 one I can speak of at the moment, and Carl, you've got to tell me if the
24:56 ty one does this as well, is it will sort of overlay its belief of what types
25:03 are.
25:03 Like, if there's, you say x equals a function return value and it knows what the
25:07 function returns, it'll have a gray, like, colon int, if it returned an int or something.
25:11 So you can kind of read the code and see what the types are without actually putting
25:17 it into the text of the code.
25:19 It's only within the editor.
25:20 Does ty do something like that, Carl?
25:22 Yes, we also have inlay type ins.
25:23 Yeah, inlay type ins, that's what it's called.
25:25 So, yeah, I don't know, that also brings an interesting challenge, not a challenge,
25:28 like a wrinkle to the recommendation of should I put types on, like, the return value
25:35 because I want to know that's a list of user, not a list of user IDs or whatever, for
25:39 example, like a list of UUID.
25:41 But if, it's going to show up anyway in the editor, maybe I don't have to write
25:45 that, right?
25:45 And so that becomes sort of somewhere where you could debate again, I think.
25:50 However, I do 100% agree with you, Rebecca, that put it on your API boundaries.
25:54 If, like, this is the place that people get into some part of your code and they
25:58 don't know or want to know about the inside of it, having types there is really helpful
26:03 both for editors, for type checkers, and just for reading code, and even for AI, which
26:08 is a crazy world.
26:09 Yeah.
26:09 Carl?
26:10 What are your thoughts here?
26:11 How much typing is too much typing?
26:13 What's the guidelines here?
26:14 I think I agree with Rebecca's answer.
26:16 I mean, that one place you definitely want to have explicit type annotations is that
26:21 API boundaries, the public API of a library, etc.
26:24 In terms of what's too much typing, I mean, there are certainly patterns
26:28 that have historically been used in Python that we still can't express well
26:34 in the type system, or that require extremely complex type annotations to
26:39 express well, and I think there it becomes a judgment call.
26:43 If it's like a core, widely used API, you may get a lot of benefit from some
26:48 very complex and verbose annotations, and so then it's worth sort of going
26:53 through that pain and the pain of adding them and of reading them in order to get that
26:57 additional typing coverage everywhere you use that API.
27:01 If it's much less frequently used code that's highly dynamic, maybe it's not worth
27:05 it in that case.
27:06 I think there's a lot of judgment calls here.
27:08 What about like one-off scripts?
27:10 You know, I'm going to write this thing to just move this data from here to there,
27:13 and once it's moved, I don't need it again.
27:15 It's done with that old system, we're going to the new one.
27:17 Maybe less typing.
27:18 Yeah, I think that's what's useful for you.
27:20 Often I feel like one-off scripts are not really one-off like maybe you want to move some
27:24 similar data later, and then it's useful if you can understand your code again,
27:27 if you want to read what you did.
27:29 You thought you didn't need it again, and all of a sudden at six months old,
27:32 you don't understand it, and the types that help a lot, right?
27:35 Yeah.
27:36 Yellow, what's your advice?
27:38 What Cara and Rebecca said makes sense to me too.
27:40 I think types have advantages in terms of documenting humor readers, what
27:45 is going on, and in terms of catching mistakes that otherwise would not be
27:49 caught until runtime perhaps.
27:51 They have costs in maybe making your code harder to read if there's too much
27:54 going on.
27:54 So add types as long as those benefits outweigh the costs.
27:57 Yeah.
27:58 I mean, do you recommend to anyone that they just 100% go full like C++,
28:04 C# on it, and just type it every single thing?
28:08 Is there an advantage like for static type checkers, you know, like mypy type stuff
28:12 you can run across and get that?
28:14 I mean, you could do that with Powerfly or TY and the CLI as well, but you know,
28:18 thinking more mypy is like kind of being real strict on some of that stuff.
28:21 Personally, I do tend to annotate almost all like function parameters and if class
28:26 attributes, if I make a class, sometimes it's not as necessary, like you don't
28:30 really need to annotate your tests perhaps, or you don't need to annotate
28:33 internal functions as much, but for my own coding, I usually find it helpful
28:36 to do that.
28:37 But sometimes I see people annotating even local variables where it's very
28:41 obvious to type check if the type is and they can just infer it reliably, and then
28:46 it really just adds noise and you shouldn't do it.
28:48 Yeah, exactly.
28:48 If you've got a function that's annotated with a return value and you say x equals
28:53 the function call, then the type checkers can infer that and you're just causing
28:57 extra noise, I guess.
29:00 So suppose you all want to change something.
29:03 What's the process of actually going through and making some changes?
29:08 Mostly sort of two levels of this.
29:10 Well, maybe there's even three levels.
29:11 The first one is if it's something that's so small that's just like a wording
29:15 clarification or something, we just make a PR to the repo and a few of us
29:19 look at it and we change it.
29:21 The second level is when it's sort of a smaller change that doesn't really
29:25 introduce a new feature and then we make a PR to the typing spec repo and
29:30 we formally have all of us sign off on it.
29:32 That's what happens like what Carl mentioned earlier of the final change in data
29:37 classes.
29:37 It's had to merge this one, yeah, add Carl.
29:41 I love it.
29:42 This repo itself doesn't have anything.
29:44 It's the Python typing repo where the decisions are made.
29:48 The typing council just has like some documentation.
29:52 Yeah.
29:52 And then the third level is peps, like really big new changes.
29:55 You can still write a PEP and then we make a recommendation and the steering
29:59 council makes a decision eventually.
30:00 So if I wanted to suggest something, I could come up here and I could open up
30:05 an issue, maybe start a conversation on typing, Python slash typing.
30:10 And you can make a pull request to change the spec.
30:12 Okay.
30:12 And so the pull request would not be to change the code, like how Python
30:17 maybe interprets code that has this new thing, but to suggest that the spec
30:22 has it, which then would start a process that ultimately might make CPython
30:26 understand it, right?
30:27 Well, CPython itself probably doesn't do anything with it.
30:30 I guess most of the things that go directly here are changes to how to interpret
30:33 things that are already in CPython.
30:37 This portion of Talk Python To Me is brought to you by us.
30:40 I want to tell you about a course I put together that I'm really proud of, Agentic
30:45 AI Programming for Python Developers.
30:48 I know a lot of you have tried AI coding tools and come away thinking, well, this is
30:52 more hassle than it's worth.
30:54 And honestly, all the vibe coding hype isn't helping.
30:58 It's a smokescreen that hides what these tools can actually do.
31:01 This course is about agentic engineering, applying real software engineering
31:06 practices with AI that understands your entire code database, runs your tests, and
31:11 builds complete features under your direction.
31:14 I've used these techniques to ship real production code across Talk Python,
31:18 Python Bytes, and completely new projects.
31:21 I migrated an entire CSS framework on a production site with thousands of lines of HTML
31:25 in a few hours, twice.
31:28 I shipped a new search feature with caching and async in under an hour.
31:32 I built a complete CLI tool for Talk Python from scratch, tested, documented, and
31:38 published to PyPI in an afternoon.
31:41 Real projects, real production code, both Greenfield and legacy.
31:46 No toy demos, no fluff.
31:48 I'll show you the guardrails, the planning techniques, and the workflows that
31:51 turn AI into a genuine engineering partner.
31:54 Check it out at talkpython.fm slash agentic dash engineering.
31:58 That's talkpython.fm slash agentic dash engineering.
32:01 The link is in your podcast player's show notes.
32:05 If it's adding something new, it will usually need to go through a path,
32:09 except if it's something very small.
32:10 Let's talk about that for a minute.
32:11 We got two representatives here of the newer breed of tools.
32:17 What's the story for inconsistencies across interpretations of the spec?
32:23 I know that there's slight variations.
32:25 I've also, you know, not putting either of you on the spotlight, but like using, say,
32:31 PyCharm and like writing code.
32:33 So it's type checkers happy and then using something like Pyright.
32:37 And so it has a real different interpretation of what you should let slide and what you
32:42 shouldn't.
32:43 I feel like Pyright is more, much more focused on like enforcing the nullability and or
32:49 the lack thereof.
32:50 And it warns of inconsistencies there where PyCharm doesn't seem to care as much.
32:54 I don't know which one I like better, but I know they're different.
32:57 And if I write code in one that I open the other, I'm like, huh, why is it
33:00 upset?
33:00 It seemed like it was fine.
33:02 How do you all navigate this?
33:03 Yeah.
33:03 One thing useful to say about the spec there is that the spec covers a lot of
33:07 things.
33:08 In particular, it tends to cover sort of the details of more advanced type
33:11 system features.
33:12 But there's a lot of very fundamental stuff about how a type checker works
33:17 in terms of how it does inference and how it does type narrowing.
33:21 And even in some cases, like you mentioned, you know, what it chooses to
33:24 emit errors on that isn't really covered by the spec, partly maybe because we
33:29 haven't gotten to it and also partly intentionally in that there may be room in
33:35 some of those cases for different type checkers to work differently if they're
33:38 serving different needs.
33:39 Like if PyCharm is primarily concerned about being a useful kind of IDE and providing go-to
33:45 definition and that sort of thing, maybe emitting lots of warnings or errors
33:50 and all kinds of things where your code might be doing something wrong isn't
33:54 as high a priority.
33:54 And another type checker might have a different priority.
33:57 One thing I do want to mention is that it may not seem like it, but things are already
34:04 much better than they used to be.
34:07 Like previously, I worked on a different type checker called PyType.
34:11 And at that time, it was, you know, sort of the Wild West.
34:14 Like we want to know how other type checkers like do something.
34:18 Well, you know, like open up the mypy playground, open up the PyRite playground,
34:22 see what tells you.
34:25 Now we at least have spec and conformance tests.
34:28 Yeah, that's really cool.
34:29 How much would you say that your two type checkers maybe bring in mypy as well?
34:36 Like how much do they agree versus disagree?
34:38 You know, like you only see the differences.
34:40 You don't see in which ways that they are the same as a consumer of them so much,
34:44 right?
34:44 You're like, why is this one squiggly when it wasn't squiggly before?
34:47 But how similar or different are they?
34:49 I don't know how we would quantify that.
34:51 I think there's a lot that is the same just because it's based on how Python actually
34:55 works.
34:56 We're both trying to model the same language and then there's certainly also
34:59 plenty of differences or things that we handle differently.
35:02 So Rebecca, do you have a better way to quantify that?
35:04 Yeah, I agree.
35:05 it's hard to quantify, I suppose, talk a bit abstractly about various type
35:11 checkers philosophies.
35:13 With Pyrefly, we really try to do a lot of type inference.
35:17 So that's a way in which we intentionally diverge a bit from mypy.
35:21 But other than that deliberate decision, if we see ways in which we are accidentally
35:25 different, we do try to fix that because otherwise people would have a hard time running
35:31 multiple type checkers or migrating.
35:33 Yeah, differences obviously cause pain for users who are using multiple type
35:37 checkers or writing libraries that need to support multiple type checkers.
35:40 So like Rebecca said, it's like if we are different from other type checkers, we want
35:45 to be sure that there's a good reason for that difference.
35:47 The difference should be because of philosophical choice, not just you happen to have
35:52 chosen slightly differently, right?
35:54 Yeah, and it's not just people who run different type checkers.
35:58 Like you pointed out, Carl, a lot of times it is if I have a library and
36:02 then different people want to consume that library, then their type checker
36:06 may or may not warn them about how my library declares its types and so on.
36:11 I'll give you a real quick example.
36:14 I have a, I can't remember which one it was, I have three or four different open
36:19 source libraries that I've created that somehow work with creating, basically passing
36:24 data to templates in web apps, right?
36:27 So one is like I want to use the Chameleon web template framework, but with fast
36:31 API or with Flask or there's some other variations like partials and so on.
36:35 I can't remember which one, but it doesn't really matter.
36:37 One of them decorated a Flask.
36:40 I think it was a Flask, especially makes it irrelevant.
36:43 A Flask endpoint and PyRite was really upset.
36:47 Like the error message filled the entire page of how it was inconsistent with
36:53 what it expected for the definition of the Flask view method.
36:56 I'm like, no one is going to call this.
36:58 Like what does it even matter what this type is?
37:01 It still runs fine.
37:02 The runtime is fine.
37:03 You know, it's no problem with this decorator.
37:05 It worked fine, but something about the way that the Flask at get returned
37:11 the type versus what my thing returned varied in like a really slight way.
37:16 I didn't care, but somebody was using some editor that used PyRite and they're like, you
37:21 have to help fix this.
37:22 I can't take all these warnings.
37:23 They're huge and they're everywhere.
37:25 Like, okay, I'll go fix it.
37:27 Right.
37:27 And I went and I put way more effort than was justified into a function type
37:32 that no one ever calls just to make the errors on some type checker I didn't use go
37:38 away.
37:38 Right.
37:39 And that's the kind of thing where it becomes just a headache.
37:41 I don't know.
37:42 I wish I remember.
37:42 I probably got that written down in an issue somebody filed, but it was, it was
37:46 a gnarly error.
37:47 And, or if you're working on an open source project, you know, you can't make
37:50 everybody use the same editor that wants to contribute on a big project.
37:55 And so you might run into this variation as well.
37:57 So there's a lot of cases.
37:58 Yeah.
37:58 It can be really difficult to make these decisions about what kind of, what
38:03 sorts of errors people want their type checker to catch or what's too pedantic.
38:08 You want your type checker to catch non-obvious errors, not just the obvious
38:12 ones that you probably would have seen by looking at the code yourself.
38:15 But then there'll be cases where somebody says, well, I don't care.
38:18 That's too pedantic.
38:19 And it is difficult to make everyone happy.
38:21 Who decides what the right signature of a flask view and point should be like if you
38:27 the framework can call it.
38:28 It should be okay.
38:29 There's not.
38:30 Just because it had a decorator before, that doesn't mean that's the official structure.
38:33 But anyway, I do think one of the bigger philosophical differences has to do around this
38:39 concept of nullability.
38:41 Do you guys call it nullability or none ability?
38:44 Like nullability comes from the other languages.
38:46 And by that, I mean, I can specify that I have an integer.
38:49 And in the Python type system, it cannot be set to none, even though in the runtime it can.
38:55 It has to be a concrete int type unless you make it a optional int or an
39:00 int pipe none or one of those type things, right?
39:03 And how strong that gets enforced seems to be one of the biggest difference
39:07 of opinions that I've seen around.
39:10 Like, how do you all think about that?
39:11 That's interesting to me that that's your experience because my experience has been that
39:16 that's actually an area where everyone seems to agree as far as I can tell that these are is
39:21 an important source of bugs and it's better to catch them.
39:23 So I think all of the type checkers, maybe you said PyCharm doesn't.
39:26 I don't think PyCharm does that.
39:28 I'm pretty sure it doesn't because I agree that it's an important thing to check, but it's
39:34 also a point of a lot of friction.
39:37 And by that, I mean, let's suppose I'm going to have a class that I need to create an
39:42 instance of and then put values into.
39:45 And I know once I put the values into it, let's say it has a user ID, I know for certain that
39:50 that's going to be an integer, right?
39:53 So I'd like to say user ID colon int because everywhere I use that object later, if it's a
39:58 function that takes an int and I specify it as optional int, I will get a type check warning
40:03 every single call site when I try to pass that.
40:07 But I know from the semantics of the behavior that it's going to always be an int
40:12 unless it's not initialized, right?
40:14 And like in this short period where I want to create it.
40:17 So I can't set the type to int.
40:19 I have to set the optional int until I've loaded it.
40:21 And, but there's like this, I don't know, that's, that's the part where I see a lot of it
40:25 show up is inconsistencies and then warnings all over the place.
40:29 So I'm like, well, but that function is actually checking if it's none and it'll return null,
40:35 you know, none or something like that.
40:36 So I totally agree with you.
40:38 It's just somewhere I've seen the most inconsistencies across maybe PyCharm versus
40:43 others.
40:44 mypy also has a legacy mode for not checking none things called non-strict optional.
40:50 We're trying to get rid of that from mypy because yeah, strict optional, like being
40:54 strict about it is the more sensible thing to do.
40:56 But it's possible that you've seen that too.
40:59 Yeah, I agree.
40:59 So what you mentioned is maybe sort of a special case of the case where you pass
41:03 something to a class and there's initialization that changes the types.
41:06 Doesn't necessarily have to deal with none.
41:08 It could also just be like the attribute doesn't exist at all beforehand
41:10 or something.
41:11 Yeah, we don't have a good solution for that.
41:13 Maybe there's room for something to support that use case better.
41:17 I don't know what it would look like.
41:18 In some cases, there's ways you can, these things can sometimes nudge you towards a
41:22 different design that is actually safer and will avoid errors.
41:26 Like in the kind of case you're talking about, you know, is it actually necessary
41:30 that an uninitialized object and an initialized one are represented by the
41:34 same type?
41:34 Or is there a way to adjust the API so that those are actually different types than you
41:38 solve the problem and your code is safer or so?
41:41 I'm thinking like you submit a web form and before you parse it, you've got to create the instance
41:46 to set the values.
41:47 And I don't know.
41:48 It's not worth diving into, but I do find this differentiation between like
41:52 the strict enforcement of none versus not none.
41:55 I think it's powerful and I do think you all are right that it does catch a lot of
41:58 errors.
41:58 It's just, it's just a difference and it's just an interesting, interesting
42:02 choice.
42:02 But I didn't get a concrete answer from the official counsel.
42:06 Nullable or noneable?
42:08 What is it?
42:09 I feel like you just don't really even talk about it as a term mostly.
42:12 It's, yeah, none is special in the type system in like how you represent
42:16 it, but it's not really special in other ways.
42:19 You don't have a term for int pipe none?
42:22 Int or none.
42:22 Historically, the term was optional, although I think that term has problems and
42:26 we're sort of moving away from it because specifically one problem is that optional can mean
42:33 you don't have to pass it in, like I say, as a function parameter.
42:37 Let's talk a little bit about TypeShed.
42:40 I think TypeShed is pretty interesting.
42:41 Maybe people don't know too much about it.
42:44 So I'm sure you all are familiar with this project that you can basically add
42:48 type information that the libraries didn't bother to include for you, right?
42:53 What are thoughts on TypeShed?
42:54 How much do you all lean on this to sort of round out missing types?
42:58 There are two parts to TypeShed, right?
43:00 There's the standard library type stubs, which I think are invaluable.
43:06 Like all the type checkers use those.
43:08 And I mean, will the standard library itself ever have inline types?
43:12 Who knows?
43:12 This might be around forever.
43:14 And then there are also the third party stubs.
43:18 And I think that's what you're describing.
43:20 They're libraries that for whatever reason don't ship with stubs themselves.
43:24 Those are in TypeShed.
43:26 And I think it's been like for a while, there's sort of been a question of like what
43:31 we want to do with like TypeShed's third party stubs, right?
43:35 Because like ideally like libraries would ship with their own types, but there
43:39 are various obstacles to that.
43:41 The obstacles that I know of used to be like, we want this to run on Python 2 and Python 3.
43:47 Or we want it to run on Python 3.3 still.
43:50 But it's been a long time since any non-type supporting version of Python was a real,
43:57 you know, a supported type of thing, right?
43:59 I mean, even 3.9 became deprecated.
44:02 So on one hand, I feel like they could be merged in, but there's also a lot of
44:07 other areas that are maybe we don't, they're not common, right?
44:12 Like other libraries, like pick some, let's say Pyramid.
44:16 I don't think the Pyramid web framework really ever got types added to it.
44:20 Somebody could go and create a typeshed stub or a types underscore pyramid you could
44:26 pip install and then we'll add the types, right?
44:28 I certainly see it being really valuable for third party things that are just
44:31 not going to get the type attention they need.
44:33 Yeah, I think typeshed is great.
44:35 I've spent a lot of time on improving it.
44:37 As Rebecca said, especially with a standard library, it's irreplaceable.
44:41 For third party libraries, I think it's become less needed over time.
44:45 It used to be that very few third party libraries had any types.
44:49 Now that's obviously changed.
44:51 A lot of libraries ship their own types, but still there are quite a few types
44:56 of libraries left where there aren't inline types and typeshed can provide
45:00 useful types.
45:01 I think typeshed also provides a service because it has a really great framework for testing
45:05 these types.
45:06 We have tools like step tests and various type checkers that help to make sure these types are
45:12 good and meet a high standard.
45:15 So yeah, I think they're still useful for many libraries.
45:17 Yeah, I was just looking at the types dash flask and I guess it must be, must
45:23 be gone because now type flask must have it internally.
45:26 So it's kind of an interim sort of thing.
45:28 That's pretty cool.
45:29 In general, typeshed has the policy that we remove the snaps from typeshed if
45:32 they are in the library itself.
45:34 I find these super valuable because if there's a library I want to work with and it just doesn't
45:39 have types for whatever reason, you can install stuff from here and all of a sudden your editor's
45:43 way happier.
45:44 I mean, I know we, you all agreed on like the API boundaries and I did as well.
45:50 It's like that's one of the really cool things.
45:51 The other thing that really makes me excited about types is if I hit dot in my editor, I get
45:57 a meaningful list of real information about what I'm working on.
46:00 And so adding, adding these types of things are pretty interesting.
46:04 I want to ask you all about sort of these rogue, rogue tools that do stuff
46:10 with Python typing that maybe y'all didn't intend.
46:12 Like we all mentioned Pydantic, we've got Typer and FastAPI, but even a little farther out
46:19 there is a bear type.
46:21 Are you familiar with bear type?
46:22 Yeah.
46:22 Bear type's interesting.
46:24 You can import, they have fun.
46:27 They have fun with their, their import names and stuff.
46:31 But basically you can put a, either a decorator onto some sort of call site or
46:36 something, or you can just do it to an entire package or entire modules rather.
46:41 So just run bear type dot claw import bear type this.
46:45 And then it actually turns into runtime type checks.
46:49 Good idea, bad idea.
46:51 Interesting.
46:52 What do you all think?
46:53 So un-Pythonic, you won't even open the webpage.
46:56 People should feel free to write whatever code helps them make like better
47:00 software.
47:01 I haven't really used bear type much myself, but it's clearly useful for
47:04 some people.
47:05 And I think generally in designing a type system, we should try to accommodate all users who
47:09 do useful things to the type system.
47:10 And that includes things like Pydentic or bear type.
47:13 It's pretty fast.
47:14 It's not as big of a hit as you would, you would imagine.
47:18 They, let me see, what are they, somewhere they had a really fun, fun saying in here, but here
47:23 we go.
47:24 Bear type brings Rust C++ inspired zero cost abstractions into the lawless world of dynamically
47:29 typed Python by enforcing type safety at the granular level of functions and
47:33 methods against type hints standardized by the Python community.
47:37 order one, non-amortized worst case time with negligible constant factors.
47:41 Like, how about that?
47:43 No, it's a pretty neat library and it's pretty fast.
47:45 I honestly, I've never used it in production.
47:47 Having type hints and squigglies in the editors or in the linters has always
47:53 been enough for me, but I can see using this if it's really critical and you're
47:57 having issues, maybe you want to catch some runtime errors.
48:00 I don't know.
48:00 It's not quite an endorsement, but it sure is like a, huh, that's different.
48:04 I definitely think that the extent to which type checkers may have a different understanding of
48:11 your code from what happens at runtime and there isn't anything built in to catch
48:15 that is sometimes a pain point.
48:18 And so the desire to have your type annotations, to find out at runtime if your
48:22 type annotations are telling you a lie, it makes a lot of sense why people would like
48:26 that.
48:27 I mean, it's something used to from other languages where the type checker is built
48:30 into the compiler.
48:30 Right.
48:31 You get like a runtime type cast, like cannot.
48:33 We kind of get that if you try to parse a thing, you know, like put the int
48:38 param around a string and it's not really a parsable as an int.
48:42 But for like real type information, I think personally I would use this as like I might apply types,
48:48 type checking to a module for debugging and development for a minute and just see
48:53 what happens and then turn it back off.
48:55 You know, I don't know that I'd just ship production code that way.
48:58 But anyway, I got a couple more questions.
49:00 We're getting shorter on time here.
49:02 What was one of the harder questions that you all, harder decisions you all had to address on the
49:09 council?
49:09 I think the most contentious one was PEP 724, if I remember the number correctly.
49:15 It was around a feature called type guards, which is around user-defined type
49:20 narrowing functions.
49:22 Initially, they find that in a way that later was found to be somewhat problematic
49:25 and we basically came up with a better set of proposed semantics that maybe we should have done
49:30 the first time around.
49:33 And what this PEP proposed, and as you can see, I sponsored it, is that we
49:37 basically changed the meaning of the existing type guards under certain conditions.
49:41 What is a type guard?
49:42 A type guard is a function, like there's a good example there, the isiterable.
49:46 It's a function that tells you how to narrow something.
49:50 So in this example, there's an isiterable type guard, which narrows an object to
49:55 an iterable of anything.
49:56 And then inside the func there, you can see if isiterable file, it knows
50:01 that it's an iterable.
50:04 And in this case, yeah, I guess it just narrows exactly to iterable any.
50:08 That's one of the ways that type guards works.
50:10 I see.
50:11 And the type that returns kind of communicates to the type system, like that this
50:15 function ensures that this, the thing that came in as an arbitrary object, in fact,
50:21 is one of these.
50:22 Okay.
50:22 Interesting.
50:23 Yeah.
50:23 So that was a tricky one, huh?
50:25 Any other standout, Rebecca or Carl?
50:27 Well, the current discussion around what is the meaning of a float annotation, still
50:32 unresolved, contentious topic.
50:34 Okay.
50:34 Gotcha.
50:35 I mean, this on PEP724 is also what came to my mind immediately as well, because
50:42 this was challenging discussion because, you know, like there were very conflicting considerations at
50:48 play.
50:49 It's like, what semantics did we want in the long term?
50:52 And what did we want the type system to look like, you know, say like 10 years
50:56 from now versus backwards compatibility and what the migration story would look
51:00 like?
51:01 It was quite tricky.
51:02 I guess that's something you will always have to be cognizant of is like every
51:07 change, even if it's an improvement, has to justify the fact that now you have
51:12 challenges with the version history over time.
51:16 I'm thinking like dict of string comma int with a capital or lowercase d.
51:22 I've got people, I did a YouTube video showing something with the lowercase
51:26 version because I was using something super modern like Python 3.11.
51:30 And I got a message like, hey, Michael, you don't know how to write Python.
51:34 Your code is broken.
51:35 This code that you wrote just doesn't even run.
51:38 I don't know how this is.
51:39 I'm like, what version of Python is in?
51:40 3.8.
51:41 Nope.
51:41 You can't use 3.8 for that.
51:43 You're going to need to get a newer one.
51:44 You know what I mean?
51:44 But like those are complexities that get added to Python because of that.
51:49 Now you've got two ways to specify what a dict is.
51:52 There's a preferred new way, but there's still the old way and it just, it sort of piles
51:57 up.
51:58 And it's very hard to ever actually get rid of the old way, even if there's no good
52:00 reason to use it anymore.
52:01 Exactly.
52:02 Once it's there, it's written in ink pretty much, right?
52:05 Like we have five or six different ways to format strings.
52:08 Maybe with t-strings at six now.
52:10 They're all going to still be there, right?
52:12 So every change, every decision you make is not just a matter of, is it the
52:16 right decision, right?
52:17 It's the, is it worth it?
52:19 I'm sure.
52:20 Yeah.
52:21 I don't know.
52:21 How do you all balance that?
52:22 Like that's tricky.
52:23 With things like the dict chains, at least we sort of know we're moving towards
52:27 better states and there's two things, but they mean exactly the same thing.
52:31 So the confusion is not as bad.
52:34 The problem with type cards is that we're going to change how some existing thing
52:38 works, like what it meant.
52:39 And I think there are good reasons that maybe that's the right thing to do, but the,
52:44 it would also have been pretty confusing for people if their existing types suddenly started
52:47 meaning something completely different.
52:49 Absolutely.
52:50 Hence float.
52:51 Okay.
52:51 What's coming next?
52:53 Like 3.15, 3.16, do you all have things that are in the works that you think are going to come
52:58 or debates that are brewing?
53:01 For 3.15, the, there's a type dict feature coming, extra items.
53:05 you can already use it in tapping extensions if you want to use it, but it will be in
53:10 CPath as of 2.15.
53:12 It's likely we'll have a small thing I added called disjoint basis, which is very technical,
53:17 but helps type narrowing in some cases.
53:19 Yeah.
53:19 I think those are the things that are likely to make it.
53:22 There's, we can only speculate about what else people can propose.
53:25 We're sort of bound by what people actually write up as peps.
53:28 We have to wait for Google to write the peps before we can approve them.
53:30 I think there's PEP 747 for type form, which I think is not, I think we recommended
53:35 its acceptance, but I don't think the steering council accepted it yet or it hasn't
53:39 been accepted formally.
53:40 I think that's on their plate.
53:41 Yeah.
53:42 Yeah.
53:42 So that's also pretty likely to make it into 3.15.
53:45 This is one example of a case that will be pretty useful to people working
53:49 with type annotations at runtime because it'll allow you to, it's sort of a meta
53:53 thing where you can annotate, have a type annotation that describes another type
53:58 annotation.
53:59 So that's useful if you're, if you're writing code that works with type annotations.
54:03 Make the peidantics of the world very happy.
54:05 I am actually pretty excited about type form because, you know, I feel like there's
54:10 a gap and we can express in the type system and we're good.
54:14 And there are cases in the existing type system, like for instance, the cast
54:18 function and some other cases where something takes any type expression as an
54:24 argument.
54:24 We actually don't have a good way to annotate that today and this will provide a nice
54:28 way to express that.
54:28 Let me pull up one thing really quick.
54:31 Quick shout out to Will McGuggan here.
54:32 He just released his Toad project, which is the new, takes textual and rich
54:38 and all that kind of stuff and applies it to like, what if we had a better cloud code
54:42 type of experience, which is pretty interesting.
54:44 So the reason I'm bringing this up is, you know, final question.
54:47 What about, do you all even worry about the role of like how types interact with AI
54:54 and agentic coding tools?
54:56 I know that if you have some code that has types on it and you give it to an AI, it's
55:02 got a better chance of understanding what's happening than if you give it purely
55:05 untyped code and say, tell me about this, right?
55:08 It doesn't even know necessarily what's being passed to it.
55:10 But is that anything you'll think about or what are your thoughts on this?
55:14 Certainly think about it some.
55:15 I mean, I think overall my feeling is that these coding agents seem to do better than
55:21 more kind of the tighter feedback loops you can give them to work with.
55:26 And so typing is another useful source of feedback where you can say, add type
55:29 annotations and make sure the type checker passes and seems so it still seems pretty useful
55:34 in that world.
55:35 Yeah, you can easily write rules that say when you are done on anything I've asked
55:39 you to do, always run ty or always run Pyrefly and make sure that there's no more, no
55:45 new errors or at least or ideally zero errors, right?
55:48 But nothing has been introduced.
55:50 Yeah, pretty interesting.
55:51 You other folks, Rebecca, Yela?
55:53 Yeah, I guess in general, I think typing will remain useful for AI.
55:57 We are probably rapidly moving to a world where a large proportion of all code
56:00 is written by AI.
56:02 Not everybody likes that opinion, Yael.
56:03 Not everybody likes that.
56:04 I guess I, maybe my current line of work makes me think that's more likely to happen.
56:08 You don't have to like the fact it's going to be night soon, but it's going to be
56:11 night.
56:12 You know what I mean?
56:12 Like there's the, I just think there's so much momentum on this, at least in
56:16 the next five years or something, that it's going to be really, it's, it's a
56:19 truth of how many people are writing code regardless of whether individuals want to
56:23 write code that way.
56:24 You know what I mean?
56:25 So I think it's a consideration.
56:26 Yeah.
56:26 Yeah.
56:26 I forgot that you worked at OpenAI.
56:28 So of course, I should pull up a codex example or something, shouldn't I?
56:32 Yeah.
56:33 Codex is great.
56:33 Use it.
56:34 No, but I mean, do you have any further insight into like the role of types
56:38 and coding agents?
56:40 I know that's not exactly what you work on, right?
56:41 You're more at the lower.
56:42 As Carl said, types can also be helpful for AI to understand code better and to
56:47 get a better feedback loop.
56:48 I feel like the very big AI, the board is like humans.
56:51 And if AI makes, sorry, if typing makes humans better at writing understanding
56:55 this code, they're probably also big AI better at it.
56:58 It's the locality of information.
57:00 You can read the function and know everything you need to know about what's going
57:03 into it without bouncing around and trying to understand blocks of code and like what might've been
57:08 created that's getting impacted.
57:09 It's good for humans and also good for AI.
57:12 Right.
57:12 Rebecca.
57:12 Because I don't have much need to, and I'll say I am maybe a little more skeptical
57:18 than most of my coworkers about the quality of AI generated code.
57:23 But that means I think I am particularly gung-ho about, you know, like get AI to use
57:29 types, type checkers, keep the guardrails there.
57:33 I think that'll be very important.
57:34 Yeah, if it's going to make a mistake, don't let it at least like make the type
57:38 system become disconnected and not working.
57:40 Like it has to keep the types hanging together as a minimum bar, right?
57:44 And you can easily set that up as an automation.
57:46 Yeah.
57:47 Interesting to think of it as guardrails rather than an accelerant.
57:50 But yeah, 100% it is.
57:52 All right, folks.
57:52 I think that's it for all the time that we have.
57:55 Thank you.
57:56 Thank you for being here.
57:57 Final thoughts before we go.
57:59 Carl, I'll let you go first.
58:00 Final thoughts for people out there interested in Python typing.
58:02 Yeah.
58:02 Well, first of all, thanks for having us on the podcast.
58:05 Really appreciate it.
58:06 And thoughts for people out there.
58:08 I guess if you have ideas of how Python typing could be improved, discuss.python.
58:14 Python.org is a good place to bring up ideas and discuss them with the typing community and see
58:19 what positive changes we can make.
58:22 Rebecca.
58:22 First, thank you, Michael.
58:24 This is a lot of fun.
58:26 Last thoughts?
58:28 Hey, so, you know, like we'll look at the typing council and sometimes think,
58:32 oh, you know, like the PEP has like governance in its name, but I wouldn't say we're really
58:37 a governing body or anything.
58:39 It's like people who are using the type system, like users, they're the ones who come up with,
58:45 you know, like all the best ideas, propose them, discuss them.
58:48 And we're just here to sort of be like, hey, you know, like we have some background and like
58:55 how type checkers work and maybe some of the history and we can provide input.
58:58 But I just encourage people, if there's a change you want to see in the type system, you know,
59:03 like propose it yourself.
59:05 It's very friendly and open community.
59:07 Yeah.
59:08 Now people who have listened know a little bit more about how to do so.
59:11 Awesome.
59:12 Thanks.
59:12 Jale, final word.
59:13 Yeah.
59:13 Also, again, thank you for having me here.
59:16 It's been great talking to all of you.
59:17 I guess what I want to say is similar to what Karin Rebecca just said.
59:20 If you want to have something changed to the type system, I'd really encourage you to sign up
59:24 for discuss.python.org, make a proposal, go through the process.
59:27 It can be somewhat daunting, perhaps, especially if you have to create a PEP, but it is
59:32 doable.
59:32 There are several recent typing PEPs have just been community members who saw something they
59:37 wanted to improve, proposed a PEP, and saw it to completion.
59:41 If there's something you want to see in the type system, then you can do
59:44 it too.
59:44 Thank you all for keeping Python typing going strong.
59:48 Really appreciate your time on the show.
59:49 See you all later.
59:50 Bye.
59:51 Bye.
59:51 This has been another episode of Talk Python To Me.
59:55 Thank you to our sponsors.
59:56 Be sure to check out what they're offering.
59:57 It really helps support the show.
59:59 Take some stress out of your life.
01:00:01 Get notified immediately about errors and performance issues in your web or mobile
01:00:06 applications with Sentry.
01:00:07 Just visit talkpython.fm slash Sentry and get started for free.
01:00:12 Be sure to use our code talkpython26.
01:00:15 That's talkpython, the numbers two, six, all one word.
01:00:19 And it's brought to you by our Agentic AI programming for Python course.
01:00:24 Learn to work with AI that actually understands your code base and build real
01:00:28 features.
01:00:29 Visit talkpython.fm slash agentic dash AI.
01:00:33 If you or your team needs to learn Python, we have over 270 hours of beginner
01:00:38 and advanced courses on topics ranging from complete beginners to async code, Flask, Django,
01:00:44 HTMX, and even LLMs.
01:00:46 Best of all, there's no subscription in sight.
01:00:48 Browse the catalog at talkpython.fm.
01:00:51 And if you're not already subscribed to the show on your favorite podcast
01:00:54 player, what are you waiting for?
01:00:56 Just search for Python in your podcast player.
01:00:58 We should be right at the top.
01:00:59 If you enjoy that geeky rap song, you can download the full track.
01:01:03 The link is actually in your podcast blur show notes.
01:01:05 This is your host, Michael Kennedy.
01:01:07 Thank you so much for listening.
01:01:08 I really appreciate it.
01:01:09 I'll see you next time.
01:01:18 Voyager.
01:01:19 Voyager.
01:01:21 And we ready to roll Upgrading the code No fear of getting whole We tapped into that modern vibe
01:01:33 Overcame each storm Talk Python To Me IceSync is the norm


