Skip to content

Instantly share code, notes, and snippets.

@Nagasaki45
Last active August 29, 2015 14:05
Show Gist options
  • Save Nagasaki45/c5a1afab4a6a62521be9 to your computer and use it in GitHub Desktop.
Save Nagasaki45/c5a1afab4a6a62521be9 to your computer and use it in GitHub Desktop.
A function to validate attribute (or attributes) of an instance (or a list of instances) against white or black list of values.
def validate_attr(instance, attr, valid, errors=None, positive=True):
'''Returns a list of errors (strings) for mom objects attribute
validation.
Parameters:
instance: instance or list of instances to validate.
attr: attribute name or list of attributes names as strings.
valid: valid value or list of valid values (invalid values if
positive=False).
errors: an optional list to aggregate the errors into.
positive: whether to treat the valid parameter as accepted value
or rejected value.
Returns:
a list of errors (strings).
'''
if errors is None:
errors = []
# recurse until the function runs on single instance / attribute
if isinstance(instance, collections.Iterable):
for i in instance:
validate_attr(i, attr, valid, errors, positive)
return errors
if isinstance(attr, collections.Iterable) and not isinstance(attr, str):
for a in attr:
validate_attr(instance, a, valid, errors, positive)
return errors
# valid values are always lists to perform "in" or "not in" upon
if not isinstance(valid, collections.Iterable) or isinstance(valid, str):
valid = [valid]
strings = {
'class': instance.__class__.__name__,
'instance': str(instance),
'attr': attr.replace('_', ' '),
'valid': valid,
}
if not hasattr(instance, attr):
errors.append(
'{class} {instance} has no attribute {attr}'.format(**strings)
)
return errors
# sets the validation_test to check if the attribute value contains
# in the valid values or if not contains in case of positive=False
if positive:
validation_test = lambda x, items: x in items
else:
validation_test = lambda x, items: x not in items
attr_value = getattr(instance, attr)
if not validation_test(attr_value, valid):
strings['attr_value'] = attr_value
error_template = '{class} {instance} {attr} is {attr_value}'
if positive and len(valid) == 1:
error_template += ' instead of {valid[0]}'
else:
error_template += ', which is invalid'
errors.append(error_template.format(**strings))
return errors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment