Commits

Adam Lowry committed df63312

Fixes #6: Dict.set shouldn't fail if passed a non-dictlike

Comments (0)

Files changed (2)

flatland/schema/containers.py

     def set(self, value, policy=None):
         """TODO: doc set()"""
         self.raw = value
-        pairs = to_pairs(value)
+        try:
+            pairs = to_pairs(value)
+        except (TypeError, ValueError):
+            return False
         self._reset()
 
         if policy is not None:
         fields = self.field_schema_mapping
         seen = set()
         converted = True
-        for key, value in pairs:
-            if key not in fields:
-                if policy != 'duck':
-                    raise KeyError(
-                        'Dict %r schema does not allow key %r' % (
-                            self.name, key))
-                continue
-            if dict.__contains__(self, key):
-                converted &= self[key].set(value)
-            else:
-                self[key] = el = fields[key]()
-                converted &= el.set(value)
-            seen.add(key)
+        try:
+            for key, value in pairs:
+                if key not in fields:
+                    if policy != 'duck':
+                        raise KeyError(
+                            'Dict %r schema does not allow key %r' % (
+                                self.name, key))
+                    continue
+                if dict.__contains__(self, key):
+                    converted &= self[key].set(value)
+                else:
+                    self[key] = el = fields[key]()
+                    converted &= el.set(value)
+                seen.add(key)
+        except (TypeError, ValueError):
+            return False
 
         if policy == 'strict':
             required = set(fields.iterkeys())

tests/schema/test_dicts.py

     for el in els:
         got = sorted(el.flatten())
         assert wanted == got
+
+
+def test_set_with_non_dictlike_data():
+    schema = Dict.of(Integer.named(u'x'), Integer.named(u'y'))
+    for bad in (123, 'bar', ['foo']):
+        el = schema()
+        el.set(bad)