Python 3.10: Welcome to pattern matching!

Python 3.10 is the newest version of the language with a two-digit minor version change since the last release, and with this release, a new way of thinking about programming was brought to the Python language - Pattern Matching.

After briefly checking how the situation was before 3.10, we will dig into how to use Pattern Matching in different scenarios. We will show examples of how to define matches on simple and more complex data types, such as dictionaries and objects. We will also understand how to use guards, and how to build composable patterns.

By the end of this talk, you will be surprised how simple, yet powerful, Pattern Matching really is. This talk and you, it is a match!

This session took place in track Python Language and was classified suitable for some domain / some python by the speaker.

Transcript (auto)

Auto-generated from the recording utilizing Open-Source AI. Speaker labels (Speaker 1, Speaker 2) reflect diarization, not identity. Timestamps refer to the recording.

Speaker 1 [00:04]

Thank you, everyone, I think. Can you hear me? I always give this talk online, so I always ask if you can hear me. So today I'm going to be talking about Python 3.10. Welcome to Python Matching. My name is Laís Ochoa. A little bit about me. I really like Python, and I happen to live in the city of Munich, so this has taken me to organize PyLadies Munich chapter. I also really like open source, and my company, they work with open source and databases, so they manage infrastructure. The name is Ivan. We actually have a booth here. I will be there, maybe, and you can say hi. You can also find me on Twitter if you want to follow me, or yes, whatever. So a little bit about how this talk is structured. I will talk about Python 3.10. In general, I will talk about pattern matching. Every time there is a heart, maybe I'm comparing two codes, and you know the one with heart has pattern matching. And I'll give my final votes. So, what happened in Python 3.10? Actually, in the release of Python 3.10, there was a party. Pablo Galindo is the release manager for Python 3.10, and there was a release party. And it was quite interesting. A lot of the Python core developers were invited to this online party, and also the community was invited to get feedback about the features. And, yeah, I just found it very cool. I don't think there was a release party for other releases, anyway. I found it really nice. One thing that happened with Python 3.10, so when this kind of releases are done, I was going to say that this for the party was kind of interesting because you could see how software such as a Python release, such important release, are done in real life, like in the tech area. So there There is the Python RC, the developer version, the beta, and alpha, and so on. So before it's released to production, you can already test and make sure that your open source code supports the Python 3.10, even before the production one is released. So that's quite interesting. And at the same time, a lot of people, they do wait until other maintainers provide support and so on. But if everybody waits, then nobody updates. So, here we could see that in this Twitter, the person was just commenting that, yeah, it's still less than 10% of all the important packages from PyPy, they still do not support Python 3.10. So, this is actually something that if you are willing to contribute to open source, this is something that you can do it in some projects, you can offer support in different versions of Python. One thing that why people don't do that is because there are breaking chains. So if you are running your latest version of Python, it would be run the Python 3.9.7. And then you're going to jump for Python 3.10, which is actually two-digit minor version. And you have no idea how many things can break it in between. So I tried to update it, one of the packages, and actually I saw a lot of issues, compatibility, and so on. So I see that it's not so smooth sometimes. what I want to tell you today, is that really worth it? Python 3.10 has something called like better error messages. And here is just a comment how this kind of little improvement actually means a lot. And a lot of people are looking forward, for example, here you see we have a production. So, action now. So, we are talking about meaningful messages. One thing that people really like, they really like that are error messages. And this kind of meaningful messages, I already saw in other languages that kind of you make a mistake And you kind of get very specific tips how to fix it. And this was something that it was missing in Python for a long time. Part of this is because this parsing was not automated, so it was I was listening yesterday, the kind of the code they had to maintain was like 8,000 lines of no automated code to make the messages. So that's why they tried to automate it, and they were very successful, and now you can have this kind of message that actually guides you where you need to fix your code, and it's quite important, especially for beginners, because when you're starting in a language, the first thing you find is errors. And if you start to get just errors, errors, and you have always this frustration, maybe you will not feel so good about the language. But that's something that actually for beginners in Python, I think it will open up and more people start using and sticking to Python. What is that new? I told you there is this better error messages, and I heard that Python 3.11 will be even better error messages. I'm curious to know what is about it. If you're also curious, there are some podcasts with Pablo Galin. He's explaining how does that work, how does this work, and also interesting to know, if you are a release manager of a Python release, you actually are a release manager for the next five years, because you have all the security bugs that you have to fix and you have to be responsible. So, it's not just a party and it's over. Actually, you have to continue. And all this talk, I took this information from the Python official documentation, especially the PEP 636, which covered the structure pattern matching tutorial, And you can find it online. I really recommend it. I know it's a lot of documentation, but actually it's good that it covers everything, and you can learn a lot from it. So, what is it new in Python 3.10? We had pattern matching, otherwise I wouldn't be talking here. We had context manager, and we had data error message and type on new operator. Those are just some of the things. I will not be covering everything. Of course, I will just cover pattern matching, But it was asked out which features do you like, which features are you more excited about. I want to ask you today which feature would you be more excited about. So about pattern matching. Are you excited about pattern matching? If you're not, I would ask you to leave. Context manager. I don't know. Are there some context manager fans here? There is one person. Maybe three. Okay. It's getting more and more allies now. Better error message, I think is also something good. I think nobody wants to be looking so much in the code if it already can give you. And type on your operator. Yay! There's some typing people here. So, yeah, we're not going to cover better error messages. I'm sure that would give a great talk, but we're going to talk about the structure of pattern matching. Pattern matching is something that it was already in some languages, if you are coming from Scala or C and so on, you already saw some things like pattern matching there. And there are things that it's used to there, and Python, it's kind of nice that it was developed after, because we have all those languages with nice ways to do pattern matching that we get inspiration from. So, pattern matching in programming, you would think more about either it will or it will not be a match. It's different from dating applications, because you could have a lot of matches there, and actually you end up without any match. And it's also different from pattern recognition, because in pattern recognition, when you have an image that you're trying to recognise and do some labelling on that, you would have some sort of threshold. For example, if 9% of this image match to a cat, it will be a cat, so to say. So, it's a bit different. In pattern matching, we're really going to stick in the sense that it will or it will not be a match. And we already had some sort of pattern matching in Python, some primitive pattern matching. So, for example, here, x, y equals to 1, 2. So, Python is smart enough to associate the number X to the 1 to do the assignment, and the number Y to 2. So, that's kind of cool. If you like try and accept, you may also find that here that is some sort of primitive pattern matching as well. You can actually have try, and you can have different accepts, and only one your objective is to match one of the exceptions and to run some code inside. So there's some sort of primitive things that were already there. Okay. So now we're going to come back about actually what's pattern matching in Python. So I was doing a lot of interviews some years ago, and I was also interviewing people from my company, and for some reason there was always the question if you play video game. For some reason people wanted to have a co-worker and also someone to play video game after the job. I wonder if someone here plays video games. At the time of this talk, I didn't play video games, but I started to play, but I don't know, actually, yeah, why did you play video games in your free time? You really like screens. So we're going to be using a game to try to understand because I know a lot of people play video games, but if you didn't play video games, it's also okay. I think you're going to try to follow here. Don't worry, if I don't say this word correct, if there is German speakers, maybe they will correct me after. And I think that is one of the challenges of today's talk, is to say the word . . Good. So, this kind of a game, you have an object and you try to match in these holes, and only the ones who have exactly the form will be entered and will also be matched. So, that is why I took this game because I think it's a perfect, perfect, perfect example of pattern matching. So, I'm going to be using this as an example. Here is just a code how to get started with pattern matching for beginners. So, we have here form, which is a string called triangle, and we're going to be looking for trying to match this string in every case of this. So, we have circle, square, triangle. So, you can see that it will use behind the scenes, it's going to be used in comparison, and we're going to be matching with the triangle. So, actually, that's what you see in the output. Here, I wanted to just bring up the name because when you're looking at the documentation, stamp up in these names, and sometimes it's like, well, what is it, like a wildcard, or what is the subject they are talking? So, a subject is something that you are going to be testing against some patterns, and you have here a subject would be triangle in this case that is a variable called form, and the pattern would be every statement of case has some sort of pattern that you want to match it with. And the wildcard, well, the wildcard is when you don't match with anything, and you still want to do something with your code. So it's like the else of the if else. So, here's just also like to give you like a flow how it works. So, you have a match of a subject, and you're going to be trying to match with each case of this. So, you have the case equals to a partner. If it's true, you're going to execute the block, and you're going to leave it. And if it's false, you're going to continue looking for your match. This seems like real life. So, you're going to continue. Maybe you find it, maybe you don't. It also happens. So, here, I want to highlight some things not to do it. And I want to explain why you should not do it. Not because it's obvious, but only because it's also the way I think about pattern matching. So, when you think about pattern matching, you should think in some sort of parameters. So, your specific case should come in the beginning. And if you are going through, you can open up for cases that englobe the beginning, so to say. If you try to use the wildcard in the beginning, this means you are accepting everything. So, it would be like you open up this box, and everything comes inside. So, it's actually not what you want. And this gives you some idea about how pattern matching should be think in the way of programming. So, you should always go from the specific case to the broadest ones. If it was not clear, you should not do it. Here we have with and without it. As I said before, I will be using a heart if I have comparations here. So, in this side where there is a heart, you have the list, and this list is going to be your subject, and you're going to be looking for the patterns and trying to find a match. As you can see here, it's very easy to understand, okay, the first case is a single list, and you are looking for one element in the list which is triangle. Does it match? A triangle is stored. In the second one, we have already two elements here. The first one is triangle, the second one is object. Do I need to know object? No. Actually, in this case, what is called is called binding. So, we are binding whatever is in the second position of the list to this variable called object. And then we can reuse in the execution block. This only exists in that context here. After you cannot find object and try to print or something like this. And then there is the... Oh, I see there is a mistake here. What? I'm missing four, you know, one, two, three, four. But yeah, the wildcard would be the ones, like, no matches are found, and it would englobe this one. If you try to do the same without the pattern matching, you would be using if, elif, and else statements. And this can be a bit nasty, because it starts to get verbose. You're going to start to, like, I have to access the second element of the list, I have to do a comparison, I have to also see the length of the list, is there elements, I have to save the second element or the element that you want as object. I have to save in a variable. So, you see that when you start to have more conditions, it's harder for you to just look at the code and say, okay, that's how it works. So, this becomes more verbose. Therefore, you can add more bugs. But actually, the bugs in the first one. But I run it before it's really indentation formatting. I also run some tests with Time IT, so you can see how fast it runs with and without it. This is with it, and this is without matching. I found it slightly fast with, but not something that I would say, okay, it's much faster. I guess not. But I tried to use some, like, exhaustion code, so I give it a match that would not match with anything and would go to the wildcard or to the else statement. And as I could see a more difference, like, without match, it was with match, it was two times faster, a little bit like that. So, it could be, I think, faster. I think the reason that it's faster is because you don't need to do so many conditionals. Some stuff is already optimised because of pattern matching. So, it could run faster. But if someone has ideas, please tell me. I think that's why. There is also something here, you can just, I don't know, compare an integer and do the pattern matching. I guess this integer, for example, numbers here. But in this case, behind the scenes, as I say, is using the equal statement. And in this case, I still would use the equal statement, in my opinion, only because I like it more explicit. So, if you have number equals equals zero, for me, it's still more explicit in the case of zero. But I think it depends on what you think you feel more comfortable. And also because I think pattern matching is still something that we are trying to use or we are getting used to it. So, yes. But I see in some cases it really helps. This is really cool. Pattern matching you can have guard. Don't be scared. It's just like least comprehension, so to say, because you have here the case, which you're going to be using you're going to be matching with, but only if something else is happening. So, we have it here. If size is lower equals to 10, or if size is higher to 10. So, we're going to do the matching only if the condition is already true. So, this is like this is basically what guard is in this context of pattern matching. This is the other thing that I found is really cool is called composable patterns. So, you can think about like a matryoshka. You can have a doll inside a doll inside a doll inside a doll. So, you can have a pattern inside a pattern inside a pattern inside a pattern. And it can get more, you can go, you already see that we are going for a more complicated kind of ways. So, you can combine composable pattern with guard and with things that we already saw. But what is composable pattern? As I say, it's a pattern inside a pattern inside a pattern. So in here, we have that we want the first element to be direction, but the second element of the list, we don't care. We want to be more flexible. We have some sort of options, but we want to be more flexible. It will be bottom or top or left or right, and we're going to be binding this whatever was here to the side because we don't know which will be, and we're going to be using the execution block. So this is basically what composable pattern is, and you can use it in your code. You can also match objects. This is really cool. I think because it's not something that I saw, for example, in C. Because here in Python, you can take an object, and you can tell, okay, I want that the color is equal to red or the color is equal to pink, and it will do the pattern matching for you. So you don't need to explicitly say all the attributes. You can just say the ones that you are interested in. And time for the photo. Sorry. Yeah, so you're going to be checking the subject. So here, what I want to tell you also is that the syntax is very similar to, like, instantiate an object. one that you take it has wrong. What is happening behind the scene is actually checking if this element is an instance of circle, and inside the instance, is there an attribute color, is it equal to red, and then it will execute, for example, and so on and so forth. So, although it's similar, it's not the same, and you will see some tricky cases that I will show you. So, there is Dictionary, I'm really sorry. I had this talk in November, and I had snow in Munich. And guess what? It's still snowing. So, I reused the photo. But the year is the last year. So, I was if you work in web development, I know you work with JSON. So, you have dictionaries, dictionaries, dictionaries, dictionaries. So, one thing I want to show you is that Pathomatic can also be used in dictionaries, so you can take a dictionary and you can do the matching with it. And I found it really cool because you don't need to explicitly tell all the keys in the dictionary. You can just go through the ones that you are looking, some pattern with it, and you can just put it here. So, for example, here I have actually year and location, but when I throw the matching, I just look for year. I just want to see if it's year 2022. Well, not there yet. I also feel we're still in 2021, to be honest. But here's the location Munich and so on. So, you don't need to explicitly say all the keys. I think it makes it easier when you're doing comparations with partners or with dictionaries when you work with dictionaries. This is a problem I found in the Stack Overflow. I really like this problem, so that's why I bring it here. The person wanted to understand, okay, I have all these dictionaries, and one of the keys is called ID, and I have match me dash full, match me dash bar, etc. And I want to find all the match that has match me. So this was the question. Can you do this with pattern matching? The answer is yes. Imagine I say no, right? And then we move forward. No, the answer is yes. So, I'll show you how to solve this question with pattern matching. So, you have it here. You would be looking for the ID, and you would be binding this to the variable called x, and you're going to be doing a guard on it. Yeah, yeah, yeah. A guard on it. And here you have when x starts with match me, you would do so we have the answer here. So he wants to know or she wants to know all the instances that start with match me. How can you do that? You use guard. So we have it here. We're going to be binding to X and checking if the X starts with match me. And we don't need to say everything, right? But you see how cool is this? Because we are kind of like mixing things from Python standard library that we use and we can use in guard. So this is a great example. So I hope you can use it if you have this question. Oh, it's already answered, by the way. I also had questions when I was using it. And this one's something that I didn't understood. And I think it will be confusing for people when you start using pattern matching. I had a dictionary with a key size. And I tried to match with an empty dictionary. Don't ask me why I tried. was really just trying. But I had this question, and I posted on Stack Overflow, I mean Twitter, and someone answered for me, like, how does it work? So, I did it with a dictionary here, and I was able to match with an empty dictionary. You have to agree with me, this is confusing. And I took a tuple, and I tried to match with an empty tuple. Of course, it did not match. So I was confused why does it work with dictionary, why does it not work with tuples. If you try with a class and you have an empty class or just some object of it, it will also match. And the reason is that dictionaries and classes in this sense, they work a bit different with pattern matching. So actually, with tuple you cannot be able to match, but yes with dictionaries. Why? The question, right? Because behind the scenes, the first check that is done is like, is it an instance of a dictionary? It is. So, we have already one case here. So that's why it matches with the empty dictionary. Faults. If, else, pattern match or whatever. I think, in my opinion, I really like pattern matching. I saw a lot of people excited, especially the people who are doing Rust, they just love pattern matching. So, I think why not to give it a chance? Actually, it's free. So, I would download Python 3.8, really try out pattern matching, but I agree that some stuff you can still do with if else. You need to think about your future self, and if it's easy to read and easy to go through, why not to give it a try? So, I want to ask you, are you going to give it a try to pattern matching? Please! Yes, those are my thoughts about it. If you have questions, actually, I've not given the slides, but I do have a thread which explains in more depth how pattern matching works with more examples, and you can find the slides around this thread. Thank you so much. I would love to catch up with all of you.

Speaker 2 [25:37]

So thank you so much. It's very interesting I was like basically like absorbed by your talk and I forget that I have to host the Q&A But anyway, I was like questions flaring in so I would try to pick one. So wow

Speaker 1 [25:50]

wow that's really interesting are you asking questions on the internet

Speaker 2 [25:55]

question on the internet. So this question is asking, are there any tools to check if your pattern matching is exhaustive?

Speaker 1 [26:05]

I don't know what does it mean, but I would say, for example, if it's exhausted, you would either use the wildcard, or if you don't do anything, you will have no house in the end. But if it's a tool outside Python, I'm not so sure. Because you can put in your execution block, okay, like in the end, okay, nothing happened, you can do some action and see, okay, it's exhausted. So it depends on how you structure. But you can put, as a last case, an exhaustion code to check. I will do it like this.

Speaker 2 [26:39]

Another question, what is the reason of using case underscore instead of else?

Speaker 1 [26:44]

This is interesting. Is there any Python core developer who can tell me? Because this is just a decision of the language, but I think in the context of pattern matching, from what I read, some stuff are they don't want to confuse the reserved words, so else is kind of already reserved for if and else, and they try to leave it outside, that's why they use the wildcard, but if there is another reason behind, I could not say for sure, because it was a decision design. But one interesting thing is also, like, matching also, because if you use regex, you have also match, right? But it's... Those words are different. In the matching, in the case pattern matching context, it works for pattern matching. And in the regex, it works for regex. So, this kind of reserved words.

Speaker 2 [27:32]

Yeah, so does MyPy support pattern matching already?

Speaker 1 [27:35]

MyPy? Yes. I don't know. But I think you can just go and see if it supports Python 3.10. If it does support Python 3.10, it can be used. Whether the code is changed, I'm not a maintainer of MyPy, so it would be hard for me to say.

Speaker 2 [27:50]

Yeah, can you pattern match on function arguments?

Speaker 1 [27:53]

Yes.

Speaker 2 [27:56]

Simple. So this is the last question that I see. Does pattern matching rely on equality operator so that objects have to implement as the dunder equal dunder method to work properly in pattern matching?

Speaker 1 [28:13]

So under the hood is actually using equals in some places. And when you're working with objects, I would say you are actually using the instance of. So I would say yes for the answer, because it's how it is implemented. But in this case, it's faster because it's optimized for better performance and so on.

Speaker 2 [28:32]

Yes, it stands against.

Speaker 1 [28:33]

Yeah, yeah, yeah, yeah, yes.

Speaker 2 [28:37]

enjoy your talk and thank you and i'm sure that you will find her around the booth so

Speaker 1 [28:41]

Thank you so much.

Laysa Uchoa

About — in the speaker's own words

Developer Advocate at Aiven, Python Developer and Pyladies Munich Organizer. I I believe that technology can make the world more democratic and just better - let's contribute to this.

Social card for talk: Python 3.10: Welcome to pattern matching!