summaryrefslogtreecommitdiffstats
path: root/google-appengine/google/appengine/api/validation.py
diff options
context:
space:
mode:
Diffstat (limited to 'google-appengine/google/appengine/api/validation.py')
-rwxr-xr-xgoogle-appengine/google/appengine/api/validation.py81
1 files changed, 49 insertions, 32 deletions
diff --git a/google-appengine/google/appengine/api/validation.py b/google-appengine/google/appengine/api/validation.py
index 00833e6..db969a7 100755
--- a/google-appengine/google/appengine/api/validation.py
+++ b/google-appengine/google/appengine/api/validation.py
@@ -218,7 +218,7 @@ class Validated(object):
"""
if key in self.ATTRIBUTES:
- value = self.GetAttribute(key)(value)
+ value = self.GetAttribute(key)(value, key)
object.__setattr__(self, key, value)
else:
raise ValidationError('Class \'%s\' does not have attribute \'%s\''
@@ -358,15 +358,16 @@ class Validator(object):
"""
self.default = default
- def __call__(self, value):
+ def __call__(self, value, key='???'):
"""Main interface to validator is call mechanism."""
- return self.Validate(value)
+ return self.Validate(value, key)
- def Validate(self, value):
+ def Validate(self, value, key='???'):
"""Override this method to customize sub-class behavior.
Args:
value: Value to validate.
+ key: Name of the field being validated.
Returns:
Value if value is valid, or a valid representation of value.
@@ -425,11 +426,12 @@ class Type(Validator):
self.expected_type = expected_type
self.convert = convert
- def Validate(self, value):
+ def Validate(self, value, key):
"""Validate that value is correct type.
Args:
value: Value to validate.
+ key: Name of the field being validated.
Returns:
None if value is None, value if value is of correct type, converted
@@ -444,12 +446,11 @@ class Type(Validator):
try:
return self.expected_type(value)
except ValueError, e:
- raise ValidationError('Type conversion failed for value \'%s\'.'
- % value,
- e)
+ raise ValidationError('Type conversion failed for value \'%s\' '
+ 'key %s.' % (value, key), e)
except TypeError, e:
- raise ValidationError('Expected value of type %s, but got \'%s\'.'
- % (self.expected_type, value))
+ raise ValidationError('Expected value of type %s for key %s, but got '
+ '\'%s\'.' % (self.expected_type, key, value))
else:
raise MissingAttribute('Missing value is required.')
else:
@@ -534,7 +535,7 @@ class Options(Validator):
super(Options, self).__init__(default)
self.options = alias_map
- def Validate(self, value):
+ def Validate(self, value, key):
"""Validate options.
Returns:
@@ -547,8 +548,8 @@ class Options(Validator):
raise ValidationError('Value for options field must not be None.')
value = str(value)
if value not in self.options:
- raise ValidationError('Value \'%s\' not in %s.'
- % (value, self.options))
+ raise ValidationError('Value \'%s\' for key %s not in %s.'
+ % (value, key, self.options))
return self.options[value]
@@ -583,7 +584,7 @@ class Optional(Validator):
self.expected_type = self.validator.expected_type
self.default = default
- def Validate(self, value):
+ def Validate(self, value, key):
"""Optionally require a value.
Normal validators do not accept None. This will accept none on
@@ -591,13 +592,20 @@ class Optional(Validator):
Args:
value: Value to be validated as optional.
+ key: Name of the field being validated.
Returns:
None if value is None, else results of contained validation.
"""
if value is None:
return None
- return self.validator(value)
+ return self.validator(value, key)
+
+ def ToValue(self, value):
+ """Convert 'value' to a simplified collection or basic type."""
+ if value is None:
+ return None
+ return self.validator.ToValue(value)
class Regex(Validator):
@@ -647,11 +655,12 @@ class Regex(Validator):
self.expected_type = string_type
- def Validate(self, value):
+ def Validate(self, value, key):
"""Does validation of a string against a regular expression.
Args:
value: String to match against regular expression.
+ key: Name of the field being validated.
Raises:
ValidationError when value does not match regular expression or
@@ -663,8 +672,8 @@ class Regex(Validator):
cast_value = TYPE_UNICODE(value)
if self.re.match(cast_value) is None:
- raise ValidationError('Value \'%s\' does not match expression \'%s\''
- % (value, self.re.pattern))
+ raise ValidationError('Value \'%s\' for key %s does not match expression '
+ '\'%s\'' % (value, key, self.re.pattern))
return cast_value
@@ -680,17 +689,19 @@ class _RegexStrValue(object):
is a list of strings, the strings are joined in to a single 'or' expression.
"""
- def __init__(self, attribute, value):
+ def __init__(self, attribute, value, key):
"""Initialize recompilable regex value.
Args:
attribute: Attribute validator associated with this regex value.
value: Initial underlying python value for regex string. Either a single
regex string or a list of regex strings.
+ key: Name of the field.
"""
self.__attribute = attribute
self.__value = value
self.__regex = None
+ self.__key = key
def __AsString(self, value):
"""Convert a value to appropriate string.
@@ -741,7 +752,8 @@ class _RegexStrValue(object):
try:
return re.compile(regex)
except re.error, e:
- raise ValidationError('Value \'%s\' does not compile: %s' % (regex, e), e)
+ raise ValidationError('Value \'%s\' for key %s does not compile: %s' %
+ (regex, self.__key, e), e)
@property
def regex(self):
@@ -790,7 +802,7 @@ class RegexStr(Validator):
AttributeDefinitionError if string_type is not a kind of string.
"""
if default is not None:
- default = _RegexStrValue(self, default)
+ default = _RegexStrValue(self, default, None)
re.compile(str(default))
super(RegexStr, self).__init__(default)
if (not issubclass(string_type, basestring) or
@@ -800,7 +812,7 @@ class RegexStr(Validator):
self.expected_type = string_type
- def Validate(self, value):
+ def Validate(self, value, key):
"""Validates that the string compiles as a regular expression.
Because the regular expression might have been expressed as a multiline
@@ -808,6 +820,7 @@ class RegexStr(Validator):
Args:
value: String to compile as a regular expression.
+ key: Name of the field being validated.
Raises:
ValueError when value does not compile as a regular expression. TypeError
@@ -815,7 +828,7 @@ class RegexStr(Validator):
"""
if isinstance(value, _RegexStrValue):
return value
- value = _RegexStrValue(self, value)
+ value = _RegexStrValue(self, value, key)
value.Validate()
return value
@@ -862,22 +875,24 @@ class Range(Validator):
self.expected_type = range_type
self._type_validator = Type(range_type)
- def Validate(self, value):
+ def Validate(self, value, key):
"""Validate that value is within range.
Validates against range-type then checks the range.
Args:
value: Value to validate.
+ key: Name of the field being validated.
Raises:
ValidationError when value is out of range. ValidationError when value
is notd of the same range type.
"""
- cast_value = self._type_validator.Validate(value)
+ cast_value = self._type_validator.Validate(value, key)
if cast_value < self.minimum or cast_value > self.maximum:
- raise ValidationError('Value \'%s\' is out of range %s - %s'
+ raise ValidationError('Value \'%s\' for %s is out of range %s - %s'
% (str(value),
+ key,
str(self.minimum),
str(self.maximum)))
return cast_value
@@ -902,27 +917,29 @@ class Repeated(Validator):
self.constructor = constructor
self.expected_type = list
- def Validate(self, value):
+ def Validate(self, value, key):
"""Do validation of sequence.
Value must be a list and all elements must be of type 'constructor'.
Args:
value: Value to validate.
+ key: Name of the field being validated.
Raises:
ValidationError if value is None, not a list or one of its elements is the
wrong type.
"""
if not isinstance(value, list):
- raise ValidationError('Repeated fields must be sequence, '
- 'but found \'%s\'.' % value)
+ raise ValidationError('Repeated fields for %s must be sequence, '
+ 'but found \'%s\'.' % (key, value))
for item in value:
if isinstance(self.constructor, Validator):
- item = self.constructor.Validate(item)
+ item = self.constructor.Validate(item, key)
elif not isinstance(item, self.constructor):
- raise ValidationError('Repeated items must be %s, but found \'%s\'.'
- % (str(self.constructor), str(item)))
+ raise ValidationError('Repeated items for %s must be %s, but found '
+ '\'%s\'.' %
+ (key, str(self.constructor), str(item)))
return value