Created
July 22, 2014 16:48
-
-
Save aaronlelevier/57891806f7b41cc65da5 to your computer and use it in GitHub Desktop.
metaclass example of looping through classes of password validation in python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PluginMount(type): | |
""" | |
A Meta Class plugin mount location for a list of plugin classes. | |
By creating this, on all subclasses of PluginMount, python will | |
instantiate a plugin attribute list and maintain it for the Class | |
using this Meta Class. | |
""" | |
def __init__(cls, name, bases, attrs): | |
if not hasattr(cls, 'plugins'): | |
cls.plugins = [] | |
else: | |
cls.plugins.append(cls) | |
class PasswordValidator(metaclass=PluginMount): | |
""" | |
Plugins extending this class will be used to validate passwords. | |
Valid plugins must provide the following method. | |
validate(self, password) | |
Receives a password to test, and either finishes silently or raises a | |
ValueError if the password was invalid. The exception may be displayed | |
to the user, so make sure it adequately describes what's wrong. | |
""" | |
def is_valid_password(password): | |
""" | |
Returns True if the password was fine, False if there was a problem. | |
""" | |
for plugin in PasswordValidator.plugins: | |
try: | |
plugin().validate(password) | |
except ValueError: | |
return False | |
return True | |
def get_password_errors(password): | |
""" | |
Returns a list of messages indicating any problems that were found | |
with the password. If it was fine, this returns an empty list. | |
""" | |
errors = [] | |
for plugin in PasswordValidator.plugins: | |
try: | |
plugin().validate(password) | |
except ValueError as e: | |
errors.append(str(e)) | |
return errors | |
class MinimumLength(PasswordValidator): | |
def validate(self, password): | |
"Raises ValueError if the password is too short." | |
if len(password) < 6: | |
raise ValueError('Passwords must be at least 6 characters.') | |
class SpecialCharacters(PasswordValidator): | |
def validate(self, password): | |
"Raises ValueError if the password doesn't contain any special characters." | |
if password.isalnum(): | |
raise ValueError('Passwords must contain at least one special character.') | |
def run(): | |
""" | |
Call run() function to demonstrate metaclass password usage | |
""" | |
for password in ('pass', 'password', 'p@ssword!'): | |
print(('Checking %r...' % password), end=' ') | |
if is_valid_password(password): | |
print('valid!') | |
else: | |
print() # Force new line | |
for error in get_password_errors(password): | |
print(' %s ' % error) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment