- Make it possible to use `colander.null as a missing` argument

to ``colander.SchemaNode`` for roundtripping purposes.

- Make it possible to pickle ``colander.null``.
This commit is contained in:
Chris McDonough
2010-06-12 18:03:00 +00:00
parent 206cc49e11
commit 165478b675
4 changed files with 33 additions and 13 deletions

View File

@@ -1,6 +1,17 @@
Changes Changes
======= =======
Next Release
------------
Bug Fixes
~~~~~~~~~
- Make it possible to use ``colander.null`` as a ``missing`` argument
to ``colander.SchemaNode`` for roundtripping purposes.
- Make it possible to pickle ``colander.null``.
0.7.0 0.7.0
----- -----

View File

@@ -8,14 +8,16 @@ import translationstring
_ = translationstring.TranslationStringFactory('colander') _ = translationstring.TranslationStringFactory('colander')
class null(object): _marker = object()
class _null(object):
def __nonzero__(self): def __nonzero__(self):
return False return False
def __repr__(self): def __repr__(self):
return '<colander.null>' return '<colander.null>'
null = null() null = _null()
def interpolate(msgs): def interpolate(msgs):
for s in msgs: for s in msgs:
@@ -1169,7 +1171,7 @@ class SchemaNode(object):
self.typ = typ self.typ = typ
self.validator = kw.pop('validator', None) self.validator = kw.pop('validator', None)
self.default = kw.pop('default', null) self.default = kw.pop('default', null)
self.missing = kw.pop('missing', null) self.missing = kw.pop('missing', _marker)
self.name = kw.pop('name', '') self.name = kw.pop('name', '')
self.title = kw.pop('title', self.name.capitalize()) self.title = kw.pop('title', self.name.capitalize())
self.description = kw.pop('description', '') self.description = kw.pop('description', '')
@@ -1194,7 +1196,7 @@ class SchemaNode(object):
A return value of ``True`` implies that a ``missing`` value A return value of ``True`` implies that a ``missing`` value
wasn't specified for this node. A return value of ``False`` wasn't specified for this node. A return value of ``False``
implies that a ``missing`` value was specified for this node.""" implies that a ``missing`` value was specified for this node."""
return self.missing is null return self.missing is _marker
def serialize(self, appstruct=null): def serialize(self, appstruct=null):
""" Serialize the :term:`appstruct` to a :term:`cstruct` based """ Serialize the :term:`appstruct` to a :term:`cstruct` based
@@ -1208,7 +1210,6 @@ class SchemaNode(object):
If an ``appstruct`` argument is not explicitly provided, it If an ``appstruct`` argument is not explicitly provided, it
defaults to :attr:`colander.null`. defaults to :attr:`colander.null`.
""" """
if appstruct is null: if appstruct is null:
appstruct = self.default appstruct = self.default
cstruct = self.typ.serialize(self, appstruct) cstruct = self.typ.serialize(self, appstruct)
@@ -1235,7 +1236,7 @@ class SchemaNode(object):
""" """
if cstruct is null: if cstruct is null:
appstruct = self.missing appstruct = self.missing
if appstruct is null: if appstruct is _marker:
raise Invalid(self, _('Required')) raise Invalid(self, _('Required'))
# We never deserialize or validate the missing value # We never deserialize or validate the missing value
return appstruct return appstruct

View File

@@ -1340,6 +1340,13 @@ class TestSchemaNode(unittest.TestCase):
node.missing = 'abc' node.missing = 'abc'
self.assertEqual(node.deserialize(), 'abc') self.assertEqual(node.deserialize(), 'abc')
def test_deserialize_null_can_be_used_as_missing(self):
from colander import null
typ = DummyType()
node = self._makeOne(typ)
node.missing = null
self.assertEqual(node.deserialize(null), null)
def test_serialize(self): def test_serialize(self):
typ = DummyType() typ = DummyType()
node = self._makeOne(typ) node = self._makeOne(typ)

View File

@@ -255,7 +255,8 @@ an ``age`` key of :attr:`colander.null`, the ``missing`` value of
.. note:: Note that ``None`` can be used for the ``missing`` schema .. note:: Note that ``None`` can be used for the ``missing`` schema
node value as required, as in the above example. It's no different node value as required, as in the above example. It's no different
than any other value used as ``missing``. than any other value used as ``missing``. or ``colander.nuil`` can
also be used as the ``missing`` value if that is helpful.
The :attr:`colander.null` value is also the default, so it needn't be The :attr:`colander.null` value is also the default, so it needn't be
specified in the cstruct. Therefore, the ``deserialized`` value of specified in the cstruct. Therefore, the ``deserialized`` value of
@@ -287,12 +288,12 @@ Value Missing Result
===================== ===================== =========================== ===================== ===================== ===========================
colander.null <missing> Invalid exception raised colander.null <missing> Invalid exception raised
<missing> <missing> Invalid exception raised <missing> <missing> Invalid exception raised
colander.null colander.null Invalid exception raised colander.null value value used
colander.null value value deserialized <missing> value value used
<missing> value value deserialized <missing> colander.null colander.null used
value <missing> value deserialized value <missing> value used
value colander.null value deserialized value colander.null value used
value_a value_b value_a deserialized value_a value_b value_a used
===================== ===================== =========================== ===================== ===================== ===========================
.. note:: ``<missing>`` in the above table represents the circumstance .. note:: ``<missing>`` in the above table represents the circumstance