Add normalize option to Decimal type

This commit is contained in:
Hong Minhee
2015-11-04 13:54:22 +09:00
parent 670680c052
commit 15bd7d30e0
3 changed files with 32 additions and 8 deletions

View File

@@ -23,6 +23,9 @@ Features
- Add `NoneOf` validator wich succeeds if the value is none of the choices.
- Add ``normalize`` option to ``Decimal``, stripping the rightmost
trailing zeros.
Bug Fixes
---------

View File

@@ -1305,24 +1305,27 @@ class Decimal(Number):
method of this class, the :attr:`colander.null` value will be
returned.
The Decimal constructor takes two optional arguments, ``quant`` and
``rounding``. If supplied, ``quant`` should be a string,
The Decimal constructor takes three optional arguments, ``quant``,
``rounding`` and ``normalize``. If supplied, ``quant`` should be a string,
(e.g. ``1.00``). If supplied, ``rounding`` should be one of the Python
``decimal`` module rounding options (e.g. ``decimal.ROUND_UP``,
``decimal.ROUND_DOWN``, etc). The serialized and deserialized result
will be quantized and rounded via
``result.quantize(decimal.Decimal(quant), rounding)``. ``rounding`` is
ignored if ``quant`` is not supplied.
ignored if ``quant`` is not supplied. If ``normalize`` is ``True``,
the serialized and deserialized result will be normalized by stripping
the rightmost trailing zeros.
The subnodes of the :class:`colander.SchemaNode` that wraps
this type are ignored.
"""
def __init__(self, quant=None, rounding=None):
def __init__(self, quant=None, rounding=None, normalize=False):
if quant is None:
self.quant = None
else:
self.quant = decimal.Decimal(quant)
self.rounding = rounding
self.normalize = normalize
def num(self, val):
result = decimal.Decimal(str(val))
@@ -1331,6 +1334,8 @@ class Decimal(Number):
result = result.quantize(self.quant)
else:
result = result.quantize(self.quant, self.rounding)
if self.normalize:
result = result.normalize()
return result
class Money(Decimal):
@@ -1346,8 +1351,7 @@ class Money(Decimal):
this type are ignored.
"""
def __init__(self):
self.quant = decimal.Decimal('.01')
self.rounding = decimal.ROUND_UP
super(Money, self).__init__(decimal.Decimal('.01'), decimal.ROUND_UP)
class Boolean(SchemaType):
""" A type representing a boolean object.

View File

@@ -1691,9 +1691,9 @@ class TestFloat(unittest.TestCase):
self.assertEqual(result, '1.0')
class TestDecimal(unittest.TestCase):
def _makeOne(self, quant=None, rounding=None):
def _makeOne(self, quant=None, rounding=None, normalize=False):
from colander import Decimal
return Decimal(quant, rounding)
return Decimal(quant, rounding, normalize)
def test_serialize_null(self):
import colander
@@ -1725,6 +1725,14 @@ class TestDecimal(unittest.TestCase):
result = typ.serialize(node, val)
self.assertEqual(result, '0.01')
def test_serialize_normalize(self):
from decimal import Decimal
val = Decimal('1.00')
node = DummySchemaNode(None)
typ = self._makeOne(normalize=True)
result = typ.serialize(node, val)
self.assertEqual(result, '1')
def test_deserialize_fails(self):
val = 'P'
node = DummySchemaNode(None)
@@ -1748,6 +1756,15 @@ class TestDecimal(unittest.TestCase):
result = typ.deserialize(node, val)
self.assertEqual(result, decimal.Decimal('1.01'))
def test_deserialize_with_normalize(self):
from decimal import Decimal
val = '1.00'
node = DummySchemaNode(None)
typ = self._makeOne(normalize=True)
result = typ.deserialize(node, val)
self.assertEqual(result, Decimal('1'))
self.assertEqual(str(result), '1')
def test_serialize_fails(self):
val = 'P'
node = DummySchemaNode(None)