 Okay, hello everyone, my name is Mario Corchero or Mario Corchero and I'm Spanish work at Bloomberg at the Python infrastructure team. This light seems not to work great I Do more things on Python so if you've read to chat with me if you want to have a trip to Spain I love traveling around Spain if you don't don't have any questions to us we can chat afterwards that would and we And I Wrote yeah, if you wonder exceptional exception, it's all about the clickbait. Okay, I had to come with this title So you've got through the proposed selection and but basically on my daily work I I create libraries for the rest of the companies and quite often when you're creating this comes like middle of a libraries You're basically just calling all the other libraries Or wrapping other libraries and you need to find a way to translate those exceptions, right? And even if you know raising an exception sounds really easy We're gonna see here that there are many ways to capture and raise them if you're a beginner to Python You'll get from this talk some kind of like a really quick deep dive into all the syntax around how to handle exceptions If you are intermediate Python developer I hope that from this talk you get some like good practices and how to do things in nicer way And maybe discover some some things if you are an experienced Python developer I have some hidden gems and small tricks for niche cases So that you learn if you are a core developer that knows everything about Python exceptions a question outside. Okay, so this part It's really you Christian So, you know recent exception is easier, right? You just do raise exception and you put a message on it And whilst that's in many times the case there are all the situations where you know You might wonder like, okay, how should I capture the exception? What does exactly the else mean and what does it do? What what goes into the finally how does finally work and how you should handle the exception if you are ready with an exception block? So this is the only image in the whole slides. So get ready for a lot of code So first of all You just try how do you capture an exception? You do accept you put the name of the exception that you want to capture here Easy, right? You might have multiple of them. So what's gonna happen? Is that in order as a waterfall? This is not the switch statement. Okay, it's gonna go one by one evaluating them So what's happening here is that if an exception is racing? He is gonna go to the first one is gonna check if the exception that was raised is of this type And then it will go if there's a couple it will go one by one And then you have this kind of set which is basically gonna gonna catch all the exceptions Easy everyone knows how an exception I get cats, right? But did you know that you can also have like any of the name to catch up to catch an exception? So for example, you can you can save an exception in a viral and then you can just you know Do an accept and save it here at the end. This is just any other name So it's basically the same as just put an exception there But because this is being evaluated you can also have a function that will return you the exception that you want And this function is actually going to be called every single time that an exception falls through this You can even have a variable that doesn't exist That's not the problem because unless the exceptions fall all the way down until you won't get any You won't get the name error that will result in this code So that means that if you have this code, which basically means that this is a bug You will never see it unless an exception is raised that does not match these two first cases Scary right use a linter So something interesting finally you have probably seen finally all it does when you do a try try accept Is that whatever you whatever you do here whether whether the exception is raised or not here finally will always be executed? So that means that if you have code here that does not write exception Finally it's going to be executed if you have code here that will raise an exception and whatever happens in the exception clause It will still be executed You also have else which is confusing for people coming from other languages that don't have a construct like that What else does is the code would be executed if no exception is thrown More or less like unless you have something special here like returning or something like that else will be always be executed unless they're unless An exception is thrown if any exception is thrown The else code won't be executed. You might wonder why would I want this? Why wouldn't just put this line within the try and the thing is it has kind of like two main things where you might want to use the Else one is it conveys different meanings. So You can see here that if you were to read the code as if it were text You can say that you are trying something if it fails You handle it some one way and if it doesn't fail and that's what the else does you want some other codes to be executed Addicently Whatever you have in the else won't be like if an exception is rated in the else It won't be handled by any of the x64. So it also changes how how the code behaves so You know we have seen try except else and finally so you might want if you wonder about the order of how this goes This code for example will you know go through the try print one? There's no exception that has been thrown so not this is not executed Then you go through the else see print 3 and then you go through to the finally because we always execute the finally I print 4 and it's like my everyone knows that right. Okay. What does this return? Right, this is really interesting like So what's gonna happen here is that actually all those returns are not going to be executed? What's gonna win here is the 4 but the same one happened with the else Like if you return something for the try the else would would not be executed If you wonder about how all this work the best way to see it is take a Python 3 8 built and just run this dot this On this function and you can see there's there's an there's a new structure and call set up finally that you can You can look for and you will understand how this works. It's And a high-level model finally always get executed and whatever happens in the finally will win always Okay, so Something important that touches my heart is login exceptions if you are looking exception There is something like I don't when it was but the first time I saw this beautiful parameter Which is X and X info it changed my life what it does is it? It allows you to log everything about the exception together with the log that you passed So that means that you'll get the trace back and exception itself in your logs or wherever you configure in your login stack Together with the message you put it's it happens so often that you log an error and you put you use X info that there is a function call Exception that will basically do that for you if you do log into the exception You are logging on error and including the trace back and exception But know that you can you can use X info with any other level like you can have any level in the On the logger and just pass X info and that will lock you the exception as well So you don't have to log an error just to get the exception trace back Okay, and now So, I don't know if you know you import this you see this like error should never pass it silently well Yeah, so you see this error should never pass Silently and then you go like you know what whenever it's an error. I'm gonna go crazy about it So I'm gonna log an exception. I'm gonna raise it again. I hate this Okay, there is there's good people bad people people that need babies and people do this don't do it Okay, I'm gonna follow you if you do this Why is it bad because if you do this you just moved from having one error to having two like now If there's gonna be a logger that you have to handle because if there is an error in your logs You need to action it and there's gonna be an exception being being passed to user When you're doing a library You're taking control away from the person that's calling you if you do this And I know I know you're saying but Mario What if I have no no don't do it and okay? There is a situation if you know no don't do it like look if you do this Okay, and I'm then I'm calling you and now I catch your action. What do I do? What do I do? What do I do you give me the options now? So if I I have to pass it if I consider this not to be an error I'm gonna get an error in my logs if I if I think that this is an error I want to log it I'm gonna get two logs and if I find our automate for example alarming on my logs I'm gonna get two reports to me right this is a pain and This this happens like you can be there are many libraries that have this thing There was there was one DB API of a of a proprietary database that and this is why it touches me that that had Basically if you try to insert a key It was it was raising an exception telling you that it was an integrity error and then giving you a nice exception You can handle but it was also logging a wording now because I was writing a library that was using that library And I needed to do what's called an absurd basically you trying to insert and if the if the thing is there You just do an update all my users were getting a warning just because of that So if you are gonna give an exception to your users, please Don't log an exception that your users already have the information enough to handle it Don't don't put an error on their message. There's no one situation when you're writing Like a web server we can discuss if you know if you want to Like discuss with me for real long we can chat about this Happy to have this discussion afterwards, but I haven't seen any situation where it's useful to log an error and raise an exception Okay, so how do you look at error if you don't want to use the exception where you get the tricep and all that information Something else you can do is you can just include that the error quite often if you are not If you don't have a lot of knowledge about how string interpolation works You tell those people just doing the person the hs what this is actually doing This is just calling the string representation of the of the exception. That's usually not what you want Okay, what you want is to get the wrapper of the of the of the exception Why is that because as you saw before if you do person the chess is it's gonna get them the message of the exception If you do person there are you're gonna get actual exception if instead of having this line here You were calling something inside which has a lot of code How do you know on earth that this is coming from a key error, right? There's no way to know it you can see it here. It's there even worse situations You can see here that you know if I had an exception you try to print the string representation of it It's just a string if you have the wrapper is a correction This is basically bad when you try to print it because look value error on the key error They are just gonna print whatever they have inside if you use the string representation of them You're just getting the content of it and if you have an exception with and with nothing in it You're just gonna get an industry so you can happen that you're using a library that has like custom exceptions that don't have any argument on it They just have you know the important part of it. It's just the name of the exception and you're you're missing all that So when I bring a log will you're logging probably you want the representation of the string of the exception? something interesting about exceptions when you have When you have an except plus the variable in the except does not leak the scope Compared to with statement or for loops or things like that This is so you know what I mean is like if you try to use that name afterwards It will just give you a name error like that doesn't exist at all This came with Python 3 exceptions and the reason is that the exceptions has an attribute hat That's a trace back the straight way how the take the stack frame and if the name will seal to be there This the stack frame will have again the exception will create the cycles and will keep your objects alive for unnecessarily for longer time. I think you know That's funny. So I just wanted to add it Now, how do you raise the exception? You can just raise an extra an instance if you create it or you can just pass the name of the class and it will create an instance for you with no arguments. I Think I've never used this one, but hey Now that CC but then again the tricky one is this one. You'll see a lot of code like this usually if it's in Python 2 There is some code you do an except exception and then you raise an exception if you do this What you're actually saying is I fail to handle the exception Okay, what this is meaning is that there was an exception when handling the exception and if you see The message that you get out of it is actually saying that says during the during the handling of the web exception another exception occur You get both exception here, but you are probably not transmitting to your users what you really want to mean Because there are three ways that you can raise an exception when you are already handling an exception So one of them is you might want to just rewrite the original obsession You can just do that by doing a race This is gonna get the exception that you're handling and just bubbling up You don't need to capture the name or anything. It will just get it This is really useful It uses one to log or get some metrics or whatever you want that you just want to you know like snoop a little bit there, but you don't want to change anything and One of you see the trace back you're gonna see that Only the original section or only the original play what he was racing is included but not this one So this is like it never happened Another way to do it is you can re-race my exception that is already That you're capturing into a name. So remember because they don't leak scope. You might need to save it This is for example, if you have you want to send a request You have multiple URLs you want to try with all of them and only if all of them fail You want to raise one of them, right? So you can just save it into on one variable and whenever you erase it both the original place and that and the one Where you re-race will appear Yeah, it's just a different way to say to to to raise an exception But now if you want to take an expression that you are handling and you just want to say hey There's this error that's happening and I want to and I just want to tell you that is I'm blaming this other exception, right? So this is it's not me So you want to raise the exception and you say that the original one is this one You can just do a race from and what this is gonna do is this is gonna tell you what this is gonna tell you users that This was this was there. This is the exception that I'm raising and the cost of it is this one if this also on adds Dunder Costs to the question that you can you can like the users can check just to know what's that? What was the original exception? And then the last one because actually raising section is easy, right? You can just suppress all together region of the original exception This is useful if you don't want your clients to the clients of your library to know What are you using behind the hoods? So basically you can do this and the original exception will be elated and they will only see the new one So you can see here because we do a race from none The only the new from only the new exception that we are rising is the only one that they can see Who that's a lot about racing appears Well another interesting thing, please don't raise not implemented That's not an exception what you probably want to raise is not implemented error If you do this you're gonna get a type error. This is gonna raise. Yes, but not what you want So if you see I once saw a test that he was checking that this was racing But it was just capturing an exception like yeah, it's racing But not what you want because this is what what's happening He is that race will always need to take something that is an exception and you've passed something else It's just gonna shoot a type error Then the same goes about capturing them if you do an accept or not implemented This is gonna raise a type error. It's not only not captured exception is raising a new one. Okay Who does that right? Well, look at the hits in GitHub. Okay, like That not implement is a whole different thing that is usually used whenever you are in Implementing your own like compression methods I think they are for your class if you want to mark a if you want to say that the method is not implemented You just raise not implemented error Okay Some more small things if you want if there is an exception that's raised on a thread you're just gonna get this beautiful thing in stdr, right and If you just want to be able to be able to propagate the exceptions from threads into your main threads You can just use something like for example futures and when you do futures result It will come to your main thread and all these bytes many people so that's why I included here why not and Let's have a quick look through the exception hierarchy and the main two exceptions You probably want to know about is base exception and exception So base exception is the base for all the exceptions in Python. Okay, but that's usually what you don't want What you usually want is exception So exception is the base for all the exception that you might want to handle and all and the base for exceptions that all the libraries define if You go to base exception, you can see things like system exit or keep it interrupt Those are that is basically that you know if you for example hit control C and you try to interrupt the program What's happening? It's that it's just raising one of those keep it interrupt So if you are capturing base exception or all exceptions, you are effectively preventing users from hitting control C Which is quite annoying Same goes with system exit basically if you do a system exit It's kind of just raising an exception that system exit if you capture that exception You can basically prevent the program from exiting. Please don't do that unless you really know what you're doing It can happen that in some situations you might want to capture that because you might want again to log or something like that But then you immediately just re-race. That's okay, but don't just try to silence or handle those ones some of the interesting exceptions you might want to know about is probably import error or You know index error or error whenever you're looking up things in dictionary or vectors And then you have value errors, which is kind of like the you know If you have an argument that you cannot handle or type error for the wrong type that you can have look This is like a minimized version. There are many more exceptions than the library or you can have a look It's all documented here Okay, so what does an exception has you have an exception in your hands. What do I do with it, right? You might be looking to the dot message attribute if you are doing that Please stop writing Python 2 if you have only some more months to move and what you have nowadays is Arx so whenever an exception is created all the arguments is saved in this Beautiful attribute and you can just retrieve it You also have trace back, which is the original trace back This is useful if for example You want to create a new exception and you want to patch the new exception with the exception of the old one And think like that usually you don't need it, but it's there. You need it and You know whenever you are creating an exception remember always to inherit from exception and not base exception Why because yeah, I know I know okay. I following in this to base exception has this name, right? There's like hmm feels like a base class. I want to use no, okay. It's a trap It's a trap because if you do this the users might then try to capture base exception And then capture exception that they should not be capturing. Okay, so always inherit from exception This is in documentation always inherit from exception. This is in documentation What else so I'm really cool trick Even if you don't do anything in the in it the Arx are going to be saved once that magic look it up It's basically the new You can define your own exception hierarchy if you want there are many libraries that do this good examples are requests SQL alchemy There's also another library that I should not pronounce because we're in a German speaking country They're really famous for doing requests as well And I know I won't pronounce it properly. He's like something like work sir But you know the one I mean look looks also because they are really nice. They have really nice well-designed exception hierarchies and Whenever you are Creating your exceptions or raising the exceptions in your library It's what you can start perfectly by raising like standard libraries exceptions Like value or value around things like that and then by using multiple inheritance You can just create your own whole own hierarchy and then remap those ones into internal ones and that won't break users Because if you if you don't use multiple inheritance inheritance whenever you're doing that That's a bug worry compatible change if you if you have a different base you can see there are Situations where people use multiple exception multiple inheritance for exceptions in both the standard libraries and well-used extended libraries Okay, some people come from C and they want to use error codes I come from C++. Don't worry. I feel the same pain as you but In general, don't use error code unless I would recommend don't use error code unless you are basically just remapping them from Other systems so for example, you can see there are some exceptions that will have an error code But this is for example because they are coming from they're basically remapping the HTTP error code into exception But this steel they are creating a specific exception for each error code and that's great because that allows me to basically Have except close where I can say what except exception I want to to catch right otherwise is like The Pokemon catch right you catch them all in a single application and then you differentiate in error codes Don't do that. Please have specific exceptions. It's so much easier to have to work with So we still have time so I'm gonna go well in very quick Whenever you catch exception and you try to raise them think what do you want to do? Like how do you want to do submit the previous exception? You want to alight it or inform it or whatever and be very critical for how we log in but there's extra content So because you want to go home and say and I learned something new There is something new being released in three eight You have a unraceable hook that you can set to whatever you want and that's basically going to be called whenever There's an exception in the interpreter that Cannot be handled at the moment. Those were just going to STD era, but now you'll be able to handle them I was speaking with Victor's dinner who would you implemented this to and maybe that can also be extended to To to be used for like if you have to raise also unraceable exceptions And then you have a threading accept hook So basically this is a this is a different way to to solve the problem We saw before where you have an exception being raised in a thread and you want to handle it You can just set this and this is one to be called You might be wondering what is that little bar right? So that's pep 570. That's positional only arguments You have the author of the peps there so you can ask him about that It basically means that everything be before that It can be passed only as a positional language and not as a not as a keyboard It's quite cool then we have if you care about Your the lifetime of the object or if you really care about memory This is a really nice trick So whenever if you for whatever reason are captured in an exception and then you're going to erase it with a name This leads to a cycle And what I mean with that is that this exception that you're raising here. It's gonna have a Thunder trace back that's you know, it's gonna have the stack frame and then it's gonna have again this Exception and what that's gonna do is when you erase it It's gonna keep alive all the objects in the stack until the next cargo collection happen That's a pain in many situations like you can see that you know They're placing the standard library where you were one to avoid that and they might be situations in your libraries But you also want to avoid that To do that you do this beautiful coat and you just do You just do try when you erase it and just a finally that removed the name Yes, you really need to do that if you want to save like if you want to remove that cycle and you will see Many occurrences in the standard libraries. Well, this is happening Okay, so now something really cool like what happens. Yeah, so, you know, you have this Everyone agrees that this is bad, right? If you have been doing Python for some time you say that oh, this is bad because you are hiding all the exceptions blah blah blah then you might see code like this and The cool thing about this is that you have a returning a finally all the exceptions are removed Nothing happened here. How cool is that right? Some linters will catch this Like I'm pilot flake it will do in the one water But this is this is bad here You're basically hiding all the exceptions and everything that happened. So never never never, please return in a finally, okay, and You can see that this is an exception of why it's bad is this Beautiful snippet of code. This is just sleeping for five seconds and whenever and every five seconds you're just gonna say I'm unstoppable, right and it's just gonna return and You didn't know about this, but the whole on the whole presentation. This was running in the background and if I managed to print the other one and This is bad because you won't be able to stop it if you try to stop you're just fitting him He goes faster, right? Like if you have if you have a finally with a return, there's no way to get around of it Well, not that one Well, that's it now that's just time for questions Yeah, a Little bit tied to thank you very much have maybe one or two questions. So anyone want to Yeah, thanks for the presentations was very good so I was just wondering first if you Was your opinion on using exceptions for kind of messaging versus actual exceptional behavior? Because in bite and it's kind of confused between the two. Yeah, so actually I miss Dallas should have said that when I go through all the exceptions You can see that in Python that there are also exceptions that are just for counter flows So you can see for example stop iteration is just an exception that is used for counter flows In general, you will see that all the exceptions in the standard library either end with error Which means that they are an error that happened or they just don't end with their like stop iteration And that's for counter flow. So if you want to use them for that Usually Some main time system is an overuse, but there might be fair situations where you want that okay? It really depends on the use case. Okay, it is not as crazy as in C++ Okay, thanks. I know you're coming from there. What's your next holiday destination? What my next holiday? I'm going to Ukraine with my mother Thank you for your great talk. Just have a quick question. Is there a technique that lets us yield exceptions yield exception Yeah, what do you mean with yield exception? There are some cases when you have multiple exceptions and you want to get them Okay, so I mean I think there is a work in progress for having like the multi exception thing on on Cinqueo I'm not an expert in it, but just behind you you have a core developer that knows a lot about that Thank you, thank you. Oh, yeah, I think there are some plans to have something in it. Sure. Yeah, okay We have three more minutes. So one more question. I think I'm gonna be outside swell Okay, if you don't have any further questions, so that's thanks Mario again