Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class LoggingService(object):
- """
- Just a contrived logging class for demonstration purposes
- """
- def log_error(self, error):
- pass
- class UserService(object):
- """
- Provide a method to authenticate the user by performing some expensive DB or network operation.
- """
- def validate_credentials(self, username, password):
- print('> UserService::validate_credentials')
- return username == 'iainjames88' and password == 'secret'
- class User(LoggingService, UserService):
- """
- A User model class for demonstration purposes. In production, this code authenticates user credentials by calling
- super().validate_credentials and having the MRO resolve which class should handle this call.
- """
- def __init__(self, username, password):
- self.username = username
- self.password = password
- def authenticate(self):
- if super().validate_credentials(self.username, self.password):
- return True
- super().log_error('Incorrect username/password combination')
- return False
- class MockUserService(UserService):
- """
- Provide an implementation for validate_credentials() method. Now, calls from super() stop here when part of MRO.
- """
- def validate_credentials(self, username, password):
- print('> MockUserService::validate_credentials')
- return True
- class MockUser(User, MockUserService):
- """
- A wrapper class around User to change it's MRO so that MockUserService is injected before UserService.
- """
- pass
- if __name__ == '__main__':
- # Normal useage of the User class which uses UserService to resolve super().validate_credentials() calls.
- user = User('iainjames88', 'secret')
- print(user.authenticate())
- # Use the wrapper class MockUser which positions the MockUserService before UserService in the MRO. Since the class
- # MockUserService provides an implementation for validate_credentials() calls to super().validate_credentials() from
- # MockUser class will be resolved by MockUserService and not passed to the next in line.
- mock_user = MockUser('iainjames88', 'secret')
- print(mock_user.authenticate())
- >>> print(MockUser('foo', 'bar').authenticate())
- > MockUserService::validate_credentials
- True
- def validate_credentials(self, username, password):
- print('> MockUserService::validate_credentials')
- assert username_ok(username), 'username expected to be ok'
- assert password_ok(password), 'password expected to be ok'
- return True
- >>> MockUser.mro()
- [<class '__main__.MockUser'>,
- <class '__main__.User'>,
- <class '__main__.LoggingService'>,
- <class '__main__.MockUserService'>,
- <class '__main__.UserService'>,
- <class 'object'>]
Add Comment
Please, Sign In to add comment