- Add a Decimal type (decimal floating point).
This commit is contained in:
@@ -1,6 +1,11 @@
|
|||||||
Changes
|
Changes
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
Next release
|
||||||
|
------------
|
||||||
|
|
||||||
|
- Add a Decimal type (decimal floating point).
|
||||||
|
|
||||||
0.6.0 (2010-05-02)
|
0.6.0 (2010-05-02)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
import decimal
|
||||||
import itertools
|
import itertools
|
||||||
import iso8601
|
import iso8601
|
||||||
import pprint
|
import pprint
|
||||||
@@ -677,65 +678,58 @@ class String(object):
|
|||||||
|
|
||||||
Str = String
|
Str = String
|
||||||
|
|
||||||
class Integer(object):
|
class Number(object):
|
||||||
|
""" Abstract base class for float, int, decimal """
|
||||||
|
num = None
|
||||||
|
def deserialize(self, node, value):
|
||||||
|
try:
|
||||||
|
return self.num(value)
|
||||||
|
except Exception:
|
||||||
|
if value == '':
|
||||||
|
if node.required:
|
||||||
|
raise Invalid(node, _('Required'))
|
||||||
|
return node.default
|
||||||
|
raise Invalid(node,
|
||||||
|
_('"${val}" is not a number',
|
||||||
|
mapping={'val':value})
|
||||||
|
)
|
||||||
|
|
||||||
|
def serialize(self, node, value):
|
||||||
|
try:
|
||||||
|
return str(self.num(value))
|
||||||
|
except Exception:
|
||||||
|
raise Invalid(node,
|
||||||
|
_('"${val}" is not a number',
|
||||||
|
mapping={'val':value}),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Integer(Number):
|
||||||
""" A type representing an integer.
|
""" A type representing an integer.
|
||||||
|
|
||||||
The subnodes of the :class:`colander.SchemaNode` that wraps
|
The subnodes of the :class:`colander.SchemaNode` that wraps
|
||||||
this type are ignored.
|
this type are ignored.
|
||||||
"""
|
"""
|
||||||
def deserialize(self, node, value):
|
num = int
|
||||||
try:
|
|
||||||
return int(value)
|
|
||||||
except Exception:
|
|
||||||
if value == '':
|
|
||||||
if node.required:
|
|
||||||
raise Invalid(node, _('Required'))
|
|
||||||
return node.default
|
|
||||||
raise Invalid(node,
|
|
||||||
_('"${val}" is not a number',
|
|
||||||
mapping={'val':value})
|
|
||||||
)
|
|
||||||
|
|
||||||
def serialize(self, node, value):
|
|
||||||
try:
|
|
||||||
return str(int(value))
|
|
||||||
except Exception:
|
|
||||||
raise Invalid(node,
|
|
||||||
_('"${val}" is not a number',
|
|
||||||
mapping={'val':value}),
|
|
||||||
)
|
|
||||||
|
|
||||||
Int = Integer
|
Int = Integer
|
||||||
|
|
||||||
class Float(object):
|
class Float(Number):
|
||||||
""" A type representing a float.
|
""" A type representing a float.
|
||||||
|
|
||||||
The subnodes of the :class:`colander.SchemaNode` that wraps
|
The subnodes of the :class:`colander.SchemaNode` that wraps
|
||||||
this type are ignored.
|
this type are ignored.
|
||||||
"""
|
"""
|
||||||
def deserialize(self, node, value):
|
num = float
|
||||||
try:
|
|
||||||
return float(value)
|
|
||||||
except Exception:
|
|
||||||
if value == '':
|
|
||||||
if node.required:
|
|
||||||
raise Invalid(node, _('Required'))
|
|
||||||
return node.default
|
|
||||||
raise Invalid(node,
|
|
||||||
_('"${val}" is not a number',
|
|
||||||
mapping={'val':value})
|
|
||||||
)
|
|
||||||
|
|
||||||
def serialize(self, node, value):
|
class Decimal(Number):
|
||||||
try:
|
""" A type representing a decimal floating point. Deserialization
|
||||||
return str(float(value))
|
returns an instance of the Python ``decimal.Decimal`` type.
|
||||||
except Exception:
|
|
||||||
raise Invalid(node,
|
|
||||||
_('"${val}" is not a number',
|
|
||||||
mapping={'val':value}),
|
|
||||||
)
|
|
||||||
|
|
||||||
Int = Integer
|
The subnodes of the :class:`colander.SchemaNode` that wraps
|
||||||
|
this type are ignored.
|
||||||
|
"""
|
||||||
|
def num(self, val):
|
||||||
|
return decimal.Decimal(str(val))
|
||||||
|
|
||||||
class Boolean(object):
|
class Boolean(object):
|
||||||
""" A type representing a boolean object.
|
""" A type representing a boolean object.
|
||||||
|
|||||||
@@ -821,6 +821,54 @@ class TestFloat(unittest.TestCase):
|
|||||||
result = typ.serialize(node, val)
|
result = typ.serialize(node, val)
|
||||||
self.assertEqual(result, '1.0')
|
self.assertEqual(result, '1.0')
|
||||||
|
|
||||||
|
class TestDecimal(unittest.TestCase):
|
||||||
|
def _makeOne(self):
|
||||||
|
from colander import Decimal
|
||||||
|
return Decimal()
|
||||||
|
|
||||||
|
def test_serialize_emptystring_required(self):
|
||||||
|
val = ''
|
||||||
|
node = DummySchemaNode(None)
|
||||||
|
typ = self._makeOne()
|
||||||
|
e = invalid_exc(typ.deserialize, node, val)
|
||||||
|
self.assertEqual(e.msg, 'Required')
|
||||||
|
|
||||||
|
def test_serialize_emptystring_notrequired(self):
|
||||||
|
val = ''
|
||||||
|
node = DummySchemaNode(None, default='default')
|
||||||
|
typ = self._makeOne()
|
||||||
|
result = typ.deserialize(node, val)
|
||||||
|
self.assertEqual(result, 'default')
|
||||||
|
|
||||||
|
def test_deserialize_fails(self):
|
||||||
|
val = 'P'
|
||||||
|
node = DummySchemaNode(None)
|
||||||
|
typ = self._makeOne()
|
||||||
|
e = invalid_exc(typ.deserialize, node, val)
|
||||||
|
self.failUnless(e.msg)
|
||||||
|
|
||||||
|
def test_deserialize_ok(self):
|
||||||
|
import decimal
|
||||||
|
val = '1.0'
|
||||||
|
node = DummySchemaNode(None)
|
||||||
|
typ = self._makeOne()
|
||||||
|
result = typ.deserialize(node, val)
|
||||||
|
self.assertEqual(result, decimal.Decimal('1.0'))
|
||||||
|
|
||||||
|
def test_serialize_fails(self):
|
||||||
|
val = 'P'
|
||||||
|
node = DummySchemaNode(None)
|
||||||
|
typ = self._makeOne()
|
||||||
|
e = invalid_exc(typ.serialize, node, val)
|
||||||
|
self.failUnless(e.msg)
|
||||||
|
|
||||||
|
def test_serialize_ok(self):
|
||||||
|
val = 1.0
|
||||||
|
node = DummySchemaNode(None)
|
||||||
|
typ = self._makeOne()
|
||||||
|
result = typ.serialize(node, val)
|
||||||
|
self.assertEqual(result, '1.0')
|
||||||
|
|
||||||
class TestBoolean(unittest.TestCase):
|
class TestBoolean(unittest.TestCase):
|
||||||
def _makeOne(self):
|
def _makeOne(self):
|
||||||
from colander import Boolean
|
from colander import Boolean
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ Types
|
|||||||
|
|
||||||
.. autoclass:: Float
|
.. autoclass:: Float
|
||||||
|
|
||||||
|
.. autoclass:: Decimal
|
||||||
|
|
||||||
.. autoclass:: Boolean
|
.. autoclass:: Boolean
|
||||||
|
|
||||||
.. autoclass:: Bool
|
.. autoclass:: Bool
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ of objects, including:
|
|||||||
|
|
||||||
- A float.
|
- A float.
|
||||||
|
|
||||||
|
- A decimal float.
|
||||||
|
|
||||||
- A boolean.
|
- A boolean.
|
||||||
|
|
||||||
- An importable Python object (to a dotted Python object path).
|
- An importable Python object (to a dotted Python object path).
|
||||||
|
|||||||
Reference in New Issue
Block a user