--- a/thirdparty/google_appengine/google/appengine/api/validation.py Tue Jan 20 01:12:43 2009 +0000
+++ b/thirdparty/google_appengine/google/appengine/api/validation.py Tue Jan 20 13:19:45 2009 +0000
@@ -224,16 +224,6 @@
raise ValidationError('Class \'%s\' does not have attribute \'%s\''
% (self.__class__, key))
- def __eq__(self, other):
- """Comparison operator."""
- if isinstance(other, type(self)):
- for attribute in self.ATTRIBUTES:
- if getattr(self, attribute) != getattr(other, attribute):
- return False
- return True
- else:
- return False
-
def __str__(self):
"""Formatted view of validated object and nested values."""
return repr(self)
@@ -678,6 +668,113 @@
return cast_value
+class _RegexStrValue(object):
+ """Simulates the regex object to support recomplation when necessary.
+
+ Used by the RegexStr class to dynamically build and recompile regular
+ expression attributes of a validated object. This object replaces the normal
+ object returned from re.compile which is immutable.
+
+ When the value of this object is a string, that string is simply used as the
+ regular expression when recompilation is needed. If the state of this object
+ is a list of strings, the strings are joined in to a single 'or' expression.
+ """
+
+ def __init__(self, attribute, value):
+ """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.
+ """
+ self.__attribute = attribute
+ self.__value = value
+ self.__regex = None
+
+ def __AsString(self, value):
+ """Convert a value to appropriate string.
+
+ Returns:
+ String version of value with all carriage returns and line feeds removed.
+ """
+ if issubclass(self.__attribute.expected_type, str):
+ cast_value = TYPE_STR(value)
+ else:
+ cast_value = TYPE_UNICODE(value)
+
+ cast_value = cast_value.replace('\n', '')
+ cast_value = cast_value.replace('\r', '')
+ return cast_value
+
+ def __BuildRegex(self):
+ """Build regex string from state.
+
+ Returns:
+ String version of regular expression. Sequence objects are constructed
+ as larger regular expression where each regex in the list is joined with
+ all the others as single 'or' expression.
+ """
+ if isinstance(self.__value, list):
+ value_list = self.__value
+ sequence = True
+ else:
+ value_list = [self.__value]
+ sequence = False
+
+ regex_list = []
+ for item in value_list:
+ regex_list.append(self.__AsString(item))
+
+ if sequence:
+ return '|'.join('(?:%s)' % item for item in regex_list)
+ else:
+ return regex_list[0]
+
+ def __Compile(self):
+ """Build regular expression object from state.
+
+ Returns:
+ Compiled regular expression based on internal value.
+ """
+ regex = self.__BuildRegex()
+ try:
+ return re.compile(regex)
+ except re.error, e:
+ raise ValidationError('Value \'%s\' does not compile: %s' % (regex, e), e)
+
+ @property
+ def regex(self):
+ """Compiled regular expression as described by underlying value."""
+ return self.__Compile()
+
+ def match(self, value):
+ """Match against internal regular expression.
+
+ Returns:
+ Regular expression object built from underlying value.
+ """
+ return re.match(self.__BuildRegex(), value)
+
+ def Validate(self):
+ """Ensure that regex string compiles."""
+ self.__Compile()
+
+ def __str__(self):
+ """Regular expression string as described by underlying value."""
+ return self.__BuildRegex()
+
+ def __eq__(self, other):
+ """Comparison against other regular expression string values."""
+ if isinstance(other, _RegexStrValue):
+ return self.__BuildRegex() == other.__BuildRegex()
+ return str(self) == other
+
+ def __ne__(self, other):
+ """Inequality operator for regular expression string value."""
+ return not self.__eq__(other)
+
+
class RegexStr(Validator):
"""Validates that a string can compile as a regex without errors.
@@ -693,7 +790,8 @@
AttributeDefinitionError if string_type is not a kind of string.
"""
if default is not None:
- default = re.compile(default)
+ default = _RegexStrValue(self, default)
+ re.compile(str(default))
super(RegexStr, self).__init__(default)
if (not issubclass(string_type, basestring) or
string_type is basestring):
@@ -715,22 +813,15 @@
ValueError when value does not compile as a regular expression. TypeError
when value does not match provided string type.
"""
- if issubclass(self.expected_type, str):
- cast_value = TYPE_STR(value)
- else:
- cast_value = TYPE_UNICODE(value)
-
- cast_value = cast_value.replace('\n', '')
- cast_value = cast_value.replace('\r', '')
- try:
- compiled = re.compile(cast_value)
- except re.error, e:
- raise ValidationError('Value \'%s\' does not compile: %s' % (value, e), e)
- return compiled
+ if isinstance(value, _RegexStrValue):
+ return value
+ value = _RegexStrValue(self, value)
+ value.Validate()
+ return value
def ToValue(self, value):
"""Returns the RE pattern for this validator."""
- return value.pattern
+ return str(value)
class Range(Validator):