1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

i18n: added translation hooks to all validators

git-svn-id: http://code.djangoproject.com/svn/django/branches/i18n@901 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Georg Bauer 2005-10-17 13:16:13 +00:00
parent 6233af6633
commit 49739a8f84

View File

@ -24,6 +24,7 @@ phone_re = re.compile(r'^[A-PR-Y0-9]{3}-[A-PR-Y0-9]{3}-[A-PR-Y0-9]{4}$', re.IGNO
url_re = re.compile(r'^http://\S+$') url_re = re.compile(r'^http://\S+$')
from django.conf.settings import JING_PATH from django.conf.settings import JING_PATH
from django.utils.translation import gettext_lazy
class ValidationError(Exception): class ValidationError(Exception):
def __init__(self, message): def __init__(self, message):
@ -57,22 +58,22 @@ def isAlphaNumeric(field_data, all_data):
def isAlphaNumericURL(field_data, all_data): def isAlphaNumericURL(field_data, all_data):
if not alnumurl_re.search(field_data): if not alnumurl_re.search(field_data):
raise ValidationError, "This value must contain only letters, numbers, underscores and slashes." raise ValidationError, _("This value must contain only letters, numbers, underscores and slashes.")
def isLowerCase(field_data, all_data): def isLowerCase(field_data, all_data):
if field_data.lower() != field_data: if field_data.lower() != field_data:
raise ValidationError, "Uppercase letters are not allowed here." raise ValidationError, _("Uppercase letters are not allowed here.")
def isUpperCase(field_data, all_data): def isUpperCase(field_data, all_data):
if field_data.upper() != field_data: if field_data.upper() != field_data:
raise ValidationError, "Lowercase letters are not allowed here." raise ValidationError, _("Lowercase letters are not allowed here.")
def isCommaSeparatedIntegerList(field_data, all_data): def isCommaSeparatedIntegerList(field_data, all_data):
for supposed_int in field_data.split(','): for supposed_int in field_data.split(','):
try: try:
int(supposed_int) int(supposed_int)
except ValueError: except ValueError:
raise ValidationError, "Enter only digits separated by commas." raise ValidationError, _("Enter only digits separated by commas.")
def isCommaSeparatedEmailList(field_data, all_data): def isCommaSeparatedEmailList(field_data, all_data):
""" """
@ -84,51 +85,51 @@ def isCommaSeparatedEmailList(field_data, all_data):
try: try:
isValidEmail(supposed_email.strip(), '') isValidEmail(supposed_email.strip(), '')
except ValidationError: except ValidationError:
raise ValidationError, "Enter valid e-mail addresses separated by commas." raise ValidationError, _("Enter valid e-mail addresses separated by commas.")
def isValidIPAddress4(field_data, all_data): def isValidIPAddress4(field_data, all_data):
if ip4_re.search(field_data): if ip4_re.search(field_data):
valid_parts = [el for el in field_data.split('.') if 0 <= int(el) <= 255] valid_parts = [el for el in field_data.split('.') if 0 <= int(el) <= 255]
if len(valid_parts) == 4: if len(valid_parts) == 4:
return return
raise validators.ValidationError, "Please enter a valid IP address." raise validators.ValidationError, _("Please enter a valid IP address.")
def isNotEmpty(field_data, all_data): def isNotEmpty(field_data, all_data):
if field_data.strip() == '': if field_data.strip() == '':
raise ValidationError, "Empty values are not allowed here." raise ValidationError, _("Empty values are not allowed here.")
def isOnlyDigits(field_data, all_data): def isOnlyDigits(field_data, all_data):
if not field_data.isdigit(): if not field_data.isdigit():
raise ValidationError, "Non-numeric characters aren't allowed here." raise ValidationError, _("Non-numeric characters aren't allowed here.")
def isNotOnlyDigits(field_data, all_data): def isNotOnlyDigits(field_data, all_data):
if field_data.isdigit(): if field_data.isdigit():
raise ValidationError, "This value can't be comprised solely of digits." raise ValidationError, _("This value can't be comprised solely of digits.")
def isInteger(field_data, all_data): def isInteger(field_data, all_data):
# This differs from isOnlyDigits because this accepts the negative sign # This differs from isOnlyDigits because this accepts the negative sign
if not integer_re.search(field_data): if not integer_re.search(field_data):
raise ValidationError, "Enter a whole number." raise ValidationError, _("Enter a whole number.")
def isOnlyLetters(field_data, all_data): def isOnlyLetters(field_data, all_data):
if not field_data.isalpha(): if not field_data.isalpha():
raise ValidationError, "Only alphabetical characters are allowed here." raise ValidationError, _("Only alphabetical characters are allowed here.")
def isValidANSIDate(field_data, all_data): def isValidANSIDate(field_data, all_data):
if not ansi_date_re.search(field_data): if not ansi_date_re.search(field_data):
raise ValidationError, 'Enter a valid date in YYYY-MM-DD format.' raise ValidationError, _('Enter a valid date in YYYY-MM-DD format.')
def isValidANSITime(field_data, all_data): def isValidANSITime(field_data, all_data):
if not ansi_time_re.search(field_data): if not ansi_time_re.search(field_data):
raise ValidationError, 'Enter a valid time in HH:MM format.' raise ValidationError, _('Enter a valid time in HH:MM format.')
def isValidANSIDatetime(field_data, all_data): def isValidANSIDatetime(field_data, all_data):
if not ansi_datetime_re.search(field_data): if not ansi_datetime_re.search(field_data):
raise ValidationError, 'Enter a valid date/time in YYYY-MM-DD HH:MM format.' raise ValidationError, _('Enter a valid date/time in YYYY-MM-DD HH:MM format.')
def isValidEmail(field_data, all_data): def isValidEmail(field_data, all_data):
if not email_re.search(field_data): if not email_re.search(field_data):
raise ValidationError, 'Enter a valid e-mail address.' raise ValidationError, _('Enter a valid e-mail address.')
def isValidImage(field_data, all_data): def isValidImage(field_data, all_data):
""" """
@ -140,18 +141,18 @@ def isValidImage(field_data, all_data):
try: try:
Image.open(StringIO(field_data['content'])) Image.open(StringIO(field_data['content']))
except IOError: # Python Imaging Library doesn't recognize it as an image except IOError: # Python Imaging Library doesn't recognize it as an image
raise ValidationError, "Upload a valid image. The file you uploaded was either not an image or a corrupted image." raise ValidationError, _("Upload a valid image. The file you uploaded was either not an image or a corrupted image.")
def isValidImageURL(field_data, all_data): def isValidImageURL(field_data, all_data):
uc = URLMimeTypeCheck(('image/jpeg', 'image/gif', 'image/png')) uc = URLMimeTypeCheck(('image/jpeg', 'image/gif', 'image/png'))
try: try:
uc(field_data, all_data) uc(field_data, all_data)
except URLMimeTypeCheck.InvalidContentType: except URLMimeTypeCheck.InvalidContentType:
raise ValidationError, "The URL %s does not point to a valid image." % field_data raise ValidationError, _("The URL %s does not point to a valid image.") % field_data
def isValidPhone(field_data, all_data): def isValidPhone(field_data, all_data):
if not phone_re.search(field_data): if not phone_re.search(field_data):
raise ValidationError, 'Phone numbers must be in XXX-XXX-XXXX format. "%s" is invalid.' % field_data raise ValidationError, _('Phone numbers must be in XXX-XXX-XXXX format. "%s" is invalid.') % field_data
def isValidQuicktimeVideoURL(field_data, all_data): def isValidQuicktimeVideoURL(field_data, all_data):
"Checks that the given URL is a video that can be played by QuickTime (qt, mpeg)" "Checks that the given URL is a video that can be played by QuickTime (qt, mpeg)"
@ -159,11 +160,11 @@ def isValidQuicktimeVideoURL(field_data, all_data):
try: try:
uc(field_data, all_data) uc(field_data, all_data)
except URLMimeTypeCheck.InvalidContentType: except URLMimeTypeCheck.InvalidContentType:
raise ValidationError, "The URL %s does not point to a valid QuickTime video." % field_data raise ValidationError, _("The URL %s does not point to a valid QuickTime video.") % field_data
def isValidURL(field_data, all_data): def isValidURL(field_data, all_data):
if not url_re.search(field_data): if not url_re.search(field_data):
raise ValidationError, "A valid URL is required." raise ValidationError, _("A valid URL is required.")
def isValidHTML(field_data, all_data): def isValidHTML(field_data, all_data):
import urllib, urllib2 import urllib, urllib2
@ -177,14 +178,14 @@ def isValidHTML(field_data, all_data):
return return
from xml.dom.minidom import parseString from xml.dom.minidom import parseString
error_messages = [e.firstChild.wholeText for e in parseString(u.read()).getElementsByTagName('messages')[0].getElementsByTagName('msg')] error_messages = [e.firstChild.wholeText for e in parseString(u.read()).getElementsByTagName('messages')[0].getElementsByTagName('msg')]
raise ValidationError, "Valid HTML is required. Specific errors are:\n%s" % "\n".join(error_messages) raise ValidationError, _("Valid HTML is required. Specific errors are:\n%s") % "\n".join(error_messages)
def isWellFormedXml(field_data, all_data): def isWellFormedXml(field_data, all_data):
from xml.dom.minidom import parseString from xml.dom.minidom import parseString
try: try:
parseString(field_data) parseString(field_data)
except Exception, e: # Naked except because we're not sure what will be thrown except Exception, e: # Naked except because we're not sure what will be thrown
raise ValidationError, "Badly formed XML: %s" % str(e) raise ValidationError, _("Badly formed XML: %s") % str(e)
def isWellFormedXmlFragment(field_data, all_data): def isWellFormedXmlFragment(field_data, all_data):
isWellFormedXml('<root>%s</root>' % field_data, all_data) isWellFormedXml('<root>%s</root>' % field_data, all_data)
@ -194,15 +195,15 @@ def isExistingURL(field_data, all_data):
try: try:
u = urllib2.urlopen(field_data) u = urllib2.urlopen(field_data)
except ValueError: except ValueError:
raise ValidationError, "Invalid URL: %s" % field_data raise ValidationError, _("Invalid URL: %s") % field_data
except: # urllib2.HTTPError, urllib2.URLError, httplib.InvalidURL, etc. except: # urllib2.HTTPError, urllib2.URLError, httplib.InvalidURL, etc.
raise ValidationError, "The URL %s is a broken link." % field_data raise ValidationError, _("The URL %s is a broken link.") % field_data
def isValidUSState(field_data, all_data): def isValidUSState(field_data, all_data):
"Checks that the given string is a valid two-letter U.S. state abbreviation" "Checks that the given string is a valid two-letter U.S. state abbreviation"
states = ['AA', 'AE', 'AK', 'AL', 'AP', 'AR', 'AS', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'FM', 'GA', 'GU', 'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME', 'MH', 'MI', 'MN', 'MO', 'MP', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM', 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'PR', 'PW', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VA', 'VI', 'VT', 'WA', 'WI', 'WV', 'WY'] states = ['AA', 'AE', 'AK', 'AL', 'AP', 'AR', 'AS', 'AZ', 'CA', 'CO', 'CT', 'DC', 'DE', 'FL', 'FM', 'GA', 'GU', 'HI', 'IA', 'ID', 'IL', 'IN', 'KS', 'KY', 'LA', 'MA', 'MD', 'ME', 'MH', 'MI', 'MN', 'MO', 'MP', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ', 'NM', 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'PR', 'PW', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VA', 'VI', 'VT', 'WA', 'WI', 'WV', 'WY']
if field_data.upper() not in states: if field_data.upper() not in states:
raise ValidationError, "Enter a valid U.S. state abbreviation." raise ValidationError, _("Enter a valid U.S. state abbreviation.")
def hasNoProfanities(field_data, all_data): def hasNoProfanities(field_data, all_data):
""" """
@ -217,7 +218,7 @@ def hasNoProfanities(field_data, all_data):
if words_seen: if words_seen:
from django.utils.text import get_text_list from django.utils.text import get_text_list
plural = len(words_seen) > 1 plural = len(words_seen) > 1
raise ValidationError, "Watch your mouth! The word%s %s %s not allowed here." % \ raise ValidationError, _("Watch your mouth! The word%s %s %s not allowed here.") % \
(plural and 's' or '', (plural and 's' or '',
get_text_list(['"%s%s%s"' % (i[0], '-'*(len(i)-2), i[-1]) for i in words_seen], 'and'), get_text_list(['"%s%s%s"' % (i[0], '-'*(len(i)-2), i[-1]) for i in words_seen], 'and'),
plural and 'are' or 'is') plural and 'are' or 'is')
@ -225,7 +226,7 @@ def hasNoProfanities(field_data, all_data):
class AlwaysMatchesOtherField: class AlwaysMatchesOtherField:
def __init__(self, other_field_name, error_message=None): def __init__(self, other_field_name, error_message=None):
self.other = other_field_name self.other = other_field_name
self.error_message = error_message or "This field must match the '%s' field." % self.other self.error_message = error_message or gettext_lazy("This field must match the '%s' field.") % self.other
self.always_test = True self.always_test = True
def __call__(self, field_data, all_data): def __call__(self, field_data, all_data):
@ -244,7 +245,7 @@ class ValidateIfOtherFieldEquals:
v(field_data, all_data) v(field_data, all_data)
class RequiredIfOtherFieldNotGiven: class RequiredIfOtherFieldNotGiven:
def __init__(self, other_field_name, error_message="Please enter something for at least one field."): def __init__(self, other_field_name, error_message=gettext_lazy("Please enter something for at least one field.")):
self.other, self.error_message = other_field_name, error_message self.other, self.error_message = other_field_name, error_message
self.always_test = True self.always_test = True
@ -253,7 +254,7 @@ class RequiredIfOtherFieldNotGiven:
raise ValidationError, self.error_message raise ValidationError, self.error_message
class RequiredIfOtherFieldsGiven: class RequiredIfOtherFieldsGiven:
def __init__(self, other_field_names, error_message="Please enter both fields or leave them both empty."): def __init__(self, other_field_names, error_message=gettext_lazy("Please enter both fields or leave them both empty.")):
self.other, self.error_message = other_field_names, error_message self.other, self.error_message = other_field_names, error_message
self.always_test = True self.always_test = True
@ -264,14 +265,14 @@ class RequiredIfOtherFieldsGiven:
class RequiredIfOtherFieldGiven(RequiredIfOtherFieldsGiven): class RequiredIfOtherFieldGiven(RequiredIfOtherFieldsGiven):
"Like RequiredIfOtherFieldsGiven, but takes a single field name instead of a list." "Like RequiredIfOtherFieldsGiven, but takes a single field name instead of a list."
def __init__(self, other_field_name, error_message="Please enter both fields or leave them both empty."): def __init__(self, other_field_name, error_message=gettext_lazy("Please enter both fields or leave them both empty.")):
RequiredIfOtherFieldsGiven.__init__(self, [other_field_name], error_message) RequiredIfOtherFieldsGiven.__init__(self, [other_field_name], error_message)
class RequiredIfOtherFieldEquals: class RequiredIfOtherFieldEquals:
def __init__(self, other_field, other_value, error_message=None): def __init__(self, other_field, other_value, error_message=None):
self.other_field = other_field self.other_field = other_field
self.other_value = other_value self.other_value = other_value
self.error_message = error_message or "This field must be given if %s is %s" % (other_field, other_value) self.error_message = error_message or gettext_lazy("This field must be given if %s is %s") % (other_field, other_value)
self.always_test = True self.always_test = True
def __call__(self, field_data, all_data): def __call__(self, field_data, all_data):
@ -282,7 +283,7 @@ class RequiredIfOtherFieldDoesNotEqual:
def __init__(self, other_field, other_value, error_message=None): def __init__(self, other_field, other_value, error_message=None):
self.other_field = other_field self.other_field = other_field
self.other_value = other_value self.other_value = other_value
self.error_message = error_message or "This field must be given if %s is not %s" % (other_field, other_value) self.error_message = error_message or gettext_lazy("This field must be given if %s is not %s") % (other_field, other_value)
self.always_test = True self.always_test = True
def __call__(self, field_data, all_data): def __call__(self, field_data, all_data):
@ -300,7 +301,7 @@ class IsLessThanOtherField:
class UniqueAmongstFieldsWithPrefix: class UniqueAmongstFieldsWithPrefix:
def __init__(self, field_name, prefix, error_message): def __init__(self, field_name, prefix, error_message):
self.field_name, self.prefix = field_name, prefix self.field_name, self.prefix = field_name, prefix
self.error_message = error_message or "Duplicate values are not allowed." self.error_message = error_message or gettext_lazy("Duplicate values are not allowed.")
def __call__(self, field_data, all_data): def __call__(self, field_data, all_data):
for field_name, value in all_data.items(): for field_name, value in all_data.items():
@ -323,7 +324,7 @@ class IsAPowerOf:
from math import log from math import log
val = log(int(field_data)) / log(self.power_of) val = log(int(field_data)) / log(self.power_of)
if val != int(val): if val != int(val):
raise ValidationError, "This value must be a power of %s." % self.power_of raise ValidationError, _("This value must be a power of %s.") % self.power_of
class IsValidFloat: class IsValidFloat:
def __init__(self, max_digits, decimal_places): def __init__(self, max_digits, decimal_places):
@ -334,12 +335,12 @@ class IsValidFloat:
try: try:
float(data) float(data)
except ValueError: except ValueError:
raise ValidationError, "Please enter a valid decimal number." raise ValidationError, _("Please enter a valid decimal number.")
if len(data) > (self.max_digits + 1): if len(data) > (self.max_digits + 1):
raise ValidationError, "Please enter a valid decimal number with at most %s total digit%s." % \ raise ValidationError, _("Please enter a valid decimal number with at most %s total digit%s.") % \
(self.max_digits, self.max_digits > 1 and 's' or '') (self.max_digits, self.max_digits > 1 and 's' or '')
if '.' in data and len(data.split('.')[1]) > self.decimal_places: if '.' in data and len(data.split('.')[1]) > self.decimal_places:
raise ValidationError, "Please enter a valid decimal number with at most %s decimal place%s." % \ raise ValidationError, _("Please enter a valid decimal number with at most %s decimal place%s.") % \
(self.decimal_places, self.decimal_places > 1 and 's' or '') (self.decimal_places, self.decimal_places > 1 and 's' or '')
class HasAllowableSize: class HasAllowableSize:
@ -349,8 +350,8 @@ class HasAllowableSize:
""" """
def __init__(self, min_size=None, max_size=None, min_error_message=None, max_error_message=None): def __init__(self, min_size=None, max_size=None, min_error_message=None, max_error_message=None):
self.min_size, self.max_size = min_size, max_size self.min_size, self.max_size = min_size, max_size
self.min_error_message = min_error_message or "Make sure your uploaded file is at least %s bytes big." % min_size self.min_error_message = min_error_message or gettext_lazy("Make sure your uploaded file is at least %s bytes big.") % min_size
self.max_error_message = max_error_message or "Make sure your uploaded file is at most %s bytes big." % min_size self.max_error_message = max_error_message or gettext_lazy("Make sure your uploaded file is at most %s bytes big.") % min_size
def __call__(self, field_data, all_data): def __call__(self, field_data, all_data):
if self.min_size is not None and len(field_data['content']) < self.min_size: if self.min_size is not None and len(field_data['content']) < self.min_size:
@ -363,7 +364,7 @@ class MatchesRegularExpression:
Checks that the field matches the given regular-expression. The regex Checks that the field matches the given regular-expression. The regex
should be in string format, not already compiled. should be in string format, not already compiled.
""" """
def __init__(self, regexp, error_message="The format for this field is wrong."): def __init__(self, regexp, error_message=gettext_lazy("The format for this field is wrong.")):
self.regexp = re.compile(regexp) self.regexp = re.compile(regexp)
self.error_message = error_message self.error_message = error_message
@ -378,7 +379,7 @@ class AnyValidator:
as a validation error. The message is rather unspecific, so it's best to as a validation error. The message is rather unspecific, so it's best to
specify one on instantiation. specify one on instantiation.
""" """
def __init__(self, validator_list=[], error_message="This field is invalid."): def __init__(self, validator_list=[], error_message=gettext_lazy("This field is invalid.")):
self.validator_list = validator_list self.validator_list = validator_list
self.error_message = error_message self.error_message = error_message
for v in validator_list: for v in validator_list:
@ -413,10 +414,10 @@ class URLMimeTypeCheck:
try: try:
info = urllib2.urlopen(field_data).info() info = urllib2.urlopen(field_data).info()
except (urllib2.HTTPError, urllib2.URLError): except (urllib2.HTTPError, urllib2.URLError):
raise URLMimeTypeCheck.CouldNotRetrieve, "Could not retrieve anything from %s." % field_data raise URLMimeTypeCheck.CouldNotRetrieve, _("Could not retrieve anything from %s.") % field_data
content_type = info['content-type'] content_type = info['content-type']
if content_type not in self.mime_type_list: if content_type not in self.mime_type_list:
raise URLMimeTypeCheck.InvalidContentType, "The URL %s returned the invalid Content-Type header '%s'." % (field_data, content_type) raise URLMimeTypeCheck.InvalidContentType, _("The URL %s returned the invalid Content-Type header '%s'.") % (field_data, content_type)
class RelaxNGCompact: class RelaxNGCompact:
"Validate against a Relax NG compact schema" "Validate against a Relax NG compact schema"
@ -448,30 +449,30 @@ class RelaxNGCompact:
# Scrape the Jing error messages to reword them more nicely. # Scrape the Jing error messages to reword them more nicely.
m = re.search(r'Expected "(.*?)" to terminate element starting on line (\d+)', message) m = re.search(r'Expected "(.*?)" to terminate element starting on line (\d+)', message)
if m: if m:
display_errors.append('Please close the unclosed %s tag from line %s. (Line starts with "%s".)' % \ display_errors.append(_('Please close the unclosed %s tag from line %s. (Line starts with "%s".)') % \
(m.group(1).replace('/', ''), m.group(2), lines[int(m.group(2)) - 1][:30])) (m.group(1).replace('/', ''), m.group(2), lines[int(m.group(2)) - 1][:30]))
continue continue
if message.strip() == 'text not allowed here': if message.strip() == 'text not allowed here':
display_errors.append('Some text starting on line %s is not allowed in that context. (Line starts with "%s".)' % \ display_errors.append(_('Some text starting on line %s is not allowed in that context. (Line starts with "%s".)') % \
(line, lines[int(line) - 1][:30])) (line, lines[int(line) - 1][:30]))
continue continue
m = re.search(r'\s*attribute "(.*?)" not allowed at this point; ignored', message) m = re.search(r'\s*attribute "(.*?)" not allowed at this point; ignored', message)
if m: if m:
display_errors.append('"%s" on line %s is an invalid attribute. (Line starts with "%s".)' % \ display_errors.append(_('"%s" on line %s is an invalid attribute. (Line starts with "%s".)') % \
(m.group(1), line, lines[int(line) - 1][:30])) (m.group(1), line, lines[int(line) - 1][:30]))
continue continue
m = re.search(r'\s*unknown element "(.*?)"', message) m = re.search(r'\s*unknown element "(.*?)"', message)
if m: if m:
display_errors.append('"<%s>" on line %s is an invalid tag. (Line starts with "%s".)' % \ display_errors.append(_('"<%s>" on line %s is an invalid tag. (Line starts with "%s".)') % \
(m.group(1), line, lines[int(line) - 1][:30])) (m.group(1), line, lines[int(line) - 1][:30]))
continue continue
if message.strip() == 'required attributes missing': if message.strip() == 'required attributes missing':
display_errors.append('A tag on line %s is missing one or more required attributes. (Line starts with "%s".)' % \ display_errors.append(_('A tag on line %s is missing one or more required attributes. (Line starts with "%s".)') % \
(line, lines[int(line) - 1][:30])) (line, lines[int(line) - 1][:30]))
continue continue
m = re.search(r'\s*bad value for attribute "(.*?)"', message) m = re.search(r'\s*bad value for attribute "(.*?)"', message)
if m: if m:
display_errors.append('The "%s" attribute on line %s has an invalid value. (Line starts with "%s".)' % \ display_errors.append(_('The "%s" attribute on line %s has an invalid value. (Line starts with "%s".)') % \
(m.group(1), line, lines[int(line) - 1][:30])) (m.group(1), line, lines[int(line) - 1][:30]))
continue continue
# Failing all those checks, use the default error message. # Failing all those checks, use the default error message.