Python 3.14: t-Strings, Multiple Interpreters, Deferred Annotations
Key Takeaways
The video covers new features and changes in Python 3.14, including t-Strings, Multiple Interpreters, and Deferred Annotations. It provides an overview of the most important updates in the latest version of Python.
Full Transcript
Python 3.14 was officially released on October 7th. And in this video today, we're going to cover the most important and most interesting new features and changes that have been made to the language. Some of these are things you can start using right away in your code, while others are more behindthe-scenes changes to how Python works in general. Now, if you like this video, make sure to hit the like button and subscribe. But now, let us get right into it. [Music] All right. Now, when you go to python.org and you hover over the downloads tab, you can see that Python 3.14.0 is the official version. So, for this video, if you want to try stuff while we're discussing it, you can either install this version here from the website. What I'm going to do to be able to work with Python 3.14 is I'm going to go to my working directory. And here I'm going to say now UVIT-Python 3.14. So, I'm going to use the UV package manager to do that. There's many ways to do that. You can use Pyen. You can compile Python yourself. You can download it from the website. There's many ways to get Python running on your system. This is the one that I'm going to choose. Uh, so I'm going to run this. It's initialized. I'm also going to go to the PI project toml here and say that I want to accept versions above or equal to 3.13. The reason for that being that I want to be able to switch back and forth to show you that certain things did not work in 3.13, but they now do work in 3.14. So I can switch back and forth easily by saying UV Python and then pin 3.13 for example, this is now using 3.13. If I go back to 3.14, I'm using 3.14. By doing this, we can try the different configurations and see what didn't work before and now does work. Now, one more thing. If there's anything about Python 3.14 that I don't cover in this video here that you're interested in. You can go to the official documentation, you will find a link to it in the description down below. And on this page, you can find every single addition, everything that was removed, optimized, changed in this particular update. Every little detail, every tiny change and tiny optimization that was made. So, if you're interested in that, I recommend going to this page. So, let us get started with the first major addition to Python 3.14, which is template strings. This is an actual new feature to the language. It didn't exist in the previous version. And the first time you see a template string, you might think it's an fstring because the syntax is essentially the same. We have a string with a placeholder in it and before that we have a letter, either F for the F string or T for the template. However, they have different use cases and they also return different objects, different types of objects. If I run the script here, you can see that the template string actually returns a template that contains strings and interpolations. So the interpolation here is mike for the placeholder name and the strings are just the raw text that we have in the template whereas the fing returns just a string. So the fstring is a string and the template returns an actual template object because also the use case is a different one. the template. The main use case of the template is to sanitize input and to build advanced logic for parsing and sanitizing input. Take a look at this code snippet for example. What we have here is still the interpolation name Mike. But what we can do now since this is not just a string but a template is we can iterate over the elements of the template and not just over the characters of a string. So we have elements as we saw we have strings and we have interpolations. And what we can do here for example is we can say go through all the elements if the element is an interpolation append the value of that interpolation in title case so we want to basically transform Mike into Mike with a capital M and we can do that programmatically by just iterating over the elements of the template and if it's an interpolation I can just say I want all the interpolations to be title case because for example all the interpolations are going to be names and if I now run this you can see I get Hello Mike, how are you? So this is a very convenient tool when it comes to parsing input, implementing custom logic for parsing or for sanitizing input. And it has the familiar fstring syntax. And the cool thing is you don't even have to return a string at all. You can also return something completely different. For example, in the documentation, it says you can also return a complex DOM tree object based on some HTML stuff that you feed into this in the form of a template. So in terms of new features, this is probably one of the major major additions of 3.14. Next up, we have the deferred evaluation of annotations as well as the addition of annotation lip to core Python. So basically this is a change that affects usability as well as performance. The idea is that when I make annotations like typins for example, these are no longer eagerly evaluated, which means they're not evaluated at definition time. They are lazily evaluated whenever needed. So we don't have the performance cost on import but on the first use and it also allows us to do stuff differently. So this is how we had to do type hinting up until recently up until Python 3.14 if we wanted to use a type that was not yet defined. For example, I have the class note down here and I have some function that has the type note for the parameter and for the return value. If I wanted to do this up until now, I had to provide a string with the name of the type. um if the type was not already defined and if I try to do something like this, if I try to specify the type before specifying uh or using the type before specifying the class or the type itself, what happened is I got an exception. This is no longer the case in Python 3.14. It works now without problems because this is lazily evaluated. I don't evaluate the type hand before I need it. So I can just define it and later on this forward reference will be evaluated when needed. So to briefly show you that this does not work in Python 3.13. I can quickly switch the version and then do UV run main.py and what you see is I get a name error. Name node is not defined because we're using something that we don't have yet. But if I switch back to 3.14 and run the same thing, it works without any problems. As I mentioned, there's also this new library called annotation lip. What we can do here is use the get annotations function and specify a format. The default format is value or values. I'm not sure what it's called. And when I run these here, we have value, we have string, and we have forward reference. We can see that the value is actually evaluating everything. So, it's actually trying to get the proper types. So, here we see class note. Uh for the string, we just get the text. And here we get the same thing as for value. But this is only because these have already been um evaluated. If I go and try to do the value annotation or get annotations with a value format in between here, this is going to lead to an exception because what happens here again is I'm forcing the evaluation by calling get annotations but it's not defined. So I run into this problem. However, if I do the same thing with a forward reference here instead, if I don't do that, then you can see that I have a forward reference to something called node. We don't know what that is going to be yet, but it is there and I can evaluate it. I can get it already. Now, next we have something that is super interesting. This is a new user-friendly concurrency model in Python. You can use multiple interpreters within the same process. So, you can basically do something like multipprocessing, but in the same process, you could say you get multi-threading with the benefits of multipprocessing to some degree. Now this is actually something that was possible already by using the C API but now it's also possible in pure Python. What we can do is we can say from concurrent import interpreters then we can create a new interpreter and we can execute something using this interpreter. So I can say get this interpreter that I just created execute something like for example printing hello world or I can also call a function using that interpreter. So when I run this you can see I get hello from sub interpreter and I get the square of 12. Now the cool thing about this is that this allows for true multi-core parallelism in python with the isolation of processes and the efficiency of threats. So this here is an actual use case. We have an interpreter pool executor. This is something new. It's from concurrent futures. We can import interpreterpool executor and it basically works in the exact same way as the threadpull executor. So what we do is we just submit a task in this case here math.factorial for a bunch of numbers between 20,000 and 22,000 or all the numbers in that range and we just do that using four different interpreters. So it's the same as four different threads but it's interpreters. So we can actually use multiple CPU cores. So when I run this you can see that this will take about 3 seconds and then I'm going to get my result. There you go. 3.34 seconds. Now we can actually compare this to running the exact same thing with a threadpull executor. So I have the same code as before. Here I have the exact same code down here again just running a threadpool executor this time. And down below I have the same thing just running it with a single interpreter single thread everything normal. And if I run this you can see that the interpreter pool executor gets this done in 3.4 seconds. The thread pool executor takes 14.4 4 seconds which is even slower than just using a single thread and a single interpreter which takes 12 seconds. So you can see that with multiple interpreters we have true multi-core parallelism in Python. Now this feature this concurrency model is not yet optimized. It's not mature. It's not supported by all thirdparty packages. It's something new, something unfamiliar, but it's starting to become mainstream and I think it's an interesting direction that Python goes into. The next important update is that freethreaded Python. So without a gill, without a global imperial lock is now an officially supported build. This is what they call phase 2. It's now officially supported but still optional. So using UV I can now just say UV Python pin 3.14T. This is going to now use the freethreaded version of Python. And interestingly, if I now run the exact same example as before, this main py file with the interpreter pool executor, the thread pool executor, and the ordinary single thread single interpreter version, I can say UV run main py and we're going to see a difference in the time. As you can see, now the multi-threaded version is even faster than the interpreter multi-interpreter version because now we have proper multi-threading. We don't have the global interpreter lock. We don't just have a single threat per interpreter that can actually do CPU inensive stuff. So this is now also true multi-core parallelism with threats instead of multiple interpreters. Now while this is interesting and promising, this is not yet something that can be reliably used because the ecosystem doesn't support it. Many packages are not working with this freethreaded version and require a specific package for that build of Python. But it's interesting to watch Python develop in this direction as well. Now, another quite useful addition to Python 3.14 is a CLI tool for async IO. So, a tool that allows us to inspect Python processes and view their asynchronous tasks. So, we have a quite simple setup here. I have a function one, a function two, both asynchronous. One waits for 15 seconds and prints a message. The other one waits for 20 seconds and prints a message. And the process also prints the process ID. So, I know what to target. And now what I can do is I can say uvrun main.py. But before I do that, I open up a second terminal. I navigate to the same directory and I prepare a command like this. In this case, I have to use pseudo privileges on Linux because otherwise I don't have the access to the process. But basically, I'm just using python-m and async io. So that's the command. This is just me using pseudo privileges with the python version of that virtual environment. The command is here. Python-m async ioops followed by the process ID. So I can run this now. Here it prints the process ID. I can type it in. I have some time. And now after entering my password, I can see the tasks that are running here and what they're doing. So, it's sleeping. After a while, it's no longer going to be sleeping. It's going to print a message. Then I can run the command again. I can see only one of the tasks is sleeping now. The other one is no longer sleeping. And I can inspect a process like this and view the asynchronous tasks. Now, there's also a second command that I can use. I can use first of all a different um ID here and I can also use the command ps tree which is doing the same thing but in a tree view. So depending on what you prefer this is a quite useful tool that you can use to inspect asynchronous tasks in your processes. Now another small change is that now all the compression algorithms are combined into a Python module called compression. So now we can say from compression import zip bz2 LZMA gzip and now we also have a new addition which is zstandard. So we can use zstd.commpress to compress with zstandard and we still can use all the old packages. We can still do bz2 that is not going to change. So I can still run all of this without any problems but it's nice to have all of these algorithms now in the same module. Another small change is that we can now use multiple exceptions in an accept branch without using parenthesis. So I can now say except value error and zero division error without using parenthesis. If I run this here with UV, you can see it works. I get the error. So it works but I got the error because of my exception. If I say UV python pin 3.13 and try the same thing again, it will tell me that multiple exception types must be parenthesized. So that is basically what I wanted to cover when it comes to Python 3.14. There are some notable mentions here that I would like to include just as a mention and then you can look them up yourself if you want to. There are as always better error messages, more specific error messages. There's also now a syntax warning in finally blocks if the statements affect the control flow. And then you have some stuff like speed up due to a new type of interpreter. You have incremental garbage collection which is also faster. And we have a safe external debugger interface. But as I said, if you're interested in more details and all the tiny little things that have been changed here in Python 3.14, I would like to refer you to the documentation. I wanted to cover the most important and major additions changes when it comes to this new version. So that's it for today's video. I hope you enjoyed it and hope you learned something. If so, let me know by hitting a like button and leaving a comment in the comment section down below. Also, if you are interested in one-on-one tutoring by me, or if you're interested in any of my services, like freelancing, consulting, or anything like that, you can go to my website, neuronline.com, to the services tab, or to the tutoring tab. There you can find what I have to offer. You can just contact me via mail or LinkedIn. And besides that, don't forget to subscribe to this channel and hit the notification bell to not miss a single future video for free. Other than that, thank you much for watching. See you in the next video and bye.
Original Description
Today we take a look at the most important new features and changes of Python 3.14.
Full List: https://docs.python.org/3/whatsnew/3.14.html
◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾◾
📚 Programming Books & Merch 📚
🐍 The Python Bible Book: https://www.neuralnine.com/books/
💻 The Algorithm Bible Book: https://www.neuralnine.com/books/
👕 Programming Merch: https://www.neuralnine.com/shop
💼 Services 💼
💻 Freelancing & Tutoring: https://www.neuralnine.com/services
🖥️ Setup & Gear 🖥️: https://neuralnine.com/extras/
🌐 Social Media & Contact 🌐
📱 Website: https://www.neuralnine.com/
📷 Instagram: https://www.instagram.com/neuralnine
🐦 Twitter: https://twitter.com/neuralnine
🤵 LinkedIn: https://www.linkedin.com/company/neuralnine/
📁 GitHub: https://github.com/NeuralNine
🎙 Discord: https://discord.gg/JU4xr8U3dm
Timestamps:
(0:00) Intro
(0:30) Setup New Version
(2:05) Template Strings (t-Strings)
(4:25) Deferred Annotations & annotationlib
(7:09) Multiple Interpreters & InterpreterPoolExecutor
(9:42) Free-Threaded Python
(10:58) AsyncIO CLI Tool
(12:38) Compression Module
(13:10) Multiple Exceptions
(13:36) Notable Mentions
(14:21) Outro & Info
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from NeuralNine · NeuralNine · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Visualizing Stock Data With Candlestick Charts in Python
NeuralNine
Python Beginner Tutorial #1 - Installation and First Program
NeuralNine
Python Beginner Tutorial #2 - Variables and Data Types
NeuralNine
Python Beginner Tutorial #3 - Operators and User Input
NeuralNine
Python Beginner Tutorial #4 - If Statements and Conditions
NeuralNine
Python Beginner Tutorial #5 - Loops
NeuralNine
Python Beginner Tutorial #6 - Sequences and Collections
NeuralNine
Python Beginner Tutorial #7 - Functions
NeuralNine
Python Beginner Tutorial #8 - Exception Handling
NeuralNine
Python Beginner Tutorial #9 - File Operations
NeuralNine
Python Beginner Tutorial #10 - String Functions
NeuralNine
Python Intermediate Tutorial #1 - Classes and Objects
NeuralNine
Python Intermediate Tutorial #2 - Inheritance
NeuralNine
Python Intermediate Tutorial #3 - Multithreading
NeuralNine
Python Intermediate Tutorial #4 - Synchronizing Threads
NeuralNine
Python Intermediate Tutorial #5 - Events and Daemon Threads
NeuralNine
Python Intermediate Tutorial #6 - Queues
NeuralNine
Python Intermediate Tutorial #7 - Sockets and Network Programming
NeuralNine
Python Intermediate Tutorial #8 - Database Programming
NeuralNine
Python Intermediate Tutorial #9 - Recursion
NeuralNine
Python Intermediate Tutorial #10 - XML Processing
NeuralNine
Python Intermediate Tutorial #11 - Logging
NeuralNine
Python Data Science Tutorial #1 - Anaconda and PyCharm Setup
NeuralNine
Python Data Science Tutorial #2 - NumPy Arrays
NeuralNine
Python Data Science Tutorial #3 - Numpy Functions
NeuralNine
Python Data Science Tutorial #4 - Plotting Functions With Matplotlib
NeuralNine
Python Data Science Tutorial #5 - Subplots and Multiple Windows
NeuralNine
Python Data Science Tutorial #6 - Matplotlib Styling
NeuralNine
Python Data Science Tutorial #7 - Bar Charts with Matplotlib
NeuralNine
Python Data Science Tutorial #8 - Pie Charts with Matplotlib
NeuralNine
Python Data Science Tutorial #9 - Plotting Histograms with Matplotlib
NeuralNine
Python Data Science Tutorial #10 - Scatter Plots with Matplotlib
NeuralNine
Python Data Science Tutorial #11 - 3D Plotting with Matplotlib
NeuralNine
Python Data Science Tutorial #12 - Pandas Series
NeuralNine
Python Data Science Tutorial #13 - Pandas Data Frames
NeuralNine
Python Data Science Tutorial #14 - Pandas Statistics
NeuralNine
Python Data Science Tutorial #15 - Pandas Sorting and Functions
NeuralNine
Python Data Science Tutorial #16 - Pandas Merging Data Frames
NeuralNine
Python Data Science Tutorial #17 - Pandas Queries
NeuralNine
Python Machine Learning Tutorial #1 - What is Machine Learning?
NeuralNine
Python Machine Learning Tutorial #2 - Linear Regression
NeuralNine
Python Machine Learning Tutorial #3 - K-Nearest Neighbors Classification
NeuralNine
Python Machine Learning #4 - Support Vector Machines
NeuralNine
Python Machine Learning Tutorial #5 - Decision Trees and Random Forest Classification
NeuralNine
Python Machine Learning Tutorial #6 - K-Means Clustering
NeuralNine
Python Machine Learning Tutorial #7 - Neural Networks
NeuralNine
Python Machine Learning Tutorial #8 - Handwritten Digit Recognition with Tensorflow
NeuralNine
Generating Poetic Texts with Recurrent Neural Networks in Python
NeuralNine
Stock Portfolio Visualization with Matplotlib in Python
NeuralNine
Analyzing Coronavirus with Python (COVID-19)
NeuralNine
Making Text Images Readable Again with Python and OpenCV
NeuralNine
Neural Networks Simply Explained (Theory)
NeuralNine
Motion Filtering with OpenCV in Python
NeuralNine
Top 5 Programming Languages To Learn in 2020
NeuralNine
Simple TCP Chat Room in Python
NeuralNine
Image Classification with Neural Networks in Python
NeuralNine
Edge Detection with OpenCV in Python
NeuralNine
S&P 500 Web Scraping with Python
NeuralNine
Simple Sentiment Text Analysis in Python
NeuralNine
Introduction - Algorithms & Data Structures #1
NeuralNine
More on: AI Pair Programming
View skill →Related AI Lessons
⚡
⚡
⚡
⚡
Reading Anthropic's "When AI Builds Itself" Changed How I Think About AI and Software Engineering
Dev.to · Hemapriya Kanagala
When AI Writes Most of My Code: What Happens to My Identity as a Software Engineer?
Medium · AI
When AI Writes Most of My Code: What Happens to My Identity as a Software Engineer?
Medium · Programming
How AI Is Changing Software Development (2023–2026)
Medium · Machine Learning
🎓
Tutor Explanation
DeepCamp AI