colander icon indicating copy to clipboard operation
colander copied to clipboard

Handle the empty MappingSchema with require=False

Open btall opened this issue 7 years ago • 0 comments

In the case where a field is a empty MappingSchema, require=False doesn't works.

Example:

  • Doesn't works: https://gist.github.com/btall/e07bc025021981779d3fe3909466006f

Workaround

--- schema.py	2017-05-26 16:59:00.979227881 +0200
+++ schema_workaround.py	2017-05-26 16:58:43.656278244 +0200
@@ -5,6 +5,8 @@
 import sys
 import colander
 
+from contextlib import contextmanager
+
 person_1 = {
     'firstname': 'foo',
     'lastname': 'bar',
@@ -33,6 +35,29 @@
     firstname = colander.SchemaNode(colander.String())
     address = Address(missing=colander.null)
 
+    @contextmanager
+    def _handle_empty_address(self, cstruct):
+        """
+        Skip it, just  the time to validation
+        And reinject it to the end of validating.
+        """
+        try:
+            address = cstruct['address']
+            is_empty = all((address[field] == colander.null) for field in address)
+            if is_empty:
+                cstruct['address'] = colander.null
+
+            yield cstruct
+
+        finally:
+            cstruct['address'] = address
+
+    def deserialize(self, cstruct=colander.null):
+        with self._handle_empty_address(cstruct) as cstruct:
+            cstruct = super(Person, self).deserialize(cstruct)
+
+        return cstruct
+
 
 def main():
     validator = Person()

Maybe that a sexy solution exists, but I don't found it in the examples of the documentation. 😄

btall avatar May 26 '17 14:05 btall