Back to Index

Every New Feature in Python 3.10.0a2


Chapters

0:0 Intro
2:25 type union operator
4:59 type alias annotation
9:52 equal length flag
11:45 bit count
12:36 mapping for dictionary views

Transcript

Hi, we're going to go through the second alpha version of Python 3.10 today. So it was released at the beginning of November. And with it, we can already see quite a few new features. So we're just going to go through those. And it seems honestly pretty interesting. So I think the first thing we're going to go through the further extensions to the type annotations.

So on that front, there are three main new features, the postponed evaluation of annotations, the type union operator, and the type alias annotation. So for those of you that are not aware, we have the timeline of the type annotations with each new Python release here. So in version three, we had the initial implementation of function annotations.

And then on and on since then, there's more has been added, there are a few different ways to do different things up until version 3.9, where everything was aligned. And they added the typing module syntax to the standard collections. So this extension of the typing annotations has been continued with version 3.10.

The first one is the postponed evaluation of annotations. And this is the point that Python will actually evaluate the type annotation in our code. So typically, this would be done at function definition time, meaning that they're evaluated line by line in a top down fashion. And obviously, that kind of makes sense.

But at the same time, this can cause issues because if we, for example, define a type at the top or refer to a type near the top of our code that actually doesn't get defined until later on, I mean, even though it still makes sense, it's just a forward reference that will cause problems.

So what they've done is postpone the evaluation until later on. So this also speeds up the module imports very slightly, and also prevents this issue of forward referencing not working. So I mean, that's pretty much it for the postponed evaluation of annotations. It's pretty straightforward. The next type union operator.

So let me show you what we had to do before. So let's go back to Python 3.9 here. So say, for example, we have a function and we can take either an integer or a float into that function. Now, before what we would have to do, or at least in 3.9, we would have to use the union like this.

And then we'd pass a list of our two types. So int float like that. I'm just going to output a float. And you'll see why in a minute. So here, we're just going to return x times by 3.142. Okay, so obviously with this, it would make sense if x is either an integer or a float, but nothing else.

So the way that we would do that before is using this union operator. And with that union operator, we would have to import that from typing. So like this. Okay, let me just save this. Okay. So now let's run it and see what happens. Okay, sorry, I need to actually do something here.

And so we can pass 4, which is an integer. And then we'll just pass this as well. So this makes sense. Okay, that's fine. It works as we would expect. So what Python 3.10 has added here. Go back to this. So we don't need to import this anymore. And instead of using this union operator, we have this really nice new syntax, slightly bitwise, or operator.

And we just use that, so int or float. And this will work in just the same way. All right, and that didn't work before. Before, we would get a syntax error. So if we run this in 3.9. Okay, unsupported type error. So that's the other new addition to typings.

And then the final one is the type alias annotation. Okay, so the current issue with the type aliases is that if we are forward referencing another type that hasn't been defined yet, we would use a string. So for example, if we are importing this type from another module, but the module hasn't been imported yet, we might want to still reference that type.

And we would do that just using a string like this. And this is fine, but obviously, it's just not very explicit as to what we're doing here. So could write something like this with type alias as a type. And we also want to return type alias. Okay, and we return name there.

So if we run that, it's fine. Okay, and we can call it and we'd say, that's the name, hello. Works fine. But the issue is here that it's not clear that this is, obviously, we've written type alias here, but if you get another name, it's not very clear that this is actually a type alias.

So what has been included now is switch over to Python 3.10. Okay, just rerun this. Okay, so works. And so what we now have in Python 3.10 is a type alias type. So if we do from type extensions, import type alias. Okay, and now we make it explicit that this is, in fact, a type alias and not a string.

Okay, and then we can run this again. Okay, that works. But now it's just more explicit that, yes, this is not string. This is, in fact, a type alias. So that's another addition. And that's everything that has been added in terms of the type annotations. And obviously, I mean, this is not like a huge, a massive change, but it's, I think it's very cool regarding the past changes in type annotations.

See that the developers are doubling down on enhancing these features. Obviously, a big strength of Python comes from its ease of use and the lack of a steep learning curve. And one of the reasons for this is the lack of need to actually explicitly define types in our code.

Unlike, for example, C, where you are explicitly defining what every variable is and the type that it is. Python, we don't need to do that. And that makes it a lot easier to get started, which is great, and that's really good. But it's also a little bit difficult when it comes to actually reading more complex code bases.

If you go into a popular open source library and read through the code, figuring out what is going into a function and what's coming out of it is really difficult. But when we start to add things like this, it makes it incredibly easy. So, for example, instead of this, or actually, maybe this is a better example.

Like here, we know that x has got to be either an integer or a float. And we know that it's going to return a float. If we got rid of these, obviously, with this function, it's really obvious. But when you have something like some big machine learning library, like TensorFlow or PyTorch, and reading through that, it's pretty confusing.

And without these types, it can get very, very difficult. But now, if you look at, for example, parts of the Transformers library, which is another machine learning library, they've started adding in types, and it makes it so much easier to read. So, for that reason, I think that these little differences or these little additions are very cool and really, really good to see.

So, on the other features that have been added, we have a few, there's a new equal length flag for the sip function. So, if we have two lists here, okay, and then we have another one, okay. Normally, if we create a zip generator with both of these, we'll see that there are no issues here.

And, I mean, it's kind of weird because neither, these are not the same length. So, this doesn't cause any issues, which, I mean, maybe that's fine. But to me, at least, that's pretty weird. What it does is actually just truncates the longer string, sorry, the longer list. And I imagine a lot of developers have had a headache trying to figure out what has gone wrong because of this kind of strange feature.

So, what they have added in Python 3.10 is a strict flag. So, rather than just allowing this to happen, we can run it with a strict flag set to true. Okay, so now we actually get a value error saying the argument two is shorter than argument one, which is a nice, I mean, it's nothing crazy, but it's a nice addition.

So, I mean, rather than blindly truncating mismatched data, we actually can check now with a built-in argument, which is pretty nice, I think. And I think it will save people a lot of time trying to figure out what has gone wrong with their code. So, it's pretty useful. The next one is the new bit count.

So, here, we're actually counting the number of active bits in that integer's binary value or binary representation. So, for one, so, zero, obviously, it's just going to be this. For one, the binary representation is this. For two, this. So, we can see, right, for the first one, there's zero ones in there.

For number one, there's one one. Number two, there's two ones. So, number three, we would expect that to be two ones, and we're sure it is. Okay, so, the final of the other features are the mapping for dictionary views. So, in Python, we have three different dictionary views that we can use.

And that is a view for keys, values, and the dictionary itself or the dictionary items. So, if we create a dictionary here, very simple one. Yeah, let's just run this script. Let me show you down here. So, we have d.keys, and that returns us the keys in our dictionary.

And then, we also have the values. Okay, and that returns a view with the values of our dictionary. And then, we also have items, which just returns everything inside our dictionary. So, what we have now, if we create a keys object here, which is our view of the keys in the dictionary, and let's have a look at the underlying attributes and methods that we have here.

So, with this new update with 3.10, we have a new attribute called the mapping attribute. And you can see it's near the bottom here. So, it returns the dictionary that this view refers to. So, if we do keys.mapping, it returns us this mapping proxy object, which wraps around our original dictionary.

So, yeah, that's the new mapping attribute that we have for our views now. And with that, that is everything that is new, the current alpha version of 3.10. I hope this has been a useful video, and thank you for watching.