+from weakref import WeakValueDictionary
+
+def localeconv():
+ "Manually install en_US for systems that don't have it."
+ d = {'currency_symbol': '$',
+ 'decimal_point': '.',
+ 'frac_digits': 2,
+ 'grouping': [3, 3, 0],
+ 'int_curr_symbol': 'USD ',
+ 'int_frac_digits': 2,
+ 'mon_decimal_point': '.',
+ 'mon_grouping': [3, 3, 0],
+ 'mon_thousands_sep': ',',
+ 'n_cs_precedes': 1,
+ 'n_sep_by_space': 0,
+ 'n_sign_posn': 1,
+ 'negative_sign': '-',
+ 'p_cs_precedes': 1,
+ 'p_sep_by_space': 0,
+ 'p_sign_posn': 1,
+ 'positive_sign': '',
+ 'thousands_sep': ','}
+ return d
+locale.localeconv = localeconv
+
+
+class CurrencyValidator(validators.FancyValidator):
+ "A validator to convert to Currency objects."
+ messages = {'amount': "Please enter a valid currency amount",
+ 'precision': "Only two digits after the decimal, please",
+ 'nonzero': "Please enter a non-zero amount"}
+
+ def _to_python(self, value, state):
+ try:
+ dec = Decimal(value)
+ except InvalidOperation:
+ raise Invalid(self.message('amount', state),
+ value, state)
+ else:
+ ret = dec.quantize(Decimal('1.00'))
+ if ret == 0:
+ raise Invalid(self.message('nonzero', state),
+ value, state)
+ elif ret != dec:
+ raise Invalid(self.message('precision', state),
+ value, state)
+ else:
+ return Currency(int(ret * 100))
+
+