Author: gh Date: 2006-12-01 11:19:05 -0700 (Fri, 01 Dec 2006) New Revision: 2106
Added: FormEncode/trunk/docs/i18n.txt FormEncode/trunk/formencode/i18n/ FormEncode/trunk/formencode/i18n/big5/ FormEncode/trunk/formencode/i18n/big5/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/de/ FormEncode/trunk/formencode/i18n/de/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/es/ FormEncode/trunk/formencode/i18n/es/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/pt_BR/ FormEncode/trunk/formencode/i18n/pt_BR/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/ru/ FormEncode/trunk/formencode/i18n/ru/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/sk/ FormEncode/trunk/formencode/i18n/sk/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/sl/ FormEncode/trunk/formencode/i18n/sl/LC_MESSAGES/ FormEncode/trunk/tests/test_i18n.py Removed: FormEncode/trunk/formencode/i18n/big5/ FormEncode/trunk/formencode/i18n/big5/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/de/ FormEncode/trunk/formencode/i18n/de/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/es/ FormEncode/trunk/formencode/i18n/es/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/pt_BR/ FormEncode/trunk/formencode/i18n/pt_BR/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/ru/ FormEncode/trunk/formencode/i18n/ru/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/sk/ FormEncode/trunk/formencode/i18n/sk/LC_MESSAGES/ FormEncode/trunk/formencode/i18n/sl/ FormEncode/trunk/formencode/i18n/sl/LC_MESSAGES/ Modified: FormEncode/trunk/docs/news.txt FormEncode/trunk/formencode/api.py FormEncode/trunk/formencode/i18n/FormEncode.pot FormEncode/trunk/formencode/i18n/big5/LC_MESSAGES/FormEncode.mo FormEncode/trunk/formencode/i18n/big5/LC_MESSAGES/FormEncode.po FormEncode/trunk/formencode/i18n/de/LC_MESSAGES/FormEncode.mo FormEncode/trunk/formencode/i18n/de/LC_MESSAGES/FormEncode.po FormEncode/trunk/formencode/i18n/es/LC_MESSAGES/FormEncode.mo FormEncode/trunk/formencode/i18n/es/LC_MESSAGES/FormEncode.po FormEncode/trunk/formencode/i18n/pt_BR/LC_MESSAGES/FormEncode.mo FormEncode/trunk/formencode/i18n/pt_BR/LC_MESSAGES/FormEncode.po FormEncode/trunk/formencode/i18n/ru/LC_MESSAGES/FormEncode.mo FormEncode/trunk/formencode/i18n/ru/LC_MESSAGES/FormEncode.po FormEncode/trunk/formencode/i18n/sk/LC_MESSAGES/FormEncode.mo FormEncode/trunk/formencode/i18n/sk/LC_MESSAGES/FormEncode.po FormEncode/trunk/formencode/i18n/sl/LC_MESSAGES/FormEncode.mo FormEncode/trunk/formencode/i18n/sl/LC_MESSAGES/FormEncode.po FormEncode/trunk/formencode/schema.py FormEncode/trunk/formencode/validators.py FormEncode/trunk/tests/test_cc_expires.py FormEncode/trunk/tests/test_cc_validator.py FormEncode/trunk/tests/test_schema.py FormEncode/trunk/tests/test_sqlschema.py Log: merge gettext-enabled branche r1947 into trunk 2105 Added: FormEncode/trunk/docs/i18n.txt =================================================================== --- FormEncode/trunk/docs/i18n.txt (rev 0) +++ FormEncode/trunk/docs/i18n.txt 2006-12-01 18:19:05 UTC (rev 2106) @@ -0,0 +1,34 @@ +FormEncode Internationalization (gettext) ++++++++++++++++++++++++++++++++++++++++++ + +There are different translation options available: + +Domain "FormEncode" +^^^^^^^^^^^^^^^^^^^ + +for standalone use of FormEncode. The language to use is determined out of the local system (see gettext documentation http://docs.python.org/lib/node733.html). Optionally you can also set the language or the domain explicitly with the function. + +example: +formencode.api.set_stdtranslation(domain="FormEncode", languages=["de"]) + +The mo files are located in the i18n subdirectory of the formencode installation. + +state._ +^^^^^^^ +A custom _ gettext function provided as attribute of the state object. + +__builtins__._ +^^^^^^^^^^^^^^ +A custom _ gettext function provided in the builtin namespace. +This function is only used when: + +Validator.use_builtin_gettext == True (True is default) + + +Without translation +^^^^^^^^^^^^^^^^^^^ + +If no translation mechanism is found a fallback returns the plain string. + + +Gregor Horvath, 2006 [EMAIL PROTECTED] Modified: FormEncode/trunk/docs/news.txt =================================================================== --- FormEncode/trunk/docs/news.txt 2006-12-01 07:04:20 UTC (rev 2105) +++ FormEncode/trunk/docs/news.txt 2006-12-01 18:19:05 UTC (rev 2106) @@ -6,6 +6,8 @@ svn trunk --------- +* gettext-enabled branch merged in + * Fixes `#1457145: Fails on URLs with port numbers <http://sourceforge.net/tracker/index.php?func=detail&aid=1457145&group_id=91231&atid=596416>`_ Modified: FormEncode/trunk/formencode/api.py =================================================================== --- FormEncode/trunk/formencode/api.py 2006-12-01 07:04:20 UTC (rev 2105) +++ FormEncode/trunk/formencode/api.py 2006-12-01 18:19:05 UTC (rev 2106) @@ -5,10 +5,34 @@ import declarative import textwrap import re +import os +from pkg_resources import resource_filename __all__ = ['NoDefault', 'Invalid', 'Validator', 'Identity', 'FancyValidator', 'is_validator'] +import gettext + +def get_localedir(): + return resource_filename(__name__, "/i18n") + +def set_stdtranslation(domain="FormEncode", languages=None, \ + localedir = get_localedir()): + + t = gettext.translation(domain=domain, \ + languages=languages, \ + localedir=localedir, fallback=True) + global _stdtrans + _stdtrans = t.ugettext + +set_stdtranslation() + +def _(s): return s # dummy i18n translation function, nothing is translated here. + # Instead this is actually done in api.Validator.message. + # The surrounding _("string") of the strings is only for extracting + # the strings automatically + # if you run pygettext with this source comment this function out temporarly + class NoDefault: pass @@ -117,7 +141,10 @@ if_missing = NoDefault repeating = False compound = False - + gettextargs = {} + use_builtins_gettext = True #In case you dont want to use __builtins__._ + #altough it may be definied, set this to False + __singletonmethods__ = ('to_python', 'from_python') def __classinit__(cls, new_attrs): @@ -141,8 +168,27 @@ return value def message(self, msgName, state, **kw): + #determine translation function try: - return self._messages[msgName] % kw + trans = state._ + except AttributeError: + try: + if self.use_builtins_gettext: + import __builtin__ + trans = __builtin__._ + + else: + trans = _stdtrans + + except AttributeError: + trans = _stdtrans + + if not callable(trans): + trans = _stdtrans + + + try: + return trans(self._messages[msgName], **self.gettextargs) % kw except KeyError, e: raise KeyError( "Key not found (%s) for %r=%r %% %r (from: %s)" @@ -294,9 +340,9 @@ strip = False messages = { - 'empty': "Please enter a value", - 'badType': "The input must be a string (not a %(type)s: %(value)r)", - 'noneType': "The input must be a string (not None)", + 'empty': _("Please enter a value"), + 'badType': _("The input must be a string (not a %(type)s: %(value)r)"), + 'noneType': _("The input must be a string (not None)"), } def to_python(self, value, state=None): Copied: FormEncode/trunk/formencode/i18n (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n) Modified: FormEncode/trunk/formencode/i18n/FormEncode.pot =================================================================== Copied: FormEncode/trunk/formencode/i18n/big5 (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/big5) Copied: FormEncode/trunk/formencode/i18n/big5/LC_MESSAGES (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/big5/LC_MESSAGES) Modified: FormEncode/trunk/formencode/i18n/big5/LC_MESSAGES/FormEncode.mo =================================================================== (Binary files differ) Modified: FormEncode/trunk/formencode/i18n/big5/LC_MESSAGES/FormEncode.po =================================================================== Copied: FormEncode/trunk/formencode/i18n/de (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/de) Copied: FormEncode/trunk/formencode/i18n/de/LC_MESSAGES (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/de/LC_MESSAGES) Modified: FormEncode/trunk/formencode/i18n/de/LC_MESSAGES/FormEncode.mo =================================================================== (Binary files differ) Modified: FormEncode/trunk/formencode/i18n/de/LC_MESSAGES/FormEncode.po =================================================================== Copied: FormEncode/trunk/formencode/i18n/es (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/es) Copied: FormEncode/trunk/formencode/i18n/es/LC_MESSAGES (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/es/LC_MESSAGES) Modified: FormEncode/trunk/formencode/i18n/es/LC_MESSAGES/FormEncode.mo =================================================================== (Binary files differ) Modified: FormEncode/trunk/formencode/i18n/es/LC_MESSAGES/FormEncode.po =================================================================== Copied: FormEncode/trunk/formencode/i18n/pt_BR (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/pt_BR) Copied: FormEncode/trunk/formencode/i18n/pt_BR/LC_MESSAGES (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/pt_BR/LC_MESSAGES) Modified: FormEncode/trunk/formencode/i18n/pt_BR/LC_MESSAGES/FormEncode.mo =================================================================== (Binary files differ) Modified: FormEncode/trunk/formencode/i18n/pt_BR/LC_MESSAGES/FormEncode.po =================================================================== Copied: FormEncode/trunk/formencode/i18n/ru (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/ru) Copied: FormEncode/trunk/formencode/i18n/ru/LC_MESSAGES (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/ru/LC_MESSAGES) Modified: FormEncode/trunk/formencode/i18n/ru/LC_MESSAGES/FormEncode.mo =================================================================== (Binary files differ) Modified: FormEncode/trunk/formencode/i18n/ru/LC_MESSAGES/FormEncode.po =================================================================== Copied: FormEncode/trunk/formencode/i18n/sk (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/sk) Copied: FormEncode/trunk/formencode/i18n/sk/LC_MESSAGES (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/sk/LC_MESSAGES) Modified: FormEncode/trunk/formencode/i18n/sk/LC_MESSAGES/FormEncode.mo =================================================================== (Binary files differ) Modified: FormEncode/trunk/formencode/i18n/sk/LC_MESSAGES/FormEncode.po =================================================================== Copied: FormEncode/trunk/formencode/i18n/sl (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/sl) Copied: FormEncode/trunk/formencode/i18n/sl/LC_MESSAGES (from rev 2105, FormEncode/branches/gettext-enabled/formencode/i18n/sl/LC_MESSAGES) Modified: FormEncode/trunk/formencode/i18n/sl/LC_MESSAGES/FormEncode.mo =================================================================== (Binary files differ) Modified: FormEncode/trunk/formencode/i18n/sl/LC_MESSAGES/FormEncode.po =================================================================== Modified: FormEncode/trunk/formencode/schema.py =================================================================== --- FormEncode/trunk/formencode/schema.py 2006-12-01 07:04:20 UTC (rev 2105) +++ FormEncode/trunk/formencode/schema.py 2006-12-01 18:19:05 UTC (rev 2106) @@ -291,7 +291,7 @@ if isinstance(v, Exception): try: return str(v) - except UnicodeDecodeError: + except (UnicodeDecodeError, UnicodeEncodeError): # There doesn't seem to be a better way to get a str() # version if possible, and unicode() if necessary, because # testing for the presence of a __unicode__ method isn't Modified: FormEncode/trunk/formencode/validators.py =================================================================== --- FormEncode/trunk/formencode/validators.py 2006-12-01 07:04:20 UTC (rev 2105) +++ FormEncode/trunk/formencode/validators.py 2006-12-01 18:19:05 UTC (rev 2106) @@ -44,6 +44,12 @@ True, False = (1==1), (0==1) +def _(s): return s # dummy translation function, nothing is translated here. + # Instead this is actually done in api.message. + # The surrounding _("string") of the strings is only for extracting + # the strings automatically + # if you run pygettext with this source comment this function out temporarly + ############################################################ ## Utility methods ############################################################ @@ -151,10 +157,10 @@ type = None messages = { - 'subclass': "%(object)r is not a subclass of %(subclass)s", - 'inSubclass': "%(object)r is not a subclass of one of the types %(subclassList)s", - 'inType': "%(object)r must be one of the types %(typeList)s", - 'type': "%(object)r must be of the type %(type)s", + 'subclass': _("%(object)r is not a subclass of %(subclass)s"), + 'inSubclass': _("%(object)r is not a subclass of one of the types %(subclassList)s"), + 'inType': _("%(object)r must be one of the types %(typeList)s"), + 'type': _("%(object)r must be of the type %(type)s"), } def __init__(self, *args, **kw): @@ -335,8 +341,8 @@ __unpackargs__ = ('maxLength',) messages = { - 'tooLong': "Enter a value less than %(maxLength)i characters long", - 'invalid': "Invalid value (value with length expected)", + 'tooLong': _("Enter a value less than %(maxLength)i characters long"), + 'invalid': _("Invalid value (value with length expected)"), } def validate_python(self, value, state): @@ -389,8 +395,8 @@ __unpackargs__ = ('minLength',) messages = { - 'tooShort': "Enter a value at least %(minLength)i characters long", - 'invalid': "Invalid value (value with length expected)", + 'tooShort': _("Enter a value at least %(minLength)i characters long"), + 'invalid': _("Invalid value (value with length expected)"), } def validate_python(self, value, state): @@ -424,7 +430,7 @@ not_empty = True messages = { - 'empty': "Please enter a value", + 'empty': _("Please enter a value"), } def validate_python(self, value, state): @@ -449,7 +455,7 @@ """ messages = { - 'notEmpty': "You cannot enter a value here", + 'notEmpty': _("You cannot enter a value here"), } def validate_python(self, value, state): @@ -500,7 +506,7 @@ __unpackargs__ = ('regex',) messages = { - 'invalid': "The input is not valid", + 'invalid': _("The input is not valid"), } def __init__(self, *args, **kw): @@ -555,7 +561,7 @@ regex = r"^[a-zA-Z_\-0-9]*$" messages = { - 'invalid': 'Enter only letters, numbers, or _ (underscore)', + 'invalid': _('Enter only letters, numbers, or _ (underscore)'), } class OneOf(FancyValidator): @@ -594,8 +600,8 @@ __unpackargs__ = ('list',) messages = { - 'invalid': "Invalid value", - 'notIn': "Value must be one of: %(items)s (not %(value)r)", + 'invalid': _("Invalid value"), + 'notIn': _("Value must be one of: %(items)s (not %(value)r)"), } def validate_python(self, value, state): @@ -658,10 +664,10 @@ __unpackargs__ = ('dict',) messages = { - 'keyNotFound': "Choose something", - 'chooseKey': "Enter a value from: %(items)s", - 'valueNotFound': "That value is not known", - 'chooseValue': "Nothing in my dictionary goes by the value %(value)s. Choose one of: %(items)s", + 'keyNotFound': _("Choose something"), + 'chooseKey': _("Enter a value from: %(items)s"), + 'valueNotFound': _("That value is not known"), + 'chooseValue': _("Nothing in my dictionary goes by the value %(value)s. Choose one of: %(items)s"), } def _to_python(self, value, state): @@ -722,9 +728,9 @@ __unpackargs__ = ('list',) messages = { - 'integer': "Must be an integer index", - 'outOfRange': "Index out of range", - 'notFound': "Item %(value)s was not found in the list", + 'integer': _("Must be an integer index"), + 'outOfRange': _("Index out of range"), + 'notFound': _("Item %(value)s was not found in the list"), } def _to_python(self, value, state): @@ -799,11 +805,11 @@ datetime_module = None messages = { - 'after': "Date must be after %(date)s", - 'before': "Date must be before %(date)s", + 'after': _("Date must be after %(date)s"), + 'before': _("Date must be before %(date)s"), # Double %'s, because this will be substituted twice: - 'date_format': "%%A, %%d %%B %%Y", - 'future': "The date must be sometime in the future", + 'date_format': _("%%A, %%d %%B %%Y"), + 'future': _("The date must be sometime in the future"), } def validate_python(self, value, state): @@ -903,7 +909,7 @@ """ messages = { - 'integer': "Please enter an integer value", + 'integer': _("Please enter an integer value"), } def _to_python(self, value, state): @@ -935,7 +941,7 @@ """ messages = { - 'number': "Please enter a number", + 'number': _("Please enter a number"), } def _to_python(self, value, state): @@ -988,8 +994,8 @@ not_empty = None messages = { - 'tooLong': "Enter a value less than %(max)i characters long", - 'tooShort': "Enter a value %(min)i characters long or more", + 'tooLong': _("Enter a value less than %(max)i characters long"), + 'tooShort': _("Enter a value %(min)i characters long or more"), } def __initargs__(self, new_attrs): @@ -1040,7 +1046,7 @@ """ encoding = 'utf-8' messages = { - 'badEncoding' : "Invalid data or incorrect encoding", + 'badEncoding' : _("Invalid data or incorrect encoding"), } def __init__(self, inputEncoding=None, outputEncoding=None, **kw): @@ -1170,12 +1176,12 @@ domainRE = re.compile(r"^[a-z0-9][a-z0-9\.\-_]*\.[a-z]+$", re.I) messages = { - 'empty': 'Please enter an email address', - 'noAt': 'An email address must contain a single @', - 'badUsername': 'The username portion of the email address is invalid (the portion before the @: %(username)s)', - 'socketError': 'An error occured when trying to connect to the server: %(error)s', - 'badDomain': 'The domain portion of the email address is invalid (the portion after the @: %(domain)s)', - 'domainDoesNotExist': 'The domain of the email address does not exist (the portion after the @: %(domain)s)', + 'empty': _('Please enter an email address'), + 'noAt': _('An email address must contain a single @'), + 'badUsername': _('The username portion of the email address is invalid (the portion before the @: %(username)s)'), + 'socketError': _('An error occured when trying to connect to the server: %(error)s'), + 'badDomain': _('The domain portion of the email address is invalid (the portion after the @: %(domain)s)'), + 'domainDoesNotExist': _('The domain of the email address does not exist (the portion after the @: %(domain)s)'), } def __init__(self, *args, **kw): @@ -1283,12 +1289,12 @@ scheme_re = re.compile(r'^[a-zA-Z]+:') messages = { - 'noScheme': 'You must start your URL with http://, https://, etc', - 'badURL': 'That is not a valid URL', - 'httpError': 'An error occurred when trying to access the URL: %(error)s', - 'socketError': 'An error occured when trying to connect to the server: %(error)s', - 'notFound': 'The server responded that the page could not be found', - 'status': 'The server responded with a bad status code (%(status)s)', + 'noScheme': _('You must start your URL with http://, https://, etc'), + 'badURL': _('That is not a valid URL'), + 'httpError': _('An error occurred when trying to access the URL: %(error)s'), + 'socketError': _('An error occured when trying to connect to the server: %(error)s'), + 'notFound': _('The server responded that the page could not be found'), + 'status': _('The server responded with a bad status code (%(status)s)'), } def _to_python(self, value, state): @@ -1391,9 +1397,9 @@ __unpackargs__ = ('extra_states',) messages = { - 'empty': 'Please enter a state code', - 'wrongLength': 'Please enter a state code with TWO letters', - 'invalid': 'That is not a valid state code', + 'empty': _('Please enter a state code'), + 'wrongLength': _('Please enter a state code with TWO letters'), + 'invalid': _('That is not a valid state code'), } def validate_python(self, value, state): @@ -1444,7 +1450,7 @@ _phoneRE = re.compile(r'^\s*(?:1-)?(\d\d\d)[\- \.]?(\d\d\d)[\- \.]?(\d\d\d\d)(?:\s*ext\.?\s*(\d+))?\s*$', re.I) messages = { - 'phoneFormat': 'Please enter a number, with area code, in the form ###-###-####, optionally with "ext.####"', + 'phoneFormat': _('Please enter a number, with area code, in the form ###-###-####, optionally with "ext.####"'), } def _to_python(self, value, state): @@ -1608,15 +1614,15 @@ 9: 30, 10: 31, 11: 30, 12: 31} messages = { - 'badFormat': 'Please enter the date in the form %(format)s', - 'monthRange': 'Please enter a month from 1 to 12', - 'invalidDay': 'Please enter a valid day', - 'dayRange': 'That month only has %(days)i days', - 'invalidDate': 'That is not a valid day (%(exception)s)', - 'unknownMonthName': "Unknown month name: %(month)s", - 'invalidYear': 'Please enter a number for the year', - 'fourDigitYear': 'Please enter a four-digit year', - 'wrongFormat': 'Please enter the date in the form %(format)s', + 'badFormat': _('Please enter the date in the form %(format)s'), + 'monthRange': _('Please enter a month from 1 to 12'), + 'invalidDay': _('Please enter a valid day'), + 'dayRange': _('That month only has %(days)i days'), + 'invalidDate': _('That is not a valid day (%(exception)s)'), + 'unknownMonthName': _("Unknown month name: %(month)s"), + 'invalidYear': _('Please enter a number for the year'), + 'fourDigitYear': _('Please enter a four-digit year'), + 'wrongFormat': _('Please enter the date in the form %(format)s'), } def _to_python(self, value, state): @@ -1794,15 +1800,15 @@ datetime_module = None messages = { - 'noAMPM': 'You must indicate AM or PM', - 'tooManyColon': 'There are too many :\'s', - 'noSeconds': 'You may not enter seconds', - 'secondsRequired': 'You must enter seconds', - 'minutesRequired': 'You must enter minutes (after a :)', - 'badNumber': 'The %(part)s value you gave is not a number: %(number)r', - 'badHour': 'You must enter an hour in the range %(range)s', - 'badMinute': 'You must enter a minute in the range 0-59', - 'badSecond': 'You must enter a second in the range 0-59', + 'noAMPM': _('You must indicate AM or PM'), + 'tooManyColon': _('There are too many :\'s'), + 'noSeconds': _('You may not enter seconds'), + 'secondsRequired': _('You must enter seconds'), + 'minutesRequired': _('You must enter minutes (after a :)'), + 'badNumber': _('The %(part)s value you gave is not a number: %(number)r'), + 'badHour': _('You must enter an hour in the range %(range)s'), + 'badMinute': _('You must enter a minute in the range 0-59'), + 'badSecond': _('You must enter a second in the range 0-59'), } def _to_python(self, value, state): @@ -1956,7 +1962,7 @@ strip = True messages = { - 'invalid': 'Please enter a zip code (5 digits)', + 'invalid': _('Please enter a zip code (5 digits)'), } class StripField(FancyValidator): @@ -1980,7 +1986,7 @@ __unpackargs__ = ('name',) messages = { - 'missing': 'The name %(name)s is missing', + 'missing': _('The name %(name)s is missing'), } def _to_python(self, valueDict, state): @@ -2021,7 +2027,7 @@ true_values = ['true', 't', 'yes', 'y', 'on', '1'] false_values = ['false', 'f', 'no', 'n', 'off', '0'] - messages = { "string" : "Value should be %(true)r or %(false)r" } + messages = { "string" : _("Value should be %(true)r or %(false)r") } def _to_python(self, value, state): if isinstance(value, (str, unicode)): @@ -2056,8 +2062,8 @@ """ messages = { - 'malformed': 'Value does not contain a signature', - 'badsig': 'Signature is not correct', + 'malformed': _('Value does not contain a signature'), + 'badsig': _('Signature is not correct'), } secret = None @@ -2179,8 +2185,8 @@ __unpackargs__ = ('*', 'field_names') messages = { - 'invalid': "Fields do not match (should be %(match)s)", - 'invalidNoMatch': "Fields do not match", + 'invalid': _("Fields do not match (should be %(match)s)"), + 'invalidNoMatch': _("Fields do not match"), } def validate_partial(self, field_dict, state): @@ -2242,9 +2248,9 @@ __unpackargs__ = ('cc_type_field', 'cc_number_field') messages = { - 'notANumber': "Please enter only the number, no other characters", - 'badLength': "You did not enter a valid number of digits", - 'invalidNumber': "That number is not valid", + 'notANumber': _("Please enter only the number, no other characters"), + 'badLength': _("You did not enter a valid number of digits"), + 'invalidNumber': _("That number is not valid"), } def validate_partial(self, field_dict, state): @@ -2359,8 +2365,8 @@ datetime_module = None messages = { - 'notANumber': "Please enter numbers only for month and year", - 'invalidNumber': "Invalid Expiration Date", + 'notANumber': _("Please enter numbers only for month and year"), + 'invalidNumber': _("Invalid Expiration Date"), } def validate_partial(self, field_dict, state): @@ -2429,8 +2435,8 @@ __unpackargs__ = ('cc_type_field', 'cc_code_field') messages = { - 'notANumber': "Please enter numbers only for credit card security code", - 'badLength': "Invalid credit card security code length", + 'notANumber': _("Please enter numbers only for credit card security code"), + 'badLength': _("Invalid credit card security code length"), } def validate_partial(self, field_dict, state): Modified: FormEncode/trunk/tests/test_cc_expires.py =================================================================== --- FormEncode/trunk/tests/test_cc_expires.py 2006-12-01 07:04:20 UTC (rev 2105) +++ FormEncode/trunk/tests/test_cc_expires.py 2006-12-01 18:19:05 UTC (rev 2106) @@ -9,11 +9,11 @@ except Invalid, e: return e.unpack_errors()['ccExpiresMonth'] -messages = CreditCardExpires._messages +messages = ed.message def test_ed(): assert validate('11', '2250') is None - assert validate('11', 'test') == messages['notANumber'] - assert validate('test', '2250') == messages['notANumber'] - assert validate('10', '2005') == messages['invalidNumber'] - assert validate('10', '05') == messages['invalidNumber'] + assert validate('11', 'test') == messages('notANumber', None) + assert validate('test', '2250') == messages('notANumber', None) + assert validate('10', '2005') == messages('invalidNumber', None) + assert validate('10', '05') == messages('invalidNumber', None) Modified: FormEncode/trunk/tests/test_cc_validator.py =================================================================== --- FormEncode/trunk/tests/test_cc_validator.py 2006-12-01 07:04:20 UTC (rev 2105) +++ FormEncode/trunk/tests/test_cc_validator.py 2006-12-01 18:19:05 UTC (rev 2106) @@ -9,11 +9,11 @@ except Invalid, e: return e.unpack_errors()['ccNumber'] -messages = CreditCardValidator._messages +messages = cc.message def test_cc(): assert validate('visa', '4'+('1'*15)) is None - assert validate('visa', '5'+('1'*12)) == messages['invalidNumber'] - assert validate('visa', '4'+('1'*11) + '2') == messages['invalidNumber'] - assert validate('visa', 'test') == messages['notANumber'] - assert validate('visa', '4'+('1'*10)) == messages['badLength'] + assert validate('visa', '5'+('1'*12)) == messages('invalidNumber', None) + assert validate('visa', '4'+('1'*11) + '2') == messages('invalidNumber', None) + assert validate('visa', 'test') == messages('notANumber', None) + assert validate('visa', '4'+('1'*10)) == messages('badLength', None) Added: FormEncode/trunk/tests/test_i18n.py =================================================================== --- FormEncode/trunk/tests/test_i18n.py (rev 0) +++ FormEncode/trunk/tests/test_i18n.py 2006-12-01 18:19:05 UTC (rev 2106) @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +import formencode + +import os + +ne = formencode.validators.NotEmpty() + +def _test_builtins(func): + def dummy(s): + return "builtins dummy" + import __builtin__ + __builtin__._ = dummy + + try: + ne.to_python("") + except formencode.api.Invalid, e: + func(e) + + del __builtin__._ + +def test_builtins(): + def withbuiltins(e): + assert str(e) == "builtins dummy" + + _test_builtins(withbuiltins) + + +def test_bultins_disabled(): + def withoutbuiltins(e): + assert str(e) <> "builtins dummy" + + ne.use_builtins_gettext = False + _test_builtins(withoutbuiltins) + + + +def test_state(): + class st(object): + def _(self, s): + return "state dummy" + + try: + ne.to_python("", state=st()) + except formencode.api.Invalid, e: + assert str(e) == "state dummy" + + +def _test_lang(language, notemptytext): + + formencode.api.set_stdtranslation(languages=[language]) + + try: + ne.to_python("") + except formencode.api.Invalid, e: + assert unicode(e) == notemptytext + + formencode.api.set_stdtranslation() #set back to defaults + + +def test_de(): + _test_lang("de", u"Bitte einen Wert eingeben") + +def test_es(): + _test_lang("es", u"Por favor introduzca un valor") + +def test_pt_BR(): + _test_lang("pt_BR", u"Por favor digite um valor") + +def test_big5(): + _test_lang("big5", u"請輸入一個值") + +def test_sk(): + _test_lang("sk",u"Zadajte hodnotu, prosím") + +def test_ru(): + _test_lang("ru",u"Необходимо ввести значение") + + +def test_sl(): + _test_lang("sl",u"Prosim, izpolnite polje") + Modified: FormEncode/trunk/tests/test_schema.py =================================================================== --- FormEncode/trunk/tests/test_schema.py 2006-12-01 07:04:20 UTC (rev 2105) +++ FormEncode/trunk/tests/test_schema.py 2006-12-01 18:19:05 UTC (rev 2106) @@ -4,6 +4,23 @@ from formencode.variabledecode import NestedVariables import cgi + +def setup_module(module): + """Disable i18n translation + """ + def notranslation(s): return s + import __builtin__ + __builtin__._ = notranslation + + + +def teardown_module(module): + """Remove translation function + """ + import __builtin__ + del __builtin__._ + + def d(**kw): return kw def cgi_parse(qs): @@ -114,9 +131,11 @@ text="The input field 'whatever' was not expected.") def test_this(): + for case in all_cases: yield case.test + def test_merge(): assert (merge_dicts(dict(a='a'), dict(b='b')) == dict(a='a', b='b')) @@ -128,4 +147,5 @@ c='foo')) == dict(a=['a1\naa1', 'a2'], b=['b\nbb', 'bbb'], c=['c'])) - + + Modified: FormEncode/trunk/tests/test_sqlschema.py =================================================================== --- FormEncode/trunk/tests/test_sqlschema.py 2006-12-01 07:04:20 UTC (rev 2105) +++ FormEncode/trunk/tests/test_sqlschema.py 2006-12-01 18:19:05 UTC (rev 2106) @@ -3,6 +3,22 @@ from formencode import validators from datetime import datetime, date +def setup_module(module): + """Disable i18n translation + """ + def notranslation(s): return s + import __builtin__ + __builtin__._ = notranslation + + + +def teardown_module(module): + """Remove translation function + """ + import __builtin__ + del __builtin__._ + + sqlhub.processConnection = connectionForURI('sqlite:/:memory:') class EventObject(SQLObject): ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ FormEncode-CVS mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/formencode-cvs
