users logging in and out ''self users {def add_user(selfusernamepassword)if username in self usersraise usernamealreadyexists(usernameif len(password raise passwordtooshort(usernameself users[usernameuser(usernamepasswordwe couldof courseextend the password validation to raise exceptions for passwords that are too easy to crack in other waysif we desired now let' prepare the login method if we weren' thinking about exceptions just nowwe might just want the method to return true or falsedepending on whether the login was successful or not but we are thinking about exceptionsand this could be good place to use them for not-so-exceptional circumstance we could raise different exceptionsfor exampleif the username does not exist or the password does not match this will allow anyone trying to log user in to elegantly handle the situation using try/except/else clause sofirst we add these new exceptionsclass invalidusername(authexception)pass class invalidpassword(authexception)pass then we can define simple login method to our authenticator class that raises these exceptions if necessary if notit flags the user as logged in and returnsdef login(selfusernamepassword)tryuser self users[usernameexcept keyerrorraise invalidusername(usernameif not user check_password(password)raise invalidpassword(usernameuseruser is_logged_in true return true notice how the keyerror is handled this could have been handled using if username not in self usersinsteadbut we chose to handle the exception directly we end up eating up this first exception and raising brand new one of our own that better suits the user-facing api