Rock Solid Python with Python Typing Transcripts
Chapter: Typing Guidance, Patterns, and Advice
Lecture: To Optional or Not

Login or purchase this course to watch this video and the rest of the course contents.
0:00 More of a pattern than advice, something you really want to keep an eye out for because the Python type system doesn't enforce it very well,
0:10 although we've certainly spoke about optional or maybe when things are not optional in the Python type system. Here's a function, getUser,
0:19 and we have an email that we pass in. Presumably we're gonna go look in a database or some lookup given email, let's find the user by that email.
0:30 You can see it says it returns a user. Great, that's really nice. However, what if a user with this email doesn't exist?
0:39 Right, if this is arbitrary email input we could put in here, there's no guarantee that the user will exist here. Right, maybe somebody says,
0:47 I'm trying to log in, here's my email. You're like, ""Well, you typed in an email that doesn't exist in our website, in our database, no user.
0:57 What do you do? If you have it written like this, we return a user, a concrete user every single time.
1:04 Remember Python types say you cannot have none, right? They're not optional or user pipe none or any of those things.
1:13 User means there is a concrete user that will always be returned. Never ever will it not be a concrete user object.
1:21 So that implies a certain kind of use case here. It requires that the author of this function, if they're gonna be true to the type system,
1:30 will throw an exception if the user is not found. There's no way to return from this function normally if there's no user, right?
1:37 You can't return none. So that's a choice you can make. And certainly people do write code like that, but that means anyone who uses your code
1:44 has to use a try except sort of design pattern. And so think about if that's what you want. If that's not what you want,
1:53 then you should say this returns an optional user, in which case it's allowed to return none if you pass an email for a user that doesn't exist.
2:03 Again, you can write this user pipe none or optional of user because the pipe thing means that here's just a combination of types.
2:11 As I've already said many times, I'm a huge fan of saying optional, like it's either a user or it's nothing.
2:18 And so I prefer this, but you take the pick, write it however, but that doesn't matter. What you need to do is say it's optional or none
2:27 or a user or none. And you have to explicitly express that if it's not the first pattern, either it's a user or it's an exception, right?
2:35 So either of these in my world are fine. I honestly kind of like the lower one a lot of times because you don't necessarily want it.
2:42 It's not a problem. You want to just check, does the user exist? If not, give me none and I'll do something, right?
2:48 So it's not an error that the user doesn't exist. It's just, you know, the type system and the first one didn't express it.
2:55 So think carefully about optional or not optional and what that means for not just the types you put in your function,
3:03 but actually the design patterns that you use and you force your users to use, your consumers of your functions. Super interesting, I think.


Talk Python's Mastodon Michael Kennedy's Mastodon